52 #ifdef _MSC_VER // compiling simulation for MS-Visual C++ - not defined for linux system 53 #pragma warning(disable: 4996) 54 #pragma warning(disable: 4267) // due to conversion warning size_t in the ros header file 55 #define _WIN32_WINNT 0x0501 67 #include "sick_scan/rosconsole_simu.hpp" 72 #include <sick_scan/RadarScan.h> 74 #include "sick_scan/Encoder.h" 79 #define _USE_MATH_DEFINES 84 #define rad2deg(x) ((x) / M_PI * 180.0) 87 #define deg2rad_const (0.017453292519943295769236907684886f) 104 unsigned char *buf = (ptr);
105 unsigned char tmpChar;
106 for (
int i = 0; i < numBytes / 2; i++)
108 tmpChar = buf[numBytes - 1 - i];
109 buf[numBytes - 1 - i] = buf[i];
124 std::vector<unsigned char> result;
125 for (
size_t j = 0; j < s.length(); j++)
127 result.push_back(s[j]);
145 return (diagnostic_msgs::DiagnosticStatus::ERROR);
160 for (
int i = 0; i < len; i++)
162 char ch = (char) ((*replyDummy)[i + off]);
177 unsigned char sick_crc8(
unsigned char *msgBlock,
int len)
179 unsigned char xorVal = 0x00;
181 for (
int i = off; i < len; i++)
184 unsigned char val = msgBlock[i];
197 bool isParamBinary =
false;
201 for (
size_t i = 0; i < s.size(); i++)
205 isParamBinary =
false;
219 isParamBinary =
true;
222 if (isParamBinary ==
true)
226 unsigned long lenId = 0x00;
227 char szDummy[255] = {0};
228 for (
size_t i = 0; i < s.size(); i++)
247 lenId |= s[i] << (8 * (7 - i));
250 sprintf(szDummy,
"<Len=%04lu>", lenId);
257 unsigned long dataProcessed = i - 8;
267 if (dataProcessed >= (lenId - 1))
277 char ch = dest[dest.length() - 1];
282 sprintf(szDummy,
"0x%02x", s[i]);
285 unsigned long dataProcessed = i - 8;
286 if (dataProcessed >= (lenId - 1))
294 sprintf(szDummy,
" CRC:<0x%02x>", s[i]);
305 for (
size_t i = 0; i < s.size(); i++)
336 diagnosticPub_(NULL), parser_(parser)
345 dynamic_reconfigure::Server<sick_scan::SickScanConfig>::CallbackType
f;
353 double min_angle, max_angle, res_angle;
357 cfg.min_ang = min_angle;
358 cfg.max_ang = max_angle;
366 if (publish_datagram_)
370 std::string cloud_topic_val =
"cloud";
371 pn.
getParam(
"cloud_topic", cloud_topic_val);
372 std::string frame_id_val = cloud_topic_val;
373 pn.
getParam(
"frame_id", frame_id_val);
393 ROS_INFO(
"Publishing laserscan-pointcloud2 to %s", cloud_topic_val.c_str());
429 const char requestScanData0[] = {
"\x02sEN LMDscandata 0\x03\0"};
434 printf(
"\nSOPAS - Error stopping streaming scan data!\n");
438 printf(
"\nSOPAS - Stopped streaming scan data.\n");
448 printf(
"\nSOPAS - Error stopping streaming LFErec, LIDoutputstate and LIDinputstate messages!\n");
452 printf(
"\nSOPAS - Stopped streaming LFErec, LIDoutputstate and LIDinputstate messages\n");
466 unsigned long val = 0;
467 for (
int i = 0; i < 4; i++)
490 if (reply->size() < 8)
496 const unsigned char *ptr = &((*reply)[0]);
499 if (binId == 0x02020202)
501 int replyLen = reply->size();
502 if (replyLen == 8 + cmdLen + 1)
523 std::vector<unsigned char> access_reply;
525 int result =
sendSOPASCommand(
"\x02sMN SetAccessMode 3 F4724744\x03\0", &access_reply);
528 ROS_ERROR(
"SOPAS - Error setting access mode");
533 if (access_reply_str !=
"sAN SetAccessMode 1")
535 ROS_ERROR_STREAM(
"SOPAS - Error setting access mode, unexpected response : " << access_reply_str);
543 std::vector<unsigned char> reboot_reply;
547 ROS_ERROR(
"SOPAS - Error rebooting scanner");
552 if (reboot_reply_str !=
"sAN mSCreboot")
554 ROS_ERROR_STREAM(
"SOPAS - Error rebooting scanner, unexpected response : " << reboot_reply_str);
559 ROS_INFO(
"SOPAS - Rebooted scanner");
575 printf(
"sick_scan driver exiting.\n");
586 std::string expectedAnswer =
"";
588 char cntWhiteCharacter = 0;
589 int initalTokenCnt = 2;
590 std::map<std::string, int> specialTokenLen;
591 char firstToken[1024] = {0};
592 specialTokenLen[
"sRI"] = 1;
593 std::string tmpStr =
"";
595 bool isBinary =
false;
596 for (
size_t i = 0; i < 4; i++)
598 if (i < requestStr.size())
600 if (requestStr[i] == 0x02)
608 int iStop = requestStr.size();
613 for (
int i = 0; i < 4; i++)
615 cmdLen |= cmdLen << 8;
616 cmdLen |= requestStr[i + 4];
622 int iStart = (isBinary ==
true) ? 8 : 0;
623 for (
int i = iStart; i < iStop; i++)
625 tmpStr += (char) requestStr[i];
629 tmpStr =
"\x2" + tmpStr;
631 if (sscanf(tmpStr.c_str(),
"\x2%s", firstToken) == 1)
633 if (specialTokenLen.find(firstToken) != specialTokenLen.end())
635 initalTokenCnt = specialTokenLen[firstToken];
640 for (
int i = iStart; i < iStop; i++)
642 if ((requestStr[i] ==
' ') || (requestStr[i] ==
'\x3'))
646 if (cntWhiteCharacter >= initalTokenCnt)
650 if (requestStr[i] ==
'\x2')
655 expectedAnswer += requestStr[i];
662 std::map<std::string, std::string> keyWordMap;
663 keyWordMap[
"sWN"] =
"sWA";
664 keyWordMap[
"sRN"] =
"sRA";
665 keyWordMap[
"sRI"] =
"sRA";
666 keyWordMap[
"sMN"] =
"sAN";
667 keyWordMap[
"sEN"] =
"sEA";
669 for (std::map<std::string, std::string>::iterator it = keyWordMap.begin(); it != keyWordMap.end(); it++)
672 std::string keyWord = it->first;
673 std::string newKeyWord = it->second;
675 size_t pos = expectedAnswer.find(keyWord);
676 if (pos == std::string::npos)
684 expectedAnswer.replace(pos, keyWord.length(), newKeyWord);
688 ROS_WARN(
"Unexpected position of key identifier.\n");
693 return (expectedAnswer);
706 std::vector<unsigned char> requestStringVec;
707 for (
size_t i = 0; i < requestStr.length(); i++)
709 requestStringVec.push_back(requestStr[i]);
727 std::string cmdStr =
"";
729 for (
size_t i = 0; i < requestStr.size(); i++)
732 cmdStr += (char) requestStr[i];
736 std::string errString;
739 errString =
"Error unexpected Sopas Answer for request " +
stripControl(requestStr);
754 std::vector<unsigned char> replyVec;
755 replyStr =
"<STX>" + replyStr +
"<ETX>";
761 std::string tmpStr =
"SOPAS Communication -" + errString;
770 if (answerStr.find(searchPattern) != std::string::npos)
778 ROS_INFO(
"IMU-Data transfer started. No checking of reply to avoid confusing with LMD Scandata\n");
783 std::string tmpMsg =
"Error Sopas answer mismatch " + errString +
"Answer= >>>" + answerStr +
"<<<";
842 ROS_FATAL(
"Failed to init device: %d", result);
849 ROS_INFO(
"Failed to init scanner Error Code: %d\nWaiting for timeout...\n" 850 "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" 851 "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" 852 "1. [Recommended] Set the communication mode with the SOPAS ET software to binary and save this setting in the scanner's EEPROM.\n" 853 "2. Use the parameter \"use_binary_protocol\" to overwrite the default settings of the driver.",
876 std::string unknownStr =
"Command or Error message not defined";
1085 bool isNav2xxOr3xx =
false;
1088 isNav2xxOr3xx =
true;
1092 isNav2xxOr3xx =
true;
1100 bool tryToStopMeasurement =
true;
1103 tryToStopMeasurement =
false;
1111 tryToStopMeasurement =
false;
1114 if (tryToStopMeasurement)
1119 switch (numberOfLayers)
1166 const int MAX_STR_LEN = 1024;
1168 int maxNumberOfEchos = 1;
1174 bool rssiFlag =
false;
1175 bool rssiResolutionIs16Bit =
true;
1176 int activeEchos = 0;
1179 pn.
getParam(
"intensity", rssiFlag);
1180 pn.
getParam(
"intensity_resolution_16bit", rssiResolutionIs16Bit);
1184 std::string sNewIPAddr =
"";
1185 boost::asio::ip::address_v4 ipNewIPAddr;
1186 bool setNewIPAddr =
false;
1187 setNewIPAddr = pn.
getParam(
"new_IP_address", sNewIPAddr);
1190 boost::system::error_code ec;
1191 ipNewIPAddr = boost::asio::ip::address_v4::from_string(sNewIPAddr, ec);
1192 if (ec == boost::system::errc::success)
1199 setNewIPAddr =
false;
1200 ROS_ERROR(
"ERROR: IP ADDRESS could not be parsed Boost Error %s:%d", ec.category().name(), ec.value());;
1204 std::string sNTPIpAdress =
"";
1205 boost::asio::ip::address_v4 NTPIpAdress;
1206 bool setUseNTP =
false;
1207 setUseNTP = pn.
getParam(
"ntp_server_address", sNTPIpAdress);
1210 boost::system::error_code ec;
1211 NTPIpAdress = boost::asio::ip::address_v4::from_string(sNTPIpAdress, ec);
1212 if (ec != boost::system::errc::success)
1215 ROS_ERROR(
"ERROR: NTP Server IP ADDRESS could not be parsed Boost Error %s:%d", ec.category().name(),
1222 pn.
getParam(
"active_echos", activeEchos);
1224 ROS_INFO(
"Parameter setting for <active_echo: %d>", activeEchos);
1225 std::vector<bool> outputChannelFlag;
1226 outputChannelFlag.resize(maxNumberOfEchos);
1229 for (i = 0; i < outputChannelFlag.size(); i++)
1247 outputChannelFlag[i] =
true;
1251 if (numOfFlags == 0)
1253 outputChannelFlag[0] =
true;
1255 ROS_WARN(
"Activate at least one echo.");
1259 int EncoderSetings = -1;
1260 pn.
getParam(
"encoder_mode", EncoderSetings);
1294 int angleRes10000th = 0;
1295 int angleStart10000th = 0;
1296 int angleEnd10000th = 0;
1309 volatile bool useBinaryCmd =
false;
1312 useBinaryCmd =
true;
1315 bool useBinaryCmdNow =
false;
1318 const int shortTimeOutInMs = 5000;
1319 const int defaultTimeOutInMs = 120000;
1323 bool restartDueToProcolChange =
false;
1328 bool NAV3xxOutputRangeSpecialHandling=
false;
1331 NAV3xxOutputRangeSpecialHandling =
true;
1340 std::vector<unsigned char> replyDummy;
1341 std::vector<unsigned char> reqBinary;
1344 for (
size_t j = 0; j < sopasCmd.length(); j++)
1346 sopasCmdVec.push_back(sopasCmd[j]);
1354 for (
int iLoop = 0; iLoop < maxCmdLoop; iLoop++)
1358 useBinaryCmdNow = useBinaryCmd;
1363 useBinaryCmdNow = !useBinaryCmdNow;
1364 useBinaryCmd = useBinaryCmdNow;
1371 if (useBinaryCmdNow)
1412 if (
false == protocolCheck)
1414 restartDueToProcolChange =
true;
1416 useBinaryCmd = useBinaryCmdNow;
1423 if (
false == protocolCheck)
1425 restartDueToProcolChange =
true;
1428 useBinaryCmd = useBinaryCmdNow;
1439 std::string deviceIdent =
"";
1446 std::string deviceIdentKeyWord =
"sRA DeviceIdent";
1447 char *ptr = (
char *) (&(replyDummy[0]));
1449 ptr += deviceIdentKeyWord.length();
1451 sscanf(ptr,
"%d", &idLen);
1452 char *ptr2 = strchr(ptr,
' ');
1456 for (
int i = 0; i < idLen; i++)
1458 deviceIdent += *ptr2;
1465 sscanf(ptr,
"%d", &versionLen);
1466 ptr2 = strchr(ptr,
' ');
1470 deviceIdent +=
" V";
1471 for (
int i = 0; i < versionLen; i++)
1473 deviceIdent += *ptr2;
1486 long dummy0, dummy1, identLen, versionLen;
1492 const char *scanMask0 =
"%04y%04ysRA DeviceIdent %02y";
1493 const char *scanMask1 =
"%02y";
1494 unsigned char *replyPtr = &(replyDummy[0]);
1497 binScanfVec(&replyDummy, scanMask0, &dummy0, &dummy1, &identLen);
1500 int off = scanDataLen0 + identLen;
1502 std::vector<unsigned char> restOfReplyDummy = std::vector<unsigned char>(replyDummy.begin() + off,
1506 binScanfVec(&restOfReplyDummy,
"%02y", &versionLen);
1508 std::string fullIdentVersionInfo = identStr +
" V" + versionStr;
1541 int deviceState = -1;
1554 &dummy1, &deviceState);
1562 switch (deviceState)
1587 int operationHours = -1;
1595 long dummy0, dummy1;
1609 double hours = 0.1 * operationHours;
1610 pn.
setParam(
"operationHours", hours);
1617 int powerOnCount = -1;
1621 long dummy0, dummy1;
1632 pn.
setParam(
"powerOnCount", powerOnCount);
1640 char szLocationName[MAX_STR_LEN] = {0};
1642 const char *searchPattern =
"sRA LocationName ";
1643 strcpy(szLocationName,
"unknown location");
1647 long dummy0, dummy1, locationNameLen;
1648 const char *binLocationNameMask =
"%4y%4ysRA LocationName %2y";
1652 locationNameLen = 0;
1661 strcpy(szLocationName, locationNameStr.c_str());
1666 if (strstr(strPtr, searchPattern) == strPtr)
1668 const char *ptr = strPtr + strlen(searchPattern);
1669 strcpy(szLocationName, ptr);
1673 ROS_WARN(
"Location command not supported.\n");
1676 pn.
setParam(
"locationName", std::string(szLocationName));
1691 bool useNegSign =
false;
1692 if (NAV3xxOutputRangeSpecialHandling == 0)
1699 std::vector<unsigned char> tmpVec;
1701 if (useBinaryCmd ==
false)
1703 for (
int i = 0; i < s.length(); i++)
1705 tmpVec.push_back((
unsigned char)s[i]);
1723 if (restartDueToProcolChange)
1735 ROS_INFO(
"IP address changed. Node restart required");
1769 angleRes10000th = (int) (boost::math::round(
1771 std::vector<unsigned char> askOutputAngularRangeReply;
1776 if (NAV3xxOutputRangeSpecialHandling)
1784 std::vector<unsigned char> reqBinary;
1796 int askTmpAngleRes10000th = 0;
1797 int askTmpAngleStart10000th = 0;
1798 int askTmpAngleEnd10000th = 0;
1799 char dummy0[MAX_STR_LEN] = {0};
1800 char dummy1[MAX_STR_LEN] = {0};
1803 int iDummy0, iDummy1;
1804 std::string askOutputAngularRangeStr =
replyToString(askOutputAngularRangeReply);
1820 askTmpAngleRes10000th = 0;
1821 askTmpAngleStart10000th = 0;
1822 askTmpAngleEnd10000th = 0;
1824 const char *askOutputAngularRangeBinMask =
"%4y%4ysRA LMPoutputRange %2y%4y%4y%4y";
1828 &askTmpAngleRes10000th,
1829 &askTmpAngleStart10000th,
1830 &askTmpAngleEnd10000th);
1835 numArgs = sscanf(askOutputAngularRangeStr.c_str(),
"%s %s %d %X %X %X", dummy0, dummy1,
1837 &askTmpAngleRes10000th,
1838 &askTmpAngleStart10000th,
1839 &askTmpAngleEnd10000th);
1843 double askTmpAngleRes = askTmpAngleRes10000th / 10000.0;
1844 double askTmpAngleStart = askTmpAngleStart10000th / 10000.0;
1845 double askTmpAngleEnd = askTmpAngleEnd10000th / 10000.0;
1847 angleRes10000th = askTmpAngleRes10000th;
1848 ROS_INFO(
"Angle resolution of scanner is %0.5lf [deg] (in 1/10000th deg: 0x%X)", askTmpAngleRes,
1849 askTmpAngleRes10000th);
1850 ROS_INFO(
"[From:To] %0.5lf [deg] to %0.5lf [deg] (in 1/10000th deg: from 0x%X to 0x%X)",
1851 askTmpAngleStart, askTmpAngleEnd, askTmpAngleStart10000th, askTmpAngleEnd10000th);
1872 angleStart10000th = (int) (boost::math::round(10000.0 * minAngSopas));
1873 angleEnd10000th = (int) (boost::math::round(10000.0 * maxAngSopas));
1875 char requestOutputAngularRange[MAX_STR_LEN];
1877 std::vector<unsigned char> outputAngularRangeReply;
1880 if (NAV3xxOutputRangeSpecialHandling == 0)
1883 sprintf(requestOutputAngularRange, pcCmdMask,
1884 angleRes10000th, angleStart10000th, angleEnd10000th,
1885 angleRes10000th, angleStart10000th, angleEnd10000th,
1886 angleRes10000th, angleStart10000th, angleEnd10000th,
1887 angleRes10000th, angleStart10000th, angleEnd10000th);
1892 sprintf(requestOutputAngularRange, pcCmdMask, angleRes10000th, angleStart10000th, angleEnd10000th);
1896 unsigned char tmpBuffer[255] = {0};
1897 unsigned char sendBuffer[255] = {0};
1899 std::vector<unsigned char> reqBinary;
1905 strcpy((
char *) tmpBuffer,
"WN LMPoutputRange ");
1906 unsigned short orgLen = strlen((
char *) tmpBuffer);
1907 if (NAV3xxOutputRangeSpecialHandling){
1908 colab::addIntegerToBuffer<UINT16>(tmpBuffer, orgLen, iStatus);
1909 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
1910 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
1911 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
1912 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
1913 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
1914 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
1915 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
1916 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
1917 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
1918 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
1919 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
1920 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
1924 colab::addIntegerToBuffer<UINT16>(tmpBuffer, orgLen, iStatus);
1925 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleRes10000th);
1926 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleStart10000th);
1927 colab::addIntegerToBuffer<UINT32>(tmpBuffer, orgLen, angleEnd10000th);
1936 reqBinary = std::vector<unsigned char>(sendBuffer, sendBuffer + sendLen);
1960 askOutputAngularRangeReply.clear();
1964 std::vector<unsigned char> reqBinary;
1975 char dummy0[MAX_STR_LEN] = {0};
1976 char dummy1[MAX_STR_LEN] = {0};
1978 int askAngleRes10000th = 0;
1979 int askAngleStart10000th = 0;
1980 int askAngleEnd10000th = 0;
1981 int iDummy0, iDummy1;
1984 std::string askOutputAngularRangeStr =
replyToString(askOutputAngularRangeReply);
2003 askAngleRes10000th = 0;
2004 askAngleStart10000th = 0;
2005 askAngleEnd10000th = 0;
2014 const char *askOutputAngularRangeBinMask =
"%4y%4ysRA LMPoutputRange %2y%4y%4y%4y";
2018 &askAngleRes10000th,
2019 &askAngleStart10000th,
2020 &askAngleEnd10000th);
2025 numArgs = sscanf(askOutputAngularRangeStr.c_str(),
"%s %s %d %X %X %X", dummy0, dummy1,
2027 &askAngleRes10000th,
2028 &askAngleStart10000th,
2029 &askAngleEnd10000th);
2033 double askTmpAngleRes = askAngleRes10000th / 10000.0;
2034 double askTmpAngleStart = askAngleStart10000th / 10000.0;
2035 double askTmpAngleEnd = askAngleEnd10000th / 10000.0;
2037 angleRes10000th = askAngleRes10000th;
2038 ROS_INFO(
"Angle resolution of scanner is %0.5lf [deg] (in 1/10000th deg: 0x%X)", askTmpAngleRes,
2039 askAngleRes10000th);
2042 double askAngleRes = askAngleRes10000th / 10000.0;
2043 double askAngleStart = askAngleStart10000th / 10000.0;
2044 double askAngleEnd = askAngleEnd10000th / 10000.0;
2051 nhPriv.setParam(
"min_ang",
2053 nhPriv.setParam(
"max_ang",
2055 ROS_INFO(
"MIN_ANG (after command verification): %8.3f [rad] %8.3f [deg]",
config_.min_ang,
2057 ROS_INFO(
"MAX_ANG (after command verification): %8.3f [rad] %8.3f [deg]",
config_.max_ang,
2073 for (
size_t i = 0; i < outputChannelFlag.size(); i++)
2084 ROS_INFO(
"LMS 5xx detected overwriting output channel flag ID");
2086 ROS_INFO(
"LMS 5xx detected overwriting resolution flag (only 8 bit supported)");
2092 ROS_INFO(
"MRS 1xxx detected overwriting resolution flag (only 8 bit supported)");
2103 for(
int fieldnum=0;fieldnum<maxFieldnum;fieldnum++)
2105 char requestFieldcfg[MAX_STR_LEN];
2107 sprintf(requestFieldcfg, pcCmdMask, fieldnum);
2109 std::vector<unsigned char> reqBinary;
2110 std::vector<unsigned char> fieldcfgReply;
2115 std::vector<unsigned char> fieldcfgReply;
2124 std::string LIDinputstateRequest =
"\x02sRN LIDinputstate\x03";
2125 std::vector<unsigned char> LIDinputstateResponse;
2128 std::vector<unsigned char> reqBinary;
2148 std::stringstream field_info;
2149 field_info <<
"Safety fieldset " << fieldset <<
", pointcounter = [ ";
2150 for(
int n = 0; n < fieldMon->
getMonFields().size(); n++)
2151 field_info << (n > 0 ?
", " :
" ") << fieldMon->
getMonFields()[n].getPointCount();
2154 for(
int n = 0; n < fieldMon->
getMonFields().size(); n++)
2158 std::stringstream field_info2;
2159 field_info2 <<
"Safety field " << n <<
", type " << (int)(fieldMon->
getMonFields()[n].fieldType()) <<
" : ";
2160 for(
int m = 0; m < fieldMon->
getMonFields()[n].getPointCount(); m++)
2163 field_info2 <<
", ";
2164 field_info2 <<
"(" << fieldMon->
getMonFields()[n].getFieldPointsX()[m] <<
"," << fieldMon->
getMonFields()[n].getFieldPointsY()[m] <<
")";
2178 char requestLMDscandatacfg[MAX_STR_LEN];
2182 sprintf(requestLMDscandatacfg, pcCmdMask,
outputChannelFlagId, rssiFlag ? 1 : 0, rssiResolutionIs16Bit ? 1 : 0,
2183 EncoderSetings != -1 ? EncoderSetings : 0);
2186 std::vector<unsigned char> reqBinary;
2197 std::vector<unsigned char> lmdScanDataCfgReply;
2203 char requestLMDscandatacfgRead[MAX_STR_LEN];
2209 std::vector<unsigned char> reqBinary;
2215 std::vector<unsigned char> lmdScanDataCfgReadReply;
2223 double scan_freq = 0;
2225 pn.
getParam(
"scan_freq", scan_freq);
2227 if (scan_freq != 0 || ang_res != 0)
2229 if (scan_freq != 0 && ang_res != 0)
2233 ROS_INFO(
"variable ang_res and scan_freq setings for NAV 3xx has not been implemented yet using 20 Hz 0.75 deg");
2237 char requestLMDscancfg[MAX_STR_LEN];
2240 sprintf(requestLMDscancfg, pcCmdMask, (
long) (scan_freq * 100 + 1e-9), (
long) (ang_res * 10000 + 1e-9));
2243 std::vector<unsigned char> reqBinary;
2249 std::vector<unsigned char> lmdScanCfgReply;
2255 char requestLMDscancfgRead[MAX_STR_LEN];
2261 std::vector<unsigned char> reqBinary;
2267 std::vector<unsigned char> lmdScanDataCfgReadReply;
2275 ROS_ERROR(
"ang_res and scan_freq have to be set, only one param is set skiping scan_fre/ang_res config");
2318 char requestEchoSetting[MAX_STR_LEN];
2319 int filterEchoSetting = 0;
2320 pn.
getParam(
"filter_echos", filterEchoSetting);
2321 if (filterEchoSetting < 0)
2322 { filterEchoSetting = 0; }
2323 if (filterEchoSetting > 2)
2324 { filterEchoSetting = 2; }
2332 sprintf(requestEchoSetting, pcCmdMask, filterEchoSetting);
2333 std::vector<unsigned char> outputFilterEchoRangeReply;
2338 std::vector<unsigned char> reqBinary;
2359 std::vector<int> startProtocolSequence;
2360 bool deviceIsRadar =
false;
2364 bool transmitRawTargets =
true;
2365 bool transmitObjects =
true;
2366 int trackingMode = 0;
2367 std::string trackingModeDescription[] = {
"BASIC",
"VEHICLE"};
2369 int numTrackingModes =
sizeof(trackingModeDescription) /
sizeof(trackingModeDescription[0]);
2371 tmpParam.
getParam(
"transmit_raw_targets", transmitRawTargets);
2372 tmpParam.
getParam(
"transmit_objects", transmitObjects);
2373 tmpParam.
getParam(
"tracking_mode", trackingMode);
2376 if ((trackingMode < 0) || (trackingMode >= numTrackingModes))
2378 ROS_WARN(
"tracking mode id invalid. Switch to tracking mode 0");
2381 ROS_INFO(
"Raw target transmission is switched [%s]", transmitRawTargets ?
"ON" :
"OFF");
2382 ROS_INFO(
"Object transmission is switched [%s]", transmitObjects ?
"ON" :
"OFF");
2383 ROS_INFO(
"Tracking mode is set to id [%d] [%s]", trackingMode, trackingModeDescription[trackingMode].c_str());
2385 deviceIsRadar =
true;
2397 if (transmitRawTargets)
2406 if (transmitObjects)
2415 switch (trackingMode)
2424 ROS_DEBUG(
"Tracking mode switching sequence unknown\n");
2432 startProtocolSequence.push_back(
CMD_RUN);
2443 bool activate_lferec =
true, activate_lidoutputstate =
true, activate_lidinputstate =
true;
2444 if (
true == tmpParam.
getParam(
"activate_lferec", activate_lferec) &&
true == activate_lferec)
2449 if (
true == tmpParam.
getParam(
"activate_lidoutputstate", activate_lidoutputstate) &&
true == activate_lidoutputstate)
2454 if (
true == tmpParam.
getParam(
"activate_lidinputstate", activate_lidinputstate) &&
true == activate_lidinputstate)
2473 startProtocolSequence.push_back(
CMD_RUN);
2479 bool imu_enable =
false;
2480 tmp.
getParam(
"imu_enable", imu_enable);
2483 if (useBinaryCmdNow ==
true)
2485 ROS_INFO(
"Enable IMU data transfer");
2492 "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/blob/master/doc/IMU.md");
2500 std::vector<int>::iterator it;
2501 for (it = startProtocolSequence.begin(); it != startProtocolSequence.end(); it++)
2504 std::vector<unsigned char> tmpReply;
2508 std::vector<unsigned char> replyDummy;
2509 std::vector<unsigned char> reqBinary;
2510 std::vector<unsigned char> sopasVec;
2545 ROS_DEBUG(
"Starting radar data ....\n");
2556 bool waitForDeviceState =
true;
2559 waitForDeviceState =
false;
2563 waitForDeviceState =
false;
2566 if (waitForDeviceState)
2568 int maxWaitForDeviceStateReady = 45;
2569 bool scannerReady =
false;
2570 for (
int i = 0; i < maxWaitForDeviceStateReady; i++)
2572 double shortSleepTime = 1.0;
2574 std::vector<unsigned char> replyDummy;
2577 int deviceState = 0;
2579 std::vector<unsigned char> reqBinary;
2580 std::vector<unsigned char> sopasVec;
2598 long dummy0, dummy1;
2603 &dummy1, &deviceState);
2611 if (deviceState == 1)
2613 scannerReady =
true;
2614 ROS_INFO(
"Scanner ready for measurement after %d [sec]", i);
2618 ROS_INFO(
"Waiting for scanner ready state since %d secs", i);
2642 std::string reply_str;
2643 std::vector<unsigned char>::const_iterator it_start, it_end;
2647 it_start = reply.begin();
2648 it_end = reply.end();
2652 it_start = reply.begin() + 8;
2653 it_end = reply.end() - 1;
2655 bool inHexPrintMode =
false;
2656 for (std::vector<unsigned char>::const_iterator it = it_start; it != it_end; it++)
2660 if (*it >= 0x20 && (inHexPrintMode ==
false))
2662 reply_str.push_back(*it);
2668 char szTmp[255] = {0};
2669 unsigned char val = *it;
2670 inHexPrintMode =
true;
2671 sprintf(szTmp,
"\\x%02x", val);
2672 for (
size_t ii = 0; ii < strlen(szTmp); ii++)
2674 reply_str.push_back(szTmp[ii]);
2687 char szDumpFileName[511] = {0};
2688 char szDir[255] = {0};
2691 ROS_INFO(
"Attention: verboseLevel is set to 1. Datagrams are stored in the /tmp folder.");
2694 strcpy(szDir,
"C:\\temp\\");
2696 strcpy(szDir,
"/tmp/");
2698 sprintf(szDumpFileName,
"%ssick_datagram_%06d.bin", szDir, cnt);
2703 ftmp = fopen(szDumpFileName,
"wb");
2706 fwrite(buffer, bufLen, 1, ftmp);
2724 char device_string[7];
2725 int version_major = -1;
2726 int version_minor = -1;
2728 strcpy(device_string,
"???");
2730 if (sscanf(identStr.c_str(),
"sRA 0 6 %6s E V%d.%d", device_string,
2731 &version_major, &version_minor) == 3
2732 && strncmp(
"TiM3", device_string, 4) == 0
2733 && version_major >= 2 && version_minor >= 50)
2735 ROS_ERROR(
"This scanner model/firmware combination does not support ranging output!");
2736 ROS_ERROR(
"Supported scanners: TiM5xx: all firmware versions; TiM3xx: firmware versions < V2.50.");
2737 ROS_ERROR(
"This is a %s, firmware version %d.%d", device_string, version_major, version_minor);
2742 bool supported =
false;
2745 if (sscanf(identStr.c_str(),
"sRA 0 6 %6s E V%d.%d", device_string, &version_major, &version_minor) == 3)
2747 std::string devStr = device_string;
2750 if (devStr.compare(0, 4,
"TiM5") == 0)
2755 if (supported ==
true)
2757 ROS_INFO(
"Device %s V%d.%d found and supported by this driver.", identStr.c_str(), version_major,
2763 if ((identStr.find(
"MRS1xxx") !=
2765 || (identStr.find(
"LMS1xxx") != std::string::npos)
2768 ROS_INFO(
"Deviceinfo %s found and supported by this driver.", identStr.c_str());
2773 if (identStr.find(
"MRS6") !=
2776 ROS_INFO(
"Deviceinfo %s found and supported by this driver.", identStr.c_str());
2780 if (identStr.find(
"RMS3xx") !=
2783 ROS_INFO(
"Deviceinfo %s found and supported by this driver.", identStr.c_str());
2788 if (supported ==
false)
2790 ROS_WARN(
"Device %s V%d.%d found and maybe unsupported by this driver.", device_string, version_major,
2792 ROS_WARN(
"Full SOPAS answer: %s", identStr.c_str());
2807 unsigned char receiveBuffer[65536];
2808 int actual_length = 0;
2809 static unsigned int iteration_count = 0;
2823 int packetsInLoop = 0;
2825 const int maxNumAllowedPacketsToProcess = 25;
2827 int numPacketsProcessed = 0;
2829 static bool firstTimeCalled =
true;
2830 static bool dumpData =
false;
2831 static int verboseLevel = 0;
2832 static bool slamBundle =
false;
2833 float timeIncrement;
2834 static std::string echoForSlam =
"";
2835 if (firstTimeCalled ==
true)
2840 tmpParam.
getParam(
"slam_echo", echoForSlam);
2841 tmpParam.
getParam(
"slam_bundle", slamBundle);
2842 tmpParam.
getParam(
"verboseLevel", verboseLevel);
2843 firstTimeCalled =
false;
2848 int result =
get_datagram(recvTimeStamp, receiveBuffer, 65536, &actual_length, useBinaryProtocol, &packetsInLoop);
2849 numPacketsProcessed++;
2855 ROS_ERROR(
"Read Error when getting datagram: %i.", result);
2859 if (actual_length <= 0)
2865 if (iteration_count++ % (
config_.skip + 1) != 0)
2875 std_msgs::String datagram_msg;
2876 datagram_msg.data = std::string(reinterpret_cast<char *>(receiveBuffer));
2881 if (verboseLevel > 0)
2887 bool deviceIsRadar =
false;
2891 deviceIsRadar =
true;
2894 if (
true == deviceIsRadar)
2899 errorCode = radar->
parseDatagram(recvTimeStamp, (
unsigned char *) receiveBuffer, actual_length,
2905 if (scanImu.
isImuDatagram((
char *) receiveBuffer, actual_length))
2915 errorCode = scanImu.
parseDatagram(recvTimeStamp, (
unsigned char *) receiveBuffer, actual_length,
2921 else if(memcmp(&receiveBuffer[8],
"sSN LIDoutputstate", strlen(
"sSN LIDoutputstate")) == 0)
2928 sick_scan::LIDoutputstateMsg outputstate_msg;
2947 else if(memcmp(&receiveBuffer[8],
"sSN LIDinputstate", strlen(
"sSN LIDinputstate")) == 0)
2952 if(fieldMon && useBinaryProtocol && actual_length > 32)
2962 else if(memcmp(&receiveBuffer[8],
"sSN LFErec", strlen(
"sSN LFErec")) == 0)
2967 sick_scan::LFErecMsg lferec_msg;
2988 else if(memcmp(&receiveBuffer[8],
"sSN LMDscandatamon", strlen(
"sSN LMDscandatamon")) == 0)
2991 ROS_DEBUG_STREAM(
"SickScanCommon: received " << actual_length <<
" byte LMDscandatamon (ignored) ...");
2997 sensor_msgs::LaserScan
msg;
2998 sick_scan::Encoder EncoderMsg;
3001 bool FireEncoder =
false;
3002 EncoderMsg.header.frame_id =
"Encoder";
3003 EncoderMsg.header.seq = numPacketsProcessed;
3004 msg.header.stamp = recvTimeStamp + ros::Duration(
config_.time_offset);
3005 double elevationAngleInRad = 0.0;
3009 char *buffer_pos = (
char *) receiveBuffer;
3010 char *dstart, *dend;
3011 bool dumpDbg =
false;
3012 bool dataToProcess =
true;
3013 std::vector<float> vang_vec;
3018 while (dataToProcess)
3020 const int maxAllowedEchos = 5;
3022 int numValidEchos = 0;
3023 int aiValidEchoIdx[maxAllowedEchos] = {0};
3028 bool publishPointCloud =
true;
3030 if (useBinaryProtocol)
3033 std::vector<unsigned char> receiveBufferVec = std::vector<unsigned char>(receiveBuffer,
3034 receiveBuffer + actual_length);
3035 #ifdef DEBUG_DUMP_TO_CONSOLE_ENABLED 3036 if (actual_length > 1000)
3044 if (receiveBufferVec.size() > 8)
3048 memcpy(&idVal, receiveBuffer + 0, 4);
3049 memcpy(&lenVal, receiveBuffer + 4, 4);
3052 if (idVal == 0x02020202)
3057 char szFileName[255];
3060 sprintf(szFileName,
"c:\\temp\\dump%05d.bin", cnt);
3062 sprintf(szFileName,
"/tmp/dump%05d.txt", cnt);
3065 fout = fopen(szFileName,
"wb");
3066 fwrite(receiveBuffer, actual_length, 1, fout);
3072 if (lenVal < actual_length)
3074 short elevAngleX200 = 0;
3076 int scanFrequencyX100 = 0;
3077 double elevAngle = 0.00;
3078 double scanFrequency = 0.0;
3079 long measurementFrequencyDiv100 = 0;
3080 int numOfEncoders = 0;
3081 int numberOf16BitChannels = 0;
3082 int numberOf8BitChannels = 0;
3083 uint32_t SystemCountScan = 0;
3084 static uint32_t lastSystemCountScan = 0;
3085 uint32_t SystemCountTransmit = 0;
3087 memcpy(&elevAngleX200, receiveBuffer + 50, 2);
3090 elevationAngleInRad = -elevAngleX200 / 200.0 *
deg2rad_const;
3092 msg.header.seq = elevAngleX200;
3094 memcpy(&SystemCountScan, receiveBuffer + 0x26, 4);
3095 swap_endian((
unsigned char *) &SystemCountScan, 4);
3097 memcpy(&SystemCountTransmit, receiveBuffer + 0x2A, 4);
3098 swap_endian((
unsigned char *) &SystemCountTransmit, 4);
3099 double timestampfloat = recvTimeStamp.sec + recvTimeStamp.nsec * 1e-9;
3101 if (SystemCountScan !=
3102 lastSystemCountScan)
3105 SystemCountTransmit);
3106 lastSystemCountScan = SystemCountScan;
3111 double timestampfloat_coor = recvTimeStamp.sec + recvTimeStamp.nsec * 1e-9;
3112 double DeltaTime = timestampfloat - timestampfloat_coor;
3115 if (
config_.sw_pll_only_publish ==
true && bRet ==
false)
3119 ROS_INFO(
"%i / %i Packet dropped Software PLL not yet locked.",
3123 ROS_INFO(
"Software PLL is expected to be ready now!");
3127 ROS_WARN(
"More packages than expected were dropped!!\n" 3128 "Check the network connection.\n" 3129 "Check if the system time has been changed in a leap.\n" 3130 "If the problems can persist, disable the software PLL with the option sw_pll_only_publish=False !");
3132 dataToProcess =
false;
3136 #ifdef DEBUG_DUMP_ENABLED 3137 double elevationAngleInDeg = elevationAngleInRad = -elevAngleX200 / 200.0;
3158 memcpy(&scanFrequencyX100, receiveBuffer + 52, 4);
3159 swap_endian((
unsigned char *) &scanFrequencyX100, 4);
3161 memcpy(&measurementFrequencyDiv100, receiveBuffer + 56, 4);
3162 swap_endian((
unsigned char *) &measurementFrequencyDiv100, 4);
3165 msg.scan_time = 1.0 / (scanFrequencyX100 / 100.0);
3168 if (measurementFrequencyDiv100 > 10000)
3170 measurementFrequencyDiv100 /= 100;
3172 msg.time_increment = 1.0 / (measurementFrequencyDiv100 * 100.0);
3173 timeIncrement = msg.time_increment;
3177 memcpy(&numOfEncoders, receiveBuffer + 60, 2);
3179 int encoderDataOffset = 6 * numOfEncoders;
3180 int32_t EncoderPosTicks[4] = {0};
3181 int16_t EncoderSpeed[4] = {0};
3183 if (numOfEncoders > 0 && numOfEncoders < 5)
3186 for (
int EncoderNum = 0; EncoderNum < numOfEncoders; EncoderNum++)
3188 memcpy(&EncoderPosTicks[EncoderNum], receiveBuffer + 62 + EncoderNum * 6, 4);
3189 swap_endian((
unsigned char *) &EncoderPosTicks[EncoderNum], 4);
3190 memcpy(&EncoderSpeed[EncoderNum], receiveBuffer + 66 + EncoderNum * 6, 2);
3191 swap_endian((
unsigned char *) &EncoderSpeed[EncoderNum], 2);
3195 EncoderMsg.enc_position = EncoderPosTicks[0];
3196 EncoderMsg.enc_speed = EncoderSpeed[0];
3197 memcpy(&numberOf16BitChannels, receiveBuffer + 62 + encoderDataOffset, 2);
3198 swap_endian((
unsigned char *) &numberOf16BitChannels, 2);
3200 int parseOff = 64 + encoderDataOffset;
3203 char szChannel[255] = {0};
3204 float scaleFactor = 1.0;
3205 float scaleFactorOffset = 0.0;
3206 int32_t startAngleDiv10000 = 1;
3207 int32_t sizeOfSingleAngularStepDiv10000 = 1;
3208 double startAngle = 0.0;
3209 double sizeOfSingleAngularStep = 0.0;
3210 short numberOfItems = 0;
3216 for (
int i = 0; i < numberOf16BitChannels; i++)
3218 int numberOfItems = 0x00;
3219 memcpy(&numberOfItems, receiveBuffer + parseOff + 19, 2);
3222 parseOff += numberOfItems * 2;
3226 memcpy(&numberOf8BitChannels, receiveBuffer + parseOff, 2);
3227 swap_endian((
unsigned char *) &numberOf8BitChannels, 2);
3229 parseOff = 64 + encoderDataOffset;
3230 enum datagram_parse_task
3239 int distChannelCnt = 0;
3241 for (
int processLoop = 0; processLoop < 2; processLoop++)
3243 int totalChannelCnt = 0;
3248 datagram_parse_task task = process_idle;
3249 bool parsePacket =
true;
3250 parseOff = 64 + encoderDataOffset;
3251 bool processData =
false;
3253 if (processLoop == 0)
3260 if (processLoop == 1)
3263 numEchos = distChannelCnt;
3264 msg.ranges.resize(numberOfItems * numEchos);
3267 msg.intensities.resize(numberOfItems * rssiCnt);
3274 vang_vec.resize(numberOfItems * vangleCnt);
3280 echoMask = (1 << numEchos) - 1;
3289 szChannel[6] =
'\0';
3291 scaleFactorOffset = 0.0;
3292 startAngleDiv10000 = 1;
3293 sizeOfSingleAngularStepDiv10000 = 1;
3295 sizeOfSingleAngularStep = 0.0;
3299 #if 1 // prepared for multiecho parsing 3302 bool doVangVecProc =
false;
3304 task = process_idle;
3307 task = process_idle;
3308 doVangVecProc =
false;
3309 int processDataLenValuesInBytes = 2;
3311 if (totalChannelCnt == numberOf16BitChannels)
3316 if (totalChannelCnt >= numberOf16BitChannels)
3318 processDataLenValuesInBytes = 1;
3321 strcpy(szChannel,
"");
3323 if (totalChannelCnt < (numberOf16BitChannels + numberOf8BitChannels))
3325 szChannel[5] =
'\0';
3326 strncpy(szChannel, (
const char *) receiveBuffer + parseOff, 5);
3333 if (strstr(szChannel,
"DIST") == szChannel)
3335 task = process_dist;
3339 memcpy(&numberOfItems, receiveBuffer + parseOff + 19, 2);
3343 if (strstr(szChannel,
"VANG") == szChannel)
3346 task = process_vang;
3349 memcpy(&numberOfItems, receiveBuffer + parseOff + 19, 2);
3352 vang_vec.resize(numberOfItems);
3355 if (strstr(szChannel,
"RSSI") == szChannel)
3357 task = process_rssi;
3362 memcpy(&numberOfItems, receiveBuffer + parseOff + 19, 2);
3369 scaleFactorOffset = 0.0;
3370 startAngleDiv10000 = 0;
3371 sizeOfSingleAngularStepDiv10000 = 0;
3374 memcpy(&scaleFactor, receiveBuffer + parseOff + 5, 4);
3375 memcpy(&scaleFactorOffset, receiveBuffer + parseOff + 9, 4);
3376 memcpy(&startAngleDiv10000, receiveBuffer + parseOff + 13, 4);
3377 memcpy(&sizeOfSingleAngularStepDiv10000, receiveBuffer + parseOff + 17, 2);
3378 memcpy(&numberOfItems, receiveBuffer + parseOff + 19, 2);
3382 swap_endian((
unsigned char *) &scaleFactorOffset, 4);
3383 swap_endian((
unsigned char *) &startAngleDiv10000, 4);
3384 swap_endian((
unsigned char *) &sizeOfSingleAngularStepDiv10000, 2);
3389 unsigned short *
data = (
unsigned short *) (receiveBuffer + parseOff + 21);
3391 unsigned char *swapPtr = (
unsigned char *) data;
3394 i < numberOfItems * processDataLenValuesInBytes; i += processDataLenValuesInBytes)
3396 if (processDataLenValuesInBytes == 1)
3402 tmp = swapPtr[i + 1];
3403 swapPtr[i + 1] = swapPtr[i];
3414 startAngle = startAngleDiv10000 / 10000.00;
3415 sizeOfSingleAngularStep = sizeOfSingleAngularStepDiv10000 / 10000.0;
3416 sizeOfSingleAngularStep *= (M_PI / 180.0);
3418 msg.angle_min = startAngle / 180.0 * M_PI - M_PI / 2;
3419 msg.angle_increment = sizeOfSingleAngularStep;
3420 msg.angle_max = msg.angle_min + (numberOfItems - 1) * msg.angle_increment;
3424 msg.angle_min -= M_PI/2;
3425 msg.angle_max -= M_PI/2;
3427 msg.angle_min *= -1.0;
3428 msg.angle_increment *= -1.0;
3429 msg.angle_max *= -1.0;
3432 float *rangePtr = NULL;
3434 if (numberOfItems > 0)
3436 rangePtr = &msg.ranges[0];
3438 float scaleFactor_001 = 0.001F * scaleFactor;
3439 for (
int i = 0; i < numberOfItems; i++)
3441 idx = i + numberOfItems * (distChannelCnt - 1);
3442 rangePtr[idx] = (float) data[i] * scaleFactor_001 + scaleFactorOffset;
3443 #ifdef DEBUG_DUMP_ENABLED 3444 if (distChannelCnt == 1)
3446 if (i == floor(numberOfItems / 2))
3448 double curTimeStamp = SystemCountScan + i * msg.time_increment * 1E6;
3462 float *intensityPtr = NULL;
3464 if (numberOfItems > 0)
3466 intensityPtr = &msg.intensities[0];
3469 for (
int i = 0; i < numberOfItems; i++)
3471 idx = i + numberOfItems * (rssiCnt - 1);
3473 float rssiVal = 0.0;
3474 if (processDataLenValuesInBytes == 2)
3476 rssiVal = (float) data[i];
3480 unsigned char *data8Ptr = (
unsigned char *) data;
3481 rssiVal = (float) data8Ptr[i];
3483 intensityPtr[idx] = rssiVal * scaleFactor + scaleFactorOffset;
3489 float *vangPtr = NULL;
3490 if (numberOfItems > 0)
3492 vangPtr = &vang_vec[0];
3494 for (
int i = 0; i < numberOfItems; i++)
3496 vangPtr[i] = (float) data[i] * scaleFactor + scaleFactorOffset;
3501 parseOff += 21 + processDataLenValuesInBytes * numberOfItems;
3510 elevAngle = elevAngleX200 / 200.0;
3511 scanFrequency = scanFrequencyX100 / 100.0;
3523 dataToProcess =
false;
3527 dstart = strchr(buffer_pos, 0x02);
3530 dend = strchr(dstart + 1, 0x03);
3532 if ((dstart != NULL) && (dend != NULL))
3534 dataToProcess =
true;
3535 dlength = dend - dstart;
3541 dataToProcess =
false;
3549 char szFileName[255];
3552 sprintf(szFileName,
"c:\\temp\\dump%05d.txt", cnt);
3554 sprintf(szFileName,
"/tmp/dump%05d.txt", cnt);
3558 fout = fopen(szFileName,
"wb");
3559 fwrite(dstart, dlength, 1, fout);
3573 publishPointCloud =
true;
3576 for (
int i = 0; i < maxAllowedEchos; i++)
3578 aiValidEchoIdx[i] = 0;
3587 bool elevationPreCalculated =
false;
3588 double elevationAngleDegree = 0.0;
3591 std::vector<float> rangeTmp = msg.ranges;
3592 std::vector<float> intensityTmp = msg.intensities;
3594 int intensityTmpNum = intensityTmp.size();
3595 float *intensityTmpPtr = NULL;
3596 if (intensityTmpNum > 0)
3598 intensityTmpPtr = &intensityTmp[0];
3606 bool useGivenElevationAngle =
false;
3607 switch (numOfLayers)
3615 if (msg.header.seq == 250)
3617 else if (msg.header.seq == 0)
3619 else if (msg.header.seq == -250)
3621 else if (msg.header.seq == -500)
3624 elevationAngleDegree = elevationAngleDegree / 180.0 * M_PI;
3629 layer = (msg.header.seq - (-2638)) / 125;
3630 layer = (23 - layer) - 1;
3633 elevationAngleDegree = elevationAngleDegree / 180.0 * M_PI;
3636 elevationPreCalculated =
true;
3637 if (vang_vec.size() > 0)
3639 useGivenElevationAngle =
true;
3660 size_t startOffset = 0;
3661 size_t endOffset = 0;
3662 int echoPartNum = msg.ranges.size() / numEchos;
3663 for (
int i = 0; i < numEchos; i++)
3666 bool sendMsg =
false;
3669 aiValidEchoIdx[numValidEchos] = i;
3673 startOffset = i * echoPartNum;
3674 endOffset = (i + 1) * echoPartNum;
3677 msg.intensities.clear();
3678 msg.ranges = std::vector<float>(
3679 rangeTmp.begin() + startOffset,
3680 rangeTmp.begin() + endOffset);
3682 if (endOffset <= intensityTmp.size() && (intensityTmp.size() > 0))
3684 msg.intensities = std::vector<float>(
3685 intensityTmp.begin() + startOffset,
3686 intensityTmp.begin() + endOffset);
3690 msg.intensities.resize(echoPartNum);
3694 char szTmp[255] = {0};
3697 const char *cpFrameId =
config_.frame_id.c_str();
3699 sprintf(szTmp,
"%s_%+04d_DIST%d", cpFrameId, msg.header.seq, i + 1);
3700 #else // experimental 3701 char szSignName[10] = {0};
3702 if ((
int) msg.header.seq < 0)
3704 strcpy(szSignName,
"NEG");
3708 strcpy(szSignName,
"POS");
3712 sprintf(szTmp,
"%s_%s_%03d_DIST%d", cpFrameId, szSignName, abs((
int) msg.header.seq), i + 1);
3717 strcpy(szTmp,
config_.frame_id.c_str());
3720 msg.header.frame_id = std::string(szTmp);
3722 if (echoForSlam.length() > 0)
3730 msg.header.frame_id = echoForSlam;
3731 strcpy(szTmp, echoForSlam.c_str());
3732 if (elevationAngleInRad != 0.0)
3734 float cosVal = cos(elevationAngleInRad);
3735 int rangeNum = msg.ranges.size();
3736 for (
int j = 0; j < rangeNum; j++)
3738 msg.ranges[j] *= cosVal;
3744 if (echoForSlam.compare(szTmp) == 0)
3756 for (
int j = 0, j_max = (
int)std::min(msg.ranges.size(), msg.intensities.size()); j < j_max; j++)
3760 msg.ranges[j] = std::numeric_limits<float>::infinity();
3772 if (numOfLayers > 4)
3777 outputChannelFlagId)
3784 printf(
"MSG received...");
3790 if (publishPointCloud ==
true)
3794 const int numChannels = 4;
3796 int numTmpLayer = numOfLayers;
3799 cloud_.header.stamp = recvTimeStamp + ros::Duration(
config_.time_offset);
3804 cloud_.height = numTmpLayer * numValidEchos;
3805 cloud_.width = msg.ranges.size();
3806 cloud_.is_bigendian =
false;
3808 cloud_.point_step = numChannels *
sizeof(float);
3810 cloud_.fields.resize(numChannels);
3811 for (
int i = 0; i < numChannels; i++)
3813 std::string channelId[] = {
"x",
"y",
"z",
"intensity"};
3814 cloud_.fields[i].name = channelId[i];
3815 cloud_.fields[i].offset = i *
sizeof(float);
3816 cloud_.fields[i].count = 1;
3817 cloud_.fields[i].datatype = sensor_msgs::PointField::FLOAT32;
3822 unsigned char *cloudDataPtr = &(
cloud_.data[0]);
3827 std::vector<float> cosAlphaTable;
3828 std::vector<float> sinAlphaTable;
3829 size_t rangeNum = rangeTmp.size() / numValidEchos;
3830 cosAlphaTable.resize(rangeNum);
3831 sinAlphaTable.resize(rangeNum);
3832 float mirror_factor = 1.0;
3840 for (
size_t iEcho = 0; iEcho < numValidEchos; iEcho++)
3846 float *cosAlphaTablePtr = &cosAlphaTable[0];
3847 float *sinAlphaTablePtr = &sinAlphaTable[0];
3849 float *vangPtr = NULL;
3850 float *rangeTmpPtr = &rangeTmp[0];
3851 if (vang_vec.size() > 0)
3853 vangPtr = &vang_vec[0];
3855 for (
size_t i = 0; i < rangeNum; i++)
3857 enum enum_index_descr
3865 long adroff = i * (numChannels * (int)
sizeof(
float));
3867 adroff += (layer - baseLayer) *
cloud_.row_step;
3869 adroff += iEcho *
cloud_.row_step * numTmpLayer;
3871 unsigned char *ptr = cloudDataPtr + adroff;
3872 float *fptr = (
float *) (cloudDataPtr + adroff);
3874 geometry_msgs::Point32 point;
3875 float range_meter = rangeTmpPtr[iEcho * rangeNum + i];
3879 if (useGivenElevationAngle)
3885 if (elevationPreCalculated)
3887 alpha = elevationAngleInRad;
3891 alpha = layer * elevationAngleDegree;
3897 cosAlphaTablePtr[i] = cos(alpha);
3898 sinAlphaTablePtr[i] = sin(alpha);
3905 float rangeCos = range_meter * cosAlphaTablePtr[i];
3907 double phi_used = phi + angleShift;
3912 fptr[idx_x] = rangeCos * cos(phi_used);
3913 fptr[idx_y] = rangeCos * sin(phi_used);
3914 fptr[idx_z] = range_meter * sinAlphaTablePtr[i] * mirror_factor;
3916 fptr[idx_intensity] = 0.0;
3919 int intensityIndex = aiValidEchoIdx[iEcho] * rangeNum + i;
3921 if (intensityIndex < intensityTmpNum)
3923 fptr[idx_intensity] = intensityTmpPtr[intensityIndex];
3926 angle += msg.angle_increment;
3930 int layerOff = (layer - baseLayer);
3934 bool shallIFire =
false;
3935 if ((msg.header.seq == 0) || (msg.header.seq == 237))
3941 static int layerCnt = 0;
3942 static int layerSeq[4];
3944 if (
config_.cloud_output_mode > 0)
3947 layerSeq[layerCnt % 4] = layer;
3962 if (
config_.cloud_output_mode == 0)
3968 else if (
config_.cloud_output_mode == 2)
3980 int numTotalShots = 360;
3981 int numPartialShots = 40;
3983 for (
int i = 0; i < numTotalShots; i += numPartialShots)
3985 sensor_msgs::PointCloud2 partialCloud;
3989 partialTimeStamp += ros::Duration((i + 0.5 * (numPartialShots - 1)) * timeIncrement);
3990 partialTimeStamp += ros::Duration((3 * numTotalShots) * timeIncrement);
3991 partialCloud.header.stamp = partialTimeStamp;
3992 partialCloud.width = numPartialShots * 3;
3994 int diffTo1100 =
cloud_.width - 3 * (numTotalShots + i);
3995 if (diffTo1100 > numPartialShots)
3997 diffTo1100 = numPartialShots;
4003 partialCloud.width += diffTo1100;
4005 partialCloud.height = 1;
4008 partialCloud.is_bigendian =
false;
4009 partialCloud.is_dense =
true;
4010 partialCloud.point_step = numChannels *
sizeof(float);
4011 partialCloud.row_step = partialCloud.point_step * partialCloud.width;
4012 partialCloud.fields.resize(numChannels);
4013 for (
int ii = 0; ii < numChannels; ii++)
4015 std::string channelId[] = {
"x",
"y",
"z",
"intensity"};
4016 partialCloud.fields[ii].name = channelId[ii];
4017 partialCloud.fields[ii].offset = ii *
sizeof(float);
4018 partialCloud.fields[ii].count = 1;
4019 partialCloud.fields[ii].datatype = sensor_msgs::PointField::FLOAT32;
4022 partialCloud.data.resize(partialCloud.row_step);
4025 for (
int j = 0; j < 4; j++)
4027 int layerIdx = (j + (layerCnt)) % 4;
4028 int rowIdx = 1 + layerSeq[layerIdx % 4];
4029 int colIdx = j * numTotalShots + i;
4030 int maxAvail =
cloud_.width - colIdx;
4036 if (maxAvail > numPartialShots)
4038 maxAvail = numPartialShots;
4044 memcpy(&(partialCloud.data[partOff]),
4046 cloud_.point_step * maxAvail);
4050 partOff += maxAvail * partialCloud.point_step;
4052 assert(partialCloud.data.size() == partialCloud.width * partialCloud.point_step);
4057 memcpy(&(partialCloud.data[0]), &(
cloud_.data[0]) + i *
cloud_.point_step,
cloud_.point_step * numPartialShots);
4065 printf(
"PUBLISH:\n");
4073 buffer_pos = dend + 1;
4080 }
while ((packetsInLoop > 0) && (numPacketsProcessed < maxNumAllowedPacketsToProcess));
4090 if (conf.min_ang > conf.max_ang)
4092 ROS_WARN(
"Maximum angle must be greater than minimum angle. Adjusting >min_ang<.");
4093 conf.min_ang = conf.max_ang;
4116 requestBinary->clear();
4117 if (requestAscii == NULL)
4121 int cmdLen = strlen(requestAscii);
4126 if (requestAscii[0] != 0x02)
4130 if (requestAscii[cmdLen - 1] != 0x03)
4135 for (
int i = 0; i < 4; i++)
4137 requestBinary->push_back(0x02);
4140 for (
int i = 0; i < 4; i++)
4142 requestBinary->push_back(0x00);
4145 unsigned long msgLen = cmdLen - 2;
4149 std::string keyWord0 =
"sMN SetAccessMode";
4150 std::string keyWord1 =
"sWN FREchoFilter";
4151 std::string keyWord2 =
"sEN LMDscandata";
4152 std::string keyWord3 =
"sWN LMDscandatacfg";
4153 std::string keyWord4 =
"sWN SetActiveApplications";
4154 std::string keyWord5 =
"sEN IMUData";
4155 std::string keyWord6 =
"sWN EIIpAddr";
4156 std::string keyWord7 =
"sMN mLMPsetscancfg";
4157 std::string keyWord8 =
"sWN TSCTCupdatetime";
4158 std::string keyWord9 =
"sWN TSCTCSrvAddr";
4159 std::string keyWord10 =
"sWN LICencres";
4160 std::string keyWord11 =
"sWN LFPmeanfilter";
4161 std::string KeyWord12 =
"sRN field";
4165 std::string cmdAscii = requestAscii;
4168 int copyUntilSpaceCnt = 2;
4170 char hexStr[255] = {0};
4172 unsigned char buffer[255];
4174 if (cmdAscii.find(keyWord0) != std::string::npos)
4176 copyUntilSpaceCnt = 2;
4177 int keyWord0Len = keyWord0.length();
4178 sscanf(requestAscii + keyWord0Len + 1,
" %d %s", &level, hexStr);
4179 buffer[0] = (
unsigned char) (0xFF & level);
4181 char hexTmp[3] = {0};
4182 for (
int i = 0; i < 4; i++)
4185 hexTmp[0] = hexStr[i * 2];
4186 hexTmp[1] = hexStr[i * 2 + 1];
4188 sscanf(hexTmp,
"%x", &val);
4189 buffer[i + 1] = (
unsigned char) (0xFF & val);
4193 if (cmdAscii.find(keyWord1) != std::string::npos)
4195 int echoCodeNumber = 0;
4196 int keyWord1Len = keyWord1.length();
4197 sscanf(requestAscii + keyWord1Len + 1,
" %d", &echoCodeNumber);
4198 buffer[0] = (
unsigned char) (0xFF & echoCodeNumber);
4201 if (cmdAscii.find(keyWord2) != std::string::npos)
4203 int scanDataStatus = 0;
4204 int keyWord2Len = keyWord2.length();
4205 sscanf(requestAscii + keyWord2Len + 1,
" %d", &scanDataStatus);
4206 buffer[0] = (
unsigned char) (0xFF & scanDataStatus);
4210 if (cmdAscii.find(keyWord3) != std::string::npos)
4212 int scanDataStatus = 0;
4213 int keyWord3Len = keyWord3.length();
4214 int dummyArr[12] = {0};
4216 int sscanfresult = sscanf(requestAscii + keyWord3Len + 1,
" %d %d %d %d %d %d %d %d %d %d %d %d",
4229 if (1 < sscanfresult)
4232 for (
int i = 0; i < 13; i++)
4236 buffer[0] = (
unsigned char) (0xFF & dummyArr[0]);
4237 buffer[1] = (
unsigned char) (0xFF & dummyArr[1]);;
4238 buffer[2] = (
unsigned char) (0xFF & dummyArr[2]);
4239 buffer[3] = (
unsigned char) (0xFF & dummyArr[3]);
4240 buffer[4] = (
unsigned char) (0xFF & dummyArr[4]);
4241 buffer[5] = (
unsigned char) (0xFF & dummyArr[5]);
4242 buffer[6] = (
unsigned char) (0xFF & dummyArr[6]);
4243 buffer[7] = (
unsigned char) (0xFF & dummyArr[7]);
4244 buffer[8] = (
unsigned char) (0xFF & dummyArr[8]);
4245 buffer[9] = (
unsigned char) (0xFF & dummyArr[9]);
4246 buffer[10] = (
unsigned char) (0xFF & dummyArr[10]);
4247 buffer[11] = (
unsigned char) (0xFF & (dummyArr[11] >> 8));
4248 buffer[12] = (
unsigned char) (0xFF & (dummyArr[11] >> 0));
4255 if (cmdAscii.find(keyWord4) != std::string::npos)
4257 char tmpStr[1024] = {0};
4258 char szApplStr[255] = {0};
4259 int keyWord4Len = keyWord4.length();
4260 int scanDataStatus = 0;
4262 strcpy(tmpStr, requestAscii + keyWord4Len + 2);
4263 sscanf(tmpStr,
"%d %s %d", &dummy0, szApplStr, &dummy1);
4266 buffer[1] = dummy0 ? 0x01 : 0x00;
4267 for (
int ii = 0; ii < 4; ii++)
4269 buffer[2 + ii] = szApplStr[ii];
4271 buffer[6] = dummy1 ? 0x01 : 0x00;
4275 if (cmdAscii.find(keyWord5) != std::string::npos)
4277 int imuSetStatus = 0;
4278 int keyWord5Len = keyWord5.length();
4279 sscanf(requestAscii + keyWord5Len + 1,
" %d", &imuSetStatus);
4280 buffer[0] = (
unsigned char) (0xFF & imuSetStatus);
4284 if (cmdAscii.find(keyWord6) != std::string::npos)
4287 int imuSetStatus = 0;
4288 int keyWord6Len = keyWord6.length();
4289 sscanf(requestAscii + keyWord6Len + 1,
" %x %x %x %x", &(adrPartArr[0]), &(adrPartArr[1]), &(adrPartArr[2]),
4291 buffer[0] = (
unsigned char) (0xFF & adrPartArr[0]);
4292 buffer[1] = (
unsigned char) (0xFF & adrPartArr[1]);
4293 buffer[2] = (
unsigned char) (0xFF & adrPartArr[2]);
4294 buffer[3] = (
unsigned char) (0xFF & adrPartArr[3]);
4305 if (cmdAscii.find(keyWord7) != std::string::npos)
4311 for (
int i = 0; i < bufferLen; i++)
4313 unsigned char uch = 0x00;
4322 char tmpStr[1024] = {0};
4323 char szApplStr[255] = {0};
4324 int keyWord7Len = keyWord7.length();
4325 int scanDataStatus = 0;
4327 strcpy(tmpStr, requestAscii + keyWord7Len + 2);
4328 sscanf(tmpStr,
"%d 1 %d", &dummy0, &dummy1);
4330 buffer[0] = (
unsigned char) (0xFF & (dummy0 >> 24));
4331 buffer[1] = (
unsigned char) (0xFF & (dummy0 >> 16));
4332 buffer[2] = (
unsigned char) (0xFF & (dummy0 >> 8));
4333 buffer[3] = (
unsigned char) (0xFF & (dummy0 >> 0));
4336 buffer[6] = (
unsigned char) (0xFF & (dummy1 >> 24));
4337 buffer[7] = (
unsigned char) (0xFF & (dummy1 >> 16));
4338 buffer[8] = (
unsigned char) (0xFF & (dummy1 >> 8));
4339 buffer[9] = (
unsigned char) (0xFF & (dummy1 >> 0));
4344 int keyWord7Len = keyWord7.length();
4345 int dummyArr[14] = {0};
4346 if (14 == sscanf(requestAscii + keyWord7Len + 1,
" %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
4347 &dummyArr[0], &dummyArr[1], &dummyArr[2],
4348 &dummyArr[3], &dummyArr[4], &dummyArr[5],
4349 &dummyArr[6], &dummyArr[7], &dummyArr[8],
4350 &dummyArr[9], &dummyArr[10], &dummyArr[11], &dummyArr[12], &dummyArr[13]))
4352 for (
int i = 0; i < 54; i++)
4356 int targetPosArr[] = {0, 4, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54};
4357 int numElem = (
sizeof(targetPosArr) /
sizeof(targetPosArr[0])) - 1;
4358 for (
int i = 0; i < numElem; i++)
4360 int lenOfBytesToRead = targetPosArr[i + 1] - targetPosArr[i];
4361 int adrPos = targetPosArr[i];
4362 unsigned char *destPtr = buffer + adrPos;
4363 memcpy(destPtr, &(dummyArr[i]), lenOfBytesToRead);
4366 bufferLen = targetPosArr[numElem];
4377 if (cmdAscii.find(keyWord8) != std::string::npos)
4379 uint32_t updatetime = 0;
4380 int keyWord8Len = keyWord8.length();
4381 sscanf(requestAscii + keyWord8Len + 1,
" %d", &updatetime);
4382 buffer[0] = (
unsigned char) (0xFF & (updatetime >> 24));
4383 buffer[1] = (
unsigned char) (0xFF & (updatetime >> 16));
4384 buffer[2] = (
unsigned char) (0xFF & (updatetime >> 8));
4385 buffer[3] = (
unsigned char) (0xFF & (updatetime >> 0));
4388 if (cmdAscii.find(keyWord9) != std::string::npos)
4391 int imuSetStatus = 0;
4392 int keyWord9Len = keyWord9.length();
4393 sscanf(requestAscii + keyWord9Len + 1,
" %x %x %x %x", &(adrPartArr[0]), &(adrPartArr[1]), &(adrPartArr[2]),
4395 buffer[0] = (
unsigned char) (0xFF & adrPartArr[0]);
4396 buffer[1] = (
unsigned char) (0xFF & adrPartArr[1]);
4397 buffer[2] = (
unsigned char) (0xFF & adrPartArr[2]);
4398 buffer[3] = (
unsigned char) (0xFF & adrPartArr[3]);
4401 if (cmdAscii.find(keyWord10) != std::string::npos)
4403 float EncResolution = 0;
4405 int keyWord10Len = keyWord10.length();
4406 sscanf(requestAscii + keyWord10Len + 1,
" %f", &EncResolution);
4407 memcpy(buffer, &EncResolution, bufferLen);
4411 if (cmdAscii.find(keyWord11) != std::string::npos)
4413 char tmpStr[1024] = {0};
4414 char szApplStr[255] = {0};
4415 int keyWord11Len = keyWord11.length();
4416 int dummy0, dummy1,dummy2;
4417 strcpy(tmpStr, requestAscii + keyWord11Len + 2);
4418 sscanf(tmpStr,
"%d %d %d", &dummy0, &dummy1, &dummy2);
4420 buffer[0] = dummy0 ? 0x01 : 0x00;
4421 buffer[1] =dummy1/256;
4422 buffer[2] =dummy1%256;
4426 if (cmdAscii.find(KeyWord12) != std::string::npos)
4428 uint32_t fieldID = 0;
4429 int keyWord12Len = KeyWord12.length();
4430 sscanf(requestAscii + keyWord12Len + 1,
"%d", &fieldID);
4434 bool switchDoBinaryData =
false;
4435 for (
int i = 1; i <= (int) (msgLen); i++)
4437 char c = requestAscii[i];
4438 if (switchDoBinaryData ==
true)
4442 if (c >=
'0' && c <=
'9')
4452 requestBinary->push_back(c);
4453 if (requestAscii[i] == 0x20)
4456 if (spaceCnt >= copyUntilSpaceCnt)
4458 switchDoBinaryData =
true;
4465 for (
int i = 0; i < bufferLen; i++)
4467 requestBinary->push_back(buffer[i]);
4470 msgLen = requestBinary->size();
4472 for (
int i = 0; i < 4; i++)
4474 unsigned char bigEndianLen = msgLen & (0xFF << (3 - i) * 8);
4475 (*requestBinary)[i + 4] = ((
unsigned char) (bigEndianLen));
4477 unsigned char xorVal = 0x00;
4478 xorVal =
sick_crc8((
unsigned char *) (&((*requestBinary)[8])), requestBinary->size() - 8);
4479 requestBinary->push_back(xorVal);
4481 for (
int i = 0; i < requestBinary->size(); i++)
4483 unsigned char c = (*requestBinary)[i];
4484 printf(
"[%c]%02x ", (c <
' ') ?
'.' : c, c) ;
4501 bool retValue =
true;
4503 if (shouldUseBinary == useBinaryCmdNow)
4519 if (shouldUseBinary ==
true)
4528 useBinaryCmdNow = shouldUseBinary;
4537 int eepwritetTimeOut = 1;
4538 bool result =
false;
4541 unsigned long adrBytesLong[4];
4542 std::string
s = ipNewIPAddr.to_string();
4543 const char *ptr = s.c_str();
4545 sscanf(ptr,
"%lu.%lu.%lu.%lu", &(adrBytesLong[0]), &(adrBytesLong[1]), &(adrBytesLong[2]), &(adrBytesLong[3]));
4548 unsigned char ipbytearray[4];
4549 for (
int i = 0; i < 4; i++)
4551 ipbytearray[i] = adrBytesLong[i] & 0xFF;
4555 char ipcommand[255];
4557 sprintf(ipcommand, pcCmdMask, ipbytearray[0], ipbytearray[1], ipbytearray[2], ipbytearray[3]);
4560 std::vector<unsigned char> reqBinary;
4578 std::vector<unsigned char> ipcomandReply;
4579 std::vector<unsigned char> resetReply;
4595 bool result =
false;
4598 unsigned long adrBytesLong[4];
4599 std::string
s = ipNewIPAddr.to_string();
4600 const char *ptr = s.c_str();
4602 sscanf(ptr,
"%lu.%lu.%lu.%lu", &(adrBytesLong[0]), &(adrBytesLong[1]), &(adrBytesLong[2]), &(adrBytesLong[3]));
4605 unsigned char ipbytearray[4];
4606 for (
int i = 0; i < 4; i++)
4608 ipbytearray[i] = adrBytesLong[i] & 0xFF;
4612 char ntpipcommand[255];
4613 char ntpupdatetimecommand[255];
4615 sprintf(ntpipcommand, pcCmdMask, ipbytearray[0], ipbytearray[1], ipbytearray[2], ipbytearray[3]);
4618 sprintf(ntpupdatetimecommand, pcCmdMaskUpdatetime, 5);
4619 std::vector<unsigned char> outputFilterntpupdatetimecommand;
4623 std::vector<unsigned char> reqBinary;
4640 std::vector<unsigned char> ipcomandReply;
4641 std::vector<unsigned char> resetReply;
void setReadTimeOutInMs(int timeOutInMs)
set timeout in milliseconds
std::vector< std::string > sopasCmdErrMsg
void check_angle_range(SickScanConfig &conf)
check angle setting in the config and adjust the min_ang to the max_ang if min_ang greater than max_a...
int loopOnce()
parsing datagram and publishing ros messages
bool isImuDatagram(char *datagram, size_t datagram_length)
virtual int init_scanner()
initialize scanner
std::vector< std::string > sopasCmdMaskVec
int binScanfGuessDataLenFromMask(const char *scanfMask)
std::vector< std::string > sopasReplyStrVec
static std::string binDataToAsciiString(const uint8_t *binary_data, int length)
std::vector< std::string > sopasCmdVec
void updateMarker(const std::vector< SickScanMonField > &fields, int fieldset, int eval_field_logic)
double getElevationDegreeResolution(void)
get angular resolution in VERTICAL direction for multilayer scanner
int getReadTimeOutInMs()
get timeout in milliseconds
double expectedFrequency_
void update_config(sick_scan::SickScanConfig &new_config, uint32_t level=0)
updating configuration
bool getUseSafetyPasWD()
flag to mark the device uses the safety scanner password Bool true for safety password false for nor...
ros::Publisher lferec_pub_
std::vector< unsigned char > stringToVector(std::string s)
Universal swapping function.
const std::string binScanfGetStringFromVec(std::vector< unsigned char > *replyDummy, int off, long len)
Convert part of unsigned char vector into a std::string.
void setHardwareID(const std::string &hwid)
std::string stripControl(std::vector< unsigned char > s)
Converts a SOPAS command to a human readable string.
static SoftwarePLL & instance()
bool isImuAckDatagram(char *datagram, size_t datagram_length)
double getExpectedFrequency(void)
get expected scan frequency
ros::Publisher lidoutputstate_pub_
bool dumpDatagramForDebugging(unsigned char *buffer, int bufLen)
static bool parseLIDoutputstateMsg(const ros::Time &timeStamp, uint8_t *receiveBuffer, int receiveLength, bool useBinaryProtocol, const std::string &frame_id, sick_scan::LIDoutputstateMsg &output_msg)
SickScanCommon(SickGenericParser *parser)
Construction of SickScanCommon.
float get_range_min(void)
Getting minimum range.
virtual void publish(const boost::shared_ptr< T > &message)
bool isCompatibleDevice(const std::string identStr) const
check the identification string
int convertAscii2BinaryCmd(const char *requestAscii, std::vector< unsigned char > *requestBinary)
Convert ASCII-message to Binary-message.
virtual int init_device()=0
bool publish_lidoutputstate_
bool getScanMirroredAndShifted()
flag to mark mirroring of rotation direction
void swap_endian(unsigned char *ptr, int numBytes)
Universal swapping function.
std::string getHumanReadableFormula(void)
int parseDatagram(ros::Time timeStamp, unsigned char *receiveBuffer, int actual_length, bool useBinaryProtocol)
int binScanfVec(const std::vector< unsigned char > *vec, const char *fmt,...)
bool setNewIpAddress(boost::asio::ip::address_v4 ipNewIPAddr, bool useBinaryCmd)
bool getIntensityResolutionIs16Bit(void)
Get the RSSI Value length.
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
dynamic_reconfigure::Server< sick_scan::SickScanConfig > dynamic_reconfigure_server_
int getActiveFieldset(void)
bool getCorrectedTimeStamp(uint32_t &sec, uint32_t &nanoSec, uint32_t tick)
diagnostic_updater::Updater diagnostics_
ros::Publisher Encoder_pub
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
std::vector< std::string > sopasReplyVec
void publish(const boost::shared_ptr< M > &message) const
double compensateAngleInRadFromRos(double angleInRadFromRos)
Compensate raw angle given in [RAD] in the ROS axis orientation system.
bool checkForProtocolChangeAndMaybeReconnect(bool &useBinaryCmdNow)
checks the current protocol type and gives information about necessary change
virtual bool rebootScanner()
Send a SOPAS command to the scanner that should cause a soft reset.
int getNumberOfLayers(void)
Getting number of scanner layers.
int getProtocolType(void)
get protocol type as enum
void setEncoderMode(int8_t _EncoderMode)
Prama for encoder mode.
SopasProtocol m_protocolId
int getNumberOfMaximumEchos(void)
Get number of maximum echoes for this laser scanner type.
static SickScanFieldMonSingleton * getInstance()
void setProtocolType(SopasProtocol cola_dialect_id)
set protocol type as enum
bool getParam(const std::string &key, std::string &s) const
std::vector< int > sopasCmdChain
ros::Publisher imuScan_pub_
void addFrameToBuffer(UINT8 *sendBuffer, UINT8 *cmdBuffer, UINT16 *len)
std::string replyToString(const std::vector< unsigned char > &reply)
Converts reply from sendSOPASCommand to string.
virtual int parse_datagram(char *datagram, size_t datagram_length, SickScanConfig &config, sensor_msgs::LaserScan &msg, int &numEchos, int &echoMask)
Parsing Ascii datagram.
static int getDiagnosticErrorCode()
return diagnostic error code (small helper function) This small helper function was introduced to all...
void checkScanTiming(float time_increment, float scan_time, float angle_increment, float tol)
bool setNTPServerAndStart(boost::asio::ip::address_v4 ipNewIPAddr, bool useBinaryCmd)
float get_range_max(void)
Getting maximum range.
int parseDatagram(ros::Time timeStamp, unsigned char *receiveBuffer, int actual_length, bool useBinaryProtocol)
bool getUseBinaryProtocol(void)
flag to decide between usage of ASCII-sopas or BINARY-sopas
std::string generateExpectedAnswerString(const std::vector< unsigned char > requestStr)
Generate expected answer string from the command string.
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
int parseAsciiDatagram(std::vector< unsigned char > datagramm)
Parsing Ascii datagram.
static SickScanRadarSingleton * getInstance()
#define ROS_WARN_STREAM(args)
ScannerBasicParam * getCurrentParamPtr()
Gets Pointer to parameter object.
#define ROS_DEBUG_STREAM(args)
static DataDumper & instance()
#define SICK_SCANNER_TIM_240_NAME
SickGenericParser * parser_
double getAngularDegreeResolution(void)
Get angular resolution in degress.
std::string getScannerName(void)
Getting name (type) of scanner.
ros::Publisher datagram_pub_
int8_t getEncoderMode()
Getter-Method for encoder mode.
int checkForBinaryAnswer(const std::vector< unsigned char > *reply)
Check block for correct framing and starting sequence of a binary message.
void setSensorIsRadar(bool _isRadar)
#define SICK_SCANNER_NAV_3XX_NAME
virtual ~SickScanCommon()
Destructor of SickScanCommon.
SickScanMarker * cloud_marker_
const std::vector< SickScanMonField > & getMonFields(void) const
#define SICK_SCANNER_MRS_1XXX_NAME
#define ROS_INFO_STREAM(args)
int sendSopasAndCheckAnswer(std::string request, std::vector< unsigned char > *reply, int cmdId)
send command and check answer
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
unsigned long convertBigEndianCharArrayToUnsignedLong(const unsigned char *vecArr)
Convert little endian to big endian (should be replaced by swap-routine)
virtual int init()
init routine of scanner
void setIntensityResolutionIs16Bit(bool _IntensityResolutionIs16Bit)
Set the RSSI Value length.
double getScanAngleShift()
unsigned char sick_crc8(unsigned char *msgBlock, int len)
calculate crc-code for last byte of binary message XOR-calucation is done ONLY over message content (...
static bool parseLFErecMsg(const ros::Time &timeStamp, uint8_t *receiveBuffer, int receiveLength, bool useBinaryProtocol, EVAL_FIELD_SUPPORT eval_field_logic, const std::string &frame_id, sick_scan::LFErecMsg &output_msg)
virtual int stop_scanner()
Stops sending scan data.
virtual int get_datagram(ros::Time &recvTimeStamp, unsigned char *receiveBuffer, int bufferSize, int *actual_length, bool isBinaryProtocol, int *numberOfRemainingFifoEntries)=0
Read a datagram from the device.
#define SICK_SCANNER_LMS_5XX_NAME
int getMaxEvalFields(void)
bool getSensorIsRadar(void)
void broadcast(int lvl, const std::string msg)
#define ROS_ERROR_STREAM(args)
int parseBinaryLIDinputstateMsg(unsigned char *datagram, int datagram_length)
Parse binary LIDinputstate message and set active field set.
static const int fifoSize
std::mutex sopasSendMutex
diagnostic_updater::DiagnosedPublisher< sensor_msgs::LaserScan > * diagnosticPub_
#define SICK_SCANNER_NAV_2XX_NAME
int parseBinaryDatagram(std::vector< unsigned char > datagramm)
sensor_msgs::PointCloud2 cloud_
int dumpUcharBufferToConsole(unsigned char *buffer, int bufLen)
ros::Publisher cloud_pub_
EVAL_FIELD_SUPPORT getUseEvalFields()
static sick_scan::SickScanCommonTcp * s
std::vector< std::vector< unsigned char > > sopasReplyBinVec
AngleCompensator * angleCompensator
bool updatePLL(uint32_t sec, uint32_t nanoSec, uint32_t curtick)
Updates PLL internale State should be called only with network send timestamps.
int init_cmdTables()
init command tables and define startup sequence
int parseReply(bool isBinary, std::vector< unsigned char > &replyVec)
Parse reply of angle compensation values given the command MCAngleCompSin (see testbed) ...
bool getDeviceIsRadar(void)
flag to mark the device as radar (instead of laser scanner)
virtual int sendSOPASCommand(const char *request, std::vector< unsigned char > *reply, int cmdLen=-1)=0
Send a SOPAS command to the device and print out the response to the console.