41 override_range_min_(0.2),
42 override_range_max_(64.0),
43 override_time_increment_(-1.0
f),
45 x_iter((modifier_.setPointCloud2FieldsByString(1,
"xyz"),
sensor_msgs::PointCloud2Iterator<float>(cloud_,
"x"))),
46 y_iter(cloud_,
"y"), z_iter(cloud_,
"z"), layer_count_(0)
56 sensor_msgs::LaserScan &scan, sensor_msgs::PointCloud2& cloud)
64 static const size_t HEADER_FIELDS = 32;
69 std::vector<char *> fields;
70 fields.reserve(datagram_length / 2);
73 char datagram_copy[datagram_length + 1];
74 strncpy(datagram_copy, datagram, datagram_length);
75 datagram_copy[datagram_length] = 0;
78 cur_field = strtok(datagram,
" ");
80 while (cur_field != NULL)
82 fields.push_back(cur_field);
83 cur_field = strtok(NULL,
" ");
86 count = fields.size();
91 if (count < HEADER_FIELDS)
94 "received less fields than minimum fields (actual: %zu, minimum: %zu), ignoring scan", count, HEADER_FIELDS);
95 ROS_WARN(
"are you using the correct node? (124 --> sick_tim310_1130000m01, > 33 --> sick_tim551_2050001, 580 --> sick_tim310s01, 592 --> sick_tim310)");
99 if (strcmp(fields[20],
"DIST1"))
101 ROS_WARN(
"Field 20 of received data is not equal to DIST1 (%s). Unexpected data, ignoring scan", fields[20]);
107 unsigned short int number_of_data = 0;
108 sscanf(fields[25],
"%hx", &number_of_data);
110 if (number_of_data < 1 || number_of_data > 1101)
112 ROS_WARN(
"Data length is outside acceptable range 1-1101 (%d). Ignoring scan", number_of_data);
115 if (count < HEADER_FIELDS + number_of_data)
117 ROS_WARN(
"Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
120 ROS_DEBUG(
"Number of data: %d", number_of_data);
123 size_t rssi_idx = 26 + number_of_data;
125 sscanf(fields[rssi_idx],
"%d", &tmp);
127 unsigned short int number_of_rssi_data = 0;
130 sscanf(fields[rssi_idx + 6],
"%hx", &number_of_rssi_data);
133 if (number_of_rssi_data != number_of_data)
135 ROS_WARN(
"Number of RSSI data is lower than number of range data (%d vs %d", number_of_data, number_of_rssi_data);
141 if (count < HEADER_FIELDS + number_of_data + number_of_rssi_data + 6)
143 ROS_WARN(
"Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
147 if (strcmp(fields[rssi_idx + 1],
"RSSI1"))
149 ROS_WARN(
"Field %zu of received data is not equal to RSSI1 (%s). Unexpected data, ignoring scan", rssi_idx + 1, fields[rssi_idx + 1]);
154 sscanf(fields[15],
"%hx", &layer);
155 scan.header.seq = layer;
159 scan.header.frame_id = layer == 0 ?
current_config_.frame_id.c_str() :
"";
167 unsigned short scanning_freq = -1;
168 sscanf(fields[16],
"%hx", &scanning_freq);
169 scan.scan_time = 1.0 / (scanning_freq / 100.0);
173 unsigned short measurement_freq = -1;
174 sscanf(fields[17],
"%hx", &measurement_freq);
176 scan.time_increment = 1.0 / (4 * measurement_freq * 100.0);
184 int starting_angle = -1;
185 sscanf(fields[23],
"%x", &starting_angle);
186 scan.angle_min = (starting_angle / 10000.0) / 180.0 * M_PI - M_PI / 2;
190 unsigned short angular_step_width = -1;
191 sscanf(fields[24],
"%hx", &angular_step_width);
192 scan.angle_increment = (angular_step_width / 10000.0) / 180.0 * M_PI;
193 scan.angle_max = scan.angle_min + (number_of_data - 1) * scan.angle_increment;
200 while (scan.angle_min + scan.angle_increment <
current_config_.min_ang)
202 scan.angle_min += scan.angle_increment;
207 int index_max = number_of_data - 1;
208 while (scan.angle_max - scan.angle_increment >
current_config_.max_ang)
210 scan.angle_max -= scan.angle_increment;
214 ROS_DEBUG(
"index_min: %d, index_max: %d", index_min, index_max);
217 double phi = scan.angle_min;
220 double alpha = -layer * M_PI / 18000;
235 scan.ranges.resize(index_max - index_min + 1);
243 for (
int j = index_min; j <= index_max; ++j)
246 unsigned short range;
247 sscanf(fields[j + 26],
"%hx", &range);
248 float range_meter = range / 1000.0;
254 scan.ranges[j - index_min] = std::numeric_limits<float>::infinity();
256 scan.ranges[j - index_min] = range_meter;
267 *
y_iter = range_meter * cos(alpha) *
sin(phi);
268 *
z_iter = range_meter * sin(alpha);
274 phi += scan.angle_increment;
279 ROS_ASSERT_MSG(
layer_count_ == 4,
"Expected four layers and layer == -500 to be the last layer! Package loss in communication!");
302 scan.intensities.resize(index_max - index_min + 1);
303 size_t offset = 26 + number_of_data + 7;
304 for (
int j = index_min; j <= index_max; ++j)
306 unsigned short intensity;
307 sscanf(fields[j + offset],
"%hx", &intensity);
308 scan.intensities[j - index_min] = intensity;
311 ROS_WARN_ONCE(
"Intensity parameter is enabled, but the scanner is not configured to send RSSI values! " 312 "Please read the section 'Enabling intensity (RSSI) output' here: http://wiki.ros.org/sick_tim.");
328 double start_time_adjusted = start_time.
toSec()
329 - number_of_data * scan.time_increment
330 + index_min * scan.time_increment
332 if (start_time_adjusted >= 0.0)
334 scan.header.stamp.fromSec(start_time_adjusted);
336 ROS_WARN(
"ROS time is 0! Did you set the parameter use_sim_time to true?");
340 float expected_time_increment = scan.scan_time * scan.angle_increment / (2.0 * M_PI);
341 if (fabs(expected_time_increment - scan.time_increment) > 0.00001)
343 ROS_WARN_THROTTLE(60,
"The time_increment, scan_time and angle_increment values reported by the scanner are inconsistent! " 344 "Expected time_increment: %.9f, reported time_increment: %.9f. " 345 "Perhaps you should set the parameter time_increment to the expected value. This message will print every 60 seconds.",
346 expected_time_increment, scan.time_increment);
virtual int parse_datagram(char *datagram, size_t datagram_length, SickTimConfig &config, sensor_msgs::LaserScan &scan, sensor_msgs::PointCloud2 &cloud)
sensor_msgs::PointCloud2Modifier modifier_
sensor_msgs::PointCloud2 cloud_
float override_range_min_
void set_range_min(float min)
#define ROS_WARN_THROTTLE(period,...)
Duration & fromSec(double t)
#define ROS_WARN_ONCE(...)
#define ROS_ASSERT_MSG(cond,...)
float override_range_max_
#define ROS_DEBUG_STREAM(args)
sick_tim::SickTimConfig current_config_
void set_range_max(float max)
void set_time_increment(float time)
virtual ~SickMRS1000Parser()
sensor_msgs::PointCloud2Iterator< float > x_iter
float override_time_increment_
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
sensor_msgs::PointCloud2Iterator< float > y_iter
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
sensor_msgs::PointCloud2Iterator< float > z_iter