ed_sensor_integration
laser_plugin.cpp
Go to the documentation of this file.
1 #include "laser_plugin.h"
2 
5 
6 #include <ed/convex_hull_calc.h>
7 #include <ed/entity.h>
8 #include <ed/io/json_writer.h>
9 #include <ed/update_request.h>
10 #include <ed/world_model.h>
11 
13 #include <geolib/Shape.h>
14 
15 #include <geometry_msgs/TransformStamped.h>
16 
17 #include <opencv2/imgproc/imgproc.hpp>
18 
19 #include <ros/console.h>
20 #include <ros/node_handle.h>
21 
22 #include <iostream>
23 
24 
31 void lasermsgToSensorRanges(const sensor_msgs::LaserScan::ConstPtr& scan, std::vector<double>& sensor_ranges)
32 {
33  if (sensor_ranges.size() != scan->ranges.size())
34  sensor_ranges.resize(scan->ranges.size());
35 
36  for(unsigned int i = 0; i < scan->ranges.size(); ++i)
37  {
38  double r = scan->ranges[i];
39  if (r > scan->range_max)
40  sensor_ranges[i] = 0;
41  else if (r == r && r > scan->range_min)
42  sensor_ranges[i] = r;
43  else
44  sensor_ranges[i] = 0;
45  }
46 }
47 
49 {
50 }
51 
53 {
54 }
55 
57 {
59 
60  std::string laser_topic;
61  config.value("laser_topic", laser_topic);
63 
64  if (config.hasError())
65  return;
66 
67  ros::NodeHandle nh;
68  nh.setCallbackQueue(&cb_queue_);
69 
70  // Communication
71  sub_scan_ = nh.subscribe<sensor_msgs::LaserScan>(laser_topic, 3, &LaserPlugin::scanCallback, this);
72 }
73 
75 {
76  cb_queue_.callAvailable();
77 
78  while(!scan_buffer_.empty())
79  {
80  sensor_msgs::LaserScan::ConstPtr scan = scan_buffer_.front();
81 
82  // - - - - - - - - - - - - - - - - - -
83  // Determine absolute laser pose based on TF
84 
85  try
86  {
87  geometry_msgs::TransformStamped gm_sensor_pose;
88  gm_sensor_pose = tf_buffer_->lookupTransform("map", scan->header.frame_id, scan->header.stamp);
89  scan_buffer_.pop();
90  geo::Pose3D sensor_pose;
91  geo::convert(gm_sensor_pose.transform, sensor_pose);
92  update(world, scan, sensor_pose, req);
93  }
94  catch(tf2::ExtrapolationException& ex)
95  {
96  ROS_WARN_STREAM_DELAYED_THROTTLE(60, "ED Laserplugin: " << ex.what());
97  ROS_DEBUG_STREAM("ED Laserplugin: " << ex.what());
98  try
99  {
100  // Now we have to check if the error was an interpolation or extrapolation error
101  // (i.e., the scan is too old or too new, respectively)
102  geometry_msgs::TransformStamped latest_transform;
103  latest_transform = tf_buffer_->lookupTransform("map", scan->header.frame_id, ros::Time(0));
104 
105  if (scan_buffer_.front()->header.stamp > latest_transform.header.stamp)
106  {
107  // Scan is too new
108  break;
109  }
110  else
111  {
112  // Otherwise it has to be too old (pop it because we cannot use it anymore)
113  scan_buffer_.pop();
114  }
115  }
116  catch(tf2::TransformException& exc)
117  {
118  scan_buffer_.pop();
119  }
120  }
121  catch(tf2::TransformException& exc)
122  {
123  ROS_ERROR_STREAM_DELAYED_THROTTLE(10, "ED Laserplugin: " << exc.what());
124  scan_buffer_.pop();
125  }
126  }
127 }
128 
129 void LaserPlugin::update(const ed::WorldModel& world, const sensor_msgs::LaserScan::ConstPtr& scan,
130  const geo::Pose3D& sensor_pose, ed::UpdateRequest& req)
131 {
132  // - - - - - - - - - - - - - - - - - -
133  // Update laser model
134 
135  std::vector<double> sensor_ranges(scan->ranges.size());
136  lasermsgToSensorRanges(scan, sensor_ranges);
137 
138  unsigned int num_beams = sensor_ranges.size();
139 
140  if (updater_.getNumBeams() != num_beams)
141  {
142  updater_.configureLaserModel(num_beams, scan->angle_min, scan->angle_max, scan->range_min, scan->range_max);
143  updater_.setLaserFrame(scan->header.frame_id);
144  }
145 
146  updater_.update(world, sensor_ranges, sensor_pose, scan->header.stamp.toSec(), req);
147 }
148 
149 // ----------------------------------------------------------------------------------------------------
150 
151 
152 void LaserPlugin::scanCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
153 {
154  ROS_DEBUG_STREAM("Received message @ timestamp " << ros::Time::now());
155 
156  scan_buffer_.push(msg);
157 }
158 
std::vector::resize
T resize(T... args)
ed::UpdateRequest
LaserUpdater::configure
void configure(tue::Configuration &config)
Configure updater.
Definition: laser/updater.cpp:258
LaserPlugin::LaserPlugin
LaserPlugin()
Definition: laser_plugin.cpp:48
std::string
LaserPlugin
Definition: laser_plugin.h:19
json_writer.h
update_request.h
ED_REGISTER_PLUGIN
#define ED_REGISTER_PLUGIN(Derived)
LaserUpdater::setLaserFrame
void setLaserFrame(const std::string &frame_id)
set the frame of the laser model
Definition: laser/updater.h:68
std::vector< double >
std::vector::size
T size(T... args)
Shape.h
LaserPlugin::updater_
LaserUpdater updater_
Definition: laser_plugin.h:41
geo::Transform3T
ed::InitData
ed::InitData::config
tue::Configuration & config
iostream
std::queue::front
T front(T... args)
laser_plugin.h
entity_update.h
LaserUpdater::configureLaserModel
void configureLaserModel(uint num_beams, double angle_min, double angle_max, double range_min, double range_max)
configure the LRF model based on a laserscan message
Definition: laser/updater.h:56
tue::config::ReaderWriter
LaserUpdater::update
void update(const ed::WorldModel &world, std::vector< double > &sensor_ranges, const geo::Pose3D &sensor_pose, const double timestamp, ed::UpdateRequest &req)
update update the worldmodel based on a novel laserscan message.
Definition: laser/updater.cpp:278
LaserPlugin::sub_scan_
ros::Subscriber sub_scan_
Definition: laser_plugin.h:37
LaserPlugin::scanCallback
void scanCallback(const sensor_msgs::LaserScan::ConstPtr &msg)
Definition: laser_plugin.cpp:152
ed::Plugin::tf_buffer_
TFBufferConstPtr tf_buffer_
std::queue::pop
T pop(T... args)
lasermsgToSensorRanges
void lasermsgToSensorRanges(const sensor_msgs::LaserScan::ConstPtr &scan, std::vector< double > &sensor_ranges)
Definition: laser_plugin.cpp:31
req
string req
LaserUpdater::getNumBeams
unsigned int getNumBeams()
get the number of beams of the model
Definition: laser/updater.h:73
ed::WorldModel
geo::convert
void convert(const geo::DepthCamera &cam_model, sensor_msgs::CameraInfo &msg)
tue::config::ReaderWriter::value
bool value(const std::string &name, T &value, RequiredOrOptional opt=REQUIRED)
world_model.h
std::queue::empty
T empty(T... args)
std::queue::push
T push(T... args)
LaserPlugin::cb_queue_
ros::CallbackQueue cb_queue_
Definition: laser_plugin.h:35
entity.h
ed::Plugin::initialize
virtual void initialize()
LaserPlugin::scan_buffer_
std::queue< sensor_msgs::LaserScan::ConstPtr > scan_buffer_
Definition: laser_plugin.h:39
convex_hull_calc.h
association_matrix.h
LaserPlugin::~LaserPlugin
virtual ~LaserPlugin()
Definition: laser_plugin.cpp:52
LaserPlugin::process
void process(const ed::WorldModel &world, ed::UpdateRequest &req)
Definition: laser_plugin.cpp:74
LaserPlugin::update
void update(const ed::WorldModel &world, const sensor_msgs::LaserScan::ConstPtr &scan, const geo::Pose3D &sensor_pose, ed::UpdateRequest &req)
Update the worldmodel based on a novel laserscan message.
Definition: laser_plugin.cpp:129
msg_conversions.h
config
tue::config::ReaderWriter config
tue::config::ReaderWriter::hasError
bool hasError() const