68 template<
typename T>
static void appendToBuffer(std::vector<uint8_t>& data_buffer,
const T& value)
71 swap_endian((
unsigned char *) &dst_value,
sizeof(dst_value));
72 size_t pos = data_buffer.size();
73 for (
size_t n = 0; n <
sizeof(dst_value); n++)
74 data_buffer.push_back(0);
75 memcpy(&data_buffer[pos], &dst_value,
sizeof(dst_value));
78 template<
typename T>
static bool readFromBuffer(
const uint8_t* receiveBuffer,
int& pos,
int receiveBufferLength, T& value,
const char* file,
int line)
80 if(pos +
sizeof(value) <= receiveBufferLength)
82 memcpy(&value, receiveBuffer + pos,
sizeof(value));
83 swap_endian((
unsigned char *) &value,
sizeof(value));
89 ROS_WARN_STREAM(
"readFromBuffer(): read pos = " << pos <<
" + sizeof(value) = " <<
sizeof(value) <<
" exceeds receiveBufferLength = " << receiveBufferLength <<
" (" << file <<
":" <<
line <<
")");
98 uint32_t stx = 0x02020202;
99 uint32_t payload_size = 0;
102 std::string sopas_cmd =
"sAN mNPOSGetData ";
103 std::copy(sopas_cmd.begin(), sopas_cmd.end(), std::back_inserter(data_buffer));
162 for (
int channel = 0; channel < navdata.
scanDataValid; channel++)
164 std::copy(navdata.
scanData[channel].contentType.begin(), navdata.
scanData[channel].contentType.end(), std::back_inserter(data_buffer));
171 for(
int data_cnt = 0; data_cnt < navdata.
scanData[channel].numData; data_cnt++)
192 payload_size = data_buffer.size() - 8;
193 std::vector<uint8_t> payload_buffer;
195 memcpy(&data_buffer[4], &payload_buffer[0], payload_buffer.size());
196 data_buffer.push_back(0);
203 std::vector<uint8_t> data_buffer_src, data_buffer_dst;
204 data_buffer_src.reserve(32*1024);
205 data_buffer_dst.reserve(32*1024);
209 navdata_src.
wait = 1;
210 navdata_src.
mask = 2;
249 navdata_src.
scanData[0].contentType =
"DIST1";
250 navdata_src.
scanData[0].scaleFactor = 1;
251 navdata_src.
scanData[0].scaleOffset = 0;
252 navdata_src.
scanData[0].startAngle = 0;
253 navdata_src.
scanData[0].angleRes = 250;
254 navdata_src.
scanData[0].timestampStart = 123456789;
255 navdata_src.
scanData[0].numData = 1024;
257 for(
int data_cnt = 0; data_cnt < navdata_src.
scanData[0].numData; data_cnt++)
258 navdata_src.
scanData[0].data[data_cnt] = data_cnt;
259 navdata_src.
scanData[1].contentType =
"ANGL1";
260 navdata_src.
scanData[1].scaleFactor = 1;
261 navdata_src.
scanData[1].scaleOffset = 0;
262 navdata_src.
scanData[1].startAngle = 0;
263 navdata_src.
scanData[1].angleRes = 250;
264 navdata_src.
scanData[1].timestampStart = 123456789;
265 navdata_src.
scanData[1].numData = 1024;
267 for(
int data_cnt = 0; data_cnt < navdata_src.
scanData[1].numData; data_cnt++)
268 navdata_src.
scanData[1].data[data_cnt] = data_cnt * navdata_src.
scanData[1].angleRes;
285 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryUnittest(): parseNAV350BinaryPositionData failed");
291 if (data_buffer_src.size() != data_buffer_dst.size() || memcmp(data_buffer_src.data(), data_buffer_dst.data(), data_buffer_src.size()) != 0)
293 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryUnittest(): parseNAV350BinaryPositionData failed");
296 ROS_DEBUG_STREAM(
"parseNAV350BinaryUnittest() passed (" << data_buffer_src.size() <<
" byte datagram)");
307 for(
int reflectorCnt = 0; reflectorCnt < landmarkData.
numReflectors; reflectorCnt++)
309 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].cartesianDataValid, __FILE__, __LINE__);
310 if (landmarkData.
reflectors[reflectorCnt].cartesianDataValid > 0)
312 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].cartesianData.x, __FILE__, __LINE__);
313 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].cartesianData.y, __FILE__, __LINE__);
315 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].polarDataValid, __FILE__, __LINE__);
316 if (landmarkData.
reflectors[reflectorCnt].polarDataValid > 0)
318 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].polarData.dist, __FILE__, __LINE__);
319 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].polarData.phi, __FILE__, __LINE__);
321 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorDataValid, __FILE__, __LINE__);
322 if (landmarkData.
reflectors[reflectorCnt].optReflectorDataValid > 0)
324 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.localID, __FILE__, __LINE__);
325 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.globalID, __FILE__, __LINE__);
326 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.type, __FILE__, __LINE__);
327 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.subType, __FILE__, __LINE__);
328 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.quality, __FILE__, __LINE__);
329 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.timestamp, __FILE__, __LINE__);
330 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.size, __FILE__, __LINE__);
331 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.hitCount, __FILE__, __LINE__);
332 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.meanEcho, __FILE__, __LINE__);
333 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.startIndex, __FILE__, __LINE__);
334 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
reflectors[reflectorCnt].optReflectorData.endIndex, __FILE__, __LINE__);
350 if (receiveBuffer == 0 || receiveBufferLength < 17 + 9 || memcmp(receiveBuffer,
"\x02\x02\x02\x02", 4) != 0)
352 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryPositionData(): invalid telegram (" << __FILE__ <<
":" << __LINE__ <<
")");
357 uint32_t payload_size = 0;
358 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, payload_size, __FILE__, __LINE__);
359 if (!success || (
int)(payload_size) + 9 > receiveBufferLength)
361 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryPositionData(): invalid telegram size (" << __FILE__ <<
":" << __LINE__ <<
")");
366 if (strncmp((
const char*)receiveBuffer + receivePos,
"sAN mNPOSGetData ", 17) != 0)
368 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryPositionData(): telegram does not start with \"sAN mNPOSGetData \"");
374 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
version, __FILE__, __LINE__);
375 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
errorCode, __FILE__, __LINE__);
376 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
wait, __FILE__, __LINE__);
377 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
mask, __FILE__, __LINE__);
381 std::map<uint8_t, std::string> errorCodeStr = { {0,
"no error"}, {1,
"wrong operating mode"}, {2,
"asynchrony Method terminated"}, {3,
"invalid data"}, {4,
"no position available"}, {5,
"timeout"}, {6,
"method already active"}, {7,
"general error"} };
382 ROS_WARN_STREAM(
"## WARNING parseNAV350BinaryPositionData(): NAV350 mNPOSGetData errorCode = " << (
int)navdata.
errorCode <<
" (\"" << errorCodeStr[navdata.
errorCode] <<
"\")");
388 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
poseData.
x, __FILE__, __LINE__);
389 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
poseData.
y, __FILE__, __LINE__);
413 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryPositionData(): \"ScanData\" = " << (
int)navdata.
scanDataValid <<
", max. 2 channel DIST1 and ANGL1 expected");
415 for (
int channel = 0; channel < navdata.
scanDataValid; channel++)
417 if (strncmp((
const char*)receiveBuffer + receivePos,
"DIST1", 5) != 0 && strncmp((
const char*)receiveBuffer + receivePos,
"ANGL1", 5) != 0)
418 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryPositionData(): \"DIST1\" resp. \"ANGL1\" not found");
419 navdata.
scanData[channel].contentType = std::string((
const char*)receiveBuffer + receivePos, 5);
421 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
scanData[channel].scaleFactor, __FILE__, __LINE__);
422 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
scanData[channel].scaleOffset, __FILE__, __LINE__);
423 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
scanData[channel].startAngle, __FILE__, __LINE__);
424 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
scanData[channel].angleRes, __FILE__, __LINE__);
425 if (std::abs(navdata.
scanData[channel].scaleFactor - 1.0f) > FLT_EPSILON || std::abs(navdata.
scanData[channel].scaleOffset - 0.0f) > FLT_EPSILON || navdata.
scanData[channel].startAngle != 0 || navdata.
scanData[channel].angleRes != 250)
427 ROS_WARN_STREAM(
"## WARNING parseNAV350BinaryPositionData(): unexpected scan data parameter: scaleFactor=" << navdata.
scanData[channel].scaleFactor <<
", scaleOffset=" << navdata.
scanData[channel].scaleOffset
428 <<
", startAngle=" << navdata.
scanData[channel].startAngle <<
", angleRes=" << navdata.
scanData[channel].angleRes);
430 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
scanData[channel].timestampStart, __FILE__, __LINE__);
431 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
scanData[channel].numData, __FILE__, __LINE__);
432 navdata.
scanData[channel].data = std::vector<uint32_t>(navdata.
scanData[channel].numData);
433 for(
int data_cnt = 0; data_cnt < navdata.
scanData[channel].numData; data_cnt++)
435 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, navdata.
scanData[channel].data[data_cnt], __FILE__, __LINE__);
443 if (strncmp((
const char*)receiveBuffer + receivePos,
"RSSI1", 5) != 0)
444 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryPositionData(): \"RSSI1\" not found");
461 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryPositionData(): parsing error");
471 if (receiveBuffer == 0 || receiveBufferLength < 19 + 9 || memcmp(receiveBuffer,
"\x02\x02\x02\x02", 4) != 0)
473 ROS_ERROR_STREAM(
"## ERROR parseNAV350LandmarkDataDoMappingResponse(): invalid telegram (" << __FILE__ <<
":" << __LINE__ <<
")");
478 uint32_t payload_size = 0;
479 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, payload_size, __FILE__, __LINE__);
480 if (!success || (
int)(payload_size) + 9 > receiveBufferLength)
482 ROS_ERROR_STREAM(
"## ERROR parseNAV350LandmarkDataDoMappingResponse(): invalid telegram size (" << __FILE__ <<
":" << __LINE__ <<
")");
486 if (strncmp((
const char*)receiveBuffer + receivePos,
"sAN mNMAPDoMapping ", 19) != 0)
488 ROS_ERROR_STREAM(
"## ERROR parseNAV350LandmarkDataDoMappingResponse(): telegram does not start with \"sAN mNMAPDoMapping \"");
493 success &=
readFromBuffer(receiveBuffer, receivePos, receiveBufferLength, landmarkData.
errorCode, __FILE__, __LINE__);
497 std::map<uint8_t, std::string> errorCodeStr = { {0,
"no error"}, {1,
"wrong operating mode"}, {2,
"asynchrony Method terminated"}, {5,
"timeout"}, {6,
"method already active"}, {7,
"general error"} };
498 ROS_WARN_STREAM(
"## WARNING parseNAV350LandmarkDataDoMappingResponse(): NAV350 landmarkData.errorCode = " << (
int)landmarkData.
errorCode <<
" (\"" << errorCodeStr[landmarkData.
errorCode] <<
"\")");
511 std::string sopas_start =
"sMN mNLAYAddLandmark ";
512 std::vector<uint8_t> request(sopas_start.begin(), sopas_start.end());
514 for(
int reflector_cnt = 0; reflector_cnt < landmarkData.
reflectors.size(); reflector_cnt++)
516 if (landmarkData.
reflectors[reflector_cnt].cartesianDataValid == 0)
517 ROS_ERROR_STREAM(
"## ERROR createNAV350BinaryAddLandmarkRequest(): " << (reflector_cnt + 1) <<
". reflector has no valid cartesian data");
518 if (landmarkData.
reflectors[reflector_cnt].optReflectorDataValid == 0)
519 ROS_ERROR_STREAM(
"## ERROR createNAV350BinaryAddLandmarkRequest(): " << (reflector_cnt + 1) <<
". reflector has no valid type and subtype");
522 request.push_back((uint8_t)landmarkData.
reflectors[reflector_cnt].optReflectorData.type);
523 request.push_back((uint8_t)landmarkData.
reflectors[reflector_cnt].optReflectorData.subType);
534 std::string sopas_start =
"sMN mNLAYAddLandmark ";
535 std::vector<uint8_t> request(sopas_start.begin(), sopas_start.end());
537 for(
int reflector_cnt = 0; reflector_cnt < landmarks.size(); reflector_cnt++)
541 request.push_back((uint8_t)landmarks[reflector_cnt].
type);
542 request.push_back((uint8_t)landmarks[reflector_cnt].subType);
543 appendToBuffer(request, (uint16_t)landmarks[reflector_cnt].size_mm);
544 appendToBuffer(request, (uint16_t)landmarks[reflector_cnt].layerID.size());
545 for(
int layer_cnt = 0; layer_cnt < landmarks[reflector_cnt].layerID.size(); layer_cnt++)
546 appendToBuffer(request, (uint16_t)landmarks[reflector_cnt].layerID[layer_cnt]);
554 std::string sopas_start =
"sMN mNPOSSetSpeed ";
555 std::vector<uint8_t> request(sopas_start.begin(), sopas_start.end());
571 elevationAngleInRad = 0;
580 msg.angle_min = (float)(0.0 + nav_angle_offset);
581 msg.angle_max = (float)(2.0 * M_PI + nav_angle_offset);
582 msg.angle_increment = (float)(0.25 * M_PI / 180.0);
583 msg.scan_time = 1.0f / 8.0f;
584 msg.time_increment =
msg.scan_time *
msg.angle_increment / (float)(2.0 * M_PI);
585 uint32_t nav_timestampStart = 0;
591 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryPositionData(): parsing error");
598 nav_pose_msg.pose_valid = 0;
615 convertNAVCartPos3DtoROSPos3D(nav_pose_msg.x, nav_pose_msg.y, nav_pose_msg.phi, nav_pose_msg.pose_x, nav_pose_msg.pose_y, nav_pose_msg.pose_yaw, nav_angle_offset);
616 nav_pose_msg.pose_valid = 1;
617 ROS_DEBUG_STREAM(
"NAV350 PoseData: x=" << nav_pose_msg.pose_x <<
", y=" << nav_pose_msg.pose_y <<
", yaw=" << (nav_pose_msg.pose_yaw*180.0/M_PI)
618 <<
" (lidar: x=" << nav_pose_msg.x <<
", y=" << nav_pose_msg.y <<
", phi=" << nav_pose_msg.phi <<
")");
635 nav_landmark_msg.reflectors[reflector_cnt].cartesian_data_valid = navdata.
landmarkData.
reflectors[reflector_cnt].cartesianDataValid;
636 nav_landmark_msg.reflectors[reflector_cnt].polar_data_valid = navdata.
landmarkData.
reflectors[reflector_cnt].polarDataValid;
637 nav_landmark_msg.reflectors[reflector_cnt].opt_reflector_data_valid = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorDataValid;
638 nav_landmark_msg.reflectors[reflector_cnt].pos_valid = 0;
641 nav_landmark_msg.reflectors[reflector_cnt].x = navdata.
landmarkData.
reflectors[reflector_cnt].cartesianData.x;
642 nav_landmark_msg.reflectors[reflector_cnt].y = navdata.
landmarkData.
reflectors[reflector_cnt].cartesianData.y;
645 nav_landmark_msg.reflectors[reflector_cnt].pos_x, nav_landmark_msg.reflectors[reflector_cnt].pos_y, nav_angle_offset);
646 nav_landmark_msg.reflectors[reflector_cnt].pos_valid = 1;
650 nav_landmark_msg.reflectors[reflector_cnt].dist = navdata.
landmarkData.
reflectors[reflector_cnt].polarData.dist;
651 nav_landmark_msg.reflectors[reflector_cnt].phi = navdata.
landmarkData.
reflectors[reflector_cnt].polarData.phi;
655 nav_landmark_msg.reflectors[reflector_cnt].local_id = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.localID;
656 nav_landmark_msg.reflectors[reflector_cnt].global_id = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.globalID;
657 nav_landmark_msg.reflectors[reflector_cnt].type = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.type;
658 nav_landmark_msg.reflectors[reflector_cnt].sub_type = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.subType;
659 nav_landmark_msg.reflectors[reflector_cnt].quality = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.quality;
660 nav_landmark_msg.reflectors[reflector_cnt].timestamp = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.timestamp;
661 nav_landmark_msg.reflectors[reflector_cnt].size = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.size;
662 nav_landmark_msg.reflectors[reflector_cnt].hit_count = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.hitCount;
663 nav_landmark_msg.reflectors[reflector_cnt].mean_echo = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.meanEcho;
664 nav_landmark_msg.reflectors[reflector_cnt].start_index = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.startIndex;
665 nav_landmark_msg.reflectors[reflector_cnt].end_index = navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorData.endIndex;
668 <<
": cartesian=" << (
int)(nav_landmark_msg.reflectors[reflector_cnt].cartesian_data_valid) <<
", x=" << nav_landmark_msg.reflectors[reflector_cnt].x <<
", y=" << nav_landmark_msg.reflectors[reflector_cnt].y
669 <<
", polar=" << (
int)(nav_landmark_msg.reflectors[reflector_cnt].polar_data_valid) <<
", dist=" << nav_landmark_msg.reflectors[reflector_cnt].dist <<
", phi=" << nav_landmark_msg.reflectors[reflector_cnt].phi
670 <<
", pos_valid=" << (
int)(nav_landmark_msg.reflectors[reflector_cnt].pos_valid) <<
", pos_x=" << nav_landmark_msg.reflectors[reflector_cnt].pos_x <<
", pos_y=" << nav_landmark_msg.reflectors[reflector_cnt].pos_y
671 <<
", optValid=" << (
int)(navdata.
landmarkData.
reflectors[reflector_cnt].optReflectorDataValid) <<
", local_id=" << nav_landmark_msg.reflectors[reflector_cnt].local_id <<
", global_id=" << nav_landmark_msg.reflectors[reflector_cnt].global_id);
681 ROS_WARN_STREAM(
"## WARNING NAV350: no scan data channel in mNPOSGetData message");
682 for(
int channel = 0; channel < navdata.
scanData.size(); channel++)
683 ROS_DEBUG_STREAM(
"NAV350 scan data channel " << (channel + 1) <<
" of " << navdata.
scanData.size() <<
": " << navdata.
scanData[channel].contentType <<
", startAngle=" << navdata.
scanData[channel].startAngle <<
", angleRes=" << navdata.
scanData[channel].angleRes <<
", numPoints=" << navdata.
scanData[channel].numData <<
", timestampStart=" << navdata.
scanData[channel].timestampStart);
685 msg.intensities.clear();
688 msg.angle_min = (float)(0.001 * navdata.
scanData[0].startAngle * M_PI / 180.0 + nav_angle_offset);
689 msg.angle_increment = (float)(0.001 * navdata.
scanData[0].angleRes * M_PI / 180.0);
690 msg.angle_max = (float)(
msg.angle_min +
msg.angle_increment * navdata.
scanData[0].numData);
691 nav_timestampStart = navdata.
scanData[0].timestampStart;
693 for(
int channel = 0; dist_scan_data == 0 && channel < navdata.
scanData.size(); channel++)
694 if (navdata.
scanData[channel].contentType ==
"DIST1")
695 dist_scan_data = &navdata.
scanData[channel];
696 if (!dist_scan_data || dist_scan_data->
numData <= 0)
698 ROS_ERROR_STREAM(
"## ERROR NAV350: No channel DIST1 found in scan data of mNPOSGetData message");
705 if (std::fabs(scaleFactor - 1.0
f) > FLT_EPSILON || std::fabs(scaleOffset) > FLT_EPSILON)
707 ROS_WARN_STREAM(
"## WARNING NAV350: using DIST1 scaleFactor=" << scaleFactor <<
" (expected: scaleFactor:=1) and scaleOffset=" << scaleOffset <<
" (expected: scaleOffset:=0) in mNPOSGetData message");
708 for(
int point_cnt = 0; point_cnt < dist_scan_data->
numData; point_cnt++)
710 msg.ranges[point_cnt] = 0.001f * (scaleFactor * (float)dist_scan_data->
data[point_cnt] + scaleOffset);
715 for(
int point_cnt = 0; point_cnt < dist_scan_data->
numData; point_cnt++)
717 msg.ranges[point_cnt] = 0.001f * (float)dist_scan_data->
data[point_cnt];
737 if (nav_timestampStart > 0)
739 uint32_t recvTimeStampSec = (uint32_t)
sec(recvTimeStamp), recvTimeStampNsec = (uint32_t)
nsec(recvTimeStamp);
741 if (softwarePLLready)
744 recvTimeStamp =
rosTime(recvTimeStampSec, recvTimeStampNsec);
750 ROS_DEBUG_STREAM(
"NAV350: SoftwarePLL still initializing, NAV-timestamp=" << nav_timestampStart <<
" ms, ROS-timestamp=" <<
rosTimeToSeconds(recvTimeStamp) <<
" sec.");
752 if (config_sw_pll_only_publish ==
true)
757 nav_pose_msg.header =
msg.header;
758 nav_landmark_msg.header =
msg.header;
766 if (std::abs(angle_offset - (+M_PI)) <= FLT_EPSILON || std::abs(angle_offset - (-M_PI)) <= FLT_EPSILON)
771 else if (std::abs(angle_offset) <= FLT_EPSILON)
778 x = (float)(x * cos(angle_offset) - y * sin(angle_offset));
779 y = (float)(x * sin(angle_offset) + y * cos(angle_offset));
786 ros_posx_m = (float)(1.0e-3 * nav_posx_mm);
787 ros_posy_m = (float)(1.0e-3 * nav_posy_mm);
792 void convertNAVCartPos3DtoROSPos3D(int32_t nav_posx_mm, int32_t nav_posy_mm, uint32_t nav_phi_mdeg,
float& ros_posx_m,
float& ros_posy_m,
float& ros_yaw_rad,
double nav_angle_offset)
795 ros_yaw_rad = (float)(1.0e-3 * nav_phi_mdeg * M_PI / 180.0 + nav_angle_offset);
800 const std::string& tf_parent_frame_id,
const std::string& tf_child_frame_id,
SickGenericParser* parser_)
805 float posx = 0, posy = 0, yaw = 0;
810 uint32_t recvTimeStampSec = (uint32_t)
sec(recvTimeStamp), recvTimeStampNsec = (uint32_t)
nsec(recvTimeStamp);
821 tf.header.stamp = recvTimeStamp;
824 tf.header.frame_id = tf_parent_frame_id;
825 tf.child_frame_id = tf_child_frame_id;
826 tf.transform.translation.x = posx;
827 tf.transform.translation.y = posy;
828 tf.transform.translation.z = 0.0;
831 tf.transform.rotation.x = q.x();
832 tf.transform.rotation.y = q.y();
833 tf.transform.rotation.z = q.z();
834 tf.transform.rotation.w = q.w();
843 marker_array.markers.reserve(1 + 2 * reflectors.size());
845 marker_array.markers.back().header =
header;
846 marker_array.markers.back().action = ros_visualization_msgs::Marker::DELETEALL;
847 for(
int reflector_cnt = 0; reflector_cnt < reflectors.size(); reflector_cnt++)
849 if (reflectors[reflector_cnt].cartesianDataValid > 0)
851 float reflector_posx = 0, reflector_posy = 0;
852 convertNAVCartPos2DtoROSPos2D(reflectors[reflector_cnt].cartesianData.x, reflectors[reflector_cnt].cartesianData.y, reflector_posx, reflector_posy, nav_angle_offset);
853 float reflector_size = 0.001f * (float)((reflectors[reflector_cnt].optReflectorDataValid > 0) ? (reflectors[reflector_cnt].optReflectorData.size) : 80);
854 int32_t reflector_id = ((reflectors[reflector_cnt].optReflectorDataValid > 0) ? (reflectors[reflector_cnt].optReflectorData.localID) : (reflector_cnt + 1));
856 marker_cylinder.ns =
"sick_scan";
857 marker_cylinder.id = reflector_cnt;
858 marker_cylinder.type = ros_visualization_msgs::Marker::CYLINDER;
859 marker_cylinder.scale.x = reflector_size;
860 marker_cylinder.scale.y = reflector_size;
861 marker_cylinder.scale.z = reflector_size;
862 marker_cylinder.pose.position.x = reflector_posx;
863 marker_cylinder.pose.position.y = reflector_posy;
864 marker_cylinder.pose.position.z = 0.0;
865 marker_cylinder.pose.orientation.x = 0.0;
866 marker_cylinder.pose.orientation.y = 0.0;
867 marker_cylinder.pose.orientation.z = 0.0;
868 marker_cylinder.pose.orientation.w = 1.0;
869 marker_cylinder.action = ros_visualization_msgs::Marker::ADD;
870 marker_cylinder.color.r = 1.0f;
871 marker_cylinder.color.g = 0.0f;
872 marker_cylinder.color.b = 0.0f;
873 marker_cylinder.color.a = 0.5f;
875 marker_cylinder.header =
header;
876 marker_array.markers.push_back(marker_cylinder);
879 marker_text.ns =
"sick_scan";
880 marker_text.id = reflector_cnt + reflectors.size();
881 marker_text.type = ros_visualization_msgs::Marker::TEXT_VIEW_FACING;
882 marker_text.text = std::to_string(reflector_id);
883 marker_text.scale.x = reflector_size;
884 marker_text.scale.y = reflector_size;
885 marker_text.scale.z = 2.0f * reflector_size;
886 marker_text.pose.position.x = reflector_posx;
887 marker_text.pose.position.y = reflector_posy + 1.5f * reflector_size;
888 marker_text.pose.position.z = 0.0;
889 marker_text.pose.orientation.x = 0.0;
890 marker_text.pose.orientation.y = 0.0;
891 marker_text.pose.orientation.z = 0.0;
892 marker_text.pose.orientation.w = 1.0;
893 marker_text.action = ros_visualization_msgs::Marker::ADD;
894 marker_text.color.r = 1.0f;
895 marker_text.color.g = 1.0f;
896 marker_text.color.b = 1.0f;
897 marker_text.color.a = 1.0f;
899 marker_text.header =
header;
900 marker_array.markers.push_back(marker_text);
908 std::vector<sick_scan_xd::NAV350ImkLandmark>
readNAVIMKfile(
const std::string& nav_imk_file)
910 std::vector<sick_scan_xd::NAV350ImkLandmark> navImkLandmarks;
911 std::ifstream imk_stream(nav_imk_file);
912 if(imk_stream.is_open())
915 while (getline(imk_stream,
line))
918 for(
int n = 0; n <
line.size(); n++)
920 if (isspace(
line[n]))
923 if (
line.empty() ||
line[0] ==
'#' || strncmp(
line.c_str(),
"globID", 6) == 0)
926 std::stringstream ss(
line);
928 std::vector<std::string>
args;
929 while (std::getline(ss, token,
' '))
932 args.push_back(token);
940 ROS_WARN_STREAM(
"## ERROR readNAVIMKfile(" << nav_imk_file <<
"): parse error, line \"" <<
line <<
"\" ignored.");
944 landmark.
globID = (uint16_t)(atoi(
args[0].c_str()) & 0xFFFF);
945 landmark.
x_mm = (int32_t)(atoi(
args[1].c_str()) & 0xFFFFFFFF);
946 landmark.
y_mm = (int32_t)(atoi(
args[2].c_str()) & 0xFFFFFFFF);
947 landmark.
type = (uint8_t)(atoi(
args[3].c_str()) & 0xFF);
948 landmark.
subType = (uint16_t)(atoi(
args[4].c_str()) & 0xFFFF);
949 landmark.
size_mm = (uint16_t)(atoi(
args[5].c_str()) & 0xFFFF);
950 for(
int n = 6; n <
args.size(); n++)
951 landmark.
layerID.push_back((uint16_t)(atoi(
args[n].c_str()) & 0xFFFF));
952 navImkLandmarks.push_back(landmark);
955 ROS_INFO_STREAM(
"sick_scan_xd::readNAVIMKfile(\"" << nav_imk_file <<
"\"): " << navImkLandmarks.size() <<
" landmarks:");
956 for(
int n = 0; n < navImkLandmarks.size(); n++)
958 std::stringstream imk_stream;
959 imk_stream << (int)navImkLandmarks[n].globID <<
" " << (
int)navImkLandmarks[n].x_mm <<
" " << (int)navImkLandmarks[n].y_mm <<
" " << (
int)navImkLandmarks[n].type <<
" " << (int)navImkLandmarks[n].subType <<
" " << (
int)navImkLandmarks[n].size_mm;
960 for(
int m = 0; m < navImkLandmarks[n].layerID.size(); m++)
961 imk_stream <<
" " << (
int)navImkLandmarks[n].layerID[m];
964 return navImkLandmarks;