00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <sick_tim/sick_mrs1000_parser.h>
00034
00035 #include <ros/ros.h>
00036
00037 namespace sick_tim
00038 {
00039
00040 SickMRS1000Parser::SickMRS1000Parser() :
00041 override_range_min_(0.2),
00042 override_range_max_(64.0),
00043 override_time_increment_(-1.0f),
00044 modifier_(cloud_),
00045 x_iter((modifier_.setPointCloud2FieldsByString(1, "xyz"), sensor_msgs::PointCloud2Iterator<float>(cloud_, "x"))),
00046 y_iter(cloud_, "y"), z_iter(cloud_, "z"), layer_count_(0)
00047
00048 {
00049 }
00050
00051 SickMRS1000Parser::~SickMRS1000Parser()
00052 {
00053 }
00054
00055 int SickMRS1000Parser::parse_datagram(char* datagram, size_t datagram_length, SickTimConfig &config,
00056 sensor_msgs::LaserScan &scan, sensor_msgs::PointCloud2& cloud)
00057 {
00058
00059 if(layer_count_ == 0)
00060 {
00061 current_config_ = config;
00062 }
00063
00064 static const size_t HEADER_FIELDS = 32;
00065 char* cur_field;
00066 size_t count;
00067
00068
00069 std::vector<char *> fields;
00070 fields.reserve(datagram_length / 2);
00071
00072
00073 char datagram_copy[datagram_length + 1];
00074 strncpy(datagram_copy, datagram, datagram_length);
00075 datagram_copy[datagram_length] = 0;
00076
00077
00078 cur_field = strtok(datagram, " ");
00079
00080 while (cur_field != NULL)
00081 {
00082 fields.push_back(cur_field);
00083 cur_field = strtok(NULL, " ");
00084 }
00085
00086 count = fields.size();
00087
00088
00089
00090
00091 if (count < HEADER_FIELDS)
00092 {
00093 ROS_WARN(
00094 "received less fields than minimum fields (actual: %zu, minimum: %zu), ignoring scan", count, HEADER_FIELDS);
00095 ROS_WARN("are you using the correct node? (124 --> sick_tim310_1130000m01, > 33 --> sick_tim551_2050001, 580 --> sick_tim310s01, 592 --> sick_tim310)");
00096
00097 return ExitError;
00098 }
00099 if (strcmp(fields[20], "DIST1"))
00100 {
00101 ROS_WARN("Field 20 of received data is not equal to DIST1 (%s). Unexpected data, ignoring scan", fields[20]);
00102 return ExitError;
00103 }
00104
00105
00106
00107 unsigned short int number_of_data = 0;
00108 sscanf(fields[25], "%hx", &number_of_data);
00109
00110 if (number_of_data < 1 || number_of_data > 1101)
00111 {
00112 ROS_WARN("Data length is outside acceptable range 1-1101 (%d). Ignoring scan", number_of_data);
00113 return ExitError;
00114 }
00115 if (count < HEADER_FIELDS + number_of_data)
00116 {
00117 ROS_WARN("Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
00118 return ExitError;
00119 }
00120 ROS_DEBUG("Number of data: %d", number_of_data);
00121
00122
00123 size_t rssi_idx = 26 + number_of_data;
00124 int tmp;
00125 sscanf(fields[rssi_idx], "%d", &tmp);
00126 bool rssi = tmp > 0;
00127 unsigned short int number_of_rssi_data = 0;
00128 if (rssi)
00129 {
00130 sscanf(fields[rssi_idx + 6], "%hx", &number_of_rssi_data);
00131
00132
00133 if (number_of_rssi_data != number_of_data)
00134 {
00135 ROS_WARN("Number of RSSI data is lower than number of range data (%d vs %d", number_of_data, number_of_rssi_data);
00136 return ExitError;
00137 }
00138
00139
00140
00141 if (count < HEADER_FIELDS + number_of_data + number_of_rssi_data + 6)
00142 {
00143 ROS_WARN("Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
00144 return ExitError;
00145 }
00146
00147 if (strcmp(fields[rssi_idx + 1], "RSSI1"))
00148 {
00149 ROS_WARN("Field %zu of received data is not equal to RSSI1 (%s). Unexpected data, ignoring scan", rssi_idx + 1, fields[rssi_idx + 1]);
00150 }
00151 }
00152
00153 short layer = -1;
00154 sscanf(fields[15], "%hx", &layer);
00155 scan.header.seq = layer;
00156
00157
00158
00159 scan.header.frame_id = layer == 0 ? current_config_.frame_id.c_str() : "";
00160
00161
00162 ROS_DEBUG_STREAM("publishing with frame_id " << scan.header.frame_id);
00163
00164 ros::Time start_time = ros::Time::now();
00165
00166
00167 unsigned short scanning_freq = -1;
00168 sscanf(fields[16], "%hx", &scanning_freq);
00169 scan.scan_time = 1.0 / (scanning_freq / 100.0);
00170
00171
00172
00173 unsigned short measurement_freq = -1;
00174 sscanf(fields[17], "%hx", &measurement_freq);
00175
00176 scan.time_increment = 1.0 / (4 * measurement_freq * 100.0);
00177 if (override_time_increment_ > 0.0)
00178 {
00179
00180 scan.time_increment = override_time_increment_;
00181 }
00182
00183
00184 int starting_angle = -1;
00185 sscanf(fields[23], "%x", &starting_angle);
00186 scan.angle_min = (starting_angle / 10000.0) / 180.0 * M_PI - M_PI / 2;
00187
00188
00189
00190 unsigned short angular_step_width = -1;
00191 sscanf(fields[24], "%hx", &angular_step_width);
00192 scan.angle_increment = (angular_step_width / 10000.0) / 180.0 * M_PI;
00193 scan.angle_max = scan.angle_min + (number_of_data - 1) * scan.angle_increment;
00194
00195
00196
00197
00198
00199 int index_min = 0;
00200 while (scan.angle_min + scan.angle_increment < current_config_.min_ang)
00201 {
00202 scan.angle_min += scan.angle_increment;
00203 index_min++;
00204 }
00205
00206
00207 int index_max = number_of_data - 1;
00208 while (scan.angle_max - scan.angle_increment > current_config_.max_ang)
00209 {
00210 scan.angle_max -= scan.angle_increment;
00211 index_max--;
00212 }
00213
00214 ROS_DEBUG("index_min: %d, index_max: %d", index_min, index_max);
00215
00216
00217 double phi = scan.angle_min;
00218
00219
00220 double alpha = -layer * M_PI / 18000;
00221
00222
00223
00224
00225
00226
00227
00228
00229 if(layer == 0){
00230 modifier_.resize(4 * (index_max - index_min + 1));
00231 x_iter = sensor_msgs::PointCloud2Iterator<float>(cloud_, "x");
00232 y_iter = sensor_msgs::PointCloud2Iterator<float>(cloud_, "y");
00233 z_iter = sensor_msgs::PointCloud2Iterator<float>(cloud_, "z");
00234
00235 scan.ranges.resize(index_max - index_min + 1);
00236
00237 cloud_.header.stamp = start_time + ros::Duration().fromSec(current_config_.time_offset);
00238 }
00239
00240
00241 if(modifier_.size() > 0){
00242 layer_count_++;
00243 for (int j = index_min; j <= index_max; ++j)
00244 {
00245
00246 unsigned short range;
00247 sscanf(fields[j + 26], "%hx", &range);
00248 float range_meter = range / 1000.0;
00249
00250
00251 if(layer == 0)
00252 {
00253 if (range == 0)
00254 scan.ranges[j - index_min] = std::numeric_limits<float>::infinity();
00255 else
00256 scan.ranges[j - index_min] = range_meter;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266 *x_iter = range_meter * cos(alpha) * cos(phi);
00267 *y_iter = range_meter * cos(alpha) * sin(phi);
00268 *z_iter = range_meter * sin(alpha);
00269
00270 ++x_iter;
00271 ++y_iter;
00272 ++z_iter;
00273
00274 phi += scan.angle_increment;
00275 }
00276
00277
00278 if(layer == -500){
00279 ROS_ASSERT_MSG(layer_count_ == 4, "Expected four layers and layer == -500 to be the last layer! Package loss in communication!");
00280 layer_count_ = 0;
00281 cloud = cloud_;
00282 cloud.header.frame_id = current_config_.frame_id.c_str();
00283 }
00284 }
00285
00286 if (current_config_.intensity) {
00287 if (rssi)
00288 {
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 scan.intensities.resize(index_max - index_min + 1);
00303 size_t offset = 26 + number_of_data + 7;
00304 for (int j = index_min; j <= index_max; ++j)
00305 {
00306 unsigned short intensity;
00307 sscanf(fields[j + offset], "%hx", &intensity);
00308 scan.intensities[j - index_min] = intensity;
00309 }
00310 } else {
00311 ROS_WARN_ONCE("Intensity parameter is enabled, but the scanner is not configured to send RSSI values! "
00312 "Please read the section 'Enabling intensity (RSSI) output' here: http://wiki.ros.org/sick_tim.");
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 scan.range_min = override_range_min_;
00324 scan.range_max = override_range_max_;
00325
00326
00327
00328 double start_time_adjusted = start_time.toSec()
00329 - number_of_data * scan.time_increment
00330 + index_min * scan.time_increment
00331 + current_config_.time_offset;
00332 if (start_time_adjusted >= 0.0)
00333 {
00334 scan.header.stamp.fromSec(start_time_adjusted);
00335 } else {
00336 ROS_WARN("ROS time is 0! Did you set the parameter use_sim_time to true?");
00337 }
00338
00339
00340 float expected_time_increment = scan.scan_time * scan.angle_increment / (2.0 * M_PI);
00341 if (fabs(expected_time_increment - scan.time_increment) > 0.00001)
00342 {
00343 ROS_WARN_THROTTLE(60, "The time_increment, scan_time and angle_increment values reported by the scanner are inconsistent! "
00344 "Expected time_increment: %.9f, reported time_increment: %.9f. "
00345 "Perhaps you should set the parameter time_increment to the expected value. This message will print every 60 seconds.",
00346 expected_time_increment, scan.time_increment);
00347 }
00348
00349 return ExitSuccess;
00350 }
00351
00352 void SickMRS1000Parser::set_range_min(float min)
00353 {
00354 override_range_min_ = min;
00355 }
00356
00357 void SickMRS1000Parser::set_range_max(float max)
00358 {
00359 override_range_max_ = max;
00360 }
00361
00362 void SickMRS1000Parser::set_time_increment(float time)
00363 {
00364 override_time_increment_ = time;
00365 }
00366
00367 }