gazebo_ros_ir_sensor.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include <string>
3 #include <assert.h>
4 
5 #include <gazebo/physics/World.hh>
6 #include <gazebo/physics/HingeJoint.hh>
7 #include <gazebo/sensors/Sensor.hh>
8 #include <gazebo/common/Exception.hh>
9 #include <gazebo/sensors/RaySensor.hh>
10 #include <gazebo/sensors/SensorTypes.hh>
11 #include <gazebo/transport/transport.hh>
12 
13 #include <sdf/sdf.hh>
14 #include <sdf/Param.hh>
15 
16 #include <tf/tf.h>
17 #include <tf/transform_listener.h>
18 
20 
21 
22 namespace gazebo {
23  // Register this plugin with the simulator
24  GZ_REGISTER_SENSOR_PLUGIN(GazeboRosIrSensor)
25 
26  // Constructor
28  this->seed_ = 0;
29  }
30 
31  // Destructor
33  this->rosnode_->shutdown();
34  delete this->rosnode_;
35  }
36 
37  // Load the controller
38  void GazeboRosIrSensor::Load(sensors::SensorPtr _parent,
39  sdf::ElementPtr _sdf) {
40  // Load plugin
41  RayPlugin::Load(_parent, this->sdf_);
42 
43  // Get the world name.
44  # if GAZEBO_MAJOR_VERSION >= 7
45  std::string worldName = _parent->WorldName();
46  # else
47  std::string worldName = _parent->GetWorldName();
48  #endif
49 
50  this->world_ = physics::get_world(worldName);
51 
52  // Save pointers
53  this->sdf_ = _sdf;
54 
56  this->parent_ray_sensor_ =
57  dynamic_pointer_cast<sensors::RaySensor>(_parent);
58 
59  if (!this->parent_ray_sensor_)
60  gzthrow("GazeboRosIrSensor controller requires a Ray Sensor as its parent");
61 
62  this->robot_namespace_ = GetRobotNamespace(_parent, _sdf, "IR_Sensor");
63 
64  if (!this->sdf_->HasElement("frameName")) {
66  "ir_sensor",
67  "IR Sensor plugin missing <frameName>, defaults to world");
68  this->frame_name_ = "/world";
69 
70  } else {
71  this->frame_name_ = this->sdf_->Get<std::string>("frameName");
72 
73  }
74 
75  if (!this->sdf_->HasElement("topicName")) {
77  "ir_sensor",
78  "IR Sensor plugin missing <topicName>, defaults to /world");
79  this->topic_name_ = "/world";
80 
81  } else {
82  this->topic_name_ = this->sdf_->Get<std::string>("topicName");
83 
84  }
85 
86  this->ir_sensor_connect_count_ = 0;
87 
88  // Make sure the ROS node for Gazebo has already been initialized.
89  if (!ros::isInitialized()) {
90  ROS_FATAL_STREAM_NAMED("ir_sensor", "A ROS node for Gazebo has not been initialized, unable to load plugin. " << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
91  return;
92  }
93 
95  "ir_sensor",
96  "Starting IR Sensor Plugin (ns = %s)",
97  this->robot_namespace_.c_str());
98 
99  // ros callback queue for processing subscription
100  this->deferred_load_thread_ = boost::thread(
101  boost::bind(&GazeboRosIrSensor::LoadThread, this));
102  }
103 
104  // Load the controller
106  this->gazebo_node_ = gazebo::transport::NodePtr(
107  new gazebo::transport::Node());
108  this->gazebo_node_->Init(this->world_name_);
109 
110  this->pmq_.startServiceThread();
111 
112  this->rosnode_ = new ros::NodeHandle(this->robot_namespace_);
113 
114  this->tf_prefix_ = tf::getPrefixParam(*this->rosnode_);
115  if (this->tf_prefix_.empty()) {
116  this->tf_prefix_ = this->robot_namespace_;
117  boost::trim_right_if(this->tf_prefix_, boost::is_any_of("/"));
118 
119  }
120 
122  "ir_sensor",
123  "IR Sensor Plugin (ns = %s) <tf_prefix>, set to \"%s\"",
124  this->robot_namespace_.c_str(),
125  this->tf_prefix_.c_str());
126 
127  // Resolve tf prefix
128  this->frame_name_ = tf::resolve(this->tf_prefix_, this->frame_name_);
129 
130  if (this->topic_name_ != "") {
132  ros::AdvertiseOptions::create<std_msgs::Float32>(
133  this->topic_name_,
134  1,
135  boost::bind(&GazeboRosIrSensor::IrSensorConnect, this),
136  boost::bind(&GazeboRosIrSensor::IrSensorDisconnect, this),
137  ros::VoidPtr(),
138  NULL);
139  this->pub_ = this->rosnode_->advertise(ao);
140  this->pub_queue_ = this->pmq_.addPub<std_msgs::Float32>();
141  }
142 
143  // Initialize the controller
144 
145  // Sensor generation off by default
146  this->parent_ray_sensor_->SetActive(false);
147 
148  }
149 
150  // Increment Count
152  this->ir_sensor_connect_count_++;
153  if (this->ir_sensor_connect_count_ == 1) {
154  # if GAZEBO_MAJOR_VERSION >= 7
155  this->ir_sensor_scan_sub_ =
156  this->gazebo_node_->Subscribe(this->parent_ray_sensor_->Topic(),
158  # else
159  this->ir_sensor_scan_sub_ =
160  this->gazebo_node_->Subscribe(this->parent_ray_sensor_->GetTopic(),
162  # endif
163  }
164  }
165 
166  // Decrement Count
168  this->ir_sensor_connect_count_--;
169  if (this->ir_sensor_connect_count_ == 0) {
170  this->ir_sensor_scan_sub_.reset();
171  }
172  }
173 
174  /**************************************************************
175  * Convert New Gazebo Message to ROS message and publish it
176  *
177  * From my research with the values returned in scan(). The maximum and
178  * minimum limits for the ray specified in the robot's XML file (look at
179  * the ir_sensor.urdf.xacro file within this repository for reference) are
180  * the values returned by `_msg->scan().ranges()`.
181  *
182  * 720 values are returned by `_msg->scan().ranges()`, however, they all seem
183  * to be the same information. Either .3 if nothing is in front of the sensor
184  * or lesser values pertaining to the distance from the sensor. If a box is
185  * in front of the sensor 0.10 m from the pheeno, ALL the values of
186  * `_msg->scan().ranges()` will read about 0.10 m.
187  *
188  * Since my inquiring lead to this conclusion, I will only use the first
189  * value coming from `_msg->scan().ranges(0)` and then multiplying it by
190  * 100 to return the values in cm instead of m.
191  **************************************************************/
192  void GazeboRosIrSensor::OnScan(ConstLaserScanStampedPtr &_msg) {
193  // Declare ROS Message
194  std_msgs::Float32 ir_sensor_msg;
195 
196  // Set the sensor value.
197  ir_sensor_msg.data = (float)_msg->scan().ranges(0) * 100.0;
198 
199  // Publish message.
200  this->pub_queue_->push(ir_sensor_msg, this->pub_);
201  }
202 }
#define NULL
void push(T &msg, ros::Publisher &pub)
gazebo::transport::SubscriberPtr ir_sensor_scan_sub_
#define ROS_INFO_NAMED(name,...)
std::string getPrefixParam(ros::NodeHandle &nh)
PubQueue< std_msgs::Float32 >::Ptr pub_queue_
ROSCPP_DECL bool isInitialized()
std::string resolve(const std::string &prefix, const std::string &frame_name)
#define ROS_FATAL_STREAM_NAMED(name, args)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf)
boost::shared_ptr< PubQueue< T > > addPub()
gazebo::transport::NodePtr gazebo_node_
void startServiceThread()
std::string GetRobotNamespace(const sensors::SensorPtr &parent, const sdf::ElementPtr &sdf, const char *pInfo=NULL)
#define GAZEBO_SENSORS_USING_DYNAMIC_POINTER_CAST
boost::shared_ptr< void > VoidPtr
sensors::RaySensorPtr parent_ray_sensor_
void OnScan(ConstLaserScanStampedPtr &_msg)


pheeno_ros_sim
Author(s): Zahi Kakish
autogenerated on Mon Jun 10 2019 14:25:55