Go to the documentation of this file.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
00048 #include <sensor_msgs/LaserScan.h>
00049 #include <occupancy_grid_utils/ray_tracer.h>
00050 #include <occupancy_grid_utils/file.h>
00051 #include <tf/transform_listener.h>
00052 #include <ros/ros.h>
00053 #include <boost/foreach.hpp>
00054 #include <boost/lexical_cast.hpp>
00055
00056 namespace flirtlib_ros
00057 {
00058
00059 namespace sm=sensor_msgs;
00060 namespace gu=occupancy_grid_utils;
00061 namespace nm=nav_msgs;
00062 namespace gm=geometry_msgs;
00063
00064 using std::string;
00065 using std::vector;
00066
00067 class ScanSimulator
00068 {
00069 public:
00070 ScanSimulator ();
00071 void publishScan (const ros::TimerEvent& e);
00072
00073 private:
00074
00075 ros::NodeHandle nh_;
00076
00077 const double cycle_time_;
00078 const string global_frame_;
00079 const unsigned num_lasers_;
00080 const sm::LaserScan scanner_params_;
00081 const string map_file_;
00082 const double resolution_;
00083
00084 nm::OccupancyGrid::Ptr grid_;
00085
00086 tf::TransformListener tf_;
00087 ros::Timer timer_;
00088 vector<ros::Publisher> scan_pubs_;
00089 ros::Publisher grid_pub_;
00090 };
00091
00092 sm::LaserScan getScannerParams ()
00093 {
00094 sm::LaserScan params;
00095 const double PI = 3.14159265;
00096 params.angle_min = -PI/2;
00097 params.angle_max = PI/2;
00098 params.angle_increment = PI/180;
00099 params.range_max = 10;
00100
00101 return params;
00102 }
00103
00104 template <class T>
00105 T getPrivateParam (const string& name)
00106 {
00107 ros::NodeHandle nh("~");
00108 T val;
00109 const bool found = nh.getParam(name, val);
00110 ROS_ASSERT_MSG (found, "Could not find parameter %s", name.c_str());
00111 ROS_DEBUG_STREAM_NAMED ("init", "Initialized " << name << " to " << val);
00112 return val;
00113 }
00114
00115
00116 ScanSimulator::ScanSimulator () :
00117 cycle_time_(0.1), global_frame_("/map"),
00118 num_lasers_(getPrivateParam<int>("num_lasers")),
00119 scanner_params_(getScannerParams()),
00120 map_file_(getPrivateParam<string>("map_file")),
00121 resolution_(getPrivateParam<double>("resolution")),
00122 grid_(gu::loadGrid(map_file_, resolution_)),
00123 timer_(nh_.createTimer(ros::Duration(cycle_time_),
00124 &ScanSimulator::publishScan, this)),
00125 grid_pub_(nh_.advertise<nm::OccupancyGrid>("grid", 10, true))
00126 {
00127 grid_pub_.publish(grid_);
00128 scan_pubs_.resize(num_lasers_);
00129 for (unsigned i=0; i<num_lasers_; i++)
00130 {
00131 const string topic = "scan" + boost::lexical_cast<string>(i);
00132 scan_pubs_[i] = nh_.advertise<sm::LaserScan>(topic, 10);
00133 }
00134 }
00135
00136
00137 void ScanSimulator::publishScan (const ros::TimerEvent& e)
00138 {
00139 for (unsigned i=0; i<num_lasers_; i++)
00140 {
00141 try
00142 {
00143 const string laser_frame = "pose" + boost::lexical_cast<string>(i);
00144 tf::StampedTransform trans;
00145 tf_.lookupTransform(global_frame_, laser_frame, ros::Time(), trans);
00146 gm::Pose pose;
00147 tf::poseTFToMsg(trans, pose);
00148 sm::LaserScan::Ptr scan = gu::simulateRangeScan(*grid_, pose,
00149 scanner_params_, true);
00150 scan->header.frame_id = laser_frame;
00151 scan->header.stamp = ros::Time::now();
00152 scan_pubs_[i].publish(scan);
00153 }
00154 catch (tf::TransformException& e)
00155 {
00156 ROS_INFO ("Not publishing scan due to transform exception");
00157 }
00158 }
00159 }
00160
00161
00162
00163
00164 }
00165
00166 int main (int argc, char** argv)
00167 {
00168 ros::init(argc, argv, "simulate_scans");
00169 flirtlib_ros::ScanSimulator node;
00170 ros::spin();
00171 return 0;
00172 }