29 #include <std_msgs/Bool.h> 30 #include <sensor_msgs/LaserScan.h> 31 #include <diagnostic_msgs/DiagnosticArray.h> 39 #include <boost/date_time/posix_time/posix_time.hpp> 40 #include <boost/thread/thread.hpp> 41 #include <boost/lexical_cast.hpp> 89 nh.
param(
"port", port, std::string(
"/dev/ttyUSB0"));
92 nh.
param(
"baud", baud, 500000);
95 nh.
param(
"scan_id", scan_id, 7);
97 if(!nh.
hasParam(
"inverted"))
ROS_WARN(
"Used default parameter for inverted");
98 nh.
param(
"inverted", inverted,
false);
100 if(!nh.
hasParam(
"frame_id"))
ROS_WARN(
"Used default parameter for frame_id");
101 nh.
param(
"frame_id", frame_id, std::string(
"base_laser_link"));
103 if(!nh.
hasParam(
"scan_duration"))
ROS_WARN(
"Used default parameter for scan_duration");
104 nh.
param(
"scan_duration", scan_duration, 0.025);
106 if(!nh.
hasParam(
"scan_cycle_time"))
ROS_WARN(
"Used default parameter for scan_cycle_time");
107 nh.
param(
"scan_cycle_time", scan_cycle_time, 0.040);
111 if(!nh.
hasParam(
"communication_timeout"))
ROS_WARN(
"Used default parameter for communication timeout");
112 nh.
param(
"communication_timeout", communication_timeout, 0.2);
123 int field_number = boost::lexical_cast<
int>(field->first);
124 ROS_DEBUG(
"Found field %d in params", field_number);
126 if(!field->second.hasMember(
"scale"))
132 if(!field->second.hasMember(
"start_angle"))
134 ROS_ERROR(
"Missing parameter start_angle");
138 if(!field->second.hasMember(
"stop_angle"))
140 ROS_ERROR(
"Missing parameter stop_angle");
145 param.
dScale = field->second[
"scale"];
147 param.
dStopAngle = field->second[
"stop_angle"];
167 ROS_ERROR(
"Node is going to shut down.");
173 syncedTimeReady =
false;
178 topicPub_LaserScan = nh.
advertise<sensor_msgs::LaserScan>(
"scan", 1);
179 topicPub_InStandby = nh.
advertise<std_msgs::Bool>(
"scan_standby", 1);
180 topicPub_Diagnostic_ = nh.
advertise<diagnostic_msgs::DiagnosticArray>(
"/diagnostics", 1);
188 std::vector< double > ranges, rangeAngles, intensities;
189 unsigned int iSickTimeStamp, iSickNow;
191 int result = scanner_.
getScan(ranges, rangeAngles, intensities, iSickTimeStamp, iSickNow, debug_);
192 static boost::posix_time::ptime point_time_communiaction_ok = boost::posix_time::microsec_clock::local_time();
199 ROS_WARN_THROTTLE(30,
"scanner %s on port %s in standby", node_name.c_str(), port.c_str());
205 publishLaserScan(ranges, rangeAngles, intensities, iSickTimeStamp, iSickNow);
208 point_time_communiaction_ok = boost::posix_time::microsec_clock::local_time();
212 boost::posix_time::time_duration diff = boost::posix_time::microsec_clock::local_time() - point_time_communiaction_ok;
231 this->inStandby_.data = inStandby;
232 topicPub_InStandby.
publish(this->inStandby_);
236 void publishLaserScan(std::vector<double> vdDistM, std::vector<double> vdAngRAD, std::vector<double> vdIntensAU,
unsigned int iSickTimeStamp,
unsigned int iSickNow)
239 int start_scan, stop_scan;
240 int num_readings = vdDistM.size();
242 stop_scan = vdDistM.size();
248 syncedSICKStamp = iSickNow;
249 syncedTimeReady =
true;
251 ROS_DEBUG(
"Got iSickNow, store sync-stamp: %d", syncedSICKStamp);
252 }
else syncedTimeReady =
false;
255 sensor_msgs::LaserScan laserScan;
256 if(syncedTimeReady) {
257 double timeDiff = (int)(iSickTimeStamp - syncedSICKStamp) *
scan_cycle_time;
258 laserScan.header.stamp = syncedROSTime +
ros::Duration(timeDiff);
260 ROS_DEBUG(
"Time::now() - calculated sick time stamp = %f",(
ros::Time::now() - laserScan.header.stamp).toSec());
266 laserScan.header.frame_id =
frame_id;
267 laserScan.angle_increment = vdAngRAD[start_scan + 1] - vdAngRAD[start_scan];
268 laserScan.range_min = 0.001;
269 laserScan.range_max = 29.5;
270 laserScan.time_increment = (
scan_duration) / (vdDistM.size());
273 num_readings = vdDistM.size();
274 laserScan.angle_min = vdAngRAD[start_scan];
275 laserScan.angle_max = vdAngRAD[stop_scan - 1];
276 laserScan.ranges.resize(num_readings);
277 laserScan.intensities.resize(num_readings);
284 laserScan.time_increment = - laserScan.time_increment;
286 laserScan.header.stamp = laserScan.header.stamp -
ros::Duration(scan_duration);
289 for(
int i = 0; i < (stop_scan - start_scan); i++)
293 laserScan.ranges[i] = vdDistM[stop_scan-1-i];
294 laserScan.intensities[i] = vdIntensAU[stop_scan-1-i];
298 laserScan.ranges[i] = vdDistM[start_scan + i];
299 laserScan.intensities[i] = vdIntensAU[start_scan + i];
304 topicPub_LaserScan.
publish(laserScan);
307 diagnostic_msgs::DiagnosticArray diagnostics;
309 diagnostics.status.resize(1);
310 diagnostics.status[0].level = 0;
312 diagnostics.status[0].message =
"sick scanner running";
313 topicPub_Diagnostic_.
publish(diagnostics);
317 diagnostic_msgs::DiagnosticArray diagnostics;
319 diagnostics.status.resize(1);
320 diagnostics.status[0].level = 2;
322 diagnostics.status[0].message = error_str;
323 topicPub_Diagnostic_.
publish(diagnostics);
327 diagnostic_msgs::DiagnosticArray diagnostics;
329 diagnostics.status.resize(1);
330 diagnostics.status[0].level = 1;
332 diagnostics.status[0].message = warn_str;
333 topicPub_Diagnostic_.
publish(diagnostics);
339 int main(
int argc,
char** argv)
348 bool bOpenScan =
false;
349 while (!bOpenScan &&
ros::ok()) {
350 ROS_INFO(
"Opening scanner... (port:%s)", nodeClass.
port.c_str());
352 bOpenScan = nodeClass.
open();
356 ROS_ERROR(
"...scanner not available on port %s. Will retry every second.", nodeClass.
port.c_str());
357 nodeClass.
publishError(
"...scanner not available on port");
361 ROS_INFO(
"...scanner opened successfully on port %s", nodeClass.
port.c_str());
ros::Publisher topicPub_Diagnostic_
double communication_timeout
const std::string & getMessage() const
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val)
void setRangeField(const int field, const ParamType ¶m)
#define ROS_WARN_THROTTLE(rate,...)
void publish(const boost::shared_ptr< M > &message) const
ValueStruct::iterator iterator
int main(int argc, char **argv)
void publishWarn(std::string warn_str)
ros::Publisher topicPub_LaserScan
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ROSCPP_DECL const std::string & getName()
Type const & getType() const
void publishError(std::string error_str)
bool open(const char *pcPort, int iBaudRate, int iScanId)
void publishStandby(bool inStandby)
void publishLaserScan(std::vector< double > vdDistM, std::vector< double > vdAngRAD, std::vector< double > vdIntensAU, unsigned int iSickTimeStamp, unsigned int iSickNow)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
const std::string & getNamespace() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool getScan(std::vector< double > &vdDistanceM, std::vector< double > &vdAngleRAD, std::vector< double > &vdIntensityAU, unsigned int &iTimestamp, unsigned int &iTimeNow, const bool debug)
bool getParam(const std::string &key, std::string &s) const
std_msgs::Bool inStandby_
unsigned int syncedSICKStamp
bool hasParam(const std::string &key) const
#define ROS_ERROR_STREAM(args)
ROSCPP_DECL void spinOnce()
ros::Publisher topicPub_InStandby