combined_robot_hw_sim.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2018, Open Source Robotics Foundation
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the Open Source Robotics Foundation
18  * nor the names of its contributors may be
19  * used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #include <algorithm>
37 #include <boost/foreach.hpp>
40 
41 namespace gazebo_ros_control
42 {
43 CombinedRobotHWSim::CombinedRobotHWSim() : class_loader_("gazebo_ros_control", "gazebo_ros_control::RobotHWSim")
44 {
45 }
46 
47 bool CombinedRobotHWSim::initSim(const std::string& robot_namespace, ros::NodeHandle model_nh,
48  gazebo::physics::ModelPtr parent_model, const urdf::Model* const urdf_model,
49  std::vector<transmission_interface::TransmissionInfo> transmissions)
50 {
51  // Get
52  std::vector<std::string> robots;
53  std::string param_name = "robot_hardware";
54  if (!model_nh.getParam(param_name, robots))
55  {
56  ROS_ERROR("Param %s not in %s", param_name.c_str(), model_nh.getNamespace().c_str());
57  return false;
58  }
59 
60  // Load each RobotHWSim
61  BOOST_FOREACH (std::string& name, robots)
62  {
63  ROS_DEBUG("Will load robot HW '%s'", name.c_str());
64 
65  // Create local node handle in namespace of this simulated hardware
66  ros::NodeHandle c_nh;
67  try
68  {
69  c_nh = ros::NodeHandle(model_nh, name);
70  }
71  catch (std::exception const& e)
72  {
73  ROS_ERROR("Exception thrown while constructing nodehandle for robot HW with name '%s':\n%s", name.c_str(),
74  e.what());
75  return false;
76  }
77 
78  // Get class type of this hardware from param
80  std::string type;
81  if (!c_nh.getParam("type", type))
82  {
83  ROS_ERROR("Could not load robot HW '%s' because the type was not specified. Did you load the robot HW "
84  "configuration on the parameter server (namespace: '%s')?",
85  name.c_str(), c_nh.getNamespace().c_str());
86  return false;
87  }
88 
89  // Load in plugin for this type
90  try
91  {
92  robot_hw = class_loader_.createInstance(type);
93  }
94  catch (const pluginlib::PluginlibException& ex)
95  {
96  ROS_ERROR("Could not load class %s: %s", type.c_str(), ex.what());
97  return false;
98  }
99 
100  // Initializes the robot HW
101  ROS_DEBUG("Initializing robot HW '%s'", name.c_str());
102  try
103  {
104  robot_hw->initSim(robot_namespace, c_nh, parent_model, urdf_model, transmissions);
105  }
106  catch (std::exception& e)
107  {
108  ROS_ERROR("Exception thrown while initializing robot HW %s.\n%s", name.c_str(), e.what());
109  return false;
110  }
111 
112  // Register hardware and add to vector
113  robot_hw_list_.push_back(robot_hw);
114  this->registerInterfaceManager(robot_hw.get());
115  ROS_DEBUG("Successfully load robot HW '%s'", name.c_str());
116  }
117 
118  return true;
119 }
120 
121 bool CombinedRobotHWSim::prepareSwitch(const std::list<hardware_interface::ControllerInfo>& start_list,
122  const std::list<hardware_interface::ControllerInfo>& stop_list)
123 {
124  // Prepare switch for each contained RobotHWSim, passing each a filtered list of controllers
125  BOOST_FOREACH (gazebo_ros_control::RobotHWSimSharedPtr& hw, robot_hw_list_)
126  {
127  std::list<hardware_interface::ControllerInfo> filtered_start_list;
128  std::list<hardware_interface::ControllerInfo> filtered_stop_list;
129 
130  filterControllerList(start_list, filtered_start_list, hw);
131  filterControllerList(stop_list, filtered_stop_list, hw);
132 
133  if (!hw->prepareSwitch(filtered_start_list, filtered_stop_list))
134  return false;
135  }
136  return true;
137 }
138 
139 void CombinedRobotHWSim::doSwitch(const std::list<hardware_interface::ControllerInfo>& start_list,
140  const std::list<hardware_interface::ControllerInfo>& stop_list)
141 {
142  // Prepare switch for each contained RobotHWSim, passing each a filtered list of controllers
143  BOOST_FOREACH (gazebo_ros_control::RobotHWSimSharedPtr& hw, robot_hw_list_)
144  {
145  std::list<hardware_interface::ControllerInfo> filtered_start_list;
146  std::list<hardware_interface::ControllerInfo> filtered_stop_list;
147 
148  // Generate a filtered version of start_list and stop_list for each RobotHW before calling doSwitch
149  filterControllerList(start_list, filtered_start_list, hw);
150  filterControllerList(stop_list, filtered_stop_list, hw);
151 
152  hw->doSwitch(filtered_start_list, filtered_stop_list);
153  }
154 }
155 
156 void CombinedRobotHWSim::readSim(ros::Time time, ros::Duration period)
157 {
158  // Call the write method of each RobotHWSim
159  BOOST_FOREACH (gazebo_ros_control::RobotHWSimSharedPtr& hw, robot_hw_list_)
160  {
161  hw->readSim(time, period);
162  }
163 }
164 
165 void CombinedRobotHWSim::writeSim(ros::Time time, ros::Duration period)
166 {
167  // Call the read method of each RobotHWSim
168  BOOST_FOREACH (gazebo_ros_control::RobotHWSimSharedPtr& hw, robot_hw_list_)
169  {
170  hw->writeSim(time, period);
171  }
172 }
173 
174 void CombinedRobotHWSim::filterControllerList(const std::list<hardware_interface::ControllerInfo>& list,
175  std::list<hardware_interface::ControllerInfo>& filtered_list,
177 {
178  filtered_list.clear();
179  for (std::list<hardware_interface::ControllerInfo>::const_iterator it = list.begin(); it != list.end(); ++it)
180  {
181  hardware_interface::ControllerInfo filtered_controller;
182  filtered_controller.name = it->name;
183  filtered_controller.type = it->type;
184 
185  if (it->claimed_resources.empty())
186  {
187  filtered_list.push_back(filtered_controller);
188  continue;
189  }
190  for (std::vector<hardware_interface::InterfaceResources>::const_iterator res_it = it->claimed_resources.begin();
191  res_it != it->claimed_resources.end(); ++res_it)
192  {
193  hardware_interface::InterfaceResources filtered_iface_resources;
194  filtered_iface_resources.hardware_interface = res_it->hardware_interface;
195  std::vector<std::string> r_hw_ifaces = robot_hw->getNames();
196 
197  std::vector<std::string>::iterator if_name =
198  std::find(r_hw_ifaces.begin(), r_hw_ifaces.end(), filtered_iface_resources.hardware_interface);
199  if (if_name == r_hw_ifaces.end()) // this hardware_interface is not registered in r_hw, so we filter it out
200  {
201  continue;
202  }
203 
204  std::vector<std::string> r_hw_iface_resources =
205  robot_hw->getInterfaceResources(filtered_iface_resources.hardware_interface);
206  std::set<std::string> filtered_resources;
207  for (std::set<std::string>::const_iterator ctrl_res = res_it->resources.begin();
208  ctrl_res != res_it->resources.end(); ++ctrl_res)
209  {
210  std::vector<std::string>::iterator res_name =
211  std::find(r_hw_iface_resources.begin(), r_hw_iface_resources.end(), *ctrl_res);
212  if (res_name != r_hw_iface_resources.end())
213  {
214  filtered_resources.insert(*ctrl_res);
215  }
216  }
217  filtered_iface_resources.resources = filtered_resources;
218  filtered_controller.claimed_resources.push_back(filtered_iface_resources);
219  }
220  filtered_list.push_back(filtered_controller);
221  }
222 }
223 }
combined_robot_hw_sim.h
boost::shared_ptr< gazebo_ros_control::RobotHWSim >
hardware_interface::InterfaceResources::hardware_interface
std::string hardware_interface
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(gazebo_ros_control::CombinedRobotHWSim, gazebo_ros_control::RobotHWSim)
urdf::Model
gazebo_ros_control::RobotHWSim
hardware_interface::ControllerInfo::type
std::string type
pluginlib::PluginlibException
class_list_macros.h
ROS_DEBUG
#define ROS_DEBUG(...)
gazebo_ros_control
gazebo_ros_control::CombinedRobotHWSim
CombinedRobotHW.
Definition: combined_robot_hw_sim.h:95
hardware_interface::ControllerInfo
hardware_interface::ControllerInfo::claimed_resources
std::vector< InterfaceResources > claimed_resources
ros::Time
ROS_ERROR
#define ROS_ERROR(...)
hardware_interface::ControllerInfo::name
std::string name
gazebo_ros_control::CombinedRobotHWSim::CombinedRobotHWSim
CombinedRobotHWSim()
Definition: combined_robot_hw_sim.cpp:76
ros::NodeHandle::getNamespace
const std::string & getNamespace() const
hardware_interface::InterfaceResources
ros::Duration
hardware_interface::InterfaceResources::resources
std::set< std::string > resources
ros::NodeHandle


qb_device_gazebo
Author(s): qbroboticsĀ®
autogenerated on Thu Apr 27 2023 02:36:26