30 #include <gazebo/physics/World.hh> 31 #include <gazebo/physics/HingeJoint.hh> 32 #include <gazebo/sensors/Sensor.hh> 33 #include <gazebo/sensors/SensorManager.hh> 34 #include <gazebo/common/Exception.hh> 35 #include <gazebo/sensors/GpuRaySensor.hh> 36 #include <gazebo/sensors/SensorTypes.hh> 37 #include <gazebo/transport/transport.hh> 38 #include <gazebo/rendering/rendering.hh> 44 #include <gazebo_plugins/gazebo_ros_utils.h> 45 #include <std_msgs/String.h> 54 GZ_REGISTER_SENSOR_PLUGIN(LeicaPlugin)
74 GpuRayPlugin::Load(_parent, this->
sdf_);
77 std::string worldName = _parent->WorldName();
80 this->
world_ = physics::get_world(worldName);
88 GAZEBO_SENSORS_USING_DYNAMIC_POINTER_CAST;
93 gzthrow(
"LeicaPlugin controller requires a Ray Sensor as its parent");
95 this->
namespace_ = GetRobotNamespace(_parent, _sdf,
"Laser");
97 if (!this->
sdf_->HasElement(
"frameName"))
99 ROS_INFO(
"LeicaPlugin missing <frameName>, defaults to /world");
105 if (!this->
sdf_->HasElement(
"topicName"))
107 ROS_INFO(
"LeicaPlugin missing <topicName>, defaults to /world");
115 ROS_FATAL_STREAM(
"A ROS node for Gazebo has not been initialized, unable to load plugin. " 116 <<
"Load the Gazebo system plugin 'leica_plugin.so')");
126 ros::SubscribeOptions::create<sensor_msgs::RegionOfInterest>(
"/c5/simulator/window",
140 this->
gazebo_node_ = gazebo::transport::NodePtr(
new gazebo::transport::Node());
142 this->
pmq_.startServiceThread();
150 boost::trim_right_if(this->
tf_prefix_, boost::is_any_of(
"/"));
180 std::unique_lock<std::mutex> lk(
mutex_);
201 sensor_msgs::LaserScan laser_msg;
202 laser_msg.header.stamp =
ros::Time(_msg->time().sec(), _msg->time().nsec());
204 laser_msg.angle_min = _msg->scan().angle_min();
205 laser_msg.angle_max = _msg->scan().angle_max();
206 laser_msg.angle_increment = _msg->scan().angle_step();
207 laser_msg.time_increment = 0;
208 laser_msg.scan_time = 0;
209 laser_msg.range_min = _msg->scan().range_min();
210 laser_msg.range_max = _msg->scan().range_max();
211 laser_msg.ranges.resize(_msg->scan().ranges_size());
212 std::copy(_msg->scan().ranges().begin(), _msg->scan().ranges().end(), laser_msg.ranges.begin());
213 laser_msg.intensities.resize(_msg->scan().intensities_size());
214 std::copy(_msg->scan().intensities().begin(), _msg->scan().intensities().end(), laser_msg.intensities.begin());
221 std::lock_guard<std::mutex> lk(
mutex_);
226 double MIN_ANGLE_LIMIT = -1.04;
229 ignition::math::Angle angle_min =
atan(_msg->y_offset - (_msg->height)*1e-3 / 2.0);
230 ignition::math::Angle angle_max =
atan(_msg->y_offset + (_msg->height)*1e-3 / 2.0);
231 if(angle_min.Radian() < MIN_ANGLE_LIMIT)
232 angle_min = MIN_ANGLE_LIMIT;
233 if((angle_max - angle_min) < ignition::math::Angle::HalfPi)
234 angle_max = angle_min + ignition::math::Angle::HalfPi;
241 ignition::math::Angle cam_angle = half_angle - update_half_angle;
242 cam->Roll(ignition::math::Angle(cam_angle), rendering::ReferenceFrame::RF_WORLD);
243 cam->SetHFOV(angle_max - angle_min);
253 static const double timeout = 0.01;
254 while (this->
nh_->
ok())
ros::Subscriber sub_
Subscriber for the laser sensor.
ros::CallbackQueue cb_queue_
Queue for the callback functions.
void gazeboMsgToROSMsg(ConstLaserScanStampedPtr &_msg)
Tailor the gazebo message to the ROS format.
std::string getPrefixParam(ros::NodeHandle &nh)
physics::WorldPtr world_
Pointer to the virtual world where the simulation takes place.
void disconnectFromLaser()
Unregister the laser.
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::string namespace_
The namespace of the Leica station.
gazebo::transport::NodePtr gazebo_node_
Node for gazebo.
ROSCPP_DECL bool isInitialized()
void gazeboLoaderThread()
Load the sensor controller.
PubQueue< sensor_msgs::LaserScan >::Ptr pub_queue_
Publisher queue.
std::string world_name_
Stores the name of the virtual world where the simulation takes place.
sdf::ElementPtr sdf_
Pointer to the *.sdf file.
std::string frame_name_
Stores the name of the root of the reference system tree.
std::string resolve(const std::string &prefix, const std::string &frame_name)
void Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf)
Load the plugin controller.
void connectToLaser()
Register de new laser and connect to its topic.
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
std::mutex mutex_
Mutex used so that no laser sensor data is published until the configuration of the scan window has b...
#define ROS_FATAL_STREAM(args)
int laser_connect_count_
A counter to register the number of laser sensors in use.
boost::thread deferred_load_thread_
Object for the sensor controller thread.
void configureScanWindow(const sensor_msgs::RegionOfInterestConstPtr &_msg)
Configure the scan window from a topic.
void callbacksQueueHelperThread()
Thread that calls all functions in the callback queue when resources are available.
ros::NodeHandle * nh_
Pointer to the ROS node.
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
std::thread queue_helper_thread_
Thread that calls all functions in the callback queue when resources are available.
gazebo::transport::SubscriberPtr laser_scan_sub_
Gazebo part of the laser sensor subscriber.
#define ROS_DEBUG_STREAM(args)
std::string tf_prefix_
tf_prefix_ as the namespace
ros::Publisher pub_
Publisher for the laser sensor.
std::string topic_name_
Saves the name of the topic where the laser scanner publishes what it reads.
#define ROS_INFO_STREAM(args)
std::condition_variable condition_variable_
Variable used to wait until the configuration of the scan window has been completed.
bool start_laser_
Flag to start the laser after the scan window has been set.
PubMultiQueue pmq_
Object for the ROS queue system.
boost::shared_ptr< void > VoidPtr
sensors::GpuRaySensorPtr parent_ray_sensor_
Pointer to the laser sensor object.
~LeicaPlugin()
Destroy the Gazebo ROS Laser object.