virtual_arm.cpp
Go to the documentation of this file.
1 
27 
28 #include <string>
29 #include <vector>
30 #include <time.h>
31 #include <ros/ros.h>
32 
33 #ifdef GAZEBO
34 #include <std_msgs/Float64.h>
35 #include <std_srvs/Empty.h>
36 
37 #include <gazebo_msgs/SetModelConfiguration.h>
38 #endif
39 
40 namespace shadowrobot
41 {
44  {
45 #ifdef GAZEBO
46  ROS_INFO("This ROS interface is built for Gazebo.");
47  // initialises the subscriber to the Gazebo joint_states messages
48  std::string prefix;
49  std::string searched_param;
50  n_tilde = ros::NodeHandle("~");
51 
52  n_tilde.searchParam("gazebo_joint_states_prefix", searched_param);
53  n_tilde.param(searched_param, prefix, std::string());
54  std::string full_topic = prefix + "joint_states";
55  gazebo_subscriber = node.subscribe(full_topic, 2, &VirtualArm::gazeboCallback, this);
56 #else
57  ROS_INFO("This ROS interface is not built for Gazebo.");
58 #endif
59 
60  srand(time(NULL));
61  initializeMap();
62  }
63 
65  {
66  }
67 
69  {
70  joints_map_mutex.lock();
71  JointData tmpData;
72 
73 #ifdef GAZEBO
74  std::string topic_prefix = "/";
75  std::string topic_suffix = "/command";
76  std::string full_topic = "";
77 #endif
78 
79  tmpData.min = -45.0;
80  tmpData.max = 90.0;
81 #ifdef GAZEBO
82  full_topic = topic_prefix + "sa_sr_position_controller" + topic_suffix;
83  gazebo_publishers.push_back(node.advertise<std_msgs::Float64>(full_topic, 2));
84  int tmp_index = 0;
85  tmpData.publisher_index = tmp_index;
86 #endif
87  joints_map["ShoulderJRotate"] = tmpData;
88  tmpData.min = 0.0;
89  tmpData.max = 90.0;
90 #ifdef GAZEBO
91  full_topic = topic_prefix + "sa_ss_position_controller" + topic_suffix;
92  gazebo_publishers.push_back(node.advertise<std_msgs::Float64>(full_topic, 2));
93  ++tmp_index;
94  tmpData.publisher_index = tmp_index;
95 #endif
96  joints_map["ShoulderJSwing"] = tmpData;
97  tmpData.min = 0.0;
98  tmpData.max = 120.0;
99 #ifdef GAZEBO
100  full_topic = topic_prefix + "sa_es_position_controller" + topic_suffix;
101  gazebo_publishers.push_back(node.advertise<std_msgs::Float64>(full_topic, 2));
102  ++tmp_index;
103  tmpData.publisher_index = tmp_index;
104 #endif
105  joints_map["ElbowJSwing"] = tmpData;
106  tmpData.min = -90.0;
107  tmpData.max = 90.0;
108 #ifdef GAZEBO
109  full_topic = topic_prefix + "sa_er_position_controller" + topic_suffix;
110  gazebo_publishers.push_back(node.advertise<std_msgs::Float64>(full_topic, 2));
111  ++tmp_index;
112  tmpData.publisher_index = tmp_index;
113 #endif
114  joints_map["ElbowJRotate"] = tmpData;
115 
116  tmpData.min = 0.0;
117  tmpData.max = 0.0;
118  joints_map["arm_link"] = tmpData;
119 
120  joints_map_mutex.unlock();
121 
122 
123 #ifdef GAZEBO
124  // if we're using Gazebo, we want to start with the elbow bent to 120
125  // first we stop the physics
126  ros::ServiceClient gazebo_phys_client = node.serviceClient<std_srvs::Empty>("/gazebo/pause_physics");
127  std_srvs::Empty empty_srv;
128  gazebo_phys_client.waitForExistence();
129  gazebo_phys_client.call(empty_srv);
130 
131  // then we set the ElbowJSwing in the model pose (the model is called arm_and_hand)
132  ros::ServiceClient set_pos_client = node.serviceClient<gazebo_msgs::SetModelConfiguration>(
133  "/gazebo/set_model_configuration");
134  gazebo_msgs::SetModelConfiguration model_srv;
135  model_srv.request.model_name = "shadow_model";
136  model_srv.request.urdf_param_name = "robot_description";
137  model_srv.request.joint_names.push_back("ElbowJSwing");
138  model_srv.request.joint_positions.push_back(2.0);
139 
140  set_pos_client.waitForExistence();
141  set_pos_client.call(model_srv);
142 
143  // sends the correct target to the controller
144  for (int i = 0; i < 500; ++i)
145  {
146  sendupdate("ElbowJSwing", 120.0);
147  sleep(.01);
148  }
149 
150  // and now we restart the physics
151  gazebo_phys_client = node.serviceClient<std_srvs::Empty>("/gazebo/unpause_physics");
152  gazebo_phys_client.waitForExistence();
153  gazebo_phys_client.call(empty_srv);
154 #endif
155  }
156 
157  int16_t VirtualArm::sendupdate(std::string joint_name, double target)
158  {
159  joints_map_mutex.lock();
160 
161  JointsMap::iterator iter = joints_map.find(joint_name);
162 
163 #ifdef GAZEBO
164  std_msgs::Float64 target_msg;
165 #endif
166 
167  // not found
168  if (iter == joints_map.end())
169  {
170  ROS_DEBUG("Joint %s not found.", joint_name.c_str());
171  joints_map_mutex.unlock();
172  return -1;
173  }
174 
175  // joint found
176  JointData tmpData(iter->second);
177  if (target < tmpData.min)
178  {
179  target = tmpData.min;
180  }
181  if (target > tmpData.max)
182  {
183  target = tmpData.max;
184  }
185 
186 #ifdef GAZEBO
187  // gazebo targets are in radians
188  target_msg.data = toRad(target);
189  gazebo_publishers[tmpData.publisher_index].publish(target_msg);
190 #else
191  tmpData.position = target;
192 #endif
193  tmpData.target = target;
194 
195  joints_map[joint_name] = tmpData;
196 
197  joints_map_mutex.unlock();
198  return 0;
199  }
200 
201  JointData VirtualArm::getJointData(std::string joint_name)
202  {
203  joints_map_mutex.lock();
204  JointsMap::iterator iter = joints_map.find(joint_name);
205 
206  // joint found
207  if (iter != joints_map.end())
208  {
209  // return 0s for absent sensors
210  iter->second.temperature = 0.0;
211  iter->second.current = 0.0;
212 #ifndef GAZEBO
213  iter->second.force = 0.0;
214 #endif
215 
216  JointData tmpData = JointData(iter->second);
217  joints_map_mutex.unlock();
218  return tmpData;
219  }
220 
221  ROS_ERROR("Joint %s not found.", joint_name.c_str());
222  JointData noData;
223  joints_map_mutex.unlock();
224  return noData;
225  }
226 
228  {
229  joints_map_mutex.lock();
230  JointsMap tmpMap;
231 
232  for (JointsMap::const_iterator it = joints_map.begin(); it != joints_map.end(); ++it)
233  {
234  JointData tmpData = it->second;
235  tmpData.temperature = 0.0;
236  tmpData.current = 0.0;
237 #ifndef GAZEBO
238  tmpData.force = 0.0;
239 #endif
240  tmpData.jointIndex = 0;
241  tmpData.flags = "";
242 
243  joints_map[it->first] = tmpData;
244  }
245 
246  tmpMap = JointsMap(joints_map);
247  joints_map_mutex.unlock();
248  return tmpMap;
249  }
250 
251  int16_t VirtualArm::setContrl(std::string contrlr_name, JointControllerData ctrlr_data)
252  {
253  ROS_WARN("The setContrl method is not yet implemented");
254  return 0;
255  }
256 
257  JointControllerData VirtualArm::getContrl(std::string contrlr_name)
258  {
259  ROS_WARN("The getContrl method is not yet implemented");
260  JointControllerData no_result;
261  return no_result;
262  }
263 
264  int16_t VirtualArm::setConfig(std::vector<std::string> myConfig)
265  {
266  ROS_WARN("The set config function is not implemented in the virtual arm.");
267  return 0;
268  }
269 
270  void VirtualArm::getConfig(std::string joint_name)
271  {
272  ROS_WARN("The get config function is not implemented in the virtual arm.");
273  }
274 
275  std::vector<DiagnosticData> VirtualArm::getDiagnostics()
276  {
277  joints_map_mutex.lock();
278  std::vector<DiagnosticData> returnVect;
279 
280  for (JointsMap::const_iterator it = joints_map.begin(); it != joints_map.end(); ++it)
281  {
282  DiagnosticData tmpDiag;
283  tmpDiag.joint_name = it->first;
284  tmpDiag.level = 0;
285  tmpDiag.flags = "";
286  tmpDiag.target_sensor_num = 0;
287  tmpDiag.position_sensor_num = 0;
288  tmpDiag.target = it->second.target;
289  tmpDiag.position = it->second.position;
290 
291  returnVect.push_back(tmpDiag);
292  }
293 
294  joints_map_mutex.unlock();
295  return returnVect;
296  }
297 
298 #ifdef GAZEBO
299  void VirtualArm::gazeboCallback(const sensor_msgs::JointStateConstPtr &msg)
300  {
301  joints_map_mutex.lock();
302  // loop on all the names in the joint_states message
303  for (unsigned int index = 0; index < msg->name.size(); ++index)
304  {
305  std::string joint_name = msg->name[index];
306  JointsMap::iterator iter = joints_map.find(joint_name);
307 
308  // not found => can be a joint from the arm / hand
309  if (iter == joints_map.end())
310  {
311  continue;
312  }
313 
314  // joint found
315  JointData tmpData(iter->second);
316 
317  tmpData.position = toDegrees(msg->position[index]);
318  tmpData.force = msg->effort[index];
319 
320  joints_map[joint_name] = tmpData;
321  }
322  joints_map_mutex.unlock();
323  }
324 
325 #endif
326 } // namespace shadowrobot
msg
virtual int16_t sendupdate(std::string joint_name, double target)
virtual JointData getJointData(std::string joint_name)
virtual std::vector< DiagnosticData > getDiagnostics()
std::string flags
a string containing flags: FORCE, TEMPERATURE, ... indicating the different cutouts / warning sent by...
std::string joint_name
the name of the joint
double toRad(double deg)
Definition: virtual_arm.h:107
bool call(MReq &req, MRes &res)
std::map< std::string, JointData > JointsMap
int target_sensor_num
the channel number of the target sensor
int position_sensor_num
the channel number of the position sensor
#define ROS_WARN(...)
virtual JointsMap getAllJointsData()
virtual int16_t setConfig(std::vector< std::string > myConfig)
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
#define ROS_INFO(...)
JointsMap joints_map
A mapping between the joint names and the information regarding those joints.
This is a parent class for the different types of Shadowhand we can have. It makes it possible to swa...
virtual int16_t setContrl(std::string contrlr_name, JointControllerData ctrlr_data)
The virtual arm can be used as a simulator. It modelizes the Shadow Robot muscle arm.
virtual void getConfig(std::string joint_name)
int16_t level
the level of alert: 0 = OK, 1 = WARNING, 2 = ERROR
double target
the actual value of the target
#define ROS_ERROR(...)
double position
the actual value of the position
virtual JointControllerData getContrl(std::string ctrlr_name)
#define ROS_DEBUG(...)
double toDegrees(double rad)
Definition: virtual_arm.h:117


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