44 override_range_min_(0.05),
45 override_range_max_(10.0),
46 override_time_increment_(-1.0)
55 sensor_msgs::LaserScan &msg)
66 static const size_t HEADER_FIELDS = 26;
67 static const size_t MIN_FOOTER_FIELDS = 5;
72 std::vector<char *> fields;
73 fields.reserve(datagram_length / 2);
76 char datagram_copy[datagram_length + 1];
77 strncpy(datagram_copy, datagram, datagram_length);
78 datagram_copy[datagram_length] = 0;
82 cur_field = strtok(datagram,
" ");
84 while (cur_field != NULL)
86 fields.push_back(cur_field);
87 cur_field = strtok(NULL,
" ");
90 count = fields.size();
95 if (count < HEADER_FIELDS + 1 + MIN_FOOTER_FIELDS)
98 "received less fields than minimum fields (actual: %zu, minimum: %zu), ignoring scan", count, HEADER_FIELDS + 1 + MIN_FOOTER_FIELDS);
99 ROS_WARN(
"are you using the correct node? (124 --> sick_tim310_1130000m01, > 32 --> sick_tim551_2050001, 580 --> sick_tim310s01, 592 --> sick_tim310)");
103 if (strcmp(fields[15],
"0"))
105 ROS_WARN(
"Field 15 of received data is not equal to 0 (%s). Unexpected data, ignoring scan", fields[15]);
108 if (strcmp(fields[20],
"DIST1"))
110 ROS_WARN(
"Field 20 of received data is not equal to DIST1i (%s). Unexpected data, ignoring scan", fields[20]);
116 unsigned short int number_of_data = 0;
117 sscanf(fields[25],
"%hx", &number_of_data);
119 if (number_of_data < 1 || number_of_data > 811)
121 ROS_WARN(
"Data length is outside acceptable range 1-811 (%d). Ignoring scan", number_of_data);
124 if (count < HEADER_FIELDS + number_of_data + 1 + MIN_FOOTER_FIELDS)
126 ROS_WARN(
"Less fields than expected (expected: >= %zu, actual: %zu). Ignoring scan",
127 HEADER_FIELDS + number_of_data + 1 + MIN_FOOTER_FIELDS, count);
130 ROS_DEBUG(
"Number of data: %d", number_of_data);
133 size_t rssi_idx = HEADER_FIELDS + number_of_data;
135 sscanf(fields[rssi_idx],
"%d", &tmp);
137 unsigned short int number_of_rssi_data = 0;
140 sscanf(fields[rssi_idx + 6],
"%hx", &number_of_rssi_data);
143 if (number_of_rssi_data != number_of_data)
145 ROS_WARN(
"Number of RSSI data (%d) is not equal to number of range data (%d)", number_of_rssi_data, number_of_data);
151 if (count < HEADER_FIELDS + number_of_data + 1 + 6 + number_of_rssi_data + MIN_FOOTER_FIELDS)
153 ROS_WARN(
"Less fields than expected with RSSI data (expected: >= %zu, actual: %zu). Ignoring scan",
154 HEADER_FIELDS + number_of_data + 1 + 6 + number_of_rssi_data + MIN_FOOTER_FIELDS, count);
158 if (strcmp(fields[rssi_idx + 1],
"RSSI1"))
160 ROS_WARN(
"Field %zu of received data is not equal to RSSI1 (%s). Unexpected data, ignoring scan", rssi_idx + 1, fields[rssi_idx + 1]);
165 msg.header.frame_id = config.frame_id;
166 ROS_DEBUG(
"publishing with frame_id %s", config.frame_id.c_str());
186 unsigned short scanning_freq = -1;
187 sscanf(fields[16],
"%hx", &scanning_freq);
188 msg.scan_time = 1.0 / (scanning_freq / 100.0);
192 unsigned short measurement_freq = -1;
193 sscanf(fields[17],
"%hx", &measurement_freq);
194 msg.time_increment = 1.0 / (measurement_freq * 100.0);
216 int starting_angle = -1;
217 sscanf(fields[23],
"%x", &starting_angle);
218 msg.angle_min = (starting_angle / 10000.0) / 180.0 * M_PI - M_PI / 2;
222 unsigned short angular_step_width = -1;
223 sscanf(fields[24],
"%hx", &angular_step_width);
224 msg.angle_increment = (angular_step_width / 10000.0) / 180.0 * M_PI;
225 msg.angle_max = msg.angle_min + (number_of_data - 1) * msg.angle_increment;
232 while (msg.angle_min + msg.angle_increment < config.min_ang)
234 msg.angle_min += msg.angle_increment;
239 int index_max = number_of_data - 1;
240 while (msg.angle_max - msg.angle_increment > config.max_ang)
242 msg.angle_max -= msg.angle_increment;
246 ROS_DEBUG(
"index_min: %d, index_max: %d", index_min, index_max);
250 msg.ranges.resize(index_max - index_min + 1);
251 for (
int j = index_min; j <= index_max; ++j)
253 unsigned short range;
254 sscanf(fields[j + HEADER_FIELDS],
"%hx", &range);
256 msg.ranges[j - index_min] = std::numeric_limits<float>::infinity();
258 msg.ranges[j - index_min] = range / 1000.0;
261 if (config.intensity) {
278 msg.intensities.resize(index_max - index_min + 1);
279 size_t offset = HEADER_FIELDS + number_of_data + 7;
280 for (
int j = index_min; j <= index_max; ++j)
282 unsigned short intensity;
283 sscanf(fields[j + offset],
"%hx", &intensity);
284 msg.intensities[j - index_min] = intensity;
287 ROS_WARN_ONCE(
"Intensity parameter is enabled, but the scanner is not configured to send RSSI values! " 288 "Please read the section 'Enabling intensity (RSSI) output' here: http://wiki.ros.org/sick_tim.");
304 double start_time_adjusted = start_time.toSec()
305 - number_of_data * msg.time_increment
306 + index_min * msg.time_increment
307 + config.time_offset;
308 if (start_time_adjusted >= 0.0)
310 msg.header.stamp.fromSec(start_time_adjusted);
312 ROS_WARN(
"ROS time is 0! Did you set the parameter use_sim_time to true?");
316 float expected_time_increment = msg.scan_time * msg.angle_increment / (2.0 * M_PI);
317 if (fabs(expected_time_increment - msg.time_increment) > 0.00001)
319 ROS_WARN_THROTTLE(60,
"The time_increment, scan_time and angle_increment values reported by the scanner are inconsistent! " 320 "Expected time_increment: %.9f, reported time_increment: %.9f. " 321 "Perhaps you should set the parameter time_increment to the expected value. This message will print every 60 seconds.",
322 expected_time_increment, msg.time_increment);
SickTim5512050001Parser()
void set_time_increment(float time)
virtual ~SickTim5512050001Parser()
virtual int parse_datagram(char *datagram, size_t datagram_length, SickTimConfig &config, sensor_msgs::LaserScan &msg)
float override_range_min_
void set_range_max(float max)
float override_range_max_
#define ROS_WARN_THROTTLE(period,...)
#define ROS_WARN_ONCE(...)
void set_range_min(float min)
float override_time_increment_