51 #pragma warning(disable: 4267) 54 #define _CRT_SECURE_NO_WARNINGS 55 #define _USE_MATH_DEFINES 61 #include "sick_scan/rosconsole_simu.hpp" 166 currentParamSet = _ptr;
311 override_range_min_((float)0.05),
312 override_range_max_((float)100.0),
313 override_time_increment_((float)-1.0)
420 if (scannerIdx == -1)
423 throw new std::string(
"scanner type " +
scannerType +
" not supported.");
480 int SickGenericParser::checkForDistAndRSSI(std::vector<char *>& fields,
int expected_number_of_data,
int& distNum,
int& rssiNum, std::vector<float>& distVal, std::vector<float>& rssiVal,
int& distMask)
490 unsigned short int number_of_data = 0;
491 if (strstr(fields[baseOffset],
"DIST") != fields[baseOffset])
493 ROS_WARN(
"Field 20 of received data does not start with DIST (is: %s). Unexpected data, ignoring scan", fields[20]);
500 bool distFnd =
false;
501 bool rssiFnd =
false;
502 if (strlen(fields[offset]) == 5)
504 if (strstr(fields[offset],
"DIST") == fields[offset])
509 if (1 == sscanf(fields[offset],
"DIST%d", &distId))
511 distMask |= (1 << (distId - 1));
514 if (strstr(fields[offset],
"RSSI") == fields[offset])
520 if (rssiFnd || distFnd)
523 if (offset >= fields.size())
525 ROS_WARN(
"Missing RSSI or DIST data");
529 sscanf(fields[offset],
"%hx", &number_of_data);
530 if (number_of_data != expected_number_of_data)
532 ROS_WARN(
"number of dist or rssi values mismatching.");
537 for (
int i = 0; i < number_of_data; i++)
541 unsigned short iRange;
543 sscanf(fields[offset + i],
"%hx", &iRange);
544 range = iRange / 1000.0;
545 distVal.push_back(range);
549 unsigned short iRSSI;
550 sscanf(fields[offset + i],
"%hx", &iRSSI);
551 rssiVal.push_back((
float)iRSSI);
554 offset += number_of_data;
560 }
while (offset < fields.size());
574 if (fabs(expected_time_increment - time_increment) > 0.00001)
576 ROS_WARN_THROTTLE(60,
"The time_increment, scan_time and angle_increment values reported by the scanner are inconsistent! " 577 "Expected time_increment: %.9f, reported time_increment: %.9f. " 578 "Perhaps you should set the parameter time_increment to the expected value. This message will print every 60 seconds.",
579 expected_time_increment, time_increment);
596 sensor_msgs::LaserScan &msg,
int &numEchos,
int &echoMask)
600 bool dumpData =
false;
601 int verboseLevel = 0;
602 tmpParam.
getParam(
"verboseLevel", verboseLevel);
604 int HEADER_FIELDS = 32;
610 std::vector<char *> fields;
611 fields.reserve(datagram_length / 2);
614 std::vector<char> datagram_copy_vec;
615 datagram_copy_vec.resize(datagram_length + 1);
616 char* datagram_copy = &(datagram_copy_vec[0]);
618 if (verboseLevel > 0) {
619 ROS_WARN(
"Verbose LEVEL activated. Only for DEBUG.");
622 if (verboseLevel > 0)
625 char szDumpFileName[255] = {0};
626 char szDir[255] = {0};
628 strcpy(szDir,
"C:\\temp\\");
630 strcpy(szDir,
"/tmp/");
632 sprintf(szDumpFileName,
"%stmp%06d.bin", szDir, cnt);
637 ftmp = fopen(szDumpFileName,
"wb");
640 fwrite(datagram, datagram_length, 1, ftmp);
647 strncpy(datagram_copy, datagram, datagram_length);
648 datagram_copy[datagram_length] = 0;
652 cur_field = strtok(datagram,
" ");
654 while (cur_field != NULL)
656 fields.push_back(cur_field);
658 cur_field = strtok(NULL,
" ");
663 count = fields.size();
666 if (verboseLevel > 0)
669 char szDumpFileName[255] = {0};
670 char szDir[255] = {0};
672 strcpy(szDir,
"C:\\temp\\");
674 strcpy(szDir,
"/tmp/");
676 sprintf(szDumpFileName,
"%stmp%06d.txt", szDir, cnt);
677 ROS_WARN(
"Verbose LEVEL activated. Only for DEBUG.");
679 ftmp = fopen(szDumpFileName,
"w");
683 for (i = 0; i < count; i++)
685 fprintf(ftmp,
"%3d: %s\n", i, fields[i]);
695 if (count < HEADER_FIELDS)
698 "received less fields than minimum fields (actual: %d, minimum: %d), ignoring scan", (
int)count, HEADER_FIELDS);
699 ROS_WARN(
"are you using the correct node? (124 --> sick_tim310_1130000m01, > 33 --> sick_tim551_2050001, 580 --> sick_tim310s01, 592 --> sick_tim310)");
704 if (
basicParams[scannerIdx].getNumberOfLayers() == 1)
706 if (strcmp(fields[15],
"0"))
708 ROS_WARN(
"Field 15 of received data is not equal to 0 (%s). Unexpected data, ignoring scan", fields[15]);
719 if (strcmp(fields[20],
"DIST1"))
721 ROS_WARN(
"Field 20 of received data is not equal to DIST1i (%s). Unexpected data, ignoring scan", fields[20]);
727 unsigned short int number_of_data = 0;
728 sscanf(fields[25],
"%hx", &number_of_data);
730 int numOfExpectedShots =
basicParams[scannerIdx].getNumberOfShots();
731 if (number_of_data < 1 || number_of_data > numOfExpectedShots)
733 ROS_WARN(
"Data length is outside acceptable range 1-%d (%d). Ignoring scan", numOfExpectedShots, number_of_data);
736 if (count < HEADER_FIELDS + number_of_data)
738 ROS_WARN(
"Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
741 ROS_DEBUG(
"Number of data: %d", number_of_data);
744 size_t rssi_idx = 26 + number_of_data;
746 if (strcmp(fields[rssi_idx],
"RSSI1") == 0)
750 unsigned short int number_of_rssi_data = 0;
753 sscanf(fields[rssi_idx + 5],
"%hx", &number_of_rssi_data);
756 if (number_of_rssi_data != number_of_data)
758 ROS_WARN(
"Number of RSSI data is lower than number of range data (%d vs %d", number_of_data, number_of_rssi_data);
764 if (count < HEADER_FIELDS + number_of_data + number_of_rssi_data + 6)
766 ROS_WARN(
"Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
770 if (strcmp(fields[rssi_idx],
"RSSI1"))
772 ROS_WARN(
"Field %zu of received data is not equal to RSSI1 (%s). Unexpected data, ignoring scan", rssi_idx + 1, fields[rssi_idx + 1]);
776 if (
basicParams[scannerIdx].getNumberOfLayers() > 1)
779 sscanf(fields[15],
"%hx", &layer);
780 msg.header.seq = layer;
783 msg.header.frame_id = config.frame_id;
785 ROS_DEBUG(
"publishing with frame_id %s", config.frame_id.c_str());
811 unsigned short scanning_freq = -1;
812 sscanf(fields[16],
"%hx", &scanning_freq);
813 msg.scan_time = 1.0 / (scanning_freq / 100.0);
817 unsigned short measurement_freq = -1;
818 sscanf(fields[17],
"%hx", &measurement_freq);
819 msg.time_increment = 1.0 / (measurement_freq * 100.0);
841 int starting_angle = -1;
842 sscanf(fields[23],
"%x", &starting_angle);
843 msg.angle_min = (starting_angle / 10000.0) / 180.0 * M_PI - M_PI / 2;
847 unsigned short angular_step_width = -1;
848 sscanf(fields[24],
"%hx", &angular_step_width);
849 msg.angle_increment = (angular_step_width / 10000.0) / 180.0 * M_PI;
850 msg.angle_max = msg.angle_min + (number_of_data - 1) * msg.angle_increment;
861 checkForDistAndRSSI(fields, number_of_data, distNum, rssiNum, msg.ranges, msg.intensities, echoMask);
862 if (config.intensity)
870 ROS_WARN_ONCE(
"Intensity parameter is enabled, but the scanner is not configured to send RSSI values! " 871 "Please read the section 'Enabling intensity (RSSI) output' here: http://wiki.ros.org/sick_tim.");
886 if (
basicParams[scannerIdx].getNumberOfLayers() > 1)
888 char szDummy[255] = { 0 };
889 sprintf(szDummy,
"%s_%+04d", config.frame_id.c_str(), msg.header.seq);
890 msg.header.frame_id = szDummy;
894 #ifndef _MSC_VER // TIMING in Simulation not correct 905 this->
checkScanTiming(msg.time_increment, msg.scan_time, msg.angle_increment, 0.00001);
void set_range_max(float max)
Setting maximum range.
void setCurrentParamPtr(ScannerBasicParam *_ptr)
Set pointer to corresponding parameter object to the parser.
int lookUpForAllowedScanner(std::string scannerName)
checks the given scannerName/scannerType of validity
void setNumberOfMaximumEchos(int _maxEchos)
Set number of maximum echoes for this laser scanner type.
double getElevationDegreeResolution(void)
get angular resolution in VERTICAL direction for multilayer scanner
SickGenericParser(std::string scannerType)
Construction of parser object.
#define SICK_SCANNER_LMS_1XX_NAME
void setNumberOfLayers(int _layerNum)
Setting number of scanner layers (depending of scanner type/family)
void setScannerType(std::string s)
setting scannertype
double getExpectedFrequency(void)
get expected scan frequency
void setElevationDegreeResolution(double _elevRes)
set angular resolution in VERTICAL direction for multilayer scanner
#define SICK_SCANNER_TIM_5XX_NAME
float get_range_min(void)
Getting minimum range.
ScannerBasicParam * currentParamSet
void setDeviceIsRadar(bool _deviceIsRadar)
flag to mark the device as radar (instead of laser scanner)
int checkForDistAndRSSI(std::vector< char * > &fields, int expected_number_of_data, int &distNum, int &rssiNum, std::vector< float > &distVal, std::vector< float > &rssiVal, int &distMask)
check for DIST and RSSI-entries in the datagram. Helper routine for parser
bool IntensityResolutionIs16Bit
int getNumberOfShots(void)
Get number of shots per scan.
float override_time_increment_
double elevationDegreeResolution
bool getIntensityResolutionIs16Bit(void)
Get the RSSI Value length.
#define SICK_SCANNER_LMS_1XXX_NAME
std::string getScannerType(void)
getting scannertype
void setNumberOfShots(int _shots)
Set number of shots per scan.
void setAngularDegreeResolution(double _res)
Set angular resolution in degrees.
int getNumberOfLayers(void)
Getting number of scanner layers.
int getNumberOfMaximumEchos(void)
Get number of maximum echoes for this laser scanner type.
float override_range_min_
#define ROS_WARN_THROTTLE(period,...)
Duration & fromSec(double t)
#define ROS_WARN_ONCE(...)
#define SICK_SCANNER_RMS_3XX_NAME
virtual ~SickGenericParser()
Destructor of parser.
float override_range_max_
virtual int parse_datagram(char *datagram, size_t datagram_length, SickScanConfig &config, sensor_msgs::LaserScan &msg, int &numEchos, int &echoMask)
Parsing Ascii datagram.
void checkScanTiming(float time_increment, float scan_time, float angle_increment, float tol)
float get_range_max(void)
Getting maximum range.
#define SICK_SCANNER_MRS_6XXX_NAME
bool getUseBinaryProtocol(void)
flag to decide between usage of ASCII-sopas or BINARY-sopas
double angleDegressResolution
ScannerBasicParam * getCurrentParamPtr()
Gets Pointer to parameter object.
double getAngularDegreeResolution(void)
Get angular resolution in degress.
void setScannerName(std::string _s)
Setting name (type) of scanner.
std::string getScannerName(void)
Getting name (type) of scanner.
std::vector< std::string > allowedScannerNames
#define SICK_SCANNER_MRS_1XXX_NAME
ScannerBasicParam()
Construction of parameter object.
void setIntensityResolutionIs16Bit(bool _IntensityResolutionIs16Bit)
Set the RSSI Value length.
bool getParam(const std::string &key, std::string &s) const
void set_time_increment(float time)
setting time increment between shots
std::vector< ScannerBasicParam > basicParams
void set_range_min(float min)
Setting minimum range.
void setUseBinaryProtocol(bool _useBinary)
flag to decide between usage of ASCII-sopas or BINARY-sopas
#define SICK_SCANNER_LMS_5XX_NAME
void setExpectedFrequency(double _freq)
set expected scan frequency
#define SICK_SCANNER_TIM_7XX_NAME
bool getDeviceIsRadar(void)
flag to mark the device as radar (instead of laser scanner)