59 #include "crc16ccitt_false.h" 63 #define PARSE_ASSERT(assertion,info) sick_scan::ResultPortParser::parseAssert((assertion),(#assertion),info,__FILE__,__LINE__) 81 std::stringstream exc_info;
82 exc_info <<
"sick_scan::ResultPortParser: assertion \"" << assertion_msg <<
"\" failed, " << info <<
" (" << file <<
":" << line;
83 throw std::invalid_argument(exc_info.str());
99 PARSE_ASSERT(binary_data.size() >= start_byte +
sizeof(value), std::string(
"ResultPortParser::copyBytesToValue(): invalid size (") + info +
")");
103 for (
int n = (
int)
sizeof(value) - 1; n >= 0; n--)
105 value = ((value << 8) | (binary_data[start_byte + n]));
110 for (
size_t n = 0; n <
sizeof(value); n++)
112 value = ((value << 8) | (binary_data[start_byte + n]));
115 return sizeof(value);
129 PARSE_ASSERT(binary_data.size() >= start_byte + dst_array.size(), std::string(
"ResultPortParser::copyBytesToArray(): invalid size (") + info +
")");
130 for (
size_t n = 0; n < dst_array.size(); n++)
132 dst_array[n] = binary_data[start_byte + n];
134 return dst_array.size();
161 PARSE_ASSERT(binary_data_with_trailer ==
false || binary_data.size() >= 2, std::string(
"ResultPortParser::computeChecksum(): invalid input, binary_data.size() = ") + std::to_string(binary_data.size()));
162 size_t len = binary_data_with_trailer ? (binary_data.size() - 2) : (binary_data.size());
166 PARSE_ASSERT(checksum1 == checksum2, std::string(
"ResultPortParser::computeChecksum(): ambigous checksums ") + std::to_string(checksum1) +
"," + std::to_string(checksum2));
167 PARSE_ASSERT(checksum1 == checksum3, std::string(
"ResultPortParser::computeChecksum(): ambigous checksums ") + std::to_string(checksum1) +
"," + std::to_string(checksum3));
168 return (uint16_t)(checksum1 & 0xFFFF);
178 return (payload_type == 0x06c2);
191 size_t bytes_decoded = 0;
194 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_header.magicword,
"Header.MagicWord");
195 PARSE_ASSERT(telegram_header.magicword == 0x5349434B, std::string(
"ResultPortParser::decodeResultPortHeader(): invalid Header.MagicWord ") + std::to_string(telegram_header.magicword));
198 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_header.length,
"Header.Length");
199 PARSE_ASSERT(telegram_header.length == 106, std::string(
"ResultPortParser::decodeResultPortHeader(): invalid Header.Length ") + std::to_string(telegram_header.length));
202 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_header.payloadtype,
"Header.PayloadType");
203 PARSE_ASSERT(telegram_header.payloadtype == 0x06c2 || telegram_header.payloadtype == 0x0642, std::string(
"ResultPortParser::decodeResultPortHeader(): invalid PayloadType ") + std::to_string(telegram_header.payloadtype));
208 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_header.payloadversion,
"Header.PayloadVersion");
211 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_header.ordernumber,
"Header.OrderNumber");
214 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_header.serialnumber,
"Header.SerialNumber");
217 telegram_header.fw_version = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
218 bytes_decoded +=
copyBytesToArray(binary_data, start_byte + bytes_decoded, telegram_header.fw_version,
"Header.FW_Version");
221 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_header.telegramcounter,
"Header.TelegramCounter");
224 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_header.systemtime,
"Header.SystemTime");
226 PARSE_ASSERT(bytes_decoded == 52, std::string(
"ResultPortParser::decodeResultPortHeader(): ") + std::to_string(bytes_decoded) +
" bytes decoded, expected 52 byte");
227 return bytes_decoded;
240 size_t bytes_decoded = 0;
268 PARSE_ASSERT(telegram_payload.quality >= 0 && telegram_payload.quality <= 100, std::string(
"ResultPortParser::decodeResultPortPayload(): invalid Payload.Quality ") + std::to_string(telegram_payload.quality));
272 PARSE_ASSERT(telegram_payload.outliersratio >= 0 && telegram_payload.outliersratio <= 100, std::string(
"ResultPortParser::decodeResultPortPayload(): invalid Payload.OutliersRatio ") + std::to_string(telegram_payload.outliersratio));
286 PARSE_ASSERT(bytes_decoded == 52, std::string(
"ResultPortParser::decodeResultPortPayload(): ") + std::to_string(bytes_decoded) +
" bytes decoded, expected 52 byte");
287 return bytes_decoded;
300 size_t bytes_decoded = 0;
303 bytes_decoded +=
copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_trailer.checksum,
"Payload.Checksum");
305 PARSE_ASSERT(bytes_decoded == 2, std::string(
"ResultPortParser::decodeResultPortTrailer(): ") + std::to_string(bytes_decoded) +
" bytes decoded, expected 2 byte");
306 return bytes_decoded;
318 size_t bytes_decoded = 0;
319 PARSE_ASSERT(binary_data.size() >= 106, std::string(
"ResultPortParser::decode(): ") + std::to_string(binary_data.size()) +
" byte binary data, expected 106 byte result port telegram");
331 PARSE_ASSERT(bytes_decoded ==
m_result_port_telegram.telegram_header.length, std::string(
"ResultPortParser::decode(): ") + std::to_string(bytes_decoded) +
" bytes decoded, expected " + std::to_string(
m_result_port_telegram.telegram_header.length) +
" byte (telegram_header.Length))");
341 catch(
const std::invalid_argument & exc)
343 ROS_ERROR_STREAM(
"## ERROR in sick_scan::ResultPortParser::decode(): exception " << exc.what());
358 for (
size_t n = 0; n <
sizeof(value); n++)
360 binary_data.push_back(value & 0xFF);
361 value = (value >> 8);
366 for (
int n =
sizeof(value) - 1; n >= 0; n--)
368 binary_data.push_back((value >> (8*n)) & 0xFF);
386 for (
size_t n = 0; n < telegram_header.fw_version.size(); n++)
387 binary_data.push_back(telegram_header.fw_version[n]);
431 std::vector<uint8_t> binary_data;
432 binary_data.reserve(106);
size_t copyBytesToValue(const std::vector< uint8_t > &binary_data, size_t start_byte, T &value, const std::string &info="", bool little_endian=false)
sick_scan::SickLocResultPortTelegramMsg m_result_port_telegram
the result port telegram decoded from binary data
std::string m_publish_frame_id
frame_id of published ros messages (type SickLocResultPortTelegramMsg)
void encodePushValue(T value, std::vector< uint8_t > &binary_data, bool little_endian=false)
virtual size_t decodeResultPortTrailer(const std::vector< uint8_t > &binary_data, size_t start_byte, sick_scan::SickLocResultPortCrcMsg &telegram_trailer)
size_t copyBytesToArray(const std::vector< uint8_t > &binary_data, size_t start_byte, std::vector< T > &dst_array, const std::string &info="")
#define PARSE_ASSERT(assertion, info)
virtual void encodeResultPortHeader(const sick_scan::SickLocResultPortHeaderMsg &telegram_header, std::vector< uint8_t > &binary_data)
unsigned crc16ccitt_false_bit(unsigned crc, void const *mem, size_t len)
virtual size_t decodeResultPortHeader(const std::vector< uint8_t > &binary_data, size_t start_byte, sick_scan::SickLocResultPortHeaderMsg &telegram_header)
virtual void encodeResultPortTrailer(uint16_t checksum, std::vector< uint8_t > &binary_data)
virtual uint16_t computeChecksum(const std::vector< uint8_t > &binary_data, bool binary_data_with_trailer=true)
virtual bool isLittleEndianPayload(uint16_t payload_type)
unsigned crc16ccitt_false_word(unsigned crc, void const *mem, size_t len)
virtual void encodeResultPortPayload(const sick_scan::SickLocResultPortPayloadMsg &telegram_payload, std::vector< uint8_t > &binary_data)
unsigned crc16ccitt_false_byte(unsigned crc, void const *mem, size_t len)
static void parseAssert(bool assertion, const std::string &assertion_msg, const std::string &info, const std::string &file, int line)
ResultPortParser(const std::string &frame_id="")
bool m_little_endian_payload
true if payload type is 0x06c2 (little endian), default: false (payload encoded in big endian format)...
virtual size_t decodeResultPortPayload(const std::vector< uint8_t > &binary_data, size_t start_byte, sick_scan::SickLocResultPortPayloadMsg &telegram_payload)
virtual std::vector< uint8_t > encode(void)
virtual bool decode(const std::vector< uint8_t > &binary_data)
#define ROS_ERROR_STREAM(args)