59 #include "crc16ccitt_false.h"
63 #define PARSE_ASSERT(assertion,info) sick_scan_xd::ResultPortParser::parseAssert((assertion),(#assertion),info,__FILE__,__LINE__)
81 std::stringstream exc_info;
82 exc_info <<
"sick_scan_xd::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");
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);
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_xd::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);
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]);
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);