hand_finder.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright 2014 Shadow Robot Company Ltd.
4 #
5 # This program is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 2 of the License, or (at your option)
8 # any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 # more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program. If not, see <http://www.gnu.org/licenses/>.
17 #
18 import rospy
19 import rospkg
20 from urdf_parser_py.urdf import URDF
21 
22 
23 class HandControllerTuning(object):
24  def __init__(self, mapping):
25  """
26 
27  """
28  ros_pack = rospkg.RosPack()
29  ethercat_path = ros_pack.get_path('sr_ethercat_hand_config')
31  self.host_control = {}
32  self.motor_control = {}
33  for hand in mapping:
34  self.friction_compensation[mapping[hand]] = \
35  ethercat_path + '/controls/' + 'friction_compensation.yaml'
36  host_path = ethercat_path + '/controls/host/' + mapping[hand] + '/'
37  self.host_control[mapping[hand]] = \
38  [host_path + 'sr_edc_calibration_controllers.yaml',
39  host_path + 'sr_edc_joint_velocity_controllers_PWM.yaml',
40  host_path + 'sr_edc_effort_controllers_PWM.yaml',
41  host_path + 'sr_edc_joint_velocity_controllers.yaml',
42  host_path + 'sr_edc_effort_controllers.yaml',
43  host_path + 'sr_edc_mixed_position_velocity_'
44  'joint_controllers_PWM.yaml',
45  host_path + 'sr_edc_joint_position_controllers_PWM.yaml',
46  host_path + 'sr_edc_mixed_position_velocity_'
47  'joint_controllers.yaml',
48  host_path + 'sr_edc_joint_position_controllers.yaml']
49 
50  self.motor_control[mapping[hand]] = \
51  ethercat_path + '/controls/motors/' +\
52  mapping[hand] + '/motor_board_effort_controllers.yaml'
53 
54 
55 class HandCalibration(object):
56  def __init__(self, mapping):
57  """
58 
59  """
60  ros_pack = rospkg.RosPack()
61  ethercat_path = ros_pack.get_path('sr_ethercat_hand_config')
62  self.calibration_path = {}
63  for hand in mapping:
64  self.calibration_path[mapping[hand]] = \
65  ethercat_path + '/calibrations/' + mapping[hand] + '/' \
66  + "calibration.yaml"
67 
68 
69 class HandConfig(object):
70 
71  def __init__(self, mapping, joint_prefix):
72  """
73 
74  """
75  # handle possibly empty mapping
76  self.mapping = {}
77  for serial_id in mapping:
78  if mapping[serial_id] == '':
79  self.mapping[serial_id] = str(serial_id)
80  else:
81  self.mapping[serial_id] = mapping[serial_id]
82  self.joint_prefix = joint_prefix
83 
84 
85 class HandJoints(object):
86 
87  @classmethod
89  joints = ['FFJ1', 'FFJ2', 'FFJ3', 'FFJ4', 'MFJ1', 'MFJ2', 'MFJ3',
90  'MFJ4', 'RFJ1', 'RFJ2', 'RFJ3', 'RFJ4', 'LFJ1', 'LFJ2',
91  'LFJ3', 'LFJ4', 'LFJ5', 'THJ1', 'THJ2', 'THJ3', 'THJ4',
92  'THJ5', 'WRJ1', 'WRJ2']
93  return joints
94 
95  def __init__(self, mapping, joint_prefix):
96  """
97 
98  """
99  self.joints = {}
100  hand_joints = []
101  joints = self.get_default_joints()
102 
103  if rospy.has_param('robot_description'):
104  robot_description = rospy.get_param('robot_description')
105 
106  # concatenate all the joints with prefixes
107  for hand in mapping:
108  if hand in joint_prefix:
109  for joint in joints:
110  hand_joints.append(joint_prefix[hand] + joint)
111  else:
112  rospy.logwarn("Cannot find serial " + hand +
113  "in joint_prefix parameters")
114 
115  # add the prefixed joints to each hand but remove fixed joints
116  hand_urdf = URDF.from_xml_string(robot_description)
117  for hand in mapping:
118  joints_tmp = []
119  self.joints[mapping[hand]] = []
120  for joint in hand_urdf.joints:
121  if joint.type != 'fixed':
122  prefix = joint.name[:3]
123  # is there an empty prefix ?
124  if "" in joint_prefix.values():
125  joints_tmp.append(joint.name)
126  elif prefix not in joint_prefix.values():
127  rospy.logdebug("joint " + joint.name + " has invalid "
128  "prefix:" + prefix)
129  elif prefix == joint_prefix[hand]:
130  joints_tmp.append(joint.name)
131  for joint_unordered in hand_joints:
132  if joint_unordered in joints_tmp:
133  self.joints[mapping[hand]].append(joint_unordered)
134 
135  else:
136  rospy.logwarn("No robot_description found on parameter server."
137  "Joint names are loaded for 5 finger hand")
138 
139  # concatenate all the joints with prefixes
140  for hand in mapping:
141  hand_joints = []
142  if hand in joint_prefix:
143  for joint in joints:
144  hand_joints.append(joint_prefix[hand] + joint)
145  else:
146  rospy.logwarn("Cannot find serial " + hand +
147  "in joint_prefix parameters")
148  self.joints[mapping[hand]] = hand_joints
149 
150 
151 class HandFinder(object):
152  """
153  The HandFinder is a utility library for detecting Shadow Hands running on
154  the system. The idea is to make it easier to write generic code,
155  using this library to handle prefixes, joint prefixes etc...
156  """
157 
158  def __init__(self):
159  """
160  Parses the parameter server to extract the necessary information.
161  """
162 
163  hand_parameters = {}
164  if rospy.has_param("/hand"):
165  self._hand_e = True
166  hand_parameters = rospy.get_param("/hand")
167  else:
168  self._hand_e = False
169  hand_parameters = {'joint_prefix': {}, 'mapping': {}}
170 
171  if rospy.has_param("/fh_hand"):
172  self._hand_h = True
173  self._hand_h_parameters = rospy.get_param("/fh_hand")
174  else:
175  self._hand_h = False
176  self._hand_h_parameters = {}
177 
178  if not (self._hand_e or self._hand_h):
179  rospy.logerr("No hand is detected")
180 
181  self.hand_config = HandConfig(hand_parameters["mapping"],
182  hand_parameters["joint_prefix"])
183  self.hand_joints = HandJoints(self.hand_config.mapping, self.hand_config.joint_prefix).joints
184  self.calibration_path = HandCalibration(self.hand_config.mapping).calibration_path
185  self.hand_control_tuning = HandControllerTuning(self.hand_config.mapping)
186 
188  if not self._hand_e:
189  rospy.logerr("No Hand E present - can't get calibration path")
190  return self.calibration_path
191 
192  def get_hand_joints(self):
193  # TODO(@anyone): update HandJoints to work with Hand H. Didn't seem necessary yet, so left for now - dg
194  if not self._hand_e:
195  rospy.logerr("No Hand E present - can't get hand joints")
196  return self.hand_joints
197 
199  if not self._hand_e:
200  rospy.logerr("No Hand E present - can't get hand parameters")
201  return self.hand_config
202 
204  if not self._hand_e:
205  rospy.logerr("No Hand E present - can't get hand control_tuning")
206  return self.hand_control_tuning
207 
208  def hand_e_available(self):
209  return self._hand_e
210 
211  def hand_h_available(self):
212  return self._hand_h
213 
214  def get_hand_e(self, number=0, serial=None):
215  hand_parameters = self.get_hand_parameters()
216  if serial is None:
217  serial = sorted(hand_parameters.mapping.keys())[number]
218  name = "right_hand" if hand_parameters.mapping[serial] == "rh" else "left_hand"
219  prefix = hand_parameters.joint_prefix[serial]
220  return name, prefix, serial
221 
222  def get_hand_h(self, number=0, name=None):
223  if name is None:
224  name = sorted(self._hand_h_parameters.keys())[number]
225  prefix = self._hand_h_parameters[name]['controller_prefix']
226  serial = self._hand_h_parameters[name]['palm']['serial_number']
227  return "hand_h", prefix, serial
228  # TODO(@anyone): replace "hand_h" with name once moveit config is auto-generated with correct movegroup name
229 
230  def get_available_prefix(self, number=0, serial=None, name=None):
231  if self._hand_e:
232  hand_parameters = self.get_hand_parameters()
233  if serial is None:
234  serial = sorted(hand_parameters.mapping.keys())[number]
235  return hand_parameters.joint_prefix[serial]
236  elif self._hand_h:
237  if name is None:
238  name = sorted(self._hand_h_parameters.keys())[number]
239  return self._hand_h_parameters[name]['controller_prefix']
def get_available_prefix(self, number=0, serial=None, name=None)
Definition: hand_finder.py:230


sr_utilities
Author(s): Ugo Cupcic
autogenerated on Tue Oct 13 2020 03:55:49