urdf.py
Go to the documentation of this file.
3 
4 # Add a 'namespace' for names so that things don't conflict between URDF and SDF?
5 # A type registry? How to scope that? Just make a 'global' type pointer?
6 # Or just qualify names? urdf.geometric, sdf.geometric
7 
8 xmlr.start_namespace('urdf')
9 
10 xmlr.add_type('element_link', xmlr.SimpleElementType('link', str))
11 xmlr.add_type('element_xyz', xmlr.SimpleElementType('xyz', 'vector3'))
12 
13 verbose = True
14 
15 class Pose(xmlr.Object):
16  def __init__(self, xyz=None, rpy=None):
17  self.xyz = xyz
18  self.rpy = rpy
19 
20  def check_valid(self):
21  assert self.xyz is not None or self.rpy is not None
22 
23  # Aliases for backwards compatibility
24  @property
25  def rotation(self): return self.rpy
26  @rotation.setter
27  def rotation(self, value): self.rpy = value
28  @property
29  def position(self): return self.xyz
30  @position.setter
31  def position(self, value): self.xyz = value
32 
33 xmlr.reflect(Pose, params = [
34  xmlr.Attribute('xyz', 'vector3', False),
35  xmlr.Attribute('rpy', 'vector3', False)
36  ])
37 
38 
39 # Common stuff
40 name_attribute = xmlr.Attribute('name', str)
41 origin_element = xmlr.Element('origin', Pose, False)
42 
43 class Color(xmlr.Object):
44  def __init__(self, *args):
45  # What about named colors?
46  count = len(args)
47  if count == 4 or count == 3:
48  self.rgba = args
49  elif count == 1:
50  self.rgba = args[0]
51  elif count == 0:
52  self.rgba = None
53  if self.rgba is not None:
54  if len(self.rgba) == 3:
55  self.rgba += [1.]
56  if len(self.rgba) != 4:
57  raise Exception('Invalid color argument count')
58 
59 xmlr.reflect(Color, params = [
60  xmlr.Attribute('rgba', 'vector4')
61  ])
62 
63 
64 class JointDynamics(xmlr.Object):
65  def __init__(self, damping=None, friction=None):
66  self.damping = damping
67  self.friction = friction
68 
69 xmlr.reflect(JointDynamics, params = [
70  xmlr.Attribute('damping', float, False),
71  xmlr.Attribute('friction', float, False)
72  ])
73 
74 
75 class Box(xmlr.Object):
76  def __init__(self, size = None):
77  self.size = size
78 
79 xmlr.reflect(Box, params = [
80  xmlr.Attribute('size', 'vector3')
81  ])
82 
83 
84 class Cylinder(xmlr.Object):
85  def __init__(self, radius = 0.0, length = 0.0):
86  self.radius = radius
87  self.length = length
88 
89 xmlr.reflect(Cylinder, params = [
90  xmlr.Attribute('radius', float),
91  xmlr.Attribute('length', float)
92  ])
93 
94 
95 class Sphere(xmlr.Object):
96  def __init__(self, radius=0.0):
97  self.radius = radius
98 
99 xmlr.reflect(Sphere, params = [
100  xmlr.Attribute('radius', float)
101  ])
102 
103 
104 class Mesh(xmlr.Object):
105  def __init__(self, filename = None, scale = None):
106  self.filename = filename
107  self.scale = scale
108 
109 xmlr.reflect(Mesh, params = [
110  xmlr.Attribute('filename', str),
111  xmlr.Attribute('scale', 'vector3', required=False)
112  ])
113 
114 
115 class GeometricType(xmlr.ValueType):
116  def __init__(self):
117  self.factory = xmlr.FactoryType('geometric', {
118  'box': Box,
119  'cylinder': Cylinder,
120  'sphere': Sphere,
121  'mesh': Mesh
122  })
123 
124  def from_xml(self, node):
125  children = xml_children(node)
126  assert len(children) == 1, 'One element only for geometric'
127  return self.factory.from_xml(children[0])
128 
129  def write_xml(self, node, obj):
130  name = self.factory.get_name(obj)
131  child = node_add(node, name)
132  obj.write_xml(child)
133 
134 xmlr.add_type('geometric', GeometricType())
135 
136 class Collision(xmlr.Object):
137  def __init__(self, geometry = None, origin = None):
138  self.geometry = geometry
139  self.origin = origin
140 
141 xmlr.reflect(Collision, params = [
142  origin_element,
143  xmlr.Element('geometry', 'geometric')
144  ])
145 
146 
147 class Texture(xmlr.Object):
148  def __init__(self, filename = None):
149  self.filename = filename
150 
151 xmlr.reflect(Texture, params = [
152  xmlr.Attribute('filename', str)
153  ])
154 
155 
156 class Material(xmlr.Object):
157  def __init__(self, name=None, color=None, texture=None):
158  self.name = name
159  self.color = color
160  self.texture = texture
161 
162  def check_valid(self):
163  if self.color is None and self.texture is None:
164  xmlr.on_error("Material has neither a color nor texture")
165 
166 xmlr.reflect(Material, params = [
167  name_attribute,
168  xmlr.Element('color', Color, False),
169  xmlr.Element('texture', Texture, False)
170  ])
171 
172 
173 class Visual(xmlr.Object):
174  def __init__(self, geometry = None, material = None, origin = None):
175  self.geometry = geometry
176  self.material = material
177  self.origin = origin
178 
179 xmlr.reflect(Visual, params = [
180  origin_element,
181  xmlr.Element('geometry', 'geometric'),
182  xmlr.Element('material', Material, False)
183  ])
184 
185 
186 class Inertia(xmlr.Object):
187  KEYS = ['ixx', 'ixy', 'ixz', 'iyy', 'iyz', 'izz']
188 
189  def __init__(self, ixx=0.0, ixy=0.0, ixz=0.0, iyy=0.0, iyz=0.0, izz=0.0):
190  self.ixx = ixx
191  self.ixy = ixy
192  self.ixz = ixz
193  self.iyy = iyy
194  self.iyz = iyz
195  self.izz = izz
196 
197  def to_matrix(self):
198  return [
199  [self.ixx, self.ixy, self.ixz],
200  [self.ixy, self.iyy, self.iyz],
201  [self.ixz, self.iyz, self.izz]]
202 
203 xmlr.reflect(Inertia, params = [xmlr.Attribute(key, float) for key in Inertia.KEYS])
204 
205 
206 class Inertial(xmlr.Object):
207  def __init__(self, mass = 0.0, inertia = None, origin=None):
208  self.mass = mass
209  self.inertia = inertia
210  self.origin = origin
211 
212 xmlr.reflect(Inertial, params = [
213  origin_element,
214  xmlr.Element('mass', 'element_value'),
215  xmlr.Element('inertia', Inertia, False)
216  ])
217 
218 
219 
220 #FIXME: we are missing the reference position here.
221 class JointCalibration(xmlr.Object):
222  def __init__(self, rising=None, falling=None):
223  self.rising = rising
224  self.falling = falling
225 
226 xmlr.reflect(JointCalibration, params = [
227  xmlr.Attribute('rising', float, False),
228  xmlr.Attribute('falling', float, False)
229  ])
230 
231 class JointLimit(xmlr.Object):
232  def __init__(self, effort=None, velocity=None, lower=None, upper=None):
233  self.effort = effort
234  self.velocity = velocity
235  self.lower = lower
236  self.upper = upper
237 
238 xmlr.reflect(JointLimit, params = [
239  xmlr.Attribute('effort', float),
240  xmlr.Attribute('lower', float, False, 0),
241  xmlr.Attribute('upper', float, False, 0),
242  xmlr.Attribute('velocity', float)
243  ])
244 
245 #FIXME: we are missing __str__ here.
246 class JointMimic(xmlr.Object):
247  def __init__(self, joint_name=None, multiplier=None, offset=None):
248  self.joint = joint_name
249  self.multiplier = multiplier
250  self.offset = offset
251 
252 xmlr.reflect(JointMimic, params = [
253  xmlr.Attribute('joint', str),
254  xmlr.Attribute('multiplier', float, False),
255  xmlr.Attribute('offset', float, False)
256  ])
257 
258 class SafetyController(xmlr.Object):
259  def __init__(self, velocity=None, position=None, lower=None, upper=None):
260  self.k_velocity = velocity
261  self.k_position = position
262  self.soft_lower_limit = lower
263  self.soft_upper_limit = upper
264 
265 xmlr.reflect(SafetyController, params = [
266  xmlr.Attribute('k_velocity', float),
267  xmlr.Attribute('k_position', float, False, 0),
268  xmlr.Attribute('soft_lower_limit', float, False, 0),
269  xmlr.Attribute('soft_upper_limit', float, False, 0)
270  ])
271 
272 class Joint(xmlr.Object):
273  TYPES = ['unknown', 'revolute', 'continuous', 'prismatic', 'floating', 'planar', 'fixed']
274 
275  def __init__(self, name=None, parent=None, child=None, joint_type=None,
276  axis=None, origin=None,
277  limit=None, dynamics=None, safety_controller=None, calibration=None,
278  mimic=None):
279  self.name = name
280  self.parent = parent
281  self.child = child
282  self.type = joint_type
283  self.axis = axis
284  self.origin = origin
285  self.limit = limit
286  self.dynamics = dynamics
287  self.safety_controller = safety_controller
288  self.calibration = calibration
289  self.mimic = mimic
290 
291  def check_valid(self):
292  assert self.type in self.TYPES, "Invalid joint type: {}".format(self.type)
293 
294  # Aliases
295  @property
296  def joint_type(self): return self.type
297  @joint_type.setter
298  def joint_type(self, value): self.type = value
299 
300 xmlr.reflect(Joint, params = [
301  name_attribute,
302  xmlr.Attribute('type', str),
303  origin_element,
304  xmlr.Element('axis', 'element_xyz', False),
305  xmlr.Element('parent', 'element_link'),
306  xmlr.Element('child', 'element_link'),
307  xmlr.Element('limit', JointLimit, False),
308  xmlr.Element('dynamics', JointDynamics, False),
309  xmlr.Element('safety_controller', SafetyController, False),
310  xmlr.Element('calibration', JointCalibration, False),
311  xmlr.Element('mimic', JointMimic, False)
312  ])
313 
314 
315 class Link(xmlr.Object):
316  def __init__(self, name=None, visual=None, inertial=None, collision=None, origin = None):
317  self.name = name
318  self.visual = visual
319  self.inertial = inertial
320  self.collision = collision
321  self.origin = origin
322 
323 xmlr.reflect(Link, params = [
324  name_attribute,
325  origin_element,
326  xmlr.Element('inertial', Inertial, False),
327  xmlr.Element('visual', Visual, False),
328  xmlr.Element('collision', Collision, False)
329  ])
330 
331 
332 class Actuator(xmlr.Object):
333  def __init__(self, name = None, hardwareInterface = None, mechanicalReduction = 1):
334  self.name = name
335  self.hardwareInterface = None
336  self.mechanicalReduction = None
337 
338 xmlr.reflect(Actuator, tag = 'actuator', params = [
339  name_attribute,
340  xmlr.Element('hardwareInterface', str),
341  xmlr.Element('mechanicalReduction', float, required = False)
342  ])
343 
344 class Transmission(xmlr.Object):
345  def __init__(self, name = None, joint = None, actuator = None):
346  self.name = name
347  self.joint = joint
348  self.actuator = actuator
349 
350 xmlr.reflect(Transmission, tag = 'new_transmission', params = [
351  name_attribute,
352  xmlr.Attribute('type', str),
353  xmlr.Element('joint', 'element_name'),
354  xmlr.Element('actuator', Actuator),
355  ])
356 
357 class PR2Compensator(xmlr.Object):
358  def __init__(self, k_belt=4000.0, kd_motor=10.0, lambda_combined=0.0, lambda_joint=60.0, lambda_motor=60.0, mass_motor=0.05):
359  self.k_belt = k_belt
360  self.kd_motor = kd_motor
361  self.lambda_combined = lambda_combined
362  self.lambda_joint = lambda_joint
363  self.lambda_motor = lambda_motor
364  self.mass_motor = mass_motor
365 
366 xmlr.reflect(PR2Compensator, tag = 'compensator', params = [
367  xmlr.Attribute('k_belt', float),
368  xmlr.Attribute('kd_motor', float),
369  xmlr.Attribute('lambda_combined', float),
370  xmlr.Attribute('lambda_joint', float),
371  xmlr.Attribute('lambda_motor', float),
372  xmlr.Attribute('mass_motor', float)
373  ])
374 
375 class PR2SimulatedActuatedJoint(xmlr.Object):
376  def __init__(self, name = None, simulated_reduction = 3000, passive_actuated_joint = None):
377  self.name = name
378  self.simulated_reduction = simulated_reduction
379  self.passive_actuated_joint = passive_actuated_joint
380 
381 xmlr.reflect(PR2SimulatedActuatedJoint, tag = 'simulated_actuated_joint', params = [
382  name_attribute,
383  xmlr.Attribute('simulated_reduction', float),
384  xmlr.Attribute('passive_actuated_joint', str, False)
385  ])
386 
387 class PR2Transmission(xmlr.Object):
388  def __init__(self, name = None, joint = None, actuator = None, mechanicalReduction = None, compensator = None, simulated_actuated_joint = None):
389  self.name = name
390  self.joint = joint
391  self.actuator = actuator
392  self.mechanicalReduction = mechanicalReduction
393  self.compensator = compensator
394  self.simulated_actuated_joint = simulated_actuated_joint
395 
396 xmlr.reflect(PR2Transmission, tag = 'pr2_transmission', params = [
397  name_attribute,
398  xmlr.Attribute('type', str),
399  xmlr.Element('joint', 'element_name'),
400  xmlr.Element('actuator', 'element_name'),
401  xmlr.Element('mechanicalReduction', float),
402  xmlr.Element('compensator', PR2Compensator, False),
403  xmlr.Element('simulated_actuated_joint', PR2SimulatedActuatedJoint, False)
404  ])
405 
406 class PR2Actuator(xmlr.Object):
407  def __init__(self, name = None, mechanicalReduction = 1):
408  self.name = name
409  self.mechanicalReduction = mechanicalReduction
410 
411 xmlr.reflect(PR2Actuator, tag = 'pr2_actuator', params = [
412  name_attribute,
413  xmlr.Attribute('mechanicalReduction', float)
414  ])
415 
416 class PR2WristTransmission(xmlr.Object):
417  def __init__(self, name = None, type = None, rightActuator = None, leftActuator = None, flexJoint = None, rollJoint = None):
418  self.name = name
419  self.type = type
420  self.rightActuator = rightActuator
421  self.leftActuator = leftActuator
422  self.flexJoint = flexJoint
423  self.rollJoint = rollJoint
424 
425 xmlr.reflect(PR2WristTransmission, tag = 'pr2_wrist_transmission', params = [
426  name_attribute,
427  xmlr.Attribute('type', str),
428  xmlr.Element('rightActuator', PR2Actuator),
429  xmlr.Element('leftActuator', PR2Actuator),
430  xmlr.Element('flexJoint', PR2Actuator),
431  xmlr.Element('rollJoint', PR2Actuator)
432  ])
433 
434 
435 class PR2GapJoint(xmlr.Object):
436  def __init__(self, L0=0.0, a=0.0, b=0.0, gear_ratio=40.0, h=0.0, mechanical_reduction=1.0, name=None, phi0=0.5, r=0.0, screw_reduction=0.0, t0=0.0, theta0=0.0):
437  self.L0 = L0
438  self.a = a
439  self.b = b
440  self.gear_ratio = gear_ratio
441  self.h = h
442  self.mechanical_reduction = mechanical_reduction
443  self.name = name
444  self.phi0 = phi0
445  self.r = r
446  self.screw_reduction = screw_reduction
447  self.t0 = t0
448  self.theta0 = theta0
449 
450 xmlr.reflect(PR2GapJoint, tag = 'pr2_gap_joint', params = [
451  xmlr.Attribute('L0', float),
452  xmlr.Attribute('a', float),
453  xmlr.Attribute('b', float),
454  xmlr.Attribute('gear_ratio', float),
455  xmlr.Attribute('h', float),
456  xmlr.Attribute('mechanical_reduction', float),
457  xmlr.Attribute('name', str),
458  xmlr.Attribute('phi0', float),
459  xmlr.Attribute('r', float),
460  xmlr.Attribute('screw_reduction', float),
461  xmlr.Attribute('t0', float),
462  xmlr.Attribute('theta0', float)
463  ])
464 
465 class PR2GripperTransmission(xmlr.Object):
466  def __init__(self, name = None, type = None, actuator = None, gap_joint = None, use_simulated_gripper_joint = None, passive_joint = [], simulated_actuated_joint = None):
467  self.aggregate_init()
468  self.name = name
469  self.type = type
470  self.actuator = actuator
471  self.gap_joint = gap_joint
472  self.use_simulated_gripper_joint = use_simulated_gripper_joint
473  self.passive_joint = passive_joint
474  self.simulated_actuated_joint = simulated_actuated_joint
475 
476 xmlr.reflect(PR2GripperTransmission, tag = 'pr2_gripper_transmission', params = [
477  name_attribute,
478  xmlr.Attribute('type', str),
479  xmlr.Element('actuator', 'element_name'),
480  xmlr.Element('gap_joint', PR2GapJoint),
481  xmlr.Element('use_simulated_gripper_joint', 'element_name'),
482  xmlr.AggregateElement('passive_joint', 'element_name', 'passive_joint'),
483  xmlr.Element('simulated_actuated_joint', PR2SimulatedActuatedJoint),
484  ])
485 
486 #xmlr.add_type('transmission', xmlr.DuckTypedFactory('transmission', [Transmission, PR2WristTransmission, PR2GripperTransmission]))
487 xmlr.add_type('transmission', xmlr.DuckTypedFactory('transmission', [Transmission, PR2Transmission, PR2WristTransmission, PR2GripperTransmission]))
488 
489 
490 class Robot(xmlr.Object):
491  def __init__(self, name = None):
492  self.aggregate_init()
493 
494  self.name = name
495  self.joints = []
496  self.links = []
497  self.materials = []
498  self.gazebos = []
499  self.transmissions = []
500 
501  self.joint_map = {}
502  self.link_map = {}
503 
504  self.parent_map = {}
505  self.child_map = {}
506 
507  def add_aggregate(self, typeName, elem):
508  xmlr.Object.add_aggregate(self, typeName, elem)
509 
510  if typeName == 'joint':
511  joint = elem
512  self.joint_map[joint.name] = joint
513  self.parent_map[ joint.child ] = (joint.name, joint.parent)
514  if joint.parent in self.child_map:
515  self.child_map[joint.parent].append( (joint.name, joint.child) )
516  else:
517  self.child_map[joint.parent] = [ (joint.name, joint.child) ]
518  elif typeName == 'link':
519  link = elem
520  self.link_map[link.name] = link
521 
522  def add_link(self, link):
523  self.add_aggregate('link', link)
524 
525  def add_joint(self, joint):
526  self.add_aggregate('joint', joint)
527 
528  def get_chain(self, root, tip, joints=True, links=True, fixed=True):
529  chain = []
530  if links:
531  chain.append(tip)
532  link = tip
533  while link != root:
534  (joint, parent) = self.parent_map[link]
535  if joints:
536  if fixed or self.joint_map[joint].joint_type != 'fixed':
537  chain.append(joint)
538  if links:
539  chain.append(parent)
540  link = parent
541  chain.reverse()
542  return chain
543 
544  def get_root(self):
545  root = None
546  for link in self.link_map:
547  if link not in self.parent_map:
548  assert root is None, "Multiple roots detected, invalid URDF."
549  root = link
550  assert root is not None, "No roots detected, invalid URDF."
551  return root
552 
553  @classmethod
554  def from_parameter_server(cls, key = 'robot_description'):
555  """
556  Retrieve the robot model on the parameter server
557  and parse it to create a URDF robot structure.
558 
559  Warning: this requires roscore to be running.
560  """
561  # Could move this into xml_reflection
562  import rospy
563  return cls.from_xml_string(rospy.get_param(key))
564 
565 xmlr.reflect(Robot, tag = 'robot', params = [
566 # name_attribute,
567  xmlr.Attribute('name', str, False), # Is 'name' a required attribute?
568  xmlr.AggregateElement('link', Link),
569  xmlr.AggregateElement('joint', Joint),
570  xmlr.AggregateElement('gazebo', xmlr.RawType()),
571  xmlr.AggregateElement('transmission', 'transmission'),
572  xmlr.AggregateElement('material', Material)
573  ])
574 
575 # Make an alias
576 URDF = Robot
577 
578 xmlr.end_namespace()
def __init__(self, name=None, type=None, rightActuator=None, leftActuator=None, flexJoint=None, rollJoint=None)
Definition: urdf.py:417
def __init__(self, name=None, type=None, actuator=None, gap_joint=None, use_simulated_gripper_joint=None, passive_joint=[], simulated_actuated_joint=None)
Definition: urdf.py:466
def __init__(self, name=None, simulated_reduction=3000, passive_actuated_joint=None)
Definition: urdf.py:376
def __init__(self, name=None, mechanicalReduction=1)
Definition: urdf.py:407
def __init__(self, L0=0.0, a=0.0, b=0.0, gear_ratio=40.0, h=0.0, mechanical_reduction=1.0, name=None, phi0=0.5, r=0.0, screw_reduction=0.0, t0=0.0, theta0=0.0)
Definition: urdf.py:436
def __init__(self, k_belt=4000.0, kd_motor=10.0, lambda_combined=0.0, lambda_joint=60.0, lambda_motor=60.0, mass_motor=0.05)
Definition: urdf.py:358


pr2_calibration_launch
Author(s): Vijay Pradeep
autogenerated on Tue Jun 1 2021 02:50:59