67 #ifdef _MSC_VER // compiling simulation for MS-Visual C++ - not defined for linux system
68 #pragma warning(disable: 4996)
69 #pragma warning(disable: 4267) // due to conversion warning size_t in the ros header file
92 #define _USE_MATH_DEFINES
98 #define rad2deg(x) ((x) / M_PI * 180.0)
101 #define deg2rad_const (0.017453292519943295769236907684886f)
116 #define RETURN_ERROR_ON_RESPONSE_TIMEOUT(result,reply) if(((result)!=ExitSuccess)&&((reply).empty()))return(ExitError)
127 unsigned char *buf = (ptr);
128 unsigned char tmpChar;
129 for (
int i = 0; i < numBytes / 2; i++)
131 tmpChar = buf[numBytes - 1 - i];
132 buf[numBytes - 1 - i] = buf[i];
147 std::vector<unsigned char> result;
148 for (
size_t j = 0; j <
s.length(); j++)
150 result.push_back(
s[j]);
162 #ifdef USE_DIAGNOSTIC_UPDATER
180 for (
int i = 0; i < len; i++)
182 char ch = (char) ((*replyDummy)[i + off]);
188 static std::vector<int>
parseFirmwareVersion(
const std::string& scannertype,
const std::string& deviceIdentStr)
190 size_t device_idx = deviceIdentStr.find(scannertype);
191 size_t version_idx = ((device_idx != std::string::npos) ? deviceIdentStr.find(
"V", device_idx) : std::string::npos);
192 std::vector<int> version_id;
193 if (version_idx != std::string::npos && version_idx + 1 < deviceIdentStr.size())
195 std::stringstream device_id_stream(deviceIdentStr.substr(version_idx + 1));
197 while (std::getline(device_id_stream, token,
'.') && version_id.size() < 3)
198 version_id.push_back(std::atoi(token.c_str()));
200 while (version_id.size() < 3)
201 version_id.push_back(
'0');
202 ROS_INFO_STREAM(scannertype <<
" firmware version " << version_id[0] <<
"." << version_id[1] <<
"." << version_id[2]);
208 static bool field_evaluation_active =
false;
209 return field_evaluation_active;
221 unsigned char sick_crc8(
unsigned char *msgBlock,
int len)
223 unsigned char xorVal = 0x00;
225 for (
int i = off; i < len; i++)
228 unsigned char val = msgBlock[i];
239 std::string
stripControl(std::vector<unsigned char> s,
int max_strlen = -1)
241 bool isParamBinary =
false;
245 for (
size_t i = 0; i <
s.size(); i++)
249 isParamBinary =
false;
263 isParamBinary =
true;
266 if (isParamBinary ==
true)
270 unsigned long lenId = 0x00;
271 char szDummy[255] = {0};
272 for (
size_t i = 0; i <
s.size(); i++)
291 lenId |=
s[i] << (8 * (7 - i));
294 sprintf(szDummy,
"<Len=%04lu>", lenId);
301 unsigned long dataProcessed = i - 8;
311 if (dataProcessed >= (lenId - 1))
321 char ch = dest[dest.length() - 1];
326 sprintf(szDummy,
"0x%02x",
s[i]);
329 unsigned long dataProcessed = i - 8;
330 if (dataProcessed >= (lenId - 1))
338 sprintf(szDummy,
" CRC:<0x%02x>",
s[i]);
349 for (
size_t i = 0; i <
s.size(); i++)
371 if(max_strlen > 0 && dest.size() > max_strlen)
373 dest.resize(max_strlen);
469 #ifdef USE_DIAGNOSTIC_UPDATER
470 #if __ROS_VERSION == 1
471 diagnostics_ = std::make_shared<diagnostic_updater::Updater>(*nh);
472 #elif __ROS_VERSION == 2
473 diagnostics_ = std::make_shared<diagnostic_updater::Updater>(nh);
484 #if defined USE_DYNAMIC_RECONFIGURE && __ROS_VERSION == 1
488 dynamic_reconfigure_server_.setCallback(
f);
489 #elif defined USE_DYNAMIC_RECONFIGURE && __ROS_VERSION == 2
490 rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr parameter_cb_handle =
491 nh->add_on_set_parameters_callback(std::bind(&sick_scan_xd::SickScanCommon::update_config_cb,
this, std::placeholders::_1));
530 datagram_pub_ = rosAdvertise<ros_std_msgs::String>(nh, nodename +
"/datagram", 1000);
535 std::string laserscan_topic = nodename +
"/scan";
537 rosGetParam(nh,
"laserscan_topic", laserscan_topic);
569 ROS_INFO_STREAM(
"use_generation_timestamp:=0, using lidar send timestamp instead of generation timestamp for software pll converted message timestamp.");
577 double expected_frequency_tolerance = 0.1;
578 rosDeclareParam(nh,
"expected_frequency_tolerance", expected_frequency_tolerance);
579 rosGetParam(nh,
"expected_frequency_tolerance", expected_frequency_tolerance);
612 nav_pose_data_pub_ = rosAdvertise<sick_scan_msg::NAVPoseData>(nh, nodename +
"/nav_pose", 100);
613 nav_landmark_data_pub_ = rosAdvertise<sick_scan_msg::NAVLandmarkData>(nh, nodename +
"/nav_landmark", 100);
614 nav_reflector_pub_ = rosAdvertise<ros_visualization_msgs::MarkerArray>(nh, nodename +
"/nav_reflectors", 100);
617 #if defined __ROS_VERSION && __ROS_VERSION == 1
620 ros_odom_subscriber_ = nh->
subscribe(
"odom", 1, &sick_scan_xd::SickScanCommon::messageCbRosOdom,
this);
621 #elif defined __ROS_VERSION && __ROS_VERSION == 2
623 nav_odom_velocity_subscriber_ = nh->create_subscription<
sick_scan_msg::NAVOdomVelocity>(
"nav_odom_velocity", 10, std::bind(&sick_scan_xd::SickScanCommon::messageCbNavOdomVelocityROS2,
this, std::placeholders::_1));
624 ros_odom_subscriber_ = nh->create_subscription<
ros_nav_msgs::Odometry>(
"odom", 10, std::bind(&sick_scan_xd::SickScanCommon::messageCbRosOdomROS2,
this, std::placeholders::_1));
634 lferec_pub_ = rosAdvertise<sick_scan_msg::LFErecMsg>(nh, nodename +
"/lferec", 100);
635 lidinputstate_pub_ = rosAdvertise<sick_scan_msg::LIDinputstateMsg>(nh, nodename +
"/lidinputstate", 100);
636 lidoutputstate_pub_ = rosAdvertise<sick_scan_msg::LIDoutputstateMsg>(nh, nodename +
"/lidoutputstate", 100);
644 lidoutputstate_pub_ = rosAdvertise<sick_scan_msg::LIDoutputstateMsg>(nh, nodename +
"/lidoutputstate", 100);
655 imuScan_pub_ = rosAdvertise<ros_sensor_msgs::Imu>(nh, nodename +
"/imu", 100);
657 Encoder_pub = rosAdvertise<sick_scan_msg::Encoder>(nh, nodename +
"/encoder", 100);
660 pub_ = rosAdvertise<ros_sensor_msgs::LaserScan>(nh, laserscan_topic, 1000);
664 #if defined USE_DIAGNOSTIC_UPDATER
669 #if defined USE_DIAGNOSTIC_UPDATER
673 diagnostics_->setHardwareID(
"none");
684 #if __ROS_VERSION == 1
691 #elif __ROS_VERSION == 2
692 diagnosticPub_ =
new DiagnosedPublishAdapter<rosPublisher<ros_sensor_msgs::LaserScan>>(
pub_, *diagnostics_,
720 return set_access_mode_3;
732 std::vector<std::string> sopas_stop_scanner_cmd = {
"\x02sEN LMDscandata 0\x03\0" };
735 sopas_stop_scanner_cmd.push_back(
"\x02sEN LFErec 0\x03");
736 sopas_stop_scanner_cmd.push_back(
"\x02sEN LIDoutputstate 0\x03");
737 sopas_stop_scanner_cmd.push_back(
"\x02sEN LIDinputstate 0\x03");
740 sopas_stop_scanner_cmd.push_back(
"\x02sMN LMCstopmeas\x03\0");
744 sopas_stop_scanner_cmd.clear();
753 for(
int cmd_idx = 0; cmd_idx < sopas_stop_scanner_cmd.size(); cmd_idx++)
755 std::vector<unsigned char> sopas_reply;
756 cmd_result =
convertSendSOPASCommand(sopas_stop_scanner_cmd[cmd_idx], &sopas_reply, (force_immediate_shutdown==
false));
757 if (force_immediate_shutdown ==
false)
763 ROS_WARN_STREAM(
"## ERROR sick_scan_common: ERROR sending sopas command \"" << sopas_stop_scanner_cmd[cmd_idx] <<
"\"");
778 unsigned long val = 0;
779 for (
int i = 0; i < 4; i++)
802 if (reply->size() < 8)
808 const unsigned char *ptr = &((*reply)[0]);
809 unsigned binId = convertBigEndianCharArrayToUnsignedLong(ptr);
810 unsigned cmdLen = convertBigEndianCharArrayToUnsignedLong(ptr + 4);
811 if (binId == 0x02020202)
813 int replyLen = reply->size();
814 if (replyLen == 8 + cmdLen + 1)
835 std::vector<unsigned char> requestBinary;
838 result =
sendSOPASCommand((
const char*)requestBinary.data(), sopas_reply, requestBinary.size(), wait_for_reply);
842 ROS_INFO_STREAM(
"sick_scan_common: sending sopas command \"" << sopas_ascii_request <<
"\"");
843 result =
sendSOPASCommand(sopas_ascii_request.c_str(), sopas_reply, sopas_ascii_request.size(), wait_for_reply);
858 std::vector<unsigned char> access_reply;
865 ROS_ERROR(
"SOPAS - Error setting access mode");
866 #ifdef USE_DIAGNOSTIC_UPDATER
873 if (access_reply_str !=
"sAN SetAccessMode 1")
875 ROS_ERROR_STREAM(
"SOPAS - Error setting access mode, unexpected response : " << access_reply_str);
876 #ifdef USE_DIAGNOSTIC_UPDATER
886 std::vector<unsigned char> reboot_reply;
890 ROS_ERROR(
"SOPAS - Error rebooting scanner");
891 #ifdef USE_DIAGNOSTIC_UPDATER
898 if (reboot_reply_str !=
"sAN mSCreboot")
900 ROS_ERROR_STREAM(
"SOPAS - Error rebooting scanner, unexpected response : " << reboot_reply_str);
901 #ifdef USE_DIAGNOSTIC_UPDATER
908 ROS_INFO(
"SOPAS - Rebooted scanner");
923 printf(
"SickScanCommon closed.\n");
934 std::string expectedAnswer =
"";
936 char cntWhiteCharacter = 0;
937 int initalTokenCnt = 2;
938 std::map<std::string, int> specialTokenLen;
939 char firstToken[1024] = {0};
940 specialTokenLen[
"sRI"] = 1;
941 std::string tmpStr =
"";
943 bool isBinary =
false;
944 for (
size_t i = 0; i < 4; i++)
946 if (i < requestStr.size())
948 if (requestStr[i] == 0x02)
956 int iStop = requestStr.size();
961 for (
int i = 0; i < 4; i++)
963 cmdLen |= cmdLen << 8;
964 cmdLen |= requestStr[i + 4];
970 int iStart = (isBinary ==
true) ? 8 : 0;
971 for (
int i = iStart; i < iStop; i++)
973 tmpStr += (char) requestStr[i];
977 tmpStr =
"\x2" + tmpStr;
979 if (sscanf(tmpStr.c_str(),
"\x2%s", firstToken) == 1)
981 if (specialTokenLen.find(firstToken) != specialTokenLen.end())
983 initalTokenCnt = specialTokenLen[firstToken];
988 for (
int i = iStart; i < iStop; i++)
990 if ((requestStr[i] ==
' ') || (requestStr[i] ==
'\x3'))
994 if (cntWhiteCharacter >= initalTokenCnt)
998 if (requestStr[i] ==
'\x2')
1003 expectedAnswer += requestStr[i];
1010 std::map<std::string, std::vector<std::string>> keyWordMap;
1011 keyWordMap[
"sWN"] = {
"sWA",
"sAN" };
1012 keyWordMap[
"sRN"] = {
"sRA",
"sAN" };
1013 keyWordMap[
"sRI"] = {
"sRA" };
1014 keyWordMap[
"sMN"] = {
"sAN",
"sMA" };
1015 keyWordMap[
"sEN"] = {
"sEA" };
1017 std::vector<std::string> expectedAnswers;
1018 for (std::map<std::string, std::vector<std::string>>::iterator it = keyWordMap.begin(); it != keyWordMap.end(); it++)
1020 const std::string& keyWord = it->first;
1021 const std::vector<std::string>& newKeyWords = it->second;
1023 size_t pos = expectedAnswer.find(keyWord);
1026 for(
int n = 0; n < newKeyWords.size(); n++)
1028 expectedAnswers.push_back(expectedAnswer);
1029 expectedAnswers.back().replace(pos, keyWord.length(), newKeyWords[n]);
1032 else if (pos != std::string::npos)
1034 ROS_WARN(
"Unexpected position of key identifier.\n");
1038 if(expectedAnswers.empty())
1040 expectedAnswers.push_back(expectedAnswer);
1042 return (expectedAnswers);
1052 std::vector<std::string> unexpected_responses;
1053 if (requestStr.find(
"SetAccessMode") != std::string::npos)
1055 unexpected_responses.push_back(std::string(
"sAN SetAccessMode 0"));
1056 unexpected_responses.push_back(std::string(
"sAN SetAccessMode \x00", 19));
1058 return unexpected_responses;
1070 std::vector<unsigned char> requestStringVec;
1071 for (
size_t i = 0; i < requestStr.length(); i++)
1073 requestStringVec.push_back(requestStr[i]);
1092 std::string cmdStr =
"";
1094 for (
size_t i = 0; i < requestStr.size(); i++)
1097 cmdStr += (char) requestStr[i];
1101 std::string errString;
1104 errString =
"Error unexpected Sopas answer for request " +
stripControl(requestStr, 64);
1119 std::vector<unsigned char> replyVec;
1120 replyStr =
"<STX>" + replyStr +
"<ETX>";
1126 std::string tmpStr =
"SOPAS Communication -" + errString;
1128 #ifdef USE_DIAGNOSTIC_UPDATER
1137 for(
int retry_answer_cnt = 0; result != 0; retry_answer_cnt++)
1140 std::string replyStrOrg = std::string((
const char*)reply->data(), reply->size());
1141 std::stringstream expectedAnswers;
1145 for(
int n = 0; n < searchPatternNeg.size(); n++)
1149 if (replyStrOrg.find(searchPatternNeg[n]) != std::string::npos)
1153 <<
"\" not expected, SOPAS command failed.");
1157 for(
int n = 0; result != 0 && n < searchPattern.size(); n++)
1159 if (answerStr.find(searchPattern[n]) != std::string::npos)
1163 expectedAnswers << (n > 0 ?
"," :
"") <<
"\"" << searchPattern[n] <<
"\"" ;
1169 ROS_INFO_STREAM(
"IMU-Data transfer started. No checking of reply to avoid confusing with LMD Scandata\n");
1174 if(answerStr.size() > 64)
1176 answerStr.resize(64);
1179 std::string tmpMsg =
"Error Sopas answer mismatch: " + errString +
", received answer: \"" + answerStr +
"\", expected patterns: " + expectedAnswers.str();
1181 #ifdef USE_DIAGNOSTIC_UPDATER
1186 if (strncmp(answerStr.c_str(),
"sFA", 3) == 0)
1188 ROS_WARN_STREAM(
"Sopas error code " << answerStr.substr(4) <<
" received from lidar");
1195 char buffer[64*1024];
1199 if (!reply->empty())
1203 reply->resize(bytes_read);
1204 std::copy(buffer, buffer + bytes_read, &(*reply)[0]);
1214 ROS_ERROR_STREAM(errString <<
", giving up after " << retry_answer_cnt <<
" unexpected answers.");
1230 std::vector<unsigned char> replyDummy, reqBinary;
1243 *reply = replyDummy;
1247 ROS_WARN_STREAM(
"## ERROR SickScanCommon: sendSopasAndCheckAnswer(\"" << sopasCmd <<
"\") failed");
1257 std::vector<std::string> sopas_response_keywords = { sopas_keyword };
1260 ROS_WARN_STREAM(
"## ERROR waiting for 2nd response \"" << sopas_keyword <<
"\" to request \"" << sopas_keyword <<
"\"");
1271 for(
int n = 0; n < sopas_change_cola_commands.size(); n++)
1275 ROS_WARN_STREAM(
"checkColaDialect: no lidar response to sopas requests \"" << sopas_change_cola_commands[n] <<
"\", aborting");
1279 ROS_INFO_STREAM(
"checkColaDialect: switched to Cola-" << (useBinaryCmd ?
"B" :
"A"));
1291 static bool tim240_binary_mode = useBinaryCmd;
1292 bool useBinaryCmdCfg = useBinaryCmd;
1295 useBinaryCmd = tim240_binary_mode;
1296 ROS_INFO_STREAM(
"checkColaDialect using Cola-" << (useBinaryCmd ?
"B" :
"A") <<
" (TiM-240)");
1300 ROS_WARN_STREAM(
"checkColaDialect: lidar response not in configured Cola-dialect Cola-" << (useBinaryCmd ?
"B" :
"A") <<
", trying different Cola configuration");
1304 ROS_WARN_STREAM(
"checkColaDialect: no lidar response in any cola configuration, check lidar and network!");
1309 ROS_WARN_STREAM(
"checkColaDialect: lidar response in configured Cola-dialect Cola-" << (!useBinaryCmd ?
"B" :
"A") <<
", changing Cola configuration and restart!");
1311 ROS_INFO_STREAM(
"checkColaDialect: restarting after Cola configuration change.");
1315 tim240_binary_mode = !tim240_binary_mode;
1316 ROS_INFO_STREAM(
"checkColaDialect: switching to Cola-" << (useBinaryCmd ?
"B" :
"A") <<
" after restart (TiM-240)");
1322 ROS_INFO_STREAM(
"checkColaDialect: lidar response in configured Cola-dialect Cola-" << (useBinaryCmd ?
"B" :
"A"));
1325 if (useBinaryCmd != useBinaryCmdCfg)
1327 ROS_INFO_STREAM(
"checkColaDialect sucessful using Cola-" << (useBinaryCmd ?
"B" :
"A") <<
", switch to Cola-" << (useBinaryCmdCfg ?
"B" :
"A") <<
" (TiM-240)");
1329 tim240_binary_mode = useBinaryCmdCfg;
1342 std::vector<unsigned char> reqBinary;
1354 std::vector<unsigned char> resetReply;
1367 std::string sopas_cmd =
"\x02sMN mNPOSGetData 1 2\x03";
1368 std::vector<unsigned char> sopas_request;
1372 return sendSOPASCommand((
const char*)sopas_request.data(), 0, sopas_request.size(),
false);
1382 if (!
parseNAV350BinaryPositionData(receiveBuffer, receiveBufferLength, elevAngleX200, elevationAngleInRad, recvTimeStamp, config_sw_pll_only_publish, config_time_offset,
parser_, numEchos,
msg, nav_pose_msg, nav_landmark_msg, navdata))
1388 ROS_ERROR_STREAM(
"## ERROR NAV350: Error sending sMN mNPOSGetData request, retrying ...");
1395 #if __ROS_VERSION > 0
1396 if (nav_tf_broadcaster_)
1399 nav_tf_broadcaster_->sendTransform(nav_pose_transform);
1406 #if __ROS_VERSION > 0
1424 ROS_DEBUG_STREAM(
"SickScanCommon::messageCbNavOdomVelocity(): vel_x=" <<
msg.vel_x <<
" m/s, vel_y=" <<
msg.vel_y <<
" m/s, omega=" <<
msg.omega <<
" rad/s, timestamp=" <<
msg.timestamp <<
", coordbase=" << (
int)
msg.coordbase);
1427 std::vector<uint8_t> setNAVSpeedRequest = { 0x02, 0x02, 0x02, 0x02, 0, 0, 0, 0 };
1428 setNAVSpeedRequest.insert(setNAVSpeedRequest.end(), setNAVSpeedRequestPayload.begin(), setNAVSpeedRequestPayload.end());
1431 ROS_ERROR_STREAM(
"SickScanCommon::messageCbNavOdomVelocity(): sendSopasAndCheckAnswer() failed");
1434 #if __ROS_VERSION > 0
1438 nav_odom_vel_msg.vel_x =
msg.twist.twist.linear.x;
1439 nav_odom_vel_msg.vel_y =
msg.twist.twist.linear.y;
1442 nav_odom_vel_msg.omega =
msg.twist.twist.angular.z;
1443 nav_odom_vel_msg.coordbase = 0;
1452 ROS_WARN_STREAM(
"## ERROR SickScanCommon::messageCbRosOdom(): SoftwarePLL not yet ready, timestamp can not be converted from system time to lidar time, odometry message ignored.");
1453 ROS_WARN_STREAM(
"## ERROR SickScanCommon::messageCbRosOdom(): Send odometry messages after SoftwarePLL is ready (i.e. has finished initialization phase).");
1526 ROS_INFO_STREAM(
"Failed to init scanner Error Code: " << result <<
"\nWaiting for timeout...\n"
1527 "If the communication mode set in the scanner memory is different from that used by the driver, the scanner's communication mode is changed.\n"
1528 "This requires a restart of the TCP-IP connection, which can extend the start time by up to 30 seconds. There are two ways to prevent this:\n"
1529 "1. [Recommended] Set the communication mode with the SOPAS ET software to binary and save this setting in the scanner's EEPROM.\n"
1530 "2. Use the parameter \"use_binary_protocol\" to overwrite the default settings of the driver.");
1552 std::string unknownStr =
"Command or Error message not defined";
1586 std::string client_authorization_pw =
"F4724744";
1587 rosDeclareParam(nh,
"client_authorization_pw", client_authorization_pw);
1588 rosGetParam(nh,
"client_authorization_pw", client_authorization_pw);
1589 if (!client_authorization_pw.empty() && client_authorization_pw !=
"F4724744")
1591 std::string s_access_mode_3 = std::string(
"\x02sMN SetAccessMode 3 ") + client_authorization_pw + std::string(
"\x03\0");
1863 bool isNav2xxOr3xx =
false;
1866 isNav2xxOr3xx =
true;
1870 isNav2xxOr3xx =
true;
1877 bool tryToStopMeasurement =
true;
1880 tryToStopMeasurement =
false;
1886 bool load_application_default =
false;
1887 rosDeclareParam(nh,
"load_application_default", load_application_default);
1888 rosGetParam(nh,
"load_application_default", load_application_default);
1889 if(load_application_default)
1894 tryToStopMeasurement =
false;
1897 if (tryToStopMeasurement)
1906 switch (numberOfLayers)
1973 int lfp_meanfilter_arg = -1, lfp_medianfilter_arg = -1;
1975 rosGetParam(nh,
"lfp_meanfilter", lfp_meanfilter_arg);
1977 rosGetParam(nh,
"lfp_medianfilter", lfp_medianfilter_arg);
1978 if (lfp_meanfilter_arg >= 0)
1981 if (lfp_meanfilter_arg == 0)
1987 if (lfp_medianfilter_arg >= 0)
1997 int glare_detection_sens_arg = -1;
1998 rosDeclareParam(nh,
"glare_detection_sens", glare_detection_sens_arg);
1999 rosGetParam(nh,
"glare_detection_sens", glare_detection_sens_arg);
2000 if (glare_detection_sens_arg >= 0)
2010 std::string scan_layer_filter =
"";
2012 rosGetParam(nh,
"scan_layer_filter", scan_layer_filter);
2013 if (!scan_layer_filter.empty())
2026 double lmd_scandatascalefactor_arg = 0;
2027 rosDeclareParam(nh,
"lmd_scandatascalefactor", lmd_scandatascalefactor_arg);
2028 rosGetParam(nh,
"lmd_scandatascalefactor", lmd_scandatascalefactor_arg);
2029 if (lmd_scandatascalefactor_arg > 0)
2050 int maxNumberOfEchos = 1;
2056 bool rssiFlag =
false;
2057 bool rssiResolutionIs16Bit =
true;
2058 int activeEchos = 0;
2062 rosDeclareParam(nh,
"intensity_resolution_16bit", rssiResolutionIs16Bit);
2063 rosGetParam(nh,
"intensity_resolution_16bit", rssiResolutionIs16Bit);
2067 std::string sNewIPAddr =
"";
2068 std::string ipNewIPAddr;
2069 bool setNewIPAddr =
false;
2071 if(
rosGetParam(nh,
"new_IP_address", sNewIPAddr) && !sNewIPAddr.empty())
2073 ipNewIPAddr = sNewIPAddr;
2079 std::string sNTPIpAdress =
"";
2080 std::string NTPIpAdress;
2081 bool setUseNTP =
false;
2083 setUseNTP =
rosGetParam(nh,
"ntp_server_address", sNTPIpAdress);
2084 if (sNTPIpAdress.empty())
2088 NTPIpAdress = sNTPIpAdress;
2096 ROS_INFO_STREAM(
"Parameter setting for <active_echo: " << activeEchos <<
">");
2097 std::vector<bool> outputChannelFlag;
2098 outputChannelFlag.resize(maxNumberOfEchos);
2101 for (
int i = 0; i < outputChannelFlag.size(); i++)
2119 outputChannelFlag[i] =
true;
2123 if (numOfFlags == 0)
2125 outputChannelFlag[0] =
true;
2127 ROS_WARN(
"Activate at least one echo.");
2131 int EncoderSettings = -1;
2179 int angleRes10000th = 0;
2180 int angleStart10000th = 0;
2181 int angleEnd10000th = 0;
2194 volatile bool useBinaryCmd =
false;
2197 useBinaryCmd =
true;
2200 bool useBinaryCmdNow =
false;
2206 rosDeclareParam(nh,
"read_timeout_millisec_default", read_timeout_millisec_default);
2207 rosGetParam(nh,
"read_timeout_millisec_default", read_timeout_millisec_default);
2208 rosDeclareParam(nh,
"read_timeout_millisec_startup", read_timeout_millisec_startup);
2209 rosGetParam(nh,
"read_timeout_millisec_startup", read_timeout_millisec_startup);
2210 const int shortTimeOutInMs = read_timeout_millisec_default;
2211 const int defaultTimeOutInMs = read_timeout_millisec_startup;
2215 bool restartDueToProcolChange =
false;
2222 bool NAV3xxOutputRangeSpecialHandling=
false;
2227 NAV3xxOutputRangeSpecialHandling =
true;
2238 ROS_WARN_STREAM(
"SickScanCommon::init_scanner(): checkColaDialect failed, restarting.");
2239 ROS_WARN_STREAM(
"It is recommended to use the binary communication (Cola-B) by:");
2240 ROS_WARN_STREAM(
"1. setting parameter use_binary_protocol true in the launch file, and");
2241 ROS_WARN_STREAM(
"2. setting the lidar communication mode with the SOPAS ET software to binary and save this setting in the scanner's EEPROM.");
2245 int initialize_scanner = 1;
2249 rosGetParam(nh,
"initialize_scanner", initialize_scanner);
2250 if (initialize_scanner == 0)
2252 ROS_WARN_STREAM(
"SickScanCommon::init_scanner(): initialize_scanner=" << initialize_scanner <<
" for TiM7xxS configured.\n");
2253 ROS_WARN_STREAM(
"Note that this mode does not initialize the lidar. The mode assumes that the scanner is in an appropriate state matching the properties otherwise set in the launchfile.");
2254 ROS_WARN_STREAM(
"DO NOT USE THIS MODE EXCEPT THE LIDAR HAS BEEN CONFIGURED AND INITIALIZED SUCCESSFULLY");
2255 ROS_WARN_STREAM(
"AND IS IN THE SAME STATE AS AFTER INITIALIZATION BY THE LAUNCHFILE!\n");
2256 ROS_WARN_STREAM(
"SickScanCommon::init_scanner(): skipping lidar initialization.\n");
2267 if (sopasCmd.empty())
2269 std::vector<unsigned char> replyDummy;
2270 std::vector<unsigned char> reqBinary;
2272 std::vector<unsigned char> sopasCmdVecTmp;
2273 for (
size_t j = 0; j < sopasCmd.length(); j++)
2275 sopasCmdVecTmp.push_back(sopasCmd[j]);
2283 for (
int iLoop = 0; iLoop < maxCmdLoop; iLoop++)
2287 useBinaryCmdNow = useBinaryCmd;
2292 useBinaryCmdNow = !useBinaryCmdNow;
2293 useBinaryCmd = useBinaryCmdNow;
2300 if (useBinaryCmdNow)
2303 if (reqBinary.size() > 0)
2321 ROS_INFO_STREAM(
"response to \"sRN SetActiveApplications\": " << sopas_reply);
2322 if (sopas_reply.find(
"FEVL\\x01") != std::string::npos)
2324 if (sopas_reply.find(
"FEVL\\x00") != std::string::npos)
2339 #ifdef USE_DIAGNOSTIC_UPDATER
2364 if (
false == protocolCheck)
2366 restartDueToProcolChange =
true;
2368 useBinaryCmd = useBinaryCmdNow;
2375 if (
false == protocolCheck)
2377 restartDueToProcolChange =
true;
2380 useBinaryCmd = useBinaryCmdNow;
2391 std::string deviceIdent =
"";
2398 std::string deviceIdentKeyWord =
"sRA DeviceIdent";
2399 char *ptr = (
char *) (&(replyDummy[0]));
2401 ptr += deviceIdentKeyWord.length();
2403 sscanf(ptr,
"%d", &idLen);
2404 char *ptr2 = strchr(ptr,
' ');
2408 for (
int j = 0; j < idLen; j++)
2410 deviceIdent += *ptr2;
2417 sscanf(ptr,
"%d", &versionLen);
2418 ptr2 = strchr(ptr,
' ');
2422 deviceIdent +=
" V";
2423 for (
int j = 0; j < versionLen; j++)
2425 deviceIdent += *ptr2;
2429 #ifdef USE_DIAGNOSTIC_UPDATER
2431 diagnostics_->setHardwareID(deviceIdent);
2442 long dummy0, dummy1, identLen, versionLen;
2448 const char *scanMask0 =
"%04y%04ysRA DeviceIdent %02y";
2449 const char *scanMask1 =
"%02y";
2450 unsigned char *replyPtr = &(replyDummy[0]);
2453 binScanfVec(&replyDummy, scanMask0, &dummy0, &dummy1, &identLen);
2456 int off = scanDataLen0 + identLen;
2458 std::vector<unsigned char> restOfReplyDummy = std::vector<unsigned char>(replyDummy.begin() + off,
2462 binScanfVec(&restOfReplyDummy,
"%02y", &versionLen);
2464 std::string fullIdentVersionInfo = identStr +
" V" + versionStr;
2465 #ifdef USE_DIAGNOSTIC_UPDATER
2467 diagnostics_->setHardwareID(fullIdentVersionInfo);
2487 #ifdef USE_DIAGNOSTIC_UPDATER
2503 int deviceState = -1;
2516 &dummy1, &deviceState);
2524 switch (deviceState)
2549 int operationHours = -1;
2557 long dummy0, dummy1;
2571 double hours = 0.1 * operationHours;
2581 int powerOnCount = -1;
2585 long dummy0, dummy1;
2607 const char *searchPattern =
"sRA LocationName ";
2608 strcpy(szLocationName,
"unknown location");
2612 long dummy0, dummy1, locationNameLen;
2613 const char *binLocationNameMask =
"%4y%4ysRA LocationName %2y";
2617 locationNameLen = 0;
2626 strcpy(szLocationName, locationNameStr.c_str());
2631 if (strstr(strPtr, searchPattern) == strPtr)
2633 const char *ptr = strPtr + strlen(searchPattern);
2634 strcpy(szLocationName, ptr);
2638 ROS_WARN(
"Location command not supported.\n");
2642 rosSetParam(nh,
"locationName", std::string(szLocationName));
2656 bool useNegSign =
false;
2657 if (NAV3xxOutputRangeSpecialHandling == 0)
2664 std::vector<unsigned char> tmpVec;
2666 if (useBinaryCmd ==
false)
2668 for (
int j = 0; j <
s.length(); j++)
2670 tmpVec.push_back((
unsigned char)
s[j]);
2690 int cfgListEntry = 1;
2692 rosGetParam(nh,
"scan_cfg_list_entry", cfgListEntry);
2702 double start_ang_rad = (scancfg.
sector_cfg[sector_cnt].start_angle / 10000.0) * (M_PI / 180.0);
2703 double stop_ang_rad = (scancfg.
sector_cfg[sector_cnt].stop_angle / 10000.0) * (M_PI / 180.0);
2708 stop_ang_rad = 2 * M_PI;
2717 scancfg.
sector_cfg[sector_cnt].start_angle = (int32_t)(std::round(10000.0 *
rad2deg(start_ang_rad)));
2718 scancfg.
sector_cfg[sector_cnt].stop_angle = (int32_t)(std::round(10000.0 *
rad2deg(stop_ang_rad)));
2719 ROS_INFO_STREAM(
"Setting LMPscancfg start_angle: " <<
rad2deg(start_ang_rad) <<
" deg, stop_angle: " <<
rad2deg(stop_ang_rad) <<
" deg (lidar sector " << sector_cnt <<
")");
2728 ROS_WARN_STREAM(
"## ERROR in init_scanner(): SickScanParseUtil::LMPscancfgToSopas() failed, start/stop angle not set, default values will be used.");
2733 ROS_WARN_STREAM(
"## ERROR in init_scanner(): SickScanParseUtil::SopasToLMPscancfg() failed, start/stop angle not set, default values will be used.");
2755 if (restartDueToProcolChange)
2767 ROS_INFO(
"IP address changed. Node restart required");
2783 if (initialize_scanner == 0)
2792 ROS_ERROR_STREAM(
"## ERROR SickScanCommon::readParseSafetyFields() failed");
2811 angleRes10000th = (int) (std::round(
2813 std::vector<unsigned char> askOutputAngularRangeReply;
2831 int cfgListEntry = 1;
2833 rosGetParam(nh,
"scan_cfg_list_entry", cfgListEntry);
2836 sprintf(requestsMNmCLsetscancfglist, pcCmdMask, cfgListEntry);
2839 std::vector<unsigned char> reqBinary;
2850 std::vector<unsigned char> lmdScanDataCfgReply;
2859 std::vector<unsigned char> reqBinary;
2873 int askTmpAngleRes10000th = 0;
2874 int askTmpAngleStart10000th = 0;
2875 int askTmpAngleEnd10000th = 0;
2880 int iDummy0, iDummy1;
2881 std::string askOutputAngularRangeStr =
replyToString(askOutputAngularRangeReply);
2897 askTmpAngleRes10000th = 0;
2898 askTmpAngleStart10000th = 0;
2899 askTmpAngleEnd10000th = 0;
2901 const char *askOutputAngularRangeBinMask =
"%4y%4ysRA LMPoutputRange %2y%4y%4y%4y";
2905 &askTmpAngleRes10000th,
2906 &askTmpAngleStart10000th,
2907 &askTmpAngleEnd10000th);
2912 numArgs = sscanf(askOutputAngularRangeStr.c_str(),
"%s %s %d %X %X %X", dummy0, dummy1,
2914 &askTmpAngleRes10000th,
2915 &askTmpAngleStart10000th,
2916 &askTmpAngleEnd10000th);
2920 double askTmpAngleRes = askTmpAngleRes10000th / 10000.0;
2921 double askTmpAngleStart = askTmpAngleStart10000th / 10000.0;
2922 double askTmpAngleEnd = askTmpAngleEnd10000th / 10000.0;
2924 angleRes10000th = askTmpAngleRes10000th;
2925 ROS_INFO_STREAM(
"Angle resolution of scanner is " << askTmpAngleRes <<
" [deg] (in 1/10000th deg: "
2926 << askTmpAngleRes10000th <<
")");
2928 "[From:To] " << askTmpAngleStart <<
" [deg] to " << askTmpAngleEnd <<
" [deg] (in 1/10000th deg: from "
2929 << askTmpAngleStart10000th <<
" to " << askTmpAngleEnd10000th <<
")");
2958 angleStart10000th = (int)(std::round(10000.0 * minAngSopas));
2959 angleEnd10000th = (int)(std::round(10000.0 * maxAngSopas));
2965 ROS_INFO(
"Angular start/stop settings for LMS 1000 not reliable.\n");
2966 double askAngleStart = -137.0;
2967 double askAngleEnd = +137.0;
2974 std::vector<unsigned char> outputAngularRangeReply;
2983 sprintf(requestOutputAngularRange, pcCmdMask, angleRes10000th, angleStart10000th, angleEnd10000th);
2986 unsigned char tmpBuffer[255] = {0};
2987 unsigned char sendBuffer[255] = {0};
2989 std::vector<unsigned char> reqBinary;
2995 strcpy((
char *) tmpBuffer,
"WN LMPoutputRange ");
2996 unsigned short orgLen = strlen((
char *) tmpBuffer);
2997 if (NAV3xxOutputRangeSpecialHandling)
2999 colab::addIntegerToBuffer<UINT16>(tmpBuffer, orgLen, iStatus);
3000 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
3001 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
3002 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
3003 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
3004 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
3005 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
3006 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
3007 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
3008 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
3009 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
3010 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
3011 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
3015 colab::addIntegerToBuffer<UINT16>(tmpBuffer, orgLen, iStatus);
3016 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
3017 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
3018 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
3027 reqBinary = std::vector<unsigned char>(sendBuffer, sendBuffer + sendLen);
3057 askOutputAngularRangeReply.clear();
3061 std::vector<unsigned char> reqBinary;
3080 int askAngleRes10000th = 0;
3081 int askAngleStart10000th = 0;
3082 int askAngleEnd10000th = 0;
3083 int iDummy0, iDummy1=0;
3088 std::string askOutputAngularRangeStr =
replyToString(askOutputAngularRangeReply);
3093 const char *askOutputAngularRangeBinMask =
"%4y%4ysRA LMPscancfg %4y%2y%4y%4y%4y";
3094 numArgs =
binScanfVec(&askOutputAngularRangeReply, askOutputAngularRangeBinMask,
3099 &askAngleRes10000th,
3100 &askAngleStart10000th,
3101 &askAngleEnd10000th);
3105 numArgs = sscanf(askOutputAngularRangeStr.c_str(),
"%s %s %X %X %X %X %X",
3110 &askAngleRes10000th,
3111 &askAngleStart10000th,
3112 &askAngleEnd10000th);
3116 double askTmpAngleRes = askAngleRes10000th / 10000.0;
3117 double askTmpAngleStart = askAngleStart10000th / 10000.0;
3118 double askTmpAngleEnd = askAngleEnd10000th / 10000.0;
3120 angleRes10000th = askAngleRes10000th;
3121 ROS_INFO_STREAM(
"Angle resolution of scanner is " << askTmpAngleRes <<
" [deg] (in 1/10000th deg: "
3122 << askAngleRes10000th <<
")");
3124 double askAngleRes = askAngleRes10000th / 10000.0;
3125 double askAngleStart = askAngleStart10000th / 10000.0;
3126 double askAngleEnd = askAngleEnd10000th / 10000.0;
3162 askOutputAngularRangeReply.clear();
3166 std::vector<unsigned char> reqBinary;
3180 int askAngleRes10000th = 0;
3181 int askAngleStart10000th = 0;
3182 int askAngleEnd10000th = 0;
3183 int iDummy0, iDummy1;
3186 std::string askOutputAngularRangeStr =
replyToString(askOutputAngularRangeReply);
3205 askAngleRes10000th = 0;
3206 askAngleStart10000th = 0;
3207 askAngleEnd10000th = 0;
3215 const char *askOutputAngularRangeBinMask =
"%4y%4ysRA LMPoutputRange %2y%4y%4y%4y";
3219 &askAngleRes10000th,
3220 &askAngleStart10000th,
3221 &askAngleEnd10000th);
3226 numArgs = sscanf(askOutputAngularRangeStr.c_str(),
"%s %s %d %X %X %X", dummy0, dummy1,
3228 &askAngleRes10000th,
3229 &askAngleStart10000th,
3230 &askAngleEnd10000th);
3234 double askTmpAngleRes = askAngleRes10000th / 10000.0;
3235 double askTmpAngleStart = askAngleStart10000th / 10000.0;
3236 double askTmpAngleEnd = askAngleEnd10000th / 10000.0;
3238 angleRes10000th = askAngleRes10000th;
3239 ROS_INFO_STREAM(
"Angle resolution of scanner is " << askTmpAngleRes <<
" [deg] (in 1/10000th deg: "
3240 << askAngleRes10000th <<
")");
3243 double askAngleRes = askAngleRes10000th / 10000.0;
3244 double askAngleStart = askAngleStart10000th / 10000.0;
3245 double askAngleEnd = askAngleEnd10000th / 10000.0;
3292 for (
size_t i = 0; i < outputChannelFlag.size(); i++)
3302 int filter_echos = 2;
3305 switch (filter_echos)
3314 ROS_INFO(
"LMS 5xx detected overwriting output channel flag ID");
3316 ROS_INFO(
"LMS 5xx detected overwriting resolution flag (only 8 bit supported)");
3322 ROS_INFO(
"MRS 1xxx detected overwriting resolution flag (only 8 bit supported)");
3332 ROS_ERROR_STREAM(
"## ERROR SickScanCommon::readParseSafetyFields() failed");
3338 || (this->parser_->getCurrentParamPtr()->getNumberOfLayers() == 4)
3339 || (this->parser_->getCurrentParamPtr()->getNumberOfLayers() == 24)
3346 int scandatacfg_timingflag = -1;
3347 rosDeclareParam(nh,
"scandatacfg_timingflag", scandatacfg_timingflag);
3348 rosGetParam(nh,
"scandatacfg_timingflag", scandatacfg_timingflag);
3349 if (scandatacfg_timingflag < 0)
3352 scandatacfg_timingflag = 0;
3354 scandatacfg_timingflag = 1;
3356 int rssi_flag = rssiFlag ? 1 : 0;
3359 int scandatacfg_azimuth_table = 0;
3360 rosDeclareParam(nh,
"scandatacfg_azimuth_table", scandatacfg_azimuth_table);
3361 rosGetParam(nh,
"scandatacfg_azimuth_table", scandatacfg_azimuth_table);
3362 if (scandatacfg_azimuth_table != 0)
3364 ROS_INFO_STREAM(
"MRS1xxx scandatacfg_azimuth_table=" << scandatacfg_azimuth_table <<
", rssi_flag=" << rssi_flag <<
", azimuth table " << ((rssi_flag & 0x02) != 0 ?
"":
"not ") <<
"activated");
3373 rssiResolutionIs16Bit ? 1 : 0,
3374 EncoderSettings > 0 ? 1 : 0,
3375 scandatacfg_timingflag);
3378 std::vector<unsigned char> reqBinary;
3390 std::vector<unsigned char> lmdScanDataCfgReply;
3407 std::vector<unsigned char> reqBinary;
3414 std::vector<unsigned char> lmdScanDataCfgReadReply;
3423 double scan_freq = 0;
3429 if (scan_freq != 0 || ang_res != 0)
3431 if (scan_freq != 0 && ang_res != 0)
3435 ROS_INFO(
"variable ang_res and scan_freq setings for OEM15xx NAV 3xx or LRD-36XX has not been implemented");
3477 int32_t start_angle_in_10000th = (int32_t)(std::round(10000.0 *
rad2deg(start_ang_rad)));
3478 int32_t stop_angle_in_10000th = (int32_t)(std::round(10000.0 *
rad2deg(stop_ang_rad)));
3480 ROS_INFO_STREAM(
"Prepare mLMPsetscancfg: Start Angle in 10000th deg in lidar notation: " << start_angle_in_10000th);
3481 ROS_INFO_STREAM(
"Prepare mLMPsetscancfg: Stop Angle in 10000th deg in lidar notation : " << stop_angle_in_10000th);
3483 lmp_scancfg_sector.
start_angle = start_angle_in_10000th;
3484 lmp_scancfg_sector.
stop_angle = stop_angle_in_10000th;
3491 lmp_scancfg.
sector_cfg.push_back(lmp_scancfg_sector);
3492 std::string lmp_scancfg_sopas;
3496 std::vector<unsigned char> reqBinary, lmp_scancfg_reply;
3508 std::string sopasReplyString =
replyToString(lmp_scancfg_reply);
3509 if (strncmp(sopasReplyString.c_str(),
"sAN mLMPsetscancfg ", 19) == 0)
3514 << (scancfg_response.
sector_cfg.size() > 0 ? (scancfg_response.
sector_cfg[0].angular_resolution / 10000.0) : -1.0) <<
" deg.");
3519 ROS_WARN_STREAM(
"sick_scan_xd::init_scanner: sick_scan_xd::SickScanParseUtil::LMPscancfgToSopas() failed");
3524 ROS_WARN_STREAM(
"sick_scan_xd::init_scanner: \"sMN mLMPsetscancfg\" currently not supported for "
3526 <<
", scan frequency and angular resolution not set, using default values ("
3527 << __FILE__ <<
":" << __LINE__ <<
")");
3556 std::vector<unsigned char> reqBinary;
3561 if (strncmp(sopasReplyString.c_str(),
"sRA LMPscancfg ", 15) == 0)
3566 << (scancfg_response.
sector_cfg.size() > 0 ? (scancfg_response.
sector_cfg[0].angular_resolution / 10000.0) : -1.0) <<
" deg.");
3571 std::vector<unsigned char> lmdScanDataCfgReadReply;
3580 ROS_ERROR(
"ang_res and scan_freq have to be set, only one param is set skiping scan_fre/ang_res config");
3627 int filterEchoSetting = 2;
3629 rosGetParam(nh,
"filter_echos", filterEchoSetting);
3631 if (filterEchoSetting < 0)
3632 { filterEchoSetting = 0; }
3633 if (filterEchoSetting > 2)
3634 { filterEchoSetting = 2; }
3642 sprintf(requestEchoSetting, pcCmdMask, filterEchoSetting);
3643 std::vector<unsigned char> outputFilterEchoRangeReply;
3648 std::vector<unsigned char> reqBinary;
3671 std::vector<int> startProtocolSequence;
3672 if (initialize_scanner == 0)
3678 bool activate_lidoutputstate =
false;
3679 bool transmitRawTargets =
true;
3680 bool transmitObjects =
true;
3681 int trackingMode = 0;
3682 std::string trackingModeDescription[] = {
"BASIC",
"VEHICLE"};
3684 int numTrackingModes =
sizeof(trackingModeDescription) /
sizeof(trackingModeDescription[0]);
3687 rosGetParam(nh,
"transmit_raw_targets", transmitRawTargets);
3690 rosGetParam(nh,
"transmit_objects", transmitObjects);
3695 rosDeclareParam(nh,
"activate_lidoutputstate", activate_lidoutputstate);
3696 rosGetParam(nh,
"activate_lidoutputstate", activate_lidoutputstate);
3698 ROS_INFO_STREAM(
"LIDoutputstate messages are switched [" << (activate_lidoutputstate ?
"ON" :
"OFF") <<
"]");
3699 ROS_INFO_STREAM(
"Raw target transmission is switched [" << (transmitRawTargets ?
"ON" :
"OFF") <<
"]");
3700 ROS_INFO_STREAM(
"Object transmission is switched [" << (transmitObjects ?
"ON" :
"OFF") <<
"]");
3701 ROS_INFO_STREAM(
"Tracking mode [" << trackingMode <<
"] [" << ((trackingMode >= 0 && trackingMode < numTrackingModes) ? trackingModeDescription[trackingMode] :
"unknown") <<
"]");
3709 if (activate_lidoutputstate)
3719 if (transmitRawTargets)
3728 if (transmitObjects)
3736 if (!transmitRawTargets && !transmitObjects)
3738 ROS_WARN(
"Both ObjectData and TargetData are disabled. Check launchfile, parameter \"transmit_raw_targets\" or \"transmit_objects\" or both should be activated.");
3741 switch (trackingMode)
3750 ROS_DEBUG(
"Tracking mode switching sequence unknown\n");
3757 startProtocolSequence.push_back(
CMD_RUN);
3766 bool activate_lferec =
true, activate_lidoutputstate =
true, activate_lidinputstate =
true;
3768 rosDeclareParam(nh,
"activate_lidoutputstate", activate_lidoutputstate);
3769 rosDeclareParam(nh,
"activate_lidinputstate", activate_lidinputstate);
3770 if (
true ==
rosGetParam(nh,
"activate_lferec", activate_lferec) &&
true == activate_lferec)
3775 if (
true ==
rosGetParam(nh,
"activate_lidoutputstate", activate_lidoutputstate) &&
true == activate_lidoutputstate)
3780 if (
true ==
rosGetParam(nh,
"activate_lidinputstate", activate_lidinputstate) &&
true == activate_lidinputstate)
3794 startProtocolSequence.push_back(
CMD_RUN);
3804 startProtocolSequence.push_back(
CMD_RUN);
3810 bool imu_enable =
false;
3815 if (useBinaryCmdNow ==
true)
3817 ROS_INFO(
"Enable IMU data transfer");
3824 "IMU USAGE NOT POSSIBLE IN ASCII COMMUNICATION MODE.\nTo use the IMU the communication with the scanner must be set to binary mode.\n This can be done by inserting the line:\n<param name=\"use_binary_protocol\" type=\"bool\" value=\"True\" />\n into the launchfile.\n See also https://github.com/SICKAG/sick_scan_xd/blob/master/doc/IMU.md");
3830 ROS_INFO(
"IMU data transfer not enabled");
3835 std::vector<int>::iterator it;
3836 for (it = startProtocolSequence.begin(); it != startProtocolSequence.end(); it++)
3841 std::vector<unsigned char> replyDummy;
3842 std::vector<unsigned char> reqBinary;
3843 std::vector<unsigned char> sopasVec;
3862 #ifdef USE_DIAGNOSTIC_UPDATER
3875 ROS_DEBUG(
"Starting radar data ....\n");
3888 if (waitForDeviceState)
3890 int maxWaitForDeviceStateReady = 45;
3891 bool scannerReady =
false;
3892 for (
int i = 0; i < maxWaitForDeviceStateReady; i++)
3894 double shortSleepTime = 1.0;
3896 std::vector<unsigned char> replyDummyDeviceState;
3899 int deviceState = 0;
3901 std::vector<unsigned char> reqBinaryDeviceState;
3902 std::vector<unsigned char> sopasVecDeviceState;
3921 long dummy0, dummy1;
3926 &dummy1, &deviceState);
3934 if (deviceState == 1)
3936 scannerReady =
true;
3937 ROS_INFO_STREAM(
"Scanner ready for measurement after " << i <<
" [sec]");
3941 ROS_INFO_STREAM(
"Waiting for scanner ready state since " << i <<
" secs");
3948 if(i==(maxWaitForDeviceStateReady-1))
3959 std::string device_type_response =
sopasReplyStrVec[cmdId], rms_type_str =
"";
3960 size_t cmd_type_idx = device_type_response.find(
"DItype ");
3961 if (cmd_type_idx != std::string::npos)
3962 device_type_response = device_type_response.substr(cmd_type_idx + 7);
3963 size_t radar_type_idx = device_type_response.find(
"RMS");
3964 if (radar_type_idx != std::string::npos)
3965 rms_type_str = device_type_response.substr(radar_type_idx, 4);
3966 ROS_INFO_STREAM(
"Radar device type response: \"" <<
sopasReplyStrVec[cmdId] <<
"\" -> device type = \"" << device_type_response <<
"\" (" << rms_type_str <<
")");
3968 if (rms_type_str ==
"RMS1")
3972 for (std::vector<int>::iterator start_cmd_iter = startProtocolSequence.begin(); start_cmd_iter != startProtocolSequence.end(); start_cmd_iter++)
3977 ROS_INFO_STREAM(
"1D radar \"" << rms_type_str <<
"\" device detected, tracking mode disabled");
3979 else if (rms_type_str ==
"RMS2")
3983 ROS_INFO_STREAM(
"3D radar \"" << rms_type_str <<
"\" device detected, tracking mode enabled");
3987 ROS_ERROR_STREAM(
"## ERROR init_scanner(): Unexpected device type \"" << device_type_response <<
"\", expected device type starting with \"RMS1\" or \"RMS2\"");
4005 int nav_curr_layer = 0;
4007 rosGetParam(nh,
"nav_curr_layer", nav_curr_layer);
4019 bool nav_do_initial_mapping =
false;
4020 rosDeclareParam(nh,
"nav_do_initial_mapping", nav_do_initial_mapping);
4021 rosGetParam(nh,
"nav_do_initial_mapping", nav_do_initial_mapping);
4022 if (nav_do_initial_mapping)
4031 int nav_map_cfg_mean = 50, nav_map_cfg_neg = 0, nav_map_cfg_x = 0, nav_map_cfg_y = 0, nav_map_cfg_phi = 0, nav_map_cfg_reflector_size = 80;
4033 rosGetParam(nh,
"nav_map_cfg_mean", nav_map_cfg_mean);
4035 rosGetParam(nh,
"nav_map_cfg_neg", nav_map_cfg_neg);
4041 rosGetParam(nh,
"nav_map_cfg_phi", nav_map_cfg_phi);
4042 rosDeclareParam(nh,
"nav_map_cfg_reflector_size", nav_map_cfg_reflector_size);
4043 rosGetParam(nh,
"nav_map_cfg_reflector_size", nav_map_cfg_reflector_size);
4044 sopasCmdVec[
CMD_SET_NAV_MAP_CFG] = std::string(
"\x02sWN NMAPMapCfg ") + std::to_string(nav_map_cfg_mean) +
" " + std::to_string(nav_map_cfg_neg) +
" " + std::to_string(nav_map_cfg_x) +
" " + std::to_string(nav_map_cfg_y) +
" " + std::to_string(nav_map_cfg_phi) +
" " +
"\x03";
4063 ROS_WARN_STREAM(
"## ERROR parseNAV350BinaryLandmarkDataDoMappingResponse() failed");
4066 landmarkData.
print();
4071 std::vector<uint8_t> addLandmarkRequest = { 0x02, 0x02, 0x02, 0x02, 0, 0, 0, 0 };
4072 addLandmarkRequest.insert(addLandmarkRequest.end(), addLandmarkRequestPayload.begin(), addLandmarkRequestPayload.end());
4079 ROS_ERROR_STREAM(
"## ERROR parseNAV350BinaryLandmarkDataDoMappingResponse(): Not enough landmarks detected for initial mapping.");
4087 std::string nav_set_landmark_layout_by_imk_file =
"";
4088 rosDeclareParam(nh,
"nav_set_landmark_layout_by_imk_file", nav_set_landmark_layout_by_imk_file);
4089 rosGetParam(nh,
"nav_set_landmark_layout_by_imk_file", nav_set_landmark_layout_by_imk_file);
4090 if (!nav_set_landmark_layout_by_imk_file.empty())
4092 std::vector<sick_scan_xd::NAV350ImkLandmark> navImkLandmarks =
readNAVIMKfile(nav_set_landmark_layout_by_imk_file);
4093 if (navImkLandmarks.size() >= 3)
4101 for (
size_t i = 0; i < navImkLandmarks.size(); i += 50)
4103 size_t limit = std::min<size_t>(navImkLandmarks.size(), i + 50);
4105 std::vector<uint8_t> addLandmarkRequest = { 0x02, 0x02, 0x02, 0x02, 0, 0, 0, 0 };
4106 addLandmarkRequest.insert(addLandmarkRequest.end(), addLandmarkRequestPayload.begin(), addLandmarkRequestPayload.end());
4108 ROS_DEBUG_STREAM(
"Sending landmarks, " << addLandmarkRequest.size() <<
" byte sopas request (" << addLandmarkRequestPayload.size()
4117 else if (navImkLandmarks.size() > 0)
4119 ROS_ERROR_STREAM(
"## ERROR readNAVIMKfile(): Less than 3 landmarks configured in \"" << nav_set_landmark_layout_by_imk_file <<
"\". At least 3 landmarks required.");
4124 ROS_ERROR_STREAM(
"## ERROR readNAVIMKfile(): Can't read or parse imk file \"" << nav_set_landmark_layout_by_imk_file <<
"\".");
4129 int nav_operation_mode = 4;
4131 rosGetParam(nh,
"nav_operation_mode", nav_operation_mode);
4133 switch(nav_operation_mode)
4151 ROS_WARN_STREAM(
"Invalid parameter nav_operation_mode = " << nav_operation_mode <<
", expected 0, 1, 2, 3 or 4, using default mode 4 (navigation)");
4152 nav_operation_mode = 4;
4161 bool nav_start_polling =
true;
4163 rosGetParam(nh,
"nav_start_polling", nav_start_polling);
4164 if (!nav_start_polling)
4165 ROS_WARN_STREAM(
"NAV350 Warning: start polling deactivated by configuration, no data will be received unless data polling started externally by sopas command \"sMN mNPOSGetData 1 2\"");
4166 for (
int retry_cnt = 0; nav_start_polling ==
true && retry_cnt < 10 &&
rosOk(); retry_cnt++)
4171 ROS_ERROR_STREAM(
"## ERROR NAV350: Error sending sMN mNPOSGetData request, retrying ...");
4192 std::string reply_str;
4193 std::vector<unsigned char>::const_iterator it_start, it_end;
4194 int binLen = this->checkForBinaryAnswer(&reply);
4197 it_start = reply.begin();
4198 it_end = reply.end();
4202 it_start = reply.begin() + 8;
4203 it_end = reply.end() - 1;
4205 bool inHexPrintMode =
false;
4206 for (std::vector<unsigned char>::const_iterator it = it_start; it != it_end; it++)
4210 if (*it >= 0x20 && (inHexPrintMode ==
false))
4212 reply_str.push_back(*it);
4218 char szTmp[255] = {0};
4219 unsigned char val = *it;
4220 inHexPrintMode =
true;
4221 sprintf(szTmp,
"\\x%02x", val);
4222 for (
size_t ii = 0; ii < strlen(szTmp); ii++)
4224 reply_str.push_back(szTmp[ii]);
4235 static size_t max_dump_size = 64 * 1024 * 1024;
4236 static size_t datasize_cnt = 0;
4237 static int file_cnt = 0;
4239 char szDumpFileName[511] = {0};
4240 char szDir[255] = {0};
4242 if (datasize_cnt > max_dump_size)
4244 ROS_WARN_STREAM(
"Attention: verboseLevel is set to 1 (debugging only). Total dump size of " << (max_dump_size / (1024 * 1024)) <<
" MByte in /tmp folder exceeded, data NOT dumped to file.");
4247 ROS_WARN(
"Attention: verboseLevel is set to 1 (debugging only). Datagrams are stored in the /tmp folder.");
4249 strcpy(szDir,
"C:\\temp\\");
4251 strcpy(szDir,
"/tmp/");
4253 sprintf(szDumpFileName,
"%ssick_datagram_%06d.bin", szDir, file_cnt);
4257 ftmp = fopen(szDumpFileName,
"wb");
4260 fwrite(buffer, bufLen, 1, ftmp);
4265 datasize_cnt += bufLen;
4279 char device_string[7];
4280 int version_major = -1;
4281 int version_minor = -1;
4283 strcpy(device_string,
"???");
4285 if (sscanf(identStr.c_str(),
"sRA 0 6 %6s E V%d.%d", device_string,
4286 &version_major, &version_minor) == 3
4287 && strncmp(
"TiM3", device_string, 4) == 0
4288 && version_major >= 2 && version_minor >= 50)
4290 ROS_ERROR(
"This scanner model/firmware combination does not support ranging output!");
4291 ROS_ERROR(
"Supported scanners: TiM5xx: all firmware versions; TiM3xx: firmware versions < V2.50.");
4292 ROS_ERROR_STREAM(
"This is a " << device_string <<
", firmware version " << version_major <<
"." << version_minor);
4297 bool supported =
false;
4300 if (sscanf(identStr.c_str(),
"sRA 0 6 %6s E V%d.%d", device_string, &version_major, &version_minor) == 3)
4302 std::string devStr = device_string;
4305 if (devStr.compare(0, 4,
"TiM5") == 0)
4310 if (supported ==
true)
4312 ROS_INFO_STREAM(
"Device " << identStr <<
" V" << version_major <<
"." << version_minor <<
" found and supported by this driver.");
4317 if ((identStr.find(
"MRS1xxx") !=
4319 || (identStr.find(
"LMS1xxx") != std::string::npos)
4322 ROS_INFO_STREAM(
"Deviceinfo " << identStr <<
" found and supported by this driver.");
4327 if (identStr.find(
"MRS6") !=
4330 ROS_INFO_STREAM(
"Deviceinfo " << identStr <<
" found and supported by this driver.");
4334 if (identStr.find(
"RMS1") != std::string::npos || identStr.find(
"RMS2") != std::string::npos)
4336 ROS_INFO_STREAM(
"Deviceinfo " << identStr <<
" found and supported by this driver.");
4341 if (identStr.find(
"LD-LRSxx") != std::string::npos)
4343 ROS_INFO_STREAM(
"Deviceinfo " << identStr <<
" found and supported by this driver.");
4347 if (supported ==
false)
4349 ROS_WARN_STREAM(
"Device " << device_string <<
"s V" << version_major <<
"." << version_minor <<
" found and maybe unsupported by this driver.");
4363 #ifdef USE_DIAGNOSTIC_UPDATER
4366 #if __ROS_VERSION == 2 // ROS 2
4367 diagnostics_->force_update();
4369 diagnostics_->update();
4374 unsigned char receiveBuffer[65536];
4375 int actual_length = 0;
4376 static unsigned int iteration_count = 0;
4381 rosTime recvTimeStampPush = recvTimeStamp;
4390 int packetsInLoop = 0;
4392 const int maxNumAllowedPacketsToProcess = 25;
4394 int numPacketsProcessed = 0;
4396 static bool firstTimeCalled =
true;
4397 static bool dumpData =
false;
4398 static int verboseLevel = 0;
4399 static bool slamBundle =
false;
4400 float timeIncrement;
4401 static std::string echoForSlam =
"";
4402 if (firstTimeCalled ==
true)
4412 firstTimeCalled =
false;
4416 const std::vector<std::string> datagram_keywords = {
4417 "LMDscandata",
"LMDscandatamon",
"mNPOSGetData",
4418 "LMDradardata",
"InertialMeasurementUnit",
"LIDoutputstate",
"LIDinputstate",
"LFErec" };
4420 int result =
get_datagram(nh, recvTimeStamp, receiveBuffer, 65536, &actual_length, useBinaryProtocol, &packetsInLoop, datagram_keywords);
4421 numPacketsProcessed++;
4423 rosDuration dur = recvTimeStampPush - recvTimeStamp;
4428 #ifdef USE_DIAGNOSTIC_UPDATER
4434 if (actual_length <= 0)
4449 datagram_msg.data = std::string(
reinterpret_cast<char *
>(receiveBuffer));
4454 if (verboseLevel > 0)
4466 if ( (useBinaryProtocol && memcmp(&receiveBuffer[8],
"sSN LIDoutputstate", strlen(
"sSN LIDoutputstate")) == 0)
4467 || (!useBinaryProtocol && memcmp(&receiveBuffer[1],
"sSN LIDoutputstate", strlen(
"sSN LIDoutputstate")) == 0))
4488 errorCode = radar->
parseDatagram(recvTimeStamp, (
unsigned char *) receiveBuffer, actual_length, useBinaryProtocol);
4494 if (scanImu.
isImuDatagram((
char *) receiveBuffer, actual_length))
4504 errorCode = scanImu.
parseDatagram(recvTimeStamp, (
unsigned char *) receiveBuffer, actual_length,
4510 else if(memcmp(&receiveBuffer[8],
"sSN LIDoutputstate", strlen(
"sSN LIDoutputstate")) == 0)
4537 else if(memcmp(&receiveBuffer[8],
"sSN LIDinputstate", strlen(
"sSN LIDinputstate")) == 0)
4542 if(fieldMon && useBinaryProtocol && actual_length > 32)
4560 else if(memcmp(&receiveBuffer[8],
"sSN LFErec", strlen(
"sSN LFErec")) == 0)
4587 else if(memcmp(&receiveBuffer[8],
"sSN LMDscandatamon", strlen(
"sSN LMDscandatamon")) == 0)
4590 ROS_DEBUG_STREAM(
"SickScanCommon: received " << actual_length <<
" byte LMDscandatamon (ignored) ...");
4593 else if(memcmp(&receiveBuffer[8],
"sMA mNPOSGetData", strlen(
"sMA mNPOSGetData")) == 0)
4596 ROS_DEBUG_STREAM(
"NAV350: received " << actual_length <<
" byte \"sMA mNPOSGetData\", waiting for \"sAN mNPOSGetData\" ...");
4605 bool FireEncoder =
false;
4606 EncoderMsg.header.frame_id =
"Encoder";
4610 double elevationAngleInRad = 0.0;
4611 short elevAngleX200 = 0;
4613 double elevAngleTelegramValToDeg = 1.0 / 200.0;
4616 elevAngleTelegramValToDeg = 1.0 / 100.0;
4621 char *buffer_pos = (
char *) receiveBuffer;
4622 char *dstart, *dend;
4623 bool dumpDbg =
false;
4624 bool dataToProcess =
true;
4625 std::vector<float> vang_vec, azimuth_vec;
4630 while (dataToProcess)
4632 const int maxAllowedEchos = 5;
4634 int numValidEchos = 0;
4635 int aiValidEchoIdx[maxAllowedEchos] = {0};
4640 bool publishPointCloud =
true;
4642 if (useBinaryProtocol)
4645 std::vector<unsigned char> receiveBufferVec = std::vector<unsigned char>(receiveBuffer,
4646 receiveBuffer + actual_length);
4647 #ifdef DEBUG_DUMP_TO_CONSOLE_ENABLED
4648 if (actual_length > 1000)
4656 if (receiveBufferVec.size() > 8)
4660 memcpy(&idVal, receiveBuffer + 0, 4);
4661 memcpy(&lenVal, receiveBuffer + 4, 4);
4664 if (idVal == 0x02020202)
4669 char szFileName[255];
4672 sprintf(szFileName,
"c:\\temp\\dump%05d.bin", cnt);
4674 sprintf(szFileName,
"/tmp/dump%05d.txt", cnt);
4677 fout = fopen(szFileName,
"wb");
4678 fwrite(receiveBuffer, actual_length, 1, fout);
4684 if (actual_length > 17 && memcmp(&receiveBuffer[8],
"sAN mNPOSGetData ", 17) == 0)
4687 success =
handleNAV350BinaryPositionData(receiveBuffer, actual_length, elevAngleX200, elevationAngleInRad, recvTimeStamp,
config_.
sw_pll_only_publish,
config_.
time_offset,
parser_, numEchos,
msg, navdata);
4689 ROS_ERROR_STREAM(
"## ERROR SickScanCommon::loopOnce(): handleNAV350BinaryPositionData() failed");
4691 else if (lenVal >= actual_length || actual_length < 64)
4696 ROS_WARN_STREAM(
"## WARNING in SickScanCommon::loopOnce(): " << actual_length <<
" byte message ignored ("
4699 ROS_INFO_STREAM(
"SickScanCommon::loopOnce(): " << actual_length <<
" byte message ignored");
4706 ROS_ERROR_STREAM(
"## ERROR SickScanCommon::loopOnce(): parseCommonBinaryResultTelegram() failed");
4710 dataToProcess =
false;
4714 timeIncrement =
msg.time_increment;
4715 echoMask = (1 << numEchos) - 1;
4724 dataToProcess =
false;
4728 dstart = strchr(buffer_pos, 0x02);
4731 dend = strchr(dstart + 1, 0x03);
4733 if ((dstart !=
NULL) && (dend !=
NULL))
4735 dataToProcess =
true;
4736 dlength = dend - dstart;
4742 dataToProcess =
false;
4750 char szFileName[255];
4753 sprintf(szFileName,
"c:\\temp\\dump%05d.txt", cnt);
4755 sprintf(szFileName,
"/tmp/dump%05d.txt", cnt);
4759 fout = fopen(szFileName,
"wb");
4760 fwrite(dstart, dlength, 1, fout);
4774 publishPointCloud =
true;
4777 for (
int i = 0; i < maxAllowedEchos; i++)
4779 aiValidEchoIdx[i] = 0;
4788 bool elevationPreCalculated =
false;
4789 double elevationAngleDegree = 0.0;
4792 std::vector<float> rangeTmp =
msg.ranges;
4793 std::vector<float> intensityTmp =
msg.intensities;
4795 int intensityTmpNum = intensityTmp.size();
4796 float *intensityTmpPtr =
NULL;
4797 if (intensityTmpNum > 0)
4799 intensityTmpPtr = &intensityTmp[0];
4808 switch (numOfLayers)
4816 if (elevAngleX200 == 250)
4818 else if (elevAngleX200 == 0)
4820 else if (elevAngleX200 == -250)
4822 else if (elevAngleX200 == -500)
4825 elevationAngleDegree = elevationAngleDegree / 180.0 * M_PI;
4830 layer = (elevAngleX200 - (-2638)) / 125;
4831 layer = (23 - layer) - 1;
4834 elevationAngleDegree = elevationAngleDegree / 180.0 * M_PI;
4837 elevationPreCalculated =
true;
4855 else if (numEchos > 0)
4858 size_t startOffset = 0;
4859 size_t endOffset = 0;
4860 int echoPartNum =
msg.ranges.size() / numEchos;
4861 for (
int i = 0; i < numEchos; i++)
4864 bool sendMsg =
false;
4867 aiValidEchoIdx[numValidEchos] = i;
4871 startOffset = i * echoPartNum;
4872 endOffset = (i + 1) * echoPartNum;
4875 msg.intensities.clear();
4876 msg.ranges = std::vector<float>(
4877 rangeTmp.begin() + startOffset,
4878 rangeTmp.begin() + endOffset);
4880 if (endOffset <= intensityTmp.size() && (intensityTmp.size() > 0))
4882 msg.intensities = std::vector<float>(
4883 intensityTmp.begin() + startOffset,
4884 intensityTmp.begin() + endOffset);
4888 msg.intensities.resize(echoPartNum);
4892 char szTmp[255] = {0};
4897 sprintf(szTmp,
"%s_%+04d_DIST%d", cpFrameId,
msg.header.seq, i + 1);
4898 #else // experimental
4899 char szSignName[10] = {0};
4900 int seqDummy = elevAngleX200;
4903 strcpy(szSignName,
"NEG");
4907 strcpy(szSignName,
"POS");
4911 sprintf(szTmp,
"%s_%s_%03d_DIST%d", cpFrameId, szSignName, abs((
int)seqDummy), i + 1);
4919 msg.header.frame_id = std::string(szTmp);
4921 if (echoForSlam.length() > 0)
4929 msg.header.frame_id = echoForSlam;
4930 strcpy(szTmp, echoForSlam.c_str());
4931 if (elevationAngleInRad != 0.0)
4933 float cosVal = (float)cos(elevationAngleInRad);
4934 int rangeNum =
msg.ranges.size();
4935 for (
int j = 0; j < rangeNum; j++)
4937 msg.ranges[j] *= cosVal;
4943 if (echoForSlam.compare(szTmp) == 0)
4955 for (
int j = 0, j_max = (
int)std::min<size_t>(
msg.ranges.size(),
msg.intensities.size()); j < j_max; j++)
4959 msg.ranges[j] = std::numeric_limits<float>::infinity();
4971 if (numOfLayers > 4)
4979 #if defined USE_DIAGNOSTIC_UPDATER // && __ROS_VERSION == 1
4999 ROS_WARN_STREAM(
"## WARNING in SickScanCommon::loopOnce(): no echos in measurement message (numEchos=" << numEchos
5000 <<
", msg.ranges.size()=" <<
msg.ranges.size() <<
", msg.intensities.size()=" <<
msg.intensities.size() <<
")");
5002 ROS_INFO_STREAM(
"SickScanCommon::loopOnce(): no echos in measurement message");
5005 if (publishPointCloud ==
true && numValidEchos > 0 &&
msg.ranges.size() > 0)
5009 const int numChannels = 4;
5011 int numTmpLayer = numOfLayers;
5024 cloud_.height = numTmpLayer * numValidEchos;
5026 cloud_.is_bigendian =
false;
5028 cloud_.point_step = numChannels *
sizeof(float);
5030 cloud_.fields.resize(numChannels);
5031 for (
int i = 0; i < numChannels; i++)
5033 std::string channelId[] = {
"x",
"y",
"z",
"intensity"};
5034 cloud_.fields[i].name = channelId[i];
5035 cloud_.fields[i].offset = i *
sizeof(float);
5036 cloud_.fields[i].count = 1;
5037 cloud_.fields[i].datatype = ros_sensor_msgs::PointField::FLOAT32;
5054 unsigned char *cloudDataPtr = &(
cloud_.data[0]);
5055 unsigned char *cloudDataPtr_polar = &(
cloud_polar_.data[0]);
5059 std::vector<float> cosAlphaTable;
5060 std::vector<float> sinAlphaTable;
5062 size_t rangeNumAllEchos = rangeTmp.size();
5063 size_t rangeNumAllEchosCloud =
cloud_.height *
cloud_.width;
5064 rangeNumAllEchos = std::min<size_t>(rangeNumAllEchos, rangeNumAllEchosCloud);
5065 size_t rangeNum = rangeNumAllEchos / numValidEchos;
5068 cosAlphaTable.resize(rangeNum);
5069 sinAlphaTable.resize(rangeNum);
5070 float mirror_factor = 1.0;
5074 mirror_factor = -1.0;
5077 size_t rangeNumPointcloudAllEchos = 0;
5079 for (
size_t iEcho = 0; iEcho < numValidEchos; iEcho++)
5087 angle =
msg.angle_min - angleShift;
5090 float *cosAlphaTablePtr = &cosAlphaTable[0];
5091 float *sinAlphaTablePtr = &sinAlphaTable[0];
5093 float *vangPtr =
NULL;
5094 float *azimuthPtr =
NULL;
5095 float *rangeTmpPtr = &rangeTmp[0];
5096 if (vang_vec.size() > 0)
5098 vangPtr = &vang_vec[0];
5100 if (azimuth_vec.size() > 0)
5102 azimuthPtr = &azimuth_vec[0];
5105 size_t rangeNumPointcloudCurEcho = 0;
5106 for (
size_t rangeIdxScan = 0; rangeIdxScan < rangeNum; rangeIdxScan++)
5108 enum enum_index_descr
5116 long pointcloud_adroff = rangeNumPointcloudCurEcho * (numChannels * (int)
sizeof(
float));
5117 pointcloud_adroff += (layer - baseLayer) *
cloud_.row_step;
5118 pointcloud_adroff += iEcho *
cloud_.row_step * numTmpLayer;
5119 assert(pointcloud_adroff <
cloud_.data.size());
5121 unsigned char *ptr = cloudDataPtr + pointcloud_adroff;
5122 float *fptr = (
float *) (cloudDataPtr + pointcloud_adroff);
5123 float *fptr_polar = (
float *) (cloudDataPtr_polar + pointcloud_adroff);
5134 if (elevationPreCalculated)
5136 alpha = (float)elevationAngleInRad;
5140 alpha = (float)(layer * elevationAngleDegree);
5146 cosAlphaTablePtr[rangeIdxScan] = cos(alpha);
5147 sinAlphaTablePtr[rangeIdxScan] = sin(alpha);
5155 float range_meter = rangeTmpPtr[iEcho * rangeNum + rangeIdxScan];
5156 bool range_modified =
false;
5157 if (range_filter.
apply(range_meter, range_modified))
5163 float rangeCos = range_meter * cosAlphaTablePtr[rangeIdxScan];
5165 double phi_used = phi + angleShift;
5173 phi_used = azimuthPtr[rangeIdxScan];
5178 fptr[idx_x] = rangeCos * (float)cos(phi2_used) * mirror_factor;
5179 fptr[idx_y] = rangeCos * (float)sin(phi2_used) * mirror_factor;
5180 fptr[idx_z] = range_meter * sinAlphaTablePtr[rangeIdxScan] * mirror_factor;
5185 fptr_polar[idx_x] = range_meter;
5186 fptr_polar[idx_y] = phi_used;
5187 fptr_polar[idx_z] = alpha;
5189 fptr[idx_intensity] = 0.0;
5192 int intensityIndex = aiValidEchoIdx[iEcho] * rangeNum + rangeIdxScan;
5194 if (intensityIndex < intensityTmpNum)
5196 fptr[idx_intensity] = intensityTmpPtr[intensityIndex];
5199 fptr_polar[idx_intensity] = fptr[idx_intensity];
5200 rangeNumPointcloudCurEcho++;
5204 rangeNumPointcloudAllEchos = std::max<size_t>(rangeNumPointcloudAllEchos, rangeNumPointcloudCurEcho);
5208 int layerOff = (layer - baseLayer);
5212 bool shallIFire =
false;
5213 if ((elevAngleX200 == 0) || (elevAngleX200 == 237))
5219 int cur_layer = (layer - baseLayer);
5224 static int layerCnt = 0;
5225 static int layerSeq[4];
5230 layerSeq[layerCnt % 4] = layer;
5278 int numTotalShots = 360;
5279 int numPartialShots = 40;
5281 for (
int i = 0; i < numTotalShots; i += numPartialShots)
5287 partialTimeStamp = partialTimeStamp +
rosDurationFromSec((i + 0.5 * (numPartialShots - 1)) * timeIncrement);
5288 partialTimeStamp = partialTimeStamp +
rosDurationFromSec((3 * numTotalShots) * timeIncrement);
5289 partialCloud.header.stamp = partialTimeStamp;
5290 partialCloud.width = numPartialShots * 3;
5292 int diffTo1100 =
cloud_.width - 3 * (numTotalShots + i);
5293 if (diffTo1100 > numPartialShots)
5295 diffTo1100 = numPartialShots;
5301 partialCloud.width += diffTo1100;
5303 partialCloud.height = 1;
5306 partialCloud.is_bigendian =
false;
5307 partialCloud.is_dense =
true;
5308 partialCloud.point_step = numChannels *
sizeof(float);
5309 partialCloud.row_step = partialCloud.point_step * partialCloud.width;
5310 partialCloud.fields.resize(numChannels);
5311 for (
int ii = 0; ii < numChannels; ii++)
5313 std::string channelId[] = {
"x",
"y",
"z",
"intensity"};
5314 partialCloud.fields[ii].name = channelId[ii];
5315 partialCloud.fields[ii].offset = ii *
sizeof(float);
5316 partialCloud.fields[ii].count = 1;
5317 partialCloud.fields[ii].datatype = ros_sensor_msgs::PointField::FLOAT32;
5320 partialCloud.data.resize(partialCloud.row_step, 0);
5323 for (
int j = 0; j < 4; j++)
5325 int layerIdx = (j + (layerCnt)) % 4;
5326 int rowIdx = 1 + layerSeq[layerIdx % 4];
5327 int colIdx = j * numTotalShots + i;
5328 int maxAvail =
cloud_.width - colIdx;
5334 if (maxAvail > numPartialShots)
5336 maxAvail = numPartialShots;
5342 memcpy(&(partialCloud.data[partOff]),
5344 cloud_.point_step * maxAvail);
5348 partOff += maxAvail * partialCloud.point_step;
5350 assert(partialCloud.data.size() == partialCloud.width * partialCloud.point_step);
5369 buffer_pos = dend + 1;
5376 }
while ((packetsInLoop > 0) && (numPacketsProcessed < maxNumAllowedPacketsToProcess));
5388 ROS_WARN(
"Maximum angle must be greater than minimum angle. Adjusting >min_ang<.");
5404 #if defined USE_DYNAMIC_RECONFIGURE && __ROS_VERSION == 2
5405 rcl_interfaces::msg::SetParametersResult SickScanCommon::update_config_cb(
const std::vector<rclcpp::Parameter> ¶meters)
5407 rcl_interfaces::msg::SetParametersResult result;
5408 result.successful =
true;
5409 result.reason =
"success";
5410 if(!parameters.empty())
5414 for (
const auto ¶meter : parameters)
5416 ROS_DEBUG_STREAM(
"SickScanCommon::update_config_cb(): parameter " << parameter.get_name());
5417 if(parameter.get_name() ==
"frame_id" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_STRING)
5418 new_config.
frame_id = parameter.as_string();
5419 else if(parameter.get_name() ==
"imu_frame_id" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_STRING)
5421 else if(parameter.get_name() ==
"intensity" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_BOOL)
5422 new_config.
intensity = parameter.as_bool();
5423 else if(parameter.get_name() ==
"auto_reboot" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_BOOL)
5425 else if(parameter.get_name() ==
"min_ang" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_DOUBLE)
5426 new_config.
min_ang = parameter.as_double();
5427 else if(parameter.get_name() ==
"max_ang" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_DOUBLE)
5428 new_config.
max_ang = parameter.as_double();
5429 else if(parameter.get_name() ==
"ang_res" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_DOUBLE)
5430 new_config.
ang_res = parameter.as_double();
5431 else if(parameter.get_name() ==
"skip" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_INTEGER)
5432 new_config.
skip = parameter.as_int();
5433 else if(parameter.get_name() ==
"sw_pll_only_publish" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_BOOL)
5435 else if(parameter.get_name() ==
"use_generation_timestamp" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_BOOL)
5437 else if(parameter.get_name() ==
"time_offset" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_DOUBLE)
5439 else if(parameter.get_name() ==
"cloud_output_mode" && parameter.get_type() == rclcpp::ParameterType::PARAMETER_INTEGER)
5457 requestBinary->clear();
5458 if (requestAscii ==
NULL)
5462 int cmdLen = strlen(requestAscii);
5467 if (requestAscii[0] != 0x02)
5471 if (requestAscii[cmdLen - 1] != 0x03)
5476 for (
int i = 0; i < 4; i++)
5478 requestBinary->push_back(0x02);
5481 for (
int i = 0; i < 4; i++)
5483 requestBinary->push_back(0x00);
5486 unsigned long msgLen = cmdLen - 2;
5490 std::string keyWord0 =
"sMN SetAccessMode";
5491 std::string keyWord1 =
"sWN FREchoFilter";
5492 std::string keyWord2 =
"sEN LMDscandata";
5493 std::string keyWord3 =
"sWN LMDscandatacfg";
5494 std::string keyWord4 =
"sWN SetActiveApplications";
5495 std::string keyWord5 =
"sEN IMUData";
5496 std::string keyWord6 =
"sWN EIIpAddr";
5497 std::string keyWord7 =
"sMN mLMPsetscancfg";
5498 std::string keyWord8 =
"sWN TSCTCupdatetime";
5499 std::string keyWord9 =
"sWN TSCTCSrvAddr";
5500 std::string keyWord10 =
"sWN LICencres";
5501 std::string keyWord11 =
"sWN LFPmeanfilter";
5502 std::string KeyWord12 =
"sRN field";
5503 std::string KeyWord13 =
"sMN mCLsetscancfglist";
5504 std::string KeyWord14 =
"sWN LFPmeanfilter";
5505 std::string KeyWord15 =
"sWN LFPmedianfilter";
5506 std::string KeyWord16 =
"sWN LMDscandatascalefactor";
5507 std::string KeyWord17 =
"sWN GlareDetectionSens";
5508 std::string KeyWord18 =
"sWN ScanLayerFilter";
5509 std::string KeyWord19 =
"sMN mNPOSGetData";
5510 std::string KeyWord20 =
"sMN mNPOSSetPose";
5511 std::string KeyWord21 =
"sWN NEVACurrLayer";
5512 std::string KeyWord22 =
"sWN NMAPMapCfg";
5513 std::string KeyWord23 =
"sWN NLMDReflSize";
5514 std::string KeyWord24 =
"sWN NPOSPoseDataFormat";
5515 std::string KeyWord25 =
"sWN NLMDLandmarkDataFormat";
5516 std::string KeyWord26 =
"sWN NAVScanDataFormat";
5517 std::string KeyWord27 =
"sMN mNLAYEraseLayout";
5518 std::string KeyWord28 =
"sWN ActiveFieldSet";
5522 std::string cmdAscii = requestAscii;
5525 int copyUntilSpaceCnt = 2;
5527 char hexStr[255] = {0};
5529 unsigned char buffer[255];
5531 if (cmdAscii.find(keyWord0) != std::string::npos)
5533 copyUntilSpaceCnt = 2;
5534 int keyWord0Len = keyWord0.length();
5535 sscanf(requestAscii + keyWord0Len + 1,
" %d %s", &level, hexStr);
5536 buffer[0] = (
unsigned char) (0xFF & level);
5538 char hexTmp[3] = {0};
5539 for (
int i = 0; i < 4; i++)
5542 hexTmp[0] = hexStr[i * 2];
5543 hexTmp[1] = hexStr[i * 2 + 1];
5545 sscanf(hexTmp,
"%x", &val);
5546 buffer[i + 1] = (
unsigned char) (0xFF & val);
5550 if (cmdAscii.find(keyWord1) != std::string::npos)
5552 int echoCodeNumber = 0;
5553 int keyWord1Len = keyWord1.length();
5554 sscanf(requestAscii + keyWord1Len + 1,
" %d", &echoCodeNumber);
5555 buffer[0] = (
unsigned char) (0xFF & echoCodeNumber);
5558 if (cmdAscii.find(keyWord2) != std::string::npos)
5560 int scanDataStatus = 0;
5561 int keyWord2Len = keyWord2.length();
5562 sscanf(requestAscii + keyWord2Len + 1,
" %d", &scanDataStatus);
5563 buffer[0] = (
unsigned char) (0xFF & scanDataStatus);
5567 if (cmdAscii.find(keyWord3) != std::string::npos)
5569 int scanDataStatus = 0;
5570 int keyWord3Len = keyWord3.length();
5571 int dummyArr[12] = {0};
5573 int sscanfresult = sscanf(requestAscii + keyWord3Len + 1,
" %d %d %d %d %d %d %d %d %d %d %d %d",
5586 if (1 < sscanfresult)
5589 for (
int i = 0; i < 13; i++)
5593 buffer[0] = (
unsigned char) (0xFF & dummyArr[0]);
5594 buffer[1] = (
unsigned char) (0xFF & dummyArr[1]);;
5595 buffer[2] = (
unsigned char) (0xFF & dummyArr[2]);
5596 buffer[3] = (
unsigned char) (0xFF & dummyArr[3]);
5597 buffer[4] = (
unsigned char) (0xFF & dummyArr[4]);
5598 buffer[5] = (
unsigned char) (0xFF & dummyArr[5]);
5599 buffer[6] = (
unsigned char) (0xFF & dummyArr[6]);
5600 buffer[7] = (
unsigned char) (0xFF & dummyArr[7]);
5601 buffer[8] = (
unsigned char) (0xFF & dummyArr[8]);
5602 buffer[9] = (
unsigned char) (0xFF & dummyArr[9]);
5603 buffer[10] = (
unsigned char) (0xFF & dummyArr[10]);
5604 buffer[11] = (
unsigned char) (0xFF & (dummyArr[11] >> 8));
5605 buffer[12] = (
unsigned char) (0xFF & (dummyArr[11] >> 0));
5612 if (cmdAscii.find(keyWord4) != std::string::npos)
5614 char tmpStr[1024] = {0};
5615 char szApplStr[255] = {0};
5616 int keyWord4Len = keyWord4.length();
5617 int scanDataStatus = 0;
5619 strcpy(tmpStr, requestAscii + keyWord4Len + 2);
5620 sscanf(tmpStr,
"%d %s %d", &dummy0, szApplStr, &dummy1);
5623 buffer[1] = dummy0 ? 0x01 : 0x00;
5624 for (
int ii = 0; ii < 4; ii++)
5626 buffer[2 + ii] = szApplStr[ii];
5628 buffer[6] = dummy1 ? 0x01 : 0x00;
5633 if (version_id[0] > 1)
5639 std::vector<uint8_t> binary_parameter = {0x00, 0x02, 0x46, 0x45, 0x56, 0x4C, field_evaluation_status, 0x52, 0x41, 0x4e, 0x47, 0x01};
5640 for (
int ii = 0; ii < binary_parameter.size(); ii++)
5641 buffer[ii] = binary_parameter[ii];
5642 bufferLen = binary_parameter.size();
5645 if (version_id[0] < 2)
5647 if (version_id[0] == 2 && version_id[1] < 2)
5654 if (version_id[0] < 2)
5656 if (version_id[0] == 2 && version_id[1] < 2)
5661 if (cmdAscii.find(keyWord5) != std::string::npos)
5663 int imuSetStatus = 0;
5664 int keyWord5Len = keyWord5.length();
5665 sscanf(requestAscii + keyWord5Len + 1,
" %d", &imuSetStatus);
5666 buffer[0] = (
unsigned char) (0xFF & imuSetStatus);
5670 if (cmdAscii.find(keyWord6) != std::string::npos)
5673 int imuSetStatus = 0;
5674 int keyWord6Len = keyWord6.length();
5675 sscanf(requestAscii + keyWord6Len + 1,
" %x %x %x %x", &(adrPartArr[0]), &(adrPartArr[1]), &(adrPartArr[2]),
5677 buffer[0] = (
unsigned char) (0xFF & adrPartArr[0]);
5678 buffer[1] = (
unsigned char) (0xFF & adrPartArr[1]);
5679 buffer[2] = (
unsigned char) (0xFF & adrPartArr[2]);
5680 buffer[3] = (
unsigned char) (0xFF & adrPartArr[3]);
5691 if (cmdAscii.find(keyWord7) != std::string::npos)
5695 for (
int i = keyWord7.length() + 2, i_max = strlen(requestAscii) - 1; i + 3 < i_max && bufferLen <
sizeof(buffer); i += 4, bufferLen++)
5697 char hex_str[] = { requestAscii[i + 2], requestAscii[i + 3],
'\0' };
5698 buffer[bufferLen] = (std::stoul(hex_str,
nullptr, 16) & 0xFF);
5705 for (
int i = 0; i < bufferLen; i++)
5707 unsigned char uch = 0x00;
5716 char tmpStr[1024] = {0};
5717 char szApplStr[255] = {0};
5718 int keyWord7Len = keyWord7.length();
5719 int scanDataStatus = 0;
5721 strcpy(tmpStr, requestAscii + keyWord7Len + 2);
5722 sscanf(tmpStr,
"%d 1 %d", &dummy0, &dummy1);
5724 buffer[0] = (
unsigned char) (0xFF & (dummy0 >> 24));
5725 buffer[1] = (
unsigned char) (0xFF & (dummy0 >> 16));
5726 buffer[2] = (
unsigned char) (0xFF & (dummy0 >> 8));
5727 buffer[3] = (
unsigned char) (0xFF & (dummy0 >> 0));
5730 buffer[6] = (
unsigned char) (0xFF & (dummy1 >> 24));
5731 buffer[7] = (
unsigned char) (0xFF & (dummy1 >> 16));
5732 buffer[8] = (
unsigned char) (0xFF & (dummy1 >> 8));
5733 buffer[9] = (
unsigned char) (0xFF & (dummy1 >> 0));
5738 int keyWord7Len = keyWord7.length();
5739 int dummyArr[14] = {0};
5740 if (14 == sscanf(requestAscii + keyWord7Len + 1,
" %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
5741 &dummyArr[0], &dummyArr[1], &dummyArr[2],
5742 &dummyArr[3], &dummyArr[4], &dummyArr[5],
5743 &dummyArr[6], &dummyArr[7], &dummyArr[8],
5744 &dummyArr[9], &dummyArr[10], &dummyArr[11], &dummyArr[12], &dummyArr[13]))
5746 for (
int i = 0; i < 54; i++)
5750 int targetPosArr[] = {0, 4, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54};
5751 int numElem = (
sizeof(targetPosArr) /
sizeof(targetPosArr[0])) - 1;
5752 for (
int i = 0; i < numElem; i++)
5754 int lenOfBytesToRead = targetPosArr[i + 1] - targetPosArr[i];
5755 int adrPos = targetPosArr[i];
5756 unsigned char *destPtr = buffer + adrPos;
5757 memcpy(destPtr, &(dummyArr[i]), lenOfBytesToRead);
5760 bufferLen = targetPosArr[numElem];
5772 if (cmdAscii.find(keyWord8) != std::string::npos)
5774 uint32_t updatetime = 0;
5775 int keyWord8Len = keyWord8.length();
5776 sscanf(requestAscii + keyWord8Len + 1,
" %d", &updatetime);
5777 buffer[0] = (
unsigned char) (0xFF & (updatetime >> 24));
5778 buffer[1] = (
unsigned char) (0xFF & (updatetime >> 16));
5779 buffer[2] = (
unsigned char) (0xFF & (updatetime >> 8));
5780 buffer[3] = (
unsigned char) (0xFF & (updatetime >> 0));
5783 if (cmdAscii.find(keyWord9) != std::string::npos)
5786 int imuSetStatus = 0;
5787 int keyWord9Len = keyWord9.length();
5788 sscanf(requestAscii + keyWord9Len + 1,
" %x %x %x %x", &(adrPartArr[0]), &(adrPartArr[1]), &(adrPartArr[2]),
5790 buffer[0] = (
unsigned char) (0xFF & adrPartArr[0]);
5791 buffer[1] = (
unsigned char) (0xFF & adrPartArr[1]);
5792 buffer[2] = (
unsigned char) (0xFF & adrPartArr[2]);
5793 buffer[3] = (
unsigned char) (0xFF & adrPartArr[3]);
5796 if (cmdAscii.find(keyWord10) != std::string::npos)
5798 float EncResolution = 0;
5800 int keyWord10Len = keyWord10.length();
5801 sscanf(requestAscii + keyWord10Len + 1,
" %f", &EncResolution);
5802 memcpy(buffer, &EncResolution, bufferLen);
5806 if (cmdAscii.find(keyWord11) != std::string::npos)
5808 char tmpStr[1024] = {0};
5809 char szApplStr[255] = {0};
5810 int keyWord11Len = keyWord11.length();
5811 int dummy0, dummy1,dummy2;
5812 strcpy(tmpStr, requestAscii + keyWord11Len + 2);
5813 sscanf(tmpStr,
"%d %d %d", &dummy0, &dummy1, &dummy2);
5815 buffer[0] = dummy0 ? 0x01 : 0x00;
5816 buffer[1] =dummy1/256;
5817 buffer[2] =dummy1%256;
5821 if (cmdAscii.find(KeyWord12) != std::string::npos)
5823 uint32_t fieldID = 0;
5824 int keyWord12Len = KeyWord12.length();
5825 sscanf(requestAscii + keyWord12Len + 1,
"%d", &fieldID);
5828 if (cmdAscii.find(KeyWord13) != std::string::npos)
5830 int scanCfgListEntry = 0;
5831 int keyWord13Len = KeyWord13.length();
5832 sscanf(requestAscii + keyWord13Len + 1,
" %d", &scanCfgListEntry);
5833 buffer[0] = (
unsigned char) (0xFF & scanCfgListEntry);
5836 if (cmdAscii.find(KeyWord14) != std::string::npos)
5839 int args[3] = { 0, 0, 0 };
5840 sscanf(requestAscii + KeyWord14.length() + 1,
" %d %d %d", &(
args[0]), &(
args[1]), &(
args[2]));
5841 buffer[0] = (
unsigned char) (0xFF &
args[0]);
5842 buffer[1] = (
unsigned char) (0xFF & (
args[1] >> 8));
5843 buffer[2] = (
unsigned char) (0xFF & (
args[1] >> 0));
5844 buffer[3] = (
unsigned char) (0xFF &
args[2]);
5847 if (cmdAscii.find(KeyWord15) != std::string::npos)
5850 int args[2] = { 0, 0 };
5851 sscanf(requestAscii + KeyWord15.length() + 1,
" %d %d", &(
args[0]), &(
args[1]));
5852 buffer[0] = (
unsigned char) (0xFF &
args[0]);
5853 buffer[1] = (
unsigned char) (0xFF & (
args[1] >> 8));
5854 buffer[2] = (
unsigned char) (0xFF & (
args[1] >> 0));
5857 if (cmdAscii.find(KeyWord16) != std::string::npos)
5861 sscanf(requestAscii + KeyWord16.length() + 1,
" %x", &
args);
5862 buffer[0] = (
unsigned char) (0xFF & (
args >> 24));
5863 buffer[1] = (
unsigned char) (0xFF & (
args >> 16));
5864 buffer[2] = (
unsigned char) (0xFF & (
args >> 8));
5865 buffer[3] = (
unsigned char) (0xFF & (
args >> 0));
5868 if (cmdAscii.find(KeyWord17) != std::string::npos)
5871 int args[1] = { 0 };
5872 sscanf(requestAscii + KeyWord17.length() + 1,
" %d", &(
args[0]));
5873 buffer[0] = (
unsigned char) (0xFF &
args[0]);
5876 if (cmdAscii.find(KeyWord18) != std::string::npos && strlen(requestAscii) > KeyWord18.length() + 1)
5885 buffer[bufferLen++] = (
unsigned char) (0xFF & (num_layers >> 8));
5886 buffer[bufferLen++] = (
unsigned char) (0xFF & num_layers);
5887 for(
int n = 0; n < num_layers; n++)
5891 if (cmdAscii.find(KeyWord19) != std::string::npos && strlen(requestAscii) > KeyWord19.length() + 1)
5894 int args[2] = { 0, 0 };
5895 sscanf(requestAscii + KeyWord19.length() + 1,
" %d %d", &(
args[0]), &(
args[1]));
5896 buffer[0] = (
unsigned char) (0xFF &
args[0]);
5897 buffer[1] = (
unsigned char) (0xFF &
args[1]);
5900 if (cmdAscii.find(KeyWord20) != std::string::npos && strlen(requestAscii) > KeyWord20.length() + 1)
5902 int32_t
args[3] = { 0, 0, 0 };
5903 sscanf(requestAscii + KeyWord20.length() + 1,
" %d %d %d", &(
args[0]), &(
args[1]), &(
args[2]));
5905 for(
int arg_cnt = 0; arg_cnt < 3; arg_cnt++)
5907 buffer[bufferLen + 0] = (
unsigned char) (0xFF & (
args[arg_cnt] >> 24));
5908 buffer[bufferLen + 1] = (
unsigned char) (0xFF & (
args[arg_cnt] >> 16));
5909 buffer[bufferLen + 2] = (
unsigned char) (0xFF & (
args[arg_cnt] >> 8));
5910 buffer[bufferLen + 3] = (
unsigned char) (0xFF & (
args[arg_cnt] >> 0));
5914 if (cmdAscii.find(KeyWord21) != std::string::npos && strlen(requestAscii) > KeyWord21.length() + 1)
5916 int args[1] = { 0 };
5917 sscanf(requestAscii + KeyWord21.length() + 1,
" %d", &(
args[0]));
5918 buffer[0] = (
unsigned char) (0xFF & (
args[0] >> 8));
5919 buffer[1] = (
unsigned char) (0xFF & (
args[0] >> 0));
5922 if (cmdAscii.find(KeyWord22) != std::string::npos && strlen(requestAscii) > KeyWord22.length() + 1)
5924 int args[5] = { 0, 0, 0, 0, 0 };
5925 sscanf(requestAscii + KeyWord22.length() + 1,
" %d %d %d %d %d", &(
args[0]), &(
args[1]), &(
args[2]), &(
args[3]), &(
args[4]));
5926 buffer[0] = (
unsigned char) (0xFF &
args[0]);
5927 buffer[1] = (
unsigned char) (0xFF &
args[1]);
5929 for(
int arg_cnt = 2; arg_cnt < 5; arg_cnt++)
5931 buffer[bufferLen + 0] = (
unsigned char) (0xFF & (
args[arg_cnt] >> 24));
5932 buffer[bufferLen + 1] = (
unsigned char) (0xFF & (
args[arg_cnt] >> 16));
5933 buffer[bufferLen + 2] = (
unsigned char) (0xFF & (
args[arg_cnt] >> 8));
5934 buffer[bufferLen + 3] = (
unsigned char) (0xFF & (
args[arg_cnt] >> 0));
5938 if (cmdAscii.find(KeyWord23) != std::string::npos && strlen(requestAscii) > KeyWord23.length() + 1)
5940 int args[1] = { 0 };
5941 sscanf(requestAscii + KeyWord23.length() + 1,
" %d", &(
args[0]));
5942 buffer[0] = (
unsigned char) (0xFF & (
args[0] >> 8));
5943 buffer[1] = (
unsigned char) (0xFF & (
args[0] >> 0));
5946 if (cmdAscii.find(KeyWord24) != std::string::npos && strlen(requestAscii) > KeyWord24.length() + 1)
5948 int args[2] = { 0, 0 };
5949 sscanf(requestAscii + KeyWord24.length() + 1,
" %d %d", &(
args[0]), &(
args[1]));
5950 buffer[0] = (
unsigned char) (0xFF & (
args[0]));
5951 buffer[1] = (
unsigned char) (0xFF & (
args[1]));
5955 if (cmdAscii.find(KeyWord25) != std::string::npos && strlen(requestAscii) > KeyWord25.length() + 1)
5957 int args[3] = { 0, 0, 0 };
5958 sscanf(requestAscii + KeyWord25.length() + 1,
" %d %d %d", &(
args[0]), &(
args[1]), &(
args[2]));
5959 buffer[0] = (
unsigned char) (0xFF & (
args[0]));
5960 buffer[1] = (
unsigned char) (0xFF & (
args[1]));
5961 buffer[2] = (
unsigned char) (0xFF & (
args[2]));
5964 if (cmdAscii.find(KeyWord26) != std::string::npos && strlen(requestAscii) > KeyWord26.length() + 1)
5966 int args[2] = { 0, 0 };
5967 sscanf(requestAscii + KeyWord26.length() + 1,
" %d %d", &(
args[0]), &(
args[1]));
5968 buffer[0] = (
unsigned char) (0xFF & (
args[0]));
5969 buffer[1] = (
unsigned char) (0xFF & (
args[1]));
5972 if (cmdAscii.find(KeyWord27) != std::string::npos && strlen(requestAscii) > KeyWord27.length() + 1)
5974 int args[1] = { 0 };
5975 sscanf(requestAscii + KeyWord27.length() + 1,
" %d", &(
args[0]));
5976 buffer[0] = (
unsigned char) (0xFF & (
args[0]));
5979 if (cmdAscii.find(KeyWord28) != std::string::npos && strlen(requestAscii) > KeyWord28.length() + 1)
5981 int args[1] = { 0 };
5982 sscanf(requestAscii + KeyWord28.length() + 1,
" %d", &(
args[0]));
5983 buffer[0] = (
unsigned char) (0xFF & (
args[0] >> 8));
5984 buffer[1] = (
unsigned char) (0xFF & (
args[0] >> 0));
5989 bool switchDoBinaryData =
false;
5990 for (
int i = 1; i <= (int) (msgLen); i++)
5992 char c = requestAscii[i];
5993 if (switchDoBinaryData ==
true)
5997 if (
c >=
'0' &&
c <=
'9')
6007 requestBinary->push_back(
c);
6008 if (requestAscii[i] == 0x20)
6011 if (spaceCnt >= copyUntilSpaceCnt)
6013 switchDoBinaryData =
true;
6020 for (
int i = 0; i < bufferLen; i++)
6022 requestBinary->push_back(buffer[i]);
6034 int msgLen = (int)requestBinary->size();
6036 for (
int i = 0; i < 4; i++)
6038 (*requestBinary)[4 + i] = (uint8_t)((msgLen >> (3 - i) * 8) & 0xFF);
6040 unsigned char xorVal = 0x00;
6041 xorVal =
sick_crc8((
unsigned char *) (&((*requestBinary)[8])), requestBinary->size() - 8);
6042 requestBinary->push_back(xorVal);
6044 for (
int i = 0; i < requestBinary->size(); i++)
6046 unsigned char c = (*requestBinary)[i];
6047 printf(
"[%c]%02x ", (
c <
' ') ?
'.' :
c,
c) ;
6061 bool retValue =
true;
6063 if (shouldUseBinary == useBinaryCmdNow)
6079 if (shouldUseBinary ==
true)
6088 useBinaryCmdNow = shouldUseBinary;
6097 int eepwritetTimeOut = 1;
6098 bool result =
false;
6101 unsigned long adrBytesLong[4];
6102 std::string
s = ipNewIPAddr;
6103 const char *ptr =
s.c_str();
6105 sscanf(ptr,
"%lu.%lu.%lu.%lu", &(adrBytesLong[0]), &(adrBytesLong[1]), &(adrBytesLong[2]), &(adrBytesLong[3]));
6108 unsigned char ipbytearray[4];
6109 for (
int i = 0; i < 4; i++)
6111 ipbytearray[i] = adrBytesLong[i] & 0xFF;
6115 char ipcommand[255];
6117 sprintf(ipcommand, pcCmdMask, ipbytearray[0], ipbytearray[1], ipbytearray[2], ipbytearray[3]);
6120 std::vector<unsigned char> reqBinary;
6139 std::vector<unsigned char> ipcomandReply;
6140 std::vector<unsigned char> resetReply;
6156 bool result =
false;
6159 unsigned long adrBytesLong[4];
6160 std::string
s = ipNewIPAddr;
6161 const char *ptr =
s.c_str();
6163 sscanf(ptr,
"%lu.%lu.%lu.%lu", &(adrBytesLong[0]), &(adrBytesLong[1]), &(adrBytesLong[2]), &(adrBytesLong[3]));
6166 unsigned char ipbytearray[4];
6167 for (
int i = 0; i < 4; i++)
6169 ipbytearray[i] = adrBytesLong[i] & 0xFF;
6173 char ntpipcommand[255];
6174 char ntpupdatetimecommand[255];
6176 sprintf(ntpipcommand, pcCmdMask, ipbytearray[0], ipbytearray[1], ipbytearray[2], ipbytearray[3]);
6179 sprintf(ntpupdatetimecommand, pcCmdMaskUpdatetime, 5);
6180 std::vector<unsigned char> outputFilterntpupdatetimecommand;
6184 std::vector<unsigned char> reqBinary;
6201 std::vector<unsigned char> ipcomandReply;
6202 std::vector<unsigned char> resetReply;
6232 std::istringstream ascii_args(parameter);
6233 std::string ascii_arg;
6234 for (
int arg_cnt = 0; getline(ascii_args, ascii_arg,
' '); arg_cnt++)
6237 if (sscanf(ascii_arg.c_str(),
"%d", &arg_val) == 1 && arg_val >= 0)
6261 std::stringstream
s;
6262 s <<
"ScanLayerFilterCfg: filter_settings=\"" << scan_layer_filter <<
"\", " << scan_layer_activated.size() <<
" layers, layer_activation=[";
6263 for(
int n = 0; n < scan_layer_activated.size(); n++)
6264 s << (n > 0 ?
"," :
"") << scan_layer_activated[n];
6266 s <<
"first_active_layer=" << first_active_layer <<
", last_active_layer=" << last_active_layer;
6277 int field_set_selection_method = -1;
6278 int active_field_set = -1;
6280 rosGetParam(
m_nh,
"field_set_selection_method", field_set_selection_method);
6283 std::vector<unsigned char> sopasReply;
6284 if (field_set_selection_method >= 0)
6291 if (active_field_set >= 0)
6305 for(
int fieldnum=0;fieldnum<maxFieldnum;fieldnum++)
6309 sprintf(requestFieldcfg, pcCmdMask, fieldnum);
6311 std::vector<unsigned char> reqBinary;
6312 std::vector<unsigned char> fieldcfgReply;
6318 std::vector<unsigned char> fieldcfgReply;
6332 std::stringstream field_info;
6333 field_info <<
"Safety fieldset " << fieldset <<
", pointcounter = [ ";
6334 for(
int n = 0; n < fieldMon->
getMonFields().size(); n++)
6335 field_info << (n > 0 ?
", " :
" ") << fieldMon->
getMonFields()[n].getPointCount();
6338 for(
int n = 0; n < fieldMon->
getMonFields().size(); n++)
6342 std::stringstream field_info2;
6343 field_info2 <<
"Safety field " << n <<
", type " << (int)(fieldMon->
getMonFields()[n].fieldType()) <<
" : ";
6344 for(
int m = 0; m < fieldMon->
getMonFields()[n].getPointCount(); m++)
6347 field_info2 <<
", ";
6348 field_info2 <<
"(" << fieldMon->
getMonFields()[n].getFieldPointsX()[m] <<
"," << fieldMon->
getMonFields()[n].getFieldPointsY()[m] <<
")";
6361 std::string LIDinputstateRequest =
"\x02sRN LIDinputstate\x03";
6362 std::vector<unsigned char> LIDinputstateResponse;
6365 std::vector<unsigned char> reqBinary;
6392 std::vector<unsigned char> reqBinary;
6393 sprintf(reqAscii,
"\x02sWN FieldSetSelectionMethod %d\x03", field_set_selection_method);
6415 std::vector<unsigned char> reqBinary;
6416 sprintf(reqAscii,
"\x02sRN FieldSetSelectionMethod\x03");
6428 uint8_t sopas_field_set_selection_method = (uint8_t)field_set_selection_method;
6430 field_set_selection_method = sopas_field_set_selection_method;
6444 std::vector<unsigned char> reqBinary;
6445 sprintf(reqAscii,
"\x02sWN ActiveFieldSet %02d\x03", active_field_set);
6468 std::vector<unsigned char> reqBinary;
6469 sprintf(reqAscii,
"\x02sRN ActiveFieldSet\x03");
6481 uint16_t sopas_active_field_set = (uint16_t)active_field_set;
6483 active_field_set = sopas_active_field_set;