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