hand_commander.cpp
Go to the documentation of this file.
1 
31 #include <controller_manager_msgs/ListControllers.h>
32 #include <sr_robot_msgs/sendupdate.h>
33 #include <std_msgs/Float64.h>
34 
35 #include <boost/algorithm/string.hpp>
36 #include <utility>
37 #include <map>
38 #include <string>
39 #include <vector>
40 
41 
42 namespace shadowrobot
43 {
44 
46 
47  HandCommander::HandCommander(const std::string &ns) :
48  node_(ns),
49  hand_type(shadowhandRosLib::UNKNOWN),
50  ethercat_controllers_found(false)
51  {
52  // Get the urdf model from the parameter server
53  // this is used for returning min and max for joints for example.
54  std::string robot_desc_string;
55  node_.param("sh_description", robot_desc_string, std::string());
56  urdf::Model robot_model;
57  if (!robot_model.initString(robot_desc_string))
58  {
59  ROS_WARN("Failed to parse urdf file - trying with robot_description instead of sh_description.");
60 
61  node_.param("robot_description", robot_desc_string, std::string());
62  if (!robot_model.initString(robot_desc_string))
63  {
64  ROS_ERROR_STREAM("Couldn't parse the urdf file on sh_description or on robot_description (namespace=" <<
65  node_.getNamespace() << ")");
66  return;
67  }
68  }
69 
70  all_joints = robot_model.joints_;
71 
72  // We use the presence of the controller_manager/list_controllers service to detect that the hand is ethercat
73  // We look for the manager in the robots namespace (that of node_ not the process).
74  if (ros::service::waitForService(node_.getNamespace() + "/controller_manager/list_controllers",
76  {
79  ROS_INFO_STREAM("HandCommander library: ETHERCAT hand detected in " << node_.getNamespace());
80  }
81  else
82  {
84  sr_hand_target_pub = node_.advertise<sr_robot_msgs::sendupdate>("srh/sendupdate", 2);
85  ROS_INFO_STREAM("HandCommander library: CAN hand detected in " << node_.getNamespace());
86  }
87  }
88 
90  {
91  }
92 
94  {
95  sr_hand_target_pub_map.clear();
96 
97  ros::ServiceClient controller_list_client = node_.serviceClient<controller_manager_msgs::ListControllers>(
98  "controller_manager/list_controllers");
99 
100  controller_manager_msgs::ListControllers controller_list;
101  std::string controlled_joint_name;
102 
103  controller_list_client.call(controller_list);
104 
105  for (size_t i = 0; i < controller_list.response.controller.size(); i++)
106  {
107  if (controller_list.response.controller[i].state == "running")
108  {
109  std::string controller = node_.resolveName(controller_list.response.controller[i].name);
110  if (node_.getParam(controller + "/joint", controlled_joint_name))
111  {
112  ROS_DEBUG("controller %d:%s controls joint %s\n",
113  static_cast<int>(i), controller.c_str(), controlled_joint_name.c_str());
114  sr_hand_target_pub_map[controlled_joint_name]
115  = node_.advertise<std_msgs::Float64>(controller + "/command", 2);
117  sr_hand_sub_topics[controlled_joint_name] = controller + "/state";
118  }
119  }
120  }
121  }
122 
123  void HandCommander::sendCommands(std::vector<sr_robot_msgs::joint> joint_vector)
124  {
126  {
128  {
130  // No controllers we found so bail out
132  {
133  return;
134  }
135  }
136  for (size_t i = 0; i < joint_vector.size(); ++i)
137  {
138  std_msgs::Float64 target;
139  target.data = joint_vector.at(i).joint_target * M_PI / 180.0;
140  sr_hand_target_pub_map[joint_vector.at(i).joint_name].publish(target);
141  }
142  }
143  else
144  {
145  sr_robot_msgs::sendupdate sendupdate_msg;
146  sendupdate_msg.sendupdate_length = joint_vector.size();
147  sendupdate_msg.sendupdate_list = joint_vector;
148 
149  sr_hand_target_pub.publish(sendupdate_msg);
150  }
151  }
152 
153  std::pair<double, double> HandCommander::get_min_max(std::string joint_name)
154  {
155  // needs to get min max for J1 and J2 if J0
156  std::vector<std::string> joint_names, split_name;
157  boost::split(split_name, joint_name, boost::is_any_of("0"));
158  if (split_name.size() == 1)
159  {
160  // not a J0
161  joint_names.push_back(joint_name);
162  }
163  else
164  {
165  // this is a J0, push J1 and J2
166  joint_names.push_back(split_name[0] + "1");
167  joint_names.push_back(split_name[0] + "2");
168  }
169 
170 
171  std::pair<double, double> min_max;
172  for (size_t i = 0; i < joint_names.size(); ++i)
173  {
174  std::string jn = joint_names[i];
175 
176  std::map<std::string, boost::shared_ptr<urdf::Joint> >::iterator it = all_joints.find(jn);
177 
178  if (it != all_joints.end())
179  {
180  min_max.first += it->second->limits->lower;
181  min_max.second += it->second->limits->upper;
182  }
183  else
184  {
185  ROS_ERROR_STREAM("Joint " << jn << " not found in the urdf description.");
186  }
187  }
188 
189  return min_max;
190  }
191 
192  std::vector<std::string> HandCommander::get_all_joints()
193  {
194  std::vector<std::string> all_joints_names;
195  std::map<std::string, std::string>::iterator it;
196 
197  for (it = sr_hand_sub_topics.begin(); it != sr_hand_sub_topics.end(); ++it)
198  {
199  all_joints_names.push_back(it->first);
200  }
201 
202  return all_joints_names;
203  }
204 
205  std::string HandCommander::get_controller_state_topic(std::string joint_name)
206  {
207  std::string topic;
208 
210  {
211  std::map<std::string, std::string>::iterator it = sr_hand_sub_topics.find(joint_name);
212  if (it != sr_hand_sub_topics.end())
213  {
214  topic = it->second;
215  }
216  else
217  {
218  ROS_ERROR_STREAM(" Controller for joint " << joint_name << " not found.");
219  }
220  }
221  else
222  {
223  topic = "shadowhand_data";
224  }
225 
226  return topic;
227  }
228 } // namespace shadowrobot
229 
230 /* For the emacs weenies in the crowd.
231 Local Variables:
232  c-basic-offset: 2
233 End:
234 */
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
list joint_names
void publish(const boost::shared_ptr< M > &message) const
URDF_EXPORT bool initString(const std::string &xmlstring)
Publisher sr_hand_target_pub
Publisher for the CAN hand targets.
std::string resolveName(const std::string &name, bool remap=true) const
boost::ptr_map< std::string, Publisher > sr_hand_target_pub_map
Publishers for the ethercat hand targets for every joint.
void sendCommands(std::vector< sr_robot_msgs::joint > joint_vector)
bool call(MReq &req, MRes &res)
std::vector< std::string > get_all_joints()
#define ROS_WARN(...)
std::pair< double, double > get_min_max(std::string joint_name)
NodeHandle node_
ros node handle
bool param(const std::string &param_name, T &param_val, const T &default_val) const
shadowhandRosLib::HandType hand_type
std::map< std::string, boost::shared_ptr< urdf::Joint > > all_joints
stores data about the hand (read from urdf)
const std::string & getNamespace() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
static const double TIMEOUT_TO_DETECT_CONTROLLER_MANAGER
HandCommander(const std::string &ns="")
std::string get_controller_state_topic(std::string joint_name)
std::map< std::string, std::string > sr_hand_sub_topics
A map of topics for the controller states.
#define ROS_INFO_STREAM(args)
bool getParam(const std::string &key, std::string &s) const
This is a library that offers a simple interface to send commands to hand joints. It is compatible wi...
#define ROS_ERROR_STREAM(args)
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)
#define ROS_DEBUG(...)


sr_hand
Author(s): Ugo Cupcic
autogenerated on Tue Oct 13 2020 03:55:53