gazebo_ros_force.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2013 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 /*
19  Desc: GazeboRosForce plugin for manipulating objects in Gazebo
20  Author: John Hsu
21  Date: 24 Sept 2008
22  */
23 
24 #include <algorithm>
25 #include <assert.h>
26 
28 
29 namespace gazebo
30 {
31 GZ_REGISTER_MODEL_PLUGIN(GazeboRosForce);
32 
34 // Constructor
36 {
37  this->wrench_msg_.force.x = 0;
38  this->wrench_msg_.force.y = 0;
39  this->wrench_msg_.force.z = 0;
40  this->wrench_msg_.torque.x = 0;
41  this->wrench_msg_.torque.y = 0;
42  this->wrench_msg_.torque.z = 0;
43 }
44 
46 // Destructor
48 {
49  this->update_connection_.reset();
50 
51  // Custom Callback Queue
52  this->queue_.clear();
53  this->queue_.disable();
54  this->rosnode_->shutdown();
55  this->callback_queue_thread_.join();
56 
57  delete this->rosnode_;
58 }
59 
61 // Load the controller
62 void GazeboRosForce::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
63 {
64  // Get the world name.
65  this->world_ = _model->GetWorld();
66 
67  // load parameters
68  this->robot_namespace_ = "";
69  if (_sdf->HasElement("robotNamespace"))
70  this->robot_namespace_ = _sdf->GetElement("robotNamespace")->Get<std::string>() + "/";
71 
72  if (!_sdf->HasElement("bodyName"))
73  {
74  ROS_FATAL_NAMED("force", "force plugin missing <bodyName>, cannot proceed");
75  return;
76  }
77  else
78  this->link_name_ = _sdf->GetElement("bodyName")->Get<std::string>();
79 
80  this->link_ = _model->GetLink(this->link_name_);
81  if (!this->link_)
82  {
83  ROS_FATAL_NAMED("force", "gazebo_ros_force plugin error: link named: %s does not exist\n",this->link_name_.c_str());
84  return;
85  }
86 
87  if (!_sdf->HasElement("topicName"))
88  {
89  ROS_FATAL_NAMED("force", "force plugin missing <topicName>, cannot proceed");
90  return;
91  }
92  else
93  this->topic_name_ = _sdf->GetElement("topicName")->Get<std::string>();
94 
95 
96  // Make sure the ROS node for Gazebo has already been initialized
97  if (!ros::isInitialized())
98  {
99  ROS_FATAL_STREAM_NAMED("force", "A ROS node for Gazebo has not been initialized, unable to load plugin. "
100  << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
101  return;
102  }
103 
104  this->rosnode_ = new ros::NodeHandle(this->robot_namespace_);
105 
106  if (this->topic_name_.find(':') != std::string::npos)
107  {
108  std::string _topic_name = this->topic_name_;
109  std::replace(this->topic_name_.begin(), this->topic_name_.end(), ':', '_');
110  ROS_WARN_STREAM("Ros topic " << _topic_name << " has been renamed to " << this->topic_name_);
111  }
112 
113  // Custom Callback Queue
114  ros::SubscribeOptions so = ros::SubscribeOptions::create<geometry_msgs::Wrench>(
115  this->topic_name_,1,
116  boost::bind( &GazeboRosForce::UpdateObjectForce,this,_1),
117  ros::VoidPtr(), &this->queue_);
118  this->sub_ = this->rosnode_->subscribe(so);
119 
120  // Custom Callback Queue
121  this->callback_queue_thread_ = boost::thread( boost::bind( &GazeboRosForce::QueueThread,this ) );
122 
123  // New Mechanism for Updating every World Cycle
124  // Listen to the update event. This event is broadcast every
125  // simulation iteration.
126  this->update_connection_ = event::Events::ConnectWorldUpdateBegin(
127  boost::bind(&GazeboRosForce::UpdateChild, this));
128 }
129 
131 // Update the controller
132 void GazeboRosForce::UpdateObjectForce(const geometry_msgs::Wrench::ConstPtr& _msg)
133 {
134  this->wrench_msg_.force.x = _msg->force.x;
135  this->wrench_msg_.force.y = _msg->force.y;
136  this->wrench_msg_.force.z = _msg->force.z;
137  this->wrench_msg_.torque.x = _msg->torque.x;
138  this->wrench_msg_.torque.y = _msg->torque.y;
139  this->wrench_msg_.torque.z = _msg->torque.z;
140 }
141 
143 // Update the controller
145 {
146  this->lock_.lock();
147  ignition::math::Vector3d force(this->wrench_msg_.force.x,this->wrench_msg_.force.y,this->wrench_msg_.force.z);
148  ignition::math::Vector3d torque(this->wrench_msg_.torque.x,this->wrench_msg_.torque.y,this->wrench_msg_.torque.z);
149  this->link_->AddForce(force);
150  this->link_->AddTorque(torque);
151  this->lock_.unlock();
152 }
153 
154 // Custom Callback Queue
156 // custom callback queue thread
158 {
159  static const double timeout = 0.01;
160 
161  while (this->rosnode_->ok())
162  {
163  this->queue_.callAvailable(ros::WallDuration(timeout));
164  }
165 }
166 
167 }
void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
geometry_msgs::Wrench wrench_msg_
Container for the wrench force that this plugin exerts on the body.
void QueueThread()
The custom callback queue thread function.
ros::CallbackQueue queue_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
GazeboRosForce()
Constructor.
ROSCPP_DECL bool isInitialized()
boost::mutex lock_
A mutex to lock access to fields that are used in ROS message callbacks.
std::string link_name_
The Link this plugin is attached to, and will exert forces on.
GZ_REGISTER_MODEL_PLUGIN(GazeboRosF3D)
physics::WorldPtr world_
A pointer to the gazebo world.
virtual ~GazeboRosForce()
Destructor.
std::string robot_namespace_
for setting ROS name space
physics::LinkPtr link_
A pointer to the Link, where force is applied.
#define ROS_FATAL_STREAM_NAMED(name, args)
event::ConnectionPtr update_connection_
#define ROS_WARN_STREAM(args)
void UpdateObjectForce(const geometry_msgs::Wrench::ConstPtr &_msg)
call back when a Wrench message is published
#define ROS_FATAL_NAMED(name,...)
std::string topic_name_
ROS Wrench topic name inputs.
ros::NodeHandle * rosnode_
A pointer to the ROS node. A node will be instantiated if it does not exist.
bool ok() const
boost::shared_ptr< void > VoidPtr
boost::thread callback_queue_thread_
Thead object for the running callback Thread.


gazebo_plugins
Author(s): John Hsu
autogenerated on Wed Aug 24 2022 02:47:52