hwi_switch_gazebo_ros_control_plugin.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
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 
19 #include <urdf/model.h>
20 
21 namespace cob_gazebo_ros_control
22 {
23 
24 // Overloaded Gazebo entry point
25 void HWISwitchGazeboRosControlPlugin::Load(gazebo::physics::ModelPtr parent, sdf::ElementPtr sdf)
26 {
27  ROS_INFO_STREAM_NAMED("cob_gazebo_ros_control","Loading cob_gazebo_ros_control plugin");
29 
30  // Save pointers to the model
31  parent_model_ = parent;
32  sdf_ = sdf;
33 
34  // Error message if the model couldn't be found
35  if (!parent_model_)
36  {
37  ROS_ERROR_STREAM_NAMED("cob_gazebo_ros_control","parent model is NULL");
38  return;
39  }
40 
41  // Check that ROS has been initialized
42  if(!ros::isInitialized())
43  {
44  ROS_FATAL_STREAM_NAMED("cob_gazebo_ros_control","A ROS node for Gazebo has not been initialized, unable to load plugin. "
45  << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
46  return;
47  }
48 
49  // Get namespace for nodehandle
50  if(sdf_->HasElement("robotNamespace"))
51  {
52  robot_namespace_ = sdf_->GetElement("robotNamespace")->Get<std::string>();
53  }
54  else
55  {
56  robot_namespace_ = parent_model_->GetName(); // default
57  }
58 
59  // Get robot_description ROS param name
60  if (sdf_->HasElement("robotParam"))
61  {
62  robot_description_ = sdf_->GetElement("robotParam")->Get<std::string>();
63  }
64  else
65  {
66  robot_description_ = "robot_description"; // default
67  }
68 
69  // Get the robot simulation interface type
70  if(sdf_->HasElement("robotSimType"))
71  {
72  //robot_hw_sim_type_str_ = sdf_->Get<std::string>("robotSimType");
73  robot_hw_sim_type_str_ = "cob_gazebo_ros_control/HWISwitchRobotHWSim";
74  ROS_WARN_STREAM_NAMED("cob_gazebo_ros_control","Tag 'robotSimType' is currently ignored. Using default plugin for RobotHWSim \""<<robot_hw_sim_type_str_<<"\"");
75  }
76  else
77  {
78  robot_hw_sim_type_str_ = "cob_gazebo_ros_control/HWISwitchRobotHWSim";
79  ROS_DEBUG_STREAM_NAMED("cob_gazebo_ros_control","Using default plugin for RobotHWSim (none specified in URDF/SDF)\""<<robot_hw_sim_type_str_<<"\"");
80  }
81 
82  // Get the Gazebo simulation period
83 #if GAZEBO_MAJOR_VERSION >= 8
84  gazebo::physics::PhysicsEnginePtr physics = gazebo::physics::get_world()->Physics();
85 #else
86  gazebo::physics::PhysicsEnginePtr physics = gazebo::physics::get_world()->GetPhysicsEngine();
87 #endif
88  ros::Duration gazebo_period(physics->GetMaxStepSize());
89 
90  // Decide the plugin control period
91  if(sdf_->HasElement("controlPeriod"))
92  {
93  control_period_ = ros::Duration(sdf_->Get<double>("controlPeriod"));
94 
95  // Check the period against the simulation period
96  if( control_period_ < gazebo_period )
97  {
98  ROS_ERROR_STREAM_NAMED("cob_gazebo_ros_control","Desired controller update period ("<<control_period_
99  <<" s) is faster than the gazebo simulation period ("<<gazebo_period<<" s).");
100  }
101  else if( control_period_ > gazebo_period )
102  {
103  ROS_WARN_STREAM_NAMED("cob_gazebo_ros_control","Desired controller update period ("<<control_period_
104  <<" s) is slower than the gazebo simulation period ("<<gazebo_period<<" s).");
105  }
106  }
107  else
108  {
109  control_period_ = gazebo_period;
110  ROS_DEBUG_STREAM_NAMED("cob_gazebo_ros_control","Control period not found in URDF/SDF, defaulting to Gazebo period of "
111  << control_period_);
112  }
113 
114  // Get parameters/settings for controllers from ROS param server
116 
117  // Initialize the emergency stop code.
118  e_stop_active_ = false;
119  last_e_stop_active_ = false;
120  if (sdf_->HasElement("eStopTopic"))
121  {
122  const std::string e_stop_topic = sdf_->GetElement("eStopTopic")->Get<std::string>();
124  }
125 
126  // Initialize the code to handle state_valid.
127  state_valid_ = true;
128  if (sdf_->HasElement("stateValidTopic"))
129  {
130  const std::string state_valid_topic = sdf_->GetElement("stateValidTopic")->Get<std::string>();
132  }
133 
134  // Determine whether to filter joints
135  if(sdf_->HasElement("filterJointsParam"))
136  {
138  filterJointsParam_ = sdf_->Get<std::string>("filterJointsParam");
139  ROS_INFO_STREAM_NAMED("cob_gazebo_ros_control","Enable joint-filtering. Using joint_names from parameter: \""<<filterJointsParam_<<"\"");
140  }
141  else
142  {
143  enable_joint_filtering_ = false;
144  filterJointsParam_ = "";
145  ROS_INFO_STREAM_NAMED("cob_gazebo_ros_control","Joint-filtering is disabled. The plugin will set up JointHandles for all joints!");
146  }
147 
148  ROS_INFO_NAMED("cob_gazebo_ros_control", "Starting cob_gazebo_ros_control plugin in namespace: %s", robot_namespace_.c_str());
149 
150  // Read urdf from ros parameter server then
151  // setup actuators and mechanism control node.
152  // This call will block if ROS is not properly initialized.
153  const std::string urdf_string = getURDF(robot_description_);
154  if (!parseTransmissionsFromURDF(urdf_string))
155  {
156  ROS_ERROR_NAMED("cob_gazebo_ros_control", "Error parsing URDF in cob_gazebo_ros_control plugin, plugin not active.\n");
157  return;
158  }
159 
160  // Load the RobotHWSim abstraction to interface the controllers with the gazebo model
161  try
162  {
163  //robot_hw_sim_loader_.reset
164  //(new pluginlib::ClassLoader<gazebo_ros_control::RobotHWSim>
165  //("gazebo_ros_control",
166  //"gazebo_ros_control::RobotHWSim"));
167 
168  //robot_hw_sim_ = robot_hw_sim_loader_->createInstance(robot_hw_sim_type_str_);
169 
171 
172 
173  urdf::Model urdf_model;
174  const urdf::Model *const urdf_model_ptr = urdf_model.initString(urdf_string) ? &urdf_model : NULL;
175 
177  {
178  if(!hwi_switch_robot_hw_sim_->enableJointFiltering(model_nh_, filterJointsParam_))
179  {
180  ROS_FATAL_STREAM_NAMED("cob_gazebo_ros_control","Joint-filtering was enabled but param '"<<filterJointsParam_<<"' was not found");
181  return;
182  }
183  }
184 
186  {
187  ROS_FATAL_NAMED("cob_gazebo_ros_control","Could not initialize robot simulation interface");
188  return;
189  }
190 
191  // Create the controller manager
192  ROS_DEBUG_STREAM_NAMED("cob_gazebo_ros_control","Loading controller_manager");
193  controller_manager_.reset
195 
196  // Listen to the update event. This event is broadcast every simulation iteration.
198  gazebo::event::Events::ConnectWorldUpdateBegin
199  (boost::bind(&HWISwitchGazeboRosControlPlugin::Update, this));
200 
201  }
203  {
204  ROS_FATAL_STREAM_NAMED("cob_gazebo_ros_control","Failed to create robot simulation interface loader: "<<ex.what());
205  }
206 
207  ROS_INFO_NAMED("cob_gazebo_ros_control", "Loaded cob_gazebo_ros_control.");
208 }
209 
210 // Called by the world update start event
212 {
213  // Get the simulation time and period
214 #if GAZEBO_MAJOR_VERSION >= 8
215  gazebo::common::Time gz_time_now = gazebo::physics::get_world()->SimTime();
216 #else
217  gazebo::common::Time gz_time_now = parent_model_->GetWorld()->GetSimTime();
218 #endif
219  ros::Time sim_time_ros(gz_time_now.sec, gz_time_now.nsec);
220  ros::Duration sim_period = sim_time_ros - last_update_sim_time_ros_;
221 
225 
226  // Check if we should update the controllers
227  if(sim_period >= control_period_) {
228  // Store this simulation time
229  last_update_sim_time_ros_ = sim_time_ros;
230 
231  // Update the robot simulation with the state of the gazebo model
232  hwi_switch_robot_hw_sim_->readSim(sim_time_ros, sim_period);
233 
234  // Compute the controller commands
235  bool reset_ctrlrs;
236  if (e_stop_active_)
237  {
238  reset_ctrlrs = false;
239  last_e_stop_active_ = true;
240  }
241  else
242  {
244  {
245  reset_ctrlrs = true;
246  last_e_stop_active_ = false;
247  }
248  else
249  {
250  reset_ctrlrs = false;
251  }
252  }
253  controller_manager_->update(sim_time_ros, sim_period, reset_ctrlrs);
254  }
255 
256  // Update the gazebo model with the result of the controller
257  // computation
258  hwi_switch_robot_hw_sim_->writeSim(sim_time_ros, sim_time_ros - last_write_sim_time_ros_);
259  last_write_sim_time_ros_ = sim_time_ros;
260 }
261 
262 // Emergency stop callback
263 void HWISwitchGazeboRosControlPlugin::eStopCB(const std_msgs::BoolConstPtr& e_stop_active)
264 {
265  e_stop_active_ = e_stop_active->data;
266 }
267 
268 // State valid callback
269 void HWISwitchGazeboRosControlPlugin::stateValidCB(const std_msgs::BoolConstPtr& state_valid)
270 {
271  state_valid_ = state_valid->data;
272 }
273 
274 // Register this plugin with the simulator
276 } // namespace
virtual void Load(gazebo::physics::ModelPtr parent, sdf::ElementPtr sdf)
#define ROS_INFO_NAMED(name,...)
#define ROS_DEBUG_STREAM_NAMED(name, args)
#define ROS_ERROR_STREAM_NAMED(name, args)
boost::shared_ptr< controller_manager::ControllerManager > controller_manager_
URDF_EXPORT bool initString(const std::string &xmlstring)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL bool isInitialized()
gazebo::event::ConnectionPtr update_connection_
gazebo::physics::ModelPtr parent_model_
#define ROS_INFO_STREAM_NAMED(name, args)
bool parseTransmissionsFromURDF(const std::string &urdf_string)
#define ROS_FATAL_STREAM_NAMED(name, args)
std::vector< transmission_interface::TransmissionInfo > transmissions_
GZ_REGISTER_MODEL_PLUGIN(HWISwitchGazeboRosControlPlugin)
boost::shared_ptr< cob_gazebo_ros_control::HWISwitchRobotHWSim > hwi_switch_robot_hw_sim_
#define ROS_FATAL_NAMED(name,...)
#define ROS_ERROR_NAMED(name,...)
std::string getURDF(std::string param_name) const
#define ROS_WARN_STREAM_NAMED(name, args)


cob_gazebo_ros_control
Author(s): Felix Messmer
autogenerated on Mon Sep 28 2020 03:19:19