62 #pragma warning(disable: 4996)
63 #pragma warning(disable: 4267)
74 #define _USE_MATH_DEFINES
100 std::string nodename;
106 cloud_radar_track_pub_ = rosAdvertise<ros_sensor_msgs::PointCloud2>(nh, nodename +
"/cloud_radar_track", 100);
108 radarScan_pub_ = rosAdvertise<sick_scan_msg::RadarScan>(nh, nodename +
"/radar", 100);
113 int range_filter_handling = 0;
119 rosGetParam(nh,
"range_filter_handling", range_filter_handling);
121 ROS_INFO_STREAM(
"Range filter configuration for SickScanRadar: range_min=" <<
range_min <<
", range_max=" <<
range_max <<
", range_filter_handling=" << range_filter_handling);
129 if (1 == sscanf(str.c_str(),
"%x", &val))
145 if (1 == sscanf(str.c_str(),
"%x", &val))
170 if (1 == sscanf(str.c_str(),
"%x", &conv.
u32_val))
174 else if (str.size() <= 4)
191 if (1 == sscanf(str.c_str(),
"%x", &conv.
u32_val))
213 #if 0 // Basic unittests, disabled by default
215 static void unittestHex2Int_32_16_8_signed(
const char* hexstr,
int value)
219 std::cout << hexstr <<
" = " << val <<
" OK" << std::endl;
221 std::cerr <<
"## ERROR: " << hexstr <<
" = " << val <<
", expected " << value << std::endl;
224 static void unittestHex2Int_32_16_signed(
const char* hexstr,
int value)
228 std::cout << hexstr <<
" = " << val <<
" OK" << std::endl;
230 std::cerr <<
"## ERROR: " << hexstr <<
" = " << val <<
", expected " << value << std::endl;
234 static void unittestsHex2Int()
236 unittestHex2Int_32_16_8_signed(
"B", 11);
237 unittestHex2Int_32_16_8_signed(
"0B", 11);
238 unittestHex2Int_32_16_8_signed(
"7B", 123);
239 unittestHex2Int_32_16_8_signed(
"A1", -95);
240 unittestHex2Int_32_16_8_signed(
"123", 291);
241 unittestHex2Int_32_16_8_signed(
"0123", 291);
242 unittestHex2Int_32_16_8_signed(
"7123", 28963);
243 unittestHex2Int_32_16_8_signed(
"9123", -28381);
244 unittestHex2Int_32_16_8_signed(
"71235", 463413);
245 unittestHex2Int_32_16_8_signed(
"A1235", 660021);
246 unittestHex2Int_32_16_8_signed(
"AB1235", 11211317);
247 unittestHex2Int_32_16_8_signed(
"7AB1235", 128651829);
248 unittestHex2Int_32_16_8_signed(
"AAB1235", 178983477);
249 unittestHex2Int_32_16_8_signed(
"1AAB1235", 447418933);
250 unittestHex2Int_32_16_8_signed(
"7AAB1235", 2058031669);
251 unittestHex2Int_32_16_8_signed(
"8AAB1235", -1968500171);
252 unittestHex2Int_32_16_8_signed(
"AAAB1235", -1431629259);
253 unittestHex2Int_32_16_signed(
"B", 11);
254 unittestHex2Int_32_16_signed(
"0B", 11);
255 unittestHex2Int_32_16_signed(
"7B", 123);
256 unittestHex2Int_32_16_signed(
"A1", 161);
257 unittestHex2Int_32_16_signed(
"123", 291);
258 unittestHex2Int_32_16_signed(
"0123", 291);
259 unittestHex2Int_32_16_signed(
"7123", 28963);
260 unittestHex2Int_32_16_signed(
"7FFF", 32767);
261 unittestHex2Int_32_16_signed(
"8000", -32768);
262 unittestHex2Int_32_16_signed(
"9123", -28381);
263 unittestHex2Int_32_16_signed(
"71235", 463413);
264 unittestHex2Int_32_16_signed(
"A1235", 660021);
265 unittestHex2Int_32_16_signed(
"AB1235", 11211317);
266 unittestHex2Int_32_16_signed(
"7AB1235", 128651829);
267 unittestHex2Int_32_16_signed(
"AAB1235", 178983477);
268 unittestHex2Int_32_16_signed(
"1AAB1235", 447418933);
269 unittestHex2Int_32_16_signed(
"7AAB1235", 2058031669);
270 unittestHex2Int_32_16_signed(
"8AAB1235", -1968500171);
271 unittestHex2Int_32_16_signed(
"AAAB1235", -1431629259);
273 #endif // Basic unittests, disabled by default
278 val = (float) (value * scale + offset);
286 ptr = (
unsigned char *) (&tmpVal);
287 int strLen = str.length();
293 for (
int i = 0; i < 4; i++)
295 std::string dummyStr =
"";
296 dummyStr += str[i * 2];
297 dummyStr += str[i * 2 + 1];
299 unsigned char ch = (0xFF & val);
324 if(
len ==
sizeof(value))
336 uint32_t u32_value = 0;
337 if(useBinaryProtocol)
339 bool success =
false;
340 uint8_t u8_value = 0;
341 uint16_t u16_value = 0;
346 u32_value = u8_value;
350 u32_value = u16_value;
363 u32_value = strtoul(field.
data,
NULL, 16);
371 int32_t i32_value = 0;
372 if(useBinaryProtocol)
374 bool success =
false;
376 int16_t i16_value = 0;
381 i32_value = i8_value;
385 i32_value = i16_value;
406 if(useBinaryProtocol)
408 if(field.
len ==
sizeof(value))
410 memcpy(&value, field.
data, field.
len);
411 swap_endian((
unsigned char *)&value,
sizeof(value));
415 ROS_WARN_STREAM(
"radarFieldToFloat(): field.len=" << field.
len <<
", expected 4 byte");
420 std::string token(field.
data);
429 return std::string(field.
data, field.
len);
436 if(datagram_length >= field_length)
439 datagram += field_length;
440 datagram_length -= field_length;
450 std::vector<RadarDatagramField> fields;
451 fields.reserve(datagram_length);
453 if(datagram_length >= 4 && memcmp(datagram,
"sSN ", 4) == 0)
457 datagram_length -= 4;
461 return std::vector<RadarDatagramField>();
464 if(datagram_length >= 4 && memcmp(datagram,
"LMDradardata ", 13) == 0)
468 datagram_length -= 13;
472 return std::vector<RadarDatagramField>();
495 uint16_t num_16_bit_channels = 0;
496 fields.back().toInteger(num_16_bit_channels);
501 for(
int channel_idx = 0; channel_idx < num_16_bit_channels; channel_idx++)
507 uint16_t amount_of_data = 0;
508 fields.back().toInteger(amount_of_data);
509 for(
int data_field_idx = 0; data_field_idx < amount_of_data; data_field_idx++)
516 uint16_t num_8_bit_channels = 0;
517 fields.back().toInteger(num_8_bit_channels);
518 if(num_8_bit_channels > 4)
520 return std::vector<RadarDatagramField>();
522 for(
int channel_idx = 0; channel_idx < num_8_bit_channels; channel_idx++)
528 uint16_t amount_of_data = 0;
529 fields.back().toInteger(amount_of_data);
530 for(
int data_field_idx = 0; data_field_idx < amount_of_data; data_field_idx++)
537 uint16_t position_data_available = 0;
538 fields.back().toInteger(position_data_available);
539 if(position_data_available)
552 uint16_t device_name_available = 0;
553 fields.back().toInteger(device_name_available);
554 if(device_name_available)
561 uint16_t comment_available = 0;
562 fields.back().toInteger(comment_available);
563 if(comment_available)
570 uint16_t timestamp_available = 0;
571 fields.back().toInteger(timestamp_available);
572 if(timestamp_available)
584 uint16_t eventinfo_available = 0;
585 fields.back().toInteger(eventinfo_available);
586 if(eventinfo_available)
596 ROS_INFO_STREAM(
"splitBinaryRadarDatagramToFields(): " << fields.size() <<
" fields, " << num_16_bit_channels <<
" 16-bit channels, " << num_8_bit_channels <<
" 8-bit channels, success=" << success);
614 std::vector<SickScanRadarObject> &objectList,
615 std::vector<SickScanRadarRawTarget> &rawTargetList,
619 bool dumpData =
false;
623 int HEADER_FIELDS = 32;
626 std::vector<RadarDatagramField> fields;
629 std::vector<char> datagram_copy_vec;
630 datagram_copy_vec.resize(datagram_length + 1);
631 char *datagram_copy = &(datagram_copy_vec[0]);
633 if (verboseLevel > 0)
638 strncpy(datagram_copy, datagram, datagram_length);
639 datagram_copy[datagram_length] = 0;
642 if(useBinaryProtocol)
648 fields.reserve(datagram_length / 2);
649 char* cur_field = strtok(datagram,
" ");
650 while (cur_field !=
NULL)
654 cur_field = strtok(
NULL,
" ");
659 size_t count = fields.size();
661 if (verboseLevel > 0 && !useBinaryProtocol)
663 std::vector<unsigned char> raw_fields;
664 for (
int i = 0; i < count; i++)
666 for(
int j = 0; j < fields[i].len; j++)
667 raw_fields.push_back(fields[i].data[j]);
668 raw_fields.push_back(
' ');
674 enum PREHEADER_TOKEN_SEQ
677 PREHEADER_TOKEN_LMDRADARDATA,
678 PREHEADER_TOKEN_UI_VERSION_NO,
679 PREHEADER_TOKEN_UI_IDENT,
680 PREHEADER_TOKEN_UDI_SERIAL_NO,
681 PREHEADER_TOKEN_XB_STATE_0,
682 PREHEADER_TOKEN_XB_STATE_1,
683 PREHEADER_TOKEN_TELEGRAM_COUNT,
684 PREHEADER_TOKEN_CYCLE_COUNT,
685 PREHEADER_TOKEN_SYSTEM_COUNT_SCAN,
686 PREHEADER_TOKEN_SYSTEM_COUNT_TRANSMIT,
687 PREHEADER_TOKEN_XB_INPUTS_0,
688 PREHEADER_TOKEN_XB_INPUTS_1,
689 PREHEADER_TOKEN_XB_OUTPUTS_0,
690 PREHEADER_TOKEN_XB_OUTPUTS_1,
691 PREHEADER_TOKEN_CYCLE_DURATION,
692 PREHEADER_TOKEN_NOISE_LEVEL,
693 PREHEADER_NUM_ENCODER_BLOCKS,
694 PREHADERR_TOKEN_FIX_NUM
733 if (count < PREHADERR_TOKEN_FIX_NUM)
735 ROS_WARN_STREAM(
"parseRadarDatagram: " << count <<
" fields in datagram, at least " << PREHADERR_TOKEN_FIX_NUM <<
" fields required");
738 for (
int i = 0; i < PREHADERR_TOKEN_FIX_NUM; i++)
740 if(i == PREHEADER_TOKEN_SSN || i == PREHEADER_TOKEN_LMDRADARDATA)
744 unsigned long int uliDummy;
748 case PREHEADER_TOKEN_UI_VERSION_NO:
749 msgPtr->radarpreheader.uiversionno = (
UINT16) (uliDummy & 0xFFFF);
751 case PREHEADER_TOKEN_UI_IDENT:
752 msgPtr->radarpreheader.radarpreheaderdeviceblock.uiident = (
UINT16) (uliDummy & 0xFFFF);
754 case PREHEADER_TOKEN_UDI_SERIAL_NO:
755 msgPtr->radarpreheader.radarpreheaderdeviceblock.udiserialno = (
UINT32) (uliDummy & 0xFFFFFFFF);
757 case PREHEADER_TOKEN_XB_STATE_0:
758 for (
int j = 0; j < 3; j++)
761 if (0 != (uliDummy & (1 << j)))
768 msgPtr->radarpreheader.radarpreheaderdeviceblock.bdeviceerror = flag;
771 msgPtr->radarpreheader.radarpreheaderdeviceblock.bcontaminationwarning = flag;
774 msgPtr->radarpreheader.radarpreheaderdeviceblock.bcontaminationerror = flag;
777 ROS_WARN(
"Flag parsing for this PREHEADER-Flag not implemented");
781 case PREHEADER_TOKEN_XB_STATE_1:
784 case PREHEADER_TOKEN_TELEGRAM_COUNT:
785 msgPtr->radarpreheader.radarpreheaderstatusblock.uitelegramcount = (
UINT16) (uliDummy & 0xFFFF);
787 case PREHEADER_TOKEN_CYCLE_COUNT:
789 msgPtr->radarpreheader.radarpreheaderstatusblock.uicyclecount = (
UINT16) (uliDummy & 0xFFFF);
791 case PREHEADER_TOKEN_SYSTEM_COUNT_SCAN:
792 msgPtr->radarpreheader.radarpreheaderstatusblock.udisystemcountscan = (
UINT32) (uliDummy & 0xFFFFFFFF);
794 case PREHEADER_TOKEN_SYSTEM_COUNT_TRANSMIT:
795 msgPtr->radarpreheader.radarpreheaderstatusblock.udisystemcounttransmit = (
UINT32) (uliDummy & 0xFFFFFFFF);
797 case PREHEADER_TOKEN_XB_INPUTS_0:
798 msgPtr->radarpreheader.radarpreheaderstatusblock.uiinputs = (
UINT8) (uliDummy & 0xFF);;
799 msgPtr->radarpreheader.radarpreheaderstatusblock.uiinputs <<= 8;
801 case PREHEADER_TOKEN_XB_INPUTS_1:
802 msgPtr->radarpreheader.radarpreheaderstatusblock.uiinputs |= (
UINT8) (uliDummy & 0xFF);;
804 case PREHEADER_TOKEN_XB_OUTPUTS_0:
805 msgPtr->radarpreheader.radarpreheaderstatusblock.uioutputs = (
UINT8) (uliDummy & 0xFF);;
806 msgPtr->radarpreheader.radarpreheaderstatusblock.uioutputs <<= 8;
808 case PREHEADER_TOKEN_XB_OUTPUTS_1:
809 msgPtr->radarpreheader.radarpreheaderstatusblock.uioutputs |= (
UINT8) (uliDummy & 0xFF);;
811 case PREHEADER_TOKEN_CYCLE_DURATION:
812 msgPtr->radarpreheader.radarpreheadermeasurementparam1block.uicycleduration = (
UINT16) (uliDummy & 0xFFFF);
814 case PREHEADER_TOKEN_NOISE_LEVEL:
815 msgPtr->radarpreheader.radarpreheadermeasurementparam1block.uinoiselevel = (
UINT16) (uliDummy & 0xFFFF);
817 case PREHEADER_NUM_ENCODER_BLOCKS:
821 if (u16NumberOfBlock > 0)
823 msgPtr->radarpreheader.radarpreheaderarrayencoderblock.resize(u16NumberOfBlock);
825 for (
int j = 0; j < u16NumberOfBlock; j++)
828 int rowIndex = PREHEADER_NUM_ENCODER_BLOCKS + j * 2 + 1;
830 msgPtr->radarpreheader.radarpreheaderarrayencoderblock[j].udiencoderpos = udiValue;
832 iencoderspeed = (int) udiValue;
833 msgPtr->radarpreheader.radarpreheaderarrayencoderblock[j].iencoderspeed = iencoderspeed;
849 std::vector<std::string> keyWordList;
850 #define DIST1_KEYWORD "DIST1"
851 #define AZMT1_KEYWORD "AZMT1"
852 #define VRAD1_KEYWORD "VRAD1"
853 #define AMPL1_KEYWORD "AMPL1"
854 #define MODE1_KEYWORD "MODE1"
856 #define P3DX1_KEYWORD "P3DX1"
857 #define P3DY1_KEYWORD "P3DY1"
858 #define V3DX1_KEYWORD "V3DX1"
859 #define V3DY1_KEYWORD "V3DY1"
860 #define OBJLEN_KEYWORD "OBLE1"
861 #define OBJID_KEYWORD "OBID1"
863 const int RAWTARGET_LOOP = 0;
864 const int OBJECT_LOOP = 1;
866 for (
int iLoop = 0; iLoop < 2; iLoop++)
902 std::vector<int> keyWordPos;
903 std::vector<float> keyWordScale;
904 std::vector<float> keyWordScaleOffset;
905 keyWordPos.resize(keyWordList.size());
906 keyWordScale.resize(keyWordList.size());
907 keyWordScaleOffset.resize(keyWordList.size());
908 for (
int i = 0; i < keyWordPos.size(); i++)
912 int numKeyWords = keyWordPos.size();
913 for (
int i = 0; i < fields.size(); i++)
915 for (
int j = 0; j < keyWordList.size(); j++)
917 if (fields[i].len == keyWordList[j].
length() && strncmp(fields[i].
data, keyWordList[j].c_str(), fields[i].len) == 0)
924 bool entriesNumOk =
true;
925 bool allow_missing_keywords =
false;
927 if (keyWordPos[0] == -1)
929 entriesNumOk =
false;
934 entriesNum = (int)
radarFieldToInt32(fields[keyWordPos[0] + 3], useBinaryProtocol);
935 for (
int i = 0; i < numKeyWords; i++)
937 if (keyWordPos[i] == -1)
939 entriesNumOk =
false;
940 ROS_WARN_STREAM(
"parseRadarDatagram(): " << (i + 1) <<
". keyword " << keyWordList[i] <<
" missing, but first keyword " << keyWordList[0] <<
" found, value set to 0.0");
941 entriesNumOk =
false;
942 allow_missing_keywords =
true;
946 int entriesNumTmp = (int)
radarFieldToInt32(fields[keyWordPos[i] + 3], useBinaryProtocol);
947 if (entriesNumTmp != entriesNum)
949 ROS_WARN_STREAM(
"parseRadarDatagram(): Number of items for keyword " << keyWordList[i] <<
" differs from number of items for " << keyWordList[0]);
950 entriesNumOk =
false;
956 if (
true == entriesNumOk ||
true == allow_missing_keywords)
960 for (
int i = 0; i < numKeyWords; i++)
962 if (
true == allow_missing_keywords && keyWordPos[i] == -1)
966 int scaleLineIdx = keyWordPos[i] + 1;
967 int scaleOffsetLineIdx = keyWordPos[i] + 2;
971 keyWordScaleOffset[i] =
radarFieldToFloat(fields[scaleOffsetLineIdx], useBinaryProtocol);
979 rawTargetList.resize(entriesNum);
984 objectList.resize(entriesNum);
988 for (
int i = 0; i < entriesNum; i++)
999 for (
int j = 0; j < numKeyWords; j++)
1001 if (
true == allow_missing_keywords && keyWordPos[j] == -1)
1005 int dataRowIdx = keyWordPos[j] + 4 + i;
1006 std::string token = keyWordList[j];
1033 rawTargetList[i].Dist(dist);
1034 rawTargetList[i].Ampl(ampl);
1035 rawTargetList[i].Azimuth(azimuth);
1036 rawTargetList[i].Mode(
mode);
1037 rawTargetList[i].Vrad(vrad);
1050 for (
int j = 0; j < numKeyWords; j++)
1052 if (
true == allow_missing_keywords && keyWordPos[j] == -1)
1056 int dataRowIdx = keyWordPos[j] + 4 + i;
1057 std::string token = keyWordList[j];
1085 objId = (int) (objIdRaw * keyWordScale[j] + 0.5);
1089 objectList[i].ObjId(objId);
1090 objectList[i].ObjLength(objLen);
1091 objectList[i].P3Dx(px);
1092 objectList[i].P3Dy(py);
1093 objectList[i].V3Dx(vx);
1094 objectList[i].V3Dy(vy);
1108 static int callCnt = 0;
1113 std::string
header =
"\x2sSN LMDradardata 1 1 112F6E9 0 0 DFB6 B055 6E596002 6E5AE0E5 0 0 0 0 0 0 1 0 0 ";
1115 int channel16BitCnt = 4;
1117 float rawTargetFactorList[] = {40.0f, 0.16f, 0.04f, 1.00f, 1.00f};
1118 float objectFactorList[] = {64.0f, 64.0f, 0.1f, 0.1f, 0.75f, 1.0f};
1120 std::string dist1_intro =
"DIST1 42200000 00000000";
1121 std::string azmt1_intro =
"AZMT1 3E23D70A 00000000";
1122 std::string vrad1_intro =
"VRAD1 3D23D70A 00000000";
1123 std::string ampl1_intro =
"AMPL1 3F800000 00000000";
1125 std::string pdx1_intro =
"P3DX1 42800000 00000000";
1126 std::string pdy1_intro =
"P3DY1 42800000 00000000";
1127 std::string v3dx_intro =
"V3DX1 3DCCCCCD 00000000";
1128 std::string v3dy_intro =
"V3DY1 3DCCCCCD 00000000";
1129 std::string oblen_intro =
"OBLE1 3F400000 00000000";
1131 int rawTargetChannel16BitCnt = 4;
1132 int rawTargetChannel8BitCnt = 1;
1133 std::string mode1_intro =
"MODE1 3F800000 00000000";
1135 std::string obid_intro =
"OBID1 3F800000 00000000";
1138 std::string trailer =
"0 0 0 0 0 0\x3";
1140 std::vector<std::string> channel16BitID;
1141 std::vector<std::string> channel8BitID;
1142 channel16BitID.push_back(dist1_intro);
1143 channel16BitID.push_back(azmt1_intro);
1144 channel16BitID.push_back(vrad1_intro);
1145 channel16BitID.push_back(ampl1_intro);
1147 channel16BitID.push_back(pdx1_intro);
1148 channel16BitID.push_back(pdy1_intro);
1149 channel16BitID.push_back(v3dx_intro);
1150 channel16BitID.push_back(v3dy_intro);
1151 channel16BitID.push_back(oblen_intro);
1154 channel8BitID.push_back(mode1_intro);
1155 channel8BitID.push_back(obid_intro);
1157 int channel8BitCnt = channel8BitID.size();
1158 int objectChannel16BitCnt = 5;
1159 channel16BitCnt = channel16BitID.size();
1162 std::vector<SickScanRadarRawTarget> rawTargetList;
1164 #if 0 // simulate railway crossing
1165 for (
float y = -20; y <= 20.0; y += 2.0)
1168 float azimuth = atan2(y, x);
1169 float dist = sqrt(x*x + y*y);
1170 float vrad = speed * sin(azimuth);
1172 float ampl = 50.0 + y;
1173 rawTarget.
Ampl(ampl);
1175 rawTarget.
Dist(dist);
1177 rawTarget.
Vrad(vrad);
1178 rawTargetList.push_back(rawTarget);
1182 std::vector<SickScanRadarObject> objectList;
1185 for (
float x = 20; x <= 100.0; x += 50.0)
1189 for (
int iY = -1; iY <= 1; iY += 2)
1193 float vehicleWidth = 1.8f;
1195 float speed = y * 10.0f;
1196 vehicle.
V3Dx(speed);
1204 vehicle.
P3Dx((xOff + 0.1 * speed * (callCnt % 20)) * 1000.0);
1205 vehicle.
P3Dy(y * 1000.0);
1206 float objLen = 6.0f + y;
1209 vehicle.
ObjId(objId++);
1210 objectList.push_back(vehicle);
1212 for (
int i = 0; i < 2; i++)
1216 xp[i] = vehicle.
P3Dx() * 0.001;
1217 yp[i] = vehicle.
P3Dy() * 0.001;
1221 yp[i] -= vehicleWidth / 2.0;
1225 yp[i] += vehicleWidth / 2.0;
1229 xp[i] -= objLen * 0.5;
1233 xp[i] += objLen * 0.5;
1236 float azimuth = atan2(yp[i], xp[i]);
1237 float dist = sqrt(xp[i] * xp[i] + yp[i] * yp[i]);
1238 float vrad = speed * cos(azimuth);
1242 rawTarget.
Ampl(ampl);
1244 rawTarget.
Dist(dist);
1246 rawTarget.
Vrad(vrad);
1247 rawTargetList.push_back(rawTarget);
1256 char szDummy[255] = {0};
1257 std::string resultStr;
1259 sprintf(szDummy,
"%x ", channel16BitCnt);
1260 resultStr += szDummy;
1261 for (
int i = 0; i < channel16BitCnt; i++)
1263 resultStr += channel16BitID[i];
1264 int valNum = rawTargetList.size();
1265 bool processRawTarget =
true;
1266 if (i < rawTargetChannel16BitCnt)
1268 valNum = rawTargetList.size();
1272 processRawTarget =
false;
1273 valNum = objectList.size();
1276 sprintf(szDummy,
" %x ", valNum);
1277 resultStr += szDummy;
1279 for (
int j = 0; j < valNum; j++)
1284 val = 1000.0 * rawTargetList[j].Dist();
1287 val = 1.0 /
deg2rad * rawTargetList[j].Azimuth();
1290 val = rawTargetList[j].Vrad();
1293 val = rawTargetList[j].Ampl();
1296 val = objectList[j].P3Dx();
1299 val = objectList[j].P3Dy();
1302 val = objectList[j].V3Dx();
1305 val = objectList[j].V3Dy();
1308 val = objectList[j].ObjLength();
1313 if (processRawTarget)
1315 val /= rawTargetFactorList[i];
1319 int idx = i - rawTargetChannel16BitCnt;
1320 val /= objectFactorList[idx];
1331 int16_t shortVal = (int16_t) (val);
1333 sprintf(szDummy,
"%08x", shortVal);
1334 strcpy(szDummy, szDummy + 4);
1335 resultStr += szDummy;
1340 sprintf(szDummy,
"%x ", channel8BitCnt);
1341 resultStr += szDummy;
1342 int valNum = rawTargetList.size();
1343 for (
int i = 0; i < channel8BitCnt; i++)
1345 resultStr += channel8BitID[i];
1347 bool processRawTarget =
true;
1348 if (i < rawTargetChannel8BitCnt)
1350 valNum = rawTargetList.size();
1354 processRawTarget =
false;
1355 valNum = objectList.size();
1357 sprintf(szDummy,
" %x ", valNum);
1358 resultStr += szDummy;
1359 for (
int j = 0; j < valNum; j++)
1364 val = rawTargetList[j].Mode();
1367 val = objectList[j].ObjId();
1372 if (processRawTarget)
1374 offset = rawTargetChannel16BitCnt;
1375 val /= rawTargetFactorList[i + offset];
1379 offset = objectChannel16BitCnt;
1380 int idx = i - rawTargetChannel8BitCnt;
1381 val /= objectFactorList[idx + offset];
1391 int8_t shortVal = (int16_t) (val);
1393 sprintf(szDummy,
"%08x", shortVal);
1394 strcpy(szDummy, szDummy + 6);
1395 resultStr += szDummy;
1400 resultStr += trailer;
1402 *actual_length = resultStr.length();
1403 strcpy((
char *) receiveBuffer, resultStr.c_str());
1407 std::string filePattern)
1409 static int callCnt = 0;
1411 char szLine[1024] = {0};
1412 char szDummyWord[1024] = {0};
1413 int actual_length = 0;
1415 char szFileName[1024] = {0};
1417 receiveBuffer[0] =
'\x02';
1420 for (
int iLoop = 0; iLoop < 2; iLoop++)
1422 sprintf(szFileName, filePattern.c_str(), callCnt);
1424 fin = fopen(szFileName,
"r");
1426 if ((fin ==
NULL) && (iLoop == 0))
1435 if ((iLoop == 1) && (fin ==
NULL))
1437 ROS_ERROR_STREAM(
"Can not find simulation file corresponding to pattern " << filePattern);
1441 while (fgets(szLine, 1024, fin) !=
NULL)
1443 char *ptr = strchr(szLine,
'\n');;
1449 ptr = strchr(szLine,
':');
1452 if (1 == sscanf(ptr + 2,
"%s", szDummyWord))
1456 receiveBuffer[actual_length++] =
' ';
1458 strcpy((
char *) receiveBuffer + actual_length, szDummyWord);
1459 actual_length += strlen(szDummyWord);
1464 receiveBuffer[actual_length] = (char)
'\x03';
1466 receiveBuffer[actual_length] = (char)
'\x00';
1468 *pActual_length = actual_length;
1473 bool useBinaryProtocol)
1477 enum enumSimulationMode
1479 EMULATE_OFF, EMULATE_SYN, EMULATE_FROM_FILE_TRAIN, EMULATE_FROM_FILE_CAR
1482 int simulationMode = EMULATE_OFF;
1486 simulationMode = EMULATE_SYN;
1489 switch (simulationMode)
1496 case EMULATE_FROM_FILE_TRAIN:
1498 "/mnt/hgfs/development/ros/bags/raw/trainSeq/tmp%06d.txt");
1500 case EMULATE_FROM_FILE_CAR:
1502 "/mnt/hgfs/development/ros/bags/raw/carSeq/tmp%06d.txt");
1506 printf(
"Simulation Mode unknown\n");
1513 std::vector<SickScanRadarObject> objectList;
1514 std::vector<SickScanRadarRawTarget> rawTargetList;
1518 throw std::logic_error(
"Binary protocol for RMSxxxx currently not supported. Please use <param name=\"use_binary_protocol\" type=\"bool\" value=\"false\"/> in your launchfile.");
1522 bool dataToProcess =
false;
1523 char *buffer_pos = (
char *) receiveBuffer;
1524 char *dstart =
NULL;
1526 int32_t dlength = 0;
1528 if (useBinaryProtocol)
1531 uint32_t binary_stx = 0x02020202;
1532 dstart = strchr(buffer_pos, 0x02);
1533 if(dstart != 0 && memcmp(dstart, &binary_stx,
sizeof(binary_stx)) == 0)
1536 memcpy(&dlength, dstart, 4);
1539 dataToProcess =
true;
1544 dstart = strchr(buffer_pos, 0x02);
1547 dend = strchr(dstart + 1, 0x03);
1549 if ((dstart !=
NULL) && (dend !=
NULL))
1551 dataToProcess =
true;
1552 dlength = dend - dstart;
1557 if(dataToProcess && dstart != 0 && dlength > 0 && dstart + dlength <= (
char*)receiveBuffer + actual_length)
1561 dataToProcess =
false;
1566 dataToProcess =
false;
1569 enum RADAR_PROC_LIST
1571 RADAR_PROC_RAW_TARGET, RADAR_PROC_TRACK, RADAR_PROC_NUM
1576 for (
int iLoop = 0; iLoop < RADAR_PROC_NUM; iLoop++)
1581 std::string channelRawTargetId[] = {
"x",
"y",
"z",
"vrad",
"amplitude"};
1582 std::string channelObjectId[] = {
"x",
"y",
"z",
"vx",
"vy",
"vz",
"objLen",
"objId"};
1583 std::vector<std::string> channelList;
1584 std::string
frameId =
"radar";
1587 case RADAR_PROC_RAW_TARGET:
1588 numTargets = rawTargetList.size();
1589 for (
int i = 0; i <
sizeof(channelRawTargetId) /
sizeof(channelRawTargetId[0]); i++)
1591 channelList.push_back(channelRawTargetId[i]);
1595 case RADAR_PROC_TRACK:
1596 numTargets = objectList.size();
1597 for (
int i = 0; i <
sizeof(channelObjectId) /
sizeof(channelObjectId[0]); i++)
1599 channelList.push_back(channelObjectId[i]);
1604 if (numTargets == 0)
1608 int numChannels = channelList.size();
1610 std::vector<float> valSingle;
1611 valSingle.resize(numChannels);
1613 cloud_.header.frame_id =
frameId;
1616 cloud_.width = numTargets;
1617 cloud_.is_bigendian =
false;
1618 cloud_.is_dense =
true;
1619 cloud_.point_step = numChannels *
sizeof(float);
1620 cloud_.row_step = cloud_.point_step * cloud_.width;
1621 cloud_.fields.resize(numChannels);
1622 for (
int i = 0; i < numChannels; i++)
1624 cloud_.fields[i].name = channelList[i];
1625 cloud_.fields[i].offset = i *
sizeof(float);
1626 cloud_.fields[i].count = 1;
1627 cloud_.fields[i].datatype = ros_sensor_msgs::PointField::FLOAT32;
1630 cloud_.data.resize(cloud_.row_step * cloud_.height, 0);
1631 float *valPtr = (
float *) (&(cloud_.data[0]));
1633 size_t numFilteredTargets = 0;
1634 for (
int i = 0; i < numTargets; i++)
1636 bool tgt_valid =
true, range_modified =
false;
1642 float range = rawTargetList[i].Dist();
1646 valSingle[0] = range * cos(
angle);
1647 valSingle[1] = range * sin(
angle);
1649 valSingle[3] = rawTargetList[i].Vrad();
1650 valSingle[4] = rawTargetList[i].Ampl();
1656 valSingle[0] = objectList[i].P3Dx();
1657 valSingle[1] = objectList[i].P3Dy();
1659 valSingle[3] = objectList[i].V3Dx();
1660 valSingle[4] = objectList[i].V3Dy();
1662 valSingle[6] = objectList[i].ObjLength();
1663 valSingle[7] = objectList[i].ObjId();
1668 numFilteredTargets++;
1671 for (
int j = 0; j < numChannels; j++)
1673 valPtr[off] = valSingle[j];
1676 if (iLoop == RADAR_PROC_RAW_TARGET)
1679 radarMsg_.targets = cloud_;
1682 if (numFilteredTargets < numTargets)
1688 case RADAR_PROC_RAW_TARGET:
1692 case RADAR_PROC_TRACK:
1704 radarMsg_.header.frame_id =
"radar";
1707 radarMsg_.objects.resize(objectList.size());
1708 for (
int i = 0; i < radarMsg_.objects.size(); i++)
1710 float vx = objectList[i].V3Dx();
1711 float vy = objectList[i].V3Dy();
1712 float v = sqrt(vx * vx + vy * vy);
1713 float heading = atan2(objectList[i].V3Dy(), objectList[i].V3Dx());
1715 radarMsg_.objects[i].id = objectList[i].ObjId();
1716 radarMsg_.objects[i].tracking_time =
timeStamp;
1718 radarMsg_.objects[i].velocity.twist.linear.x = objectList[i].V3Dx();
1719 radarMsg_.objects[i].velocity.twist.linear.y = objectList[i].V3Dy();
1720 radarMsg_.objects[i].velocity.twist.linear.z = 0.0;
1722 radarMsg_.objects[i].bounding_box_center.position.x = objectList[i].P3Dx();
1723 radarMsg_.objects[i].bounding_box_center.position.y = objectList[i].P3Dy();
1724 radarMsg_.objects[i].bounding_box_center.position.z = 0.0;
1726 float heading2 = heading / 2.0;
1730 radarMsg_.objects[i].bounding_box_center.orientation.x = 0.0;
1731 radarMsg_.objects[i].bounding_box_center.orientation.y = 0.0;
1732 radarMsg_.objects[i].bounding_box_center.orientation.z = sin(heading2);
1733 radarMsg_.objects[i].bounding_box_center.orientation.w = cos(heading2);
1736 radarMsg_.objects[i].bounding_box_size.x = objectList[i].ObjLength();
1737 radarMsg_.objects[i].bounding_box_size.y = 1.7;
1738 radarMsg_.objects[i].bounding_box_size.z = 1.7;
1739 for (
int ii = 0; ii < 6; ii++)
1741 int mainDiagOffset = ii * 6 + ii;
1742 radarMsg_.objects[i].object_box_center.covariance[mainDiagOffset] = 1.0;
1743 radarMsg_.objects[i].velocity.covariance[mainDiagOffset] = 1.0;
1745 radarMsg_.objects[i].object_box_center.pose = radarMsg_.objects[i].bounding_box_center;
1746 radarMsg_.objects[i].object_box_size = radarMsg_.objects[i].bounding_box_size;