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));
204 m_little_endian_payload = isLittleEndianPayload(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;
243 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.errorcode,
"Payload.ErrorCode", m_little_endian_payload);
246 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.scancounter,
"Payload.ScanCounter", m_little_endian_payload);
249 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.timestamp,
"Payload.Timestamp", m_little_endian_payload);
252 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.posex,
"Payload.PoseX", m_little_endian_payload);
255 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.posey,
"Payload.PoseY", m_little_endian_payload);
258 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.poseyaw,
"Payload.PoseYaw", m_little_endian_payload);
261 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.reserved1,
"Payload.Reserved1", m_little_endian_payload);
264 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.reserved2,
"Payload.Reserved2", m_little_endian_payload);
267 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.quality,
"Payload.Quality", m_little_endian_payload);
268 PARSE_ASSERT(telegram_payload.quality >= 0 && telegram_payload.quality <= 100, std::string(
"ResultPortParser::decodeResultPortPayload(): invalid Payload.Quality ") + std::to_string(telegram_payload.quality));
271 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.outliersratio,
"Payload.OutliersRatio", m_little_endian_payload);
272 PARSE_ASSERT(telegram_payload.outliersratio >= 0 && telegram_payload.outliersratio <= 100, std::string(
"ResultPortParser::decodeResultPortPayload(): invalid Payload.OutliersRatio ") + std::to_string(telegram_payload.outliersratio));
275 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.covariancex,
"Payload.CovarianceX", m_little_endian_payload);
278 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.covariancey,
"Payload.", m_little_endian_payload);
281 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.covarianceyaw,
"Payload.CovarianceYaw", m_little_endian_payload);
284 bytes_decoded += copyBytesToValue(binary_data, start_byte + bytes_decoded, telegram_payload.reserved3,
"Payload.Reserved3", m_little_endian_payload);
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");
320 m_result_port_telegram.header.stamp =
ROS::now();
321 m_result_port_telegram.header.frame_id = m_publish_frame_id;
324 bytes_decoded += decodeResultPortHeader(binary_data, bytes_decoded, m_result_port_telegram.telegram_header);
327 bytes_decoded += decodeResultPortPayload(binary_data, bytes_decoded, m_result_port_telegram.telegram_payload);
330 bytes_decoded += decodeResultPortTrailer(binary_data, bytes_decoded, m_result_port_telegram.telegram_trailer);
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))");
336 uint16_t checksum = computeChecksum(binary_data);
337 PARSE_ASSERT(checksum == m_result_port_telegram.telegram_trailer.checksum, std::string(
"ResultPortParser::decode(): invalid checksum ") + std::to_string(m_result_port_telegram.telegram_trailer.checksum) +
" decoded, expected checksum " + std::to_string(checksum));
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);
380 encodePushValue(telegram_header.magicword, binary_data);
381 encodePushValue(telegram_header.length, binary_data);
382 encodePushValue(telegram_header.payloadtype, binary_data);
383 encodePushValue(telegram_header.payloadversion, binary_data);
384 encodePushValue(telegram_header.ordernumber, binary_data);
385 encodePushValue(telegram_header.serialnumber, binary_data);
386 for (
size_t n = 0; n < telegram_header.fw_version.size(); n++)
387 binary_data.push_back(telegram_header.fw_version[n]);
388 encodePushValue(telegram_header.telegramcounter, binary_data);
389 encodePushValue(telegram_header.systemtime, binary_data);
399 encodePushValue(telegram_payload.errorcode, binary_data, m_little_endian_payload);
400 encodePushValue(telegram_payload.scancounter, binary_data, m_little_endian_payload);
401 encodePushValue(telegram_payload.timestamp, binary_data, m_little_endian_payload);
402 encodePushValue(telegram_payload.posex, binary_data, m_little_endian_payload);
403 encodePushValue(telegram_payload.posey, binary_data, m_little_endian_payload);
404 encodePushValue(telegram_payload.poseyaw, binary_data, m_little_endian_payload);
405 encodePushValue(telegram_payload.reserved1, binary_data, m_little_endian_payload);
406 encodePushValue(telegram_payload.reserved2, binary_data, m_little_endian_payload);
407 encodePushValue(telegram_payload.quality, binary_data, m_little_endian_payload);
408 encodePushValue(telegram_payload.outliersratio, binary_data, m_little_endian_payload);
409 encodePushValue(telegram_payload.covariancex, binary_data, m_little_endian_payload);
410 encodePushValue(telegram_payload.covariancey, binary_data, m_little_endian_payload);
411 encodePushValue(telegram_payload.covarianceyaw, binary_data, m_little_endian_payload);
412 encodePushValue(telegram_payload.reserved3, binary_data, m_little_endian_payload);
422 encodePushValue(checksum, binary_data);
431 std::vector<uint8_t> binary_data;
432 binary_data.reserve(106);
433 m_little_endian_payload = isLittleEndianPayload(m_result_port_telegram.telegram_header.payloadtype);
434 encodeResultPortHeader(m_result_port_telegram.telegram_header, binary_data);
435 encodeResultPortPayload(m_result_port_telegram.telegram_payload, binary_data);
436 uint16_t checksum = computeChecksum(binary_data,
false);
437 m_result_port_telegram.telegram_trailer.checksum = checksum;
438 encodeResultPortTrailer(checksum, binary_data);