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
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #include <ros/ros.h>
00062
00063
00064 #include <sensor_msgs/LaserScan.h>
00065 #include <diagnostic_msgs/DiagnosticArray.h>
00066
00067
00068
00069
00070
00071 #include <cob_sick_s300/ScannerSickS300.h>
00072
00073
00074
00075 class NodeClass
00076 {
00077
00078 public:
00079
00080 ros::NodeHandle nh;
00081
00082 ros::Publisher topicPub_LaserScan;
00083 ros::Publisher topicPub_Diagnostic_;
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 std::string port;
00096 int baud, scan_id;
00097 bool inverted;
00098 double scan_duration, scan_cycle_time;
00099 std::string frame_id;
00100 ros::Time syncedROSTime;
00101 unsigned int syncedSICKStamp;
00102 bool syncedTimeReady;
00103
00104
00105 NodeClass()
00106 {
00107
00108 nh = ros::NodeHandle("~");
00109
00110 if(!nh.hasParam("port")) ROS_WARN("Used default parameter for port");
00111 nh.param("port", port, std::string("/dev/ttyUSB0"));
00112
00113 if(!nh.hasParam("baud")) ROS_WARN("Used default parameter for baud");
00114 nh.param("baud", baud, 500000);
00115
00116 if(!nh.hasParam("scan_id")) ROS_WARN("Used default parameter for scan_id");
00117 nh.param("scan_id", scan_id, 7);
00118
00119 if(!nh.hasParam("inverted")) ROS_WARN("Used default parameter for inverted");
00120 nh.param("inverted", inverted, false);
00121
00122 if(!nh.hasParam("frame_id")) ROS_WARN("Used default parameter for frame_id");
00123 nh.param("frame_id", frame_id, std::string("/base_laser_link"));
00124
00125 if(!nh.hasParam("scan_duration")) ROS_WARN("Used default parameter for scan_duration");
00126 nh.param("scan_duration", scan_duration, 0.025);
00127
00128 if(!nh.hasParam("scan_cycle_time")) ROS_WARN("Used default parameter for scan_cycle_time");
00129 nh.param("scan_cycle_time", scan_cycle_time, 0.040);
00130
00131 syncedSICKStamp = 0;
00132 syncedROSTime = ros::Time::now();
00133 syncedTimeReady = false;
00134
00135
00136 topicPub_LaserScan = nh.advertise<sensor_msgs::LaserScan>("scan", 1);
00137 topicPub_Diagnostic_ = nh.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1);
00138
00139
00140
00141
00142
00143
00144 }
00145
00146
00147 ~NodeClass()
00148 {
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 void publishLaserScan(std::vector<double> vdDistM, std::vector<double> vdAngRAD, std::vector<double> vdIntensAU, unsigned int iSickTimeStamp, unsigned int iSickNow)
00161 {
00162
00163 int start_scan, stop_scan;
00164 int num_readings = vdDistM.size();
00165 start_scan = 0;
00166 stop_scan = vdDistM.size();
00167
00168
00169
00170 if(iSickNow != 0) {
00171 syncedROSTime = ros::Time::now() - ros::Duration(scan_cycle_time);
00172 syncedSICKStamp = iSickNow;
00173 syncedTimeReady = true;
00174
00175 ROS_DEBUG("Got iSickNow, store sync-stamp: %d", syncedSICKStamp);
00176 }
00177
00178
00179 sensor_msgs::LaserScan laserScan;
00180 if(syncedTimeReady) {
00181 double timeDiff = (int)(iSickTimeStamp - syncedSICKStamp) * scan_cycle_time;
00182 laserScan.header.stamp = syncedROSTime + ros::Duration(timeDiff);
00183
00184 ROS_DEBUG("Time::now() - calculated sick time stamp = %f",(ros::Time::now() - laserScan.header.stamp).toSec());
00185 } else {
00186 laserScan.header.stamp = ros::Time::now();
00187 }
00188
00189
00190 laserScan.header.frame_id = frame_id;
00191 laserScan.angle_increment = vdAngRAD[start_scan + 1] - vdAngRAD[start_scan];
00192 laserScan.range_min = 0.001;
00193 laserScan.range_max = 30.0;
00194 laserScan.time_increment = (scan_duration) / (vdDistM.size());
00195
00196
00197 num_readings = vdDistM.size();
00198 laserScan.angle_min = vdAngRAD[start_scan];
00199 laserScan.angle_max = vdAngRAD[stop_scan - 1];
00200 laserScan.ranges.resize(num_readings);
00201 laserScan.intensities.resize(num_readings);
00202
00203
00204
00205 if(inverted) {
00206
00207
00208 laserScan.time_increment = - laserScan.time_increment;
00209 } else {
00210 laserScan.header.stamp = laserScan.header.stamp - ros::Duration(scan_duration);
00211 }
00212
00213 for(int i = 0; i < (stop_scan - start_scan); i++)
00214 {
00215 if(inverted)
00216 {
00217 laserScan.ranges[i] = vdDistM[stop_scan-1-i];
00218 laserScan.intensities[i] = vdIntensAU[stop_scan-1-i];
00219 }
00220 else
00221 {
00222 laserScan.ranges[i] = vdDistM[start_scan + i];
00223 laserScan.intensities[i] = vdIntensAU[start_scan + i];
00224 }
00225 }
00226
00227
00228 topicPub_LaserScan.publish(laserScan);
00229
00230
00231 diagnostic_msgs::DiagnosticArray diagnostics;
00232 diagnostics.status.resize(1);
00233 diagnostics.status[0].level = 0;
00234 diagnostics.status[0].name = nh.getNamespace();
00235 diagnostics.status[0].message = "sick scanner running";
00236 topicPub_Diagnostic_.publish(diagnostics);
00237 }
00238
00239 void publishError(std::string error_str) {
00240 diagnostic_msgs::DiagnosticArray diagnostics;
00241 diagnostics.status.resize(1);
00242 diagnostics.status[0].level = 2;
00243 diagnostics.status[0].name = nh.getNamespace();
00244 diagnostics.status[0].message = error_str;
00245 topicPub_Diagnostic_.publish(diagnostics);
00246 }
00247 };
00248
00249
00250
00251 int main(int argc, char** argv)
00252 {
00253
00254 ros::init(argc, argv, "sick_s300");
00255
00256 NodeClass nodeClass;
00257 ScannerSickS300 SickS300;
00258
00259 int iBaudRate = nodeClass.baud;
00260 int iScanId = nodeClass.scan_id;
00261 bool bOpenScan = false, bRecScan = false;
00262 bool firstTry = true;
00263
00264 unsigned int iSickTimeStamp, iSickNow;
00265 std::vector<double> vdDistM, vdAngRAD, vdIntensAU;
00266
00267 while (!bOpenScan)
00268 {
00269 ROS_INFO("Opening scanner... (port:%s)",nodeClass.port.c_str());
00270 bOpenScan = SickS300.open(nodeClass.port.c_str(), iBaudRate, iScanId);
00271
00272
00273 if(!bOpenScan)
00274 {
00275 ROS_ERROR("...scanner not available on port %s. Will retry every second.",nodeClass.port.c_str());
00276 nodeClass.publishError("...scanner not available on port");
00277 firstTry = false;
00278 }
00279 sleep(1);
00280 }
00281 ROS_INFO("...scanner opened successfully on port %s",nodeClass.port.c_str());
00282
00283
00284 ros::Rate loop_rate(5);
00285 while(nodeClass.nh.ok())
00286 {
00287
00288 ROS_DEBUG("Reading scanner...");
00289 bRecScan = SickS300.getScan(vdDistM, vdAngRAD, vdIntensAU, iSickTimeStamp, iSickNow);
00290 ROS_DEBUG("...read %d points from scanner successfully",(int)vdDistM.size());
00291
00292 if(bRecScan)
00293 {
00294 ROS_DEBUG("...publishing LaserScan message");
00295 nodeClass.publishLaserScan(vdDistM, vdAngRAD, vdIntensAU, iSickTimeStamp, iSickNow);
00296 }
00297 else
00298 {
00299 ROS_WARN("...no Scan available");
00300 }
00301
00302
00303 ros::spinOnce();
00304 loop_rate.sleep();
00305 }
00306 return 0;
00307 }