Skip to content

Commit a3258ee

Browse files
k-okadasloretz
authored andcommitted
update backward compatibility on visual and collisions (#47)
* add test to build robot model from python urdf classes * add more tests on python urdf build * update backward compatibility Link(visual=...) does not set <visual> on <link> since 0.4.0, breaks backward compatibility * Robot accepts version kwarg Signed-off-by: Shane Loretz <sloretz@osrfoundation.org> Co-authored-by: Shane Loretz <sloretz@osrfoundation.org>
1 parent 9c8ab87 commit a3258ee

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed

src/urdf_parser_py/urdf.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,12 @@ def __init__(self, name=None, visual=None, inertial=None, collision=None,
355355
self.aggregate_init()
356356
self.name = name
357357
self.visuals = []
358+
if visual:
359+
self.visual = visual
358360
self.inertial = inertial
359361
self.collisions = []
362+
if collision:
363+
self.collision = collision
360364
self.origin = origin
361365

362366
def __get_visual(self):
@@ -370,6 +374,8 @@ def __set_visual(self, visual):
370374
self.visuals[0] = visual
371375
else:
372376
self.visuals.append(visual)
377+
if visual:
378+
self.add_aggregate('visual', visual)
373379

374380
def __get_collision(self):
375381
"""Return the first collision or None."""
@@ -382,6 +388,8 @@ def __set_collision(self, collision):
382388
self.collisions[0] = collision
383389
else:
384390
self.collisions.append(collision)
391+
if collision:
392+
self.add_aggregate('collision', collision)
385393

386394
# Properties for backwards compatibility
387395
visual = property(__get_visual, __set_visual)

test/test_urdf.py

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ def parse_and_compare(self, orig):
3131
rewritten = minidom.parseString(robot.to_xml_string())
3232
self.assertTrue(xml_matches(xml, rewritten))
3333

34+
def xml_and_compare(self, robot, xml):
35+
robot_xml_string = robot.to_xml_string()
36+
robot_xml = minidom.parseString(robot_xml_string)
37+
orig_xml = minidom.parseString(xml)
38+
self.assertTrue(xml_matches(robot_xml, orig_xml))
39+
3440
def test_new_transmission(self):
3541
xml = '''<?xml version="1.0"?>
3642
<robot name="test" version="1.0">
@@ -46,6 +52,18 @@ def test_new_transmission(self):
4652
</robot>'''
4753
self.parse_and_compare(xml)
4854

55+
robot = urdf.Robot(name='test', version='1.0')
56+
trans = urdf.Transmission(name='simple_trans')
57+
trans.type = 'transmission_interface/SimpleTransmission'
58+
joint = urdf.TransmissionJoint(name='foo_joint')
59+
joint.add_aggregate('hardwareInterface', 'EffortJointInterface')
60+
trans.add_aggregate('joint', joint)
61+
actuator = urdf.Actuator(name='foo_motor')
62+
actuator.mechanicalReduction = 50.0
63+
trans.add_aggregate('actuator', actuator)
64+
robot.add_aggregate('transmission', trans)
65+
self.xml_and_compare(robot, xml)
66+
4967
def test_new_transmission_multiple_joints(self):
5068
xml = '''<?xml version="1.0"?>
5169
<robot name="test" version="1.0">
@@ -65,6 +83,22 @@ def test_new_transmission_multiple_joints(self):
6583
</robot>'''
6684
self.parse_and_compare(xml)
6785

86+
robot = urdf.Robot(name='test', version='1.0')
87+
trans = urdf.Transmission(name='simple_trans')
88+
trans.type = 'transmission_interface/SimpleTransmission'
89+
joint = urdf.TransmissionJoint(name='foo_joint')
90+
joint.add_aggregate('hardwareInterface', 'EffortJointInterface')
91+
trans.add_aggregate('joint', joint)
92+
joint = urdf.TransmissionJoint(name='bar_joint')
93+
joint.add_aggregate('hardwareInterface', 'EffortJointInterface')
94+
joint.add_aggregate('hardwareInterface', 'EffortJointInterface')
95+
trans.add_aggregate('joint', joint)
96+
actuator = urdf.Actuator(name='foo_motor')
97+
actuator.mechanicalReduction = 50.0
98+
trans.add_aggregate('actuator', actuator)
99+
robot.add_aggregate('transmission', trans)
100+
self.xml_and_compare(robot, xml)
101+
68102
def test_new_transmission_multiple_actuators(self):
69103
xml = '''<?xml version="1.0"?>
70104
<robot name="test" version="1.0">
@@ -81,6 +115,20 @@ def test_new_transmission_multiple_actuators(self):
81115
</robot>'''
82116
self.parse_and_compare(xml)
83117

118+
robot = urdf.Robot(name='test', version='1.0')
119+
trans = urdf.Transmission(name='simple_trans')
120+
trans.type = 'transmission_interface/SimpleTransmission'
121+
joint = urdf.TransmissionJoint(name='foo_joint')
122+
joint.add_aggregate('hardwareInterface', 'EffortJointInterface')
123+
trans.add_aggregate('joint', joint)
124+
actuator = urdf.Actuator(name='foo_motor')
125+
actuator.mechanicalReduction = 50.0
126+
trans.add_aggregate('actuator', actuator)
127+
actuator = urdf.Actuator(name='bar_motor')
128+
trans.add_aggregate('actuator', actuator)
129+
robot.add_aggregate('transmission', trans)
130+
self.xml_and_compare(robot, xml)
131+
84132
def test_new_transmission_missing_joint(self):
85133
xml = '''<?xml version="1.0"?>
86134
<robot name="test" version="1.0">
@@ -113,6 +161,11 @@ def test_old_transmission(self):
113161
</robot>'''
114162
self.parse_and_compare(xml)
115163

164+
robot = urdf.Robot(name='test', version='1.0')
165+
trans = urdf.PR2Transmission(name='PR2_trans', joint='foo_joint', actuator='foo_motor', type='SimpleTransmission', mechanicalReduction=1.0)
166+
robot.add_aggregate('transmission', trans)
167+
self.xml_and_compare(robot, xml)
168+
116169
def test_link_material_missing_color_and_texture(self):
117170
xml = '''<?xml version="1.0"?>
118171
<robot name="test" version="1.0">
@@ -127,6 +180,20 @@ def test_link_material_missing_color_and_texture(self):
127180
</robot>'''
128181
self.parse_and_compare(xml)
129182

183+
robot = urdf.Robot(name='test', version='1.0')
184+
link = urdf.Link(name='link',
185+
visual=urdf.Visual(geometry=urdf.Cylinder(length=1, radius=1),
186+
material=urdf.Material(name='mat')))
187+
robot.add_link(link)
188+
self.xml_and_compare(robot, xml)
189+
190+
robot = urdf.Robot(name='test', version='1.0')
191+
link = urdf.Link(name='link')
192+
link.visual = urdf.Visual(geometry=urdf.Cylinder(length=1, radius=1),
193+
material=urdf.Material(name='mat'))
194+
robot.add_link(link)
195+
self.xml_and_compare(robot, xml)
196+
130197
def test_robot_material(self):
131198
xml = '''<?xml version="1.0"?>
132199
<robot name="test" version="1.0">
@@ -136,6 +203,11 @@ def test_robot_material(self):
136203
</robot>'''
137204
self.parse_and_compare(xml)
138205

206+
robot = urdf.Robot(name='test', version='1.0')
207+
material = urdf.Material(name='mat', color=urdf.Color([0.0, 0.0, 0.0, 1.0]))
208+
robot.add_aggregate('material', material)
209+
self.xml_and_compare(robot, xml)
210+
139211
def test_robot_material_missing_color_and_texture(self):
140212
xml = '''<?xml version="1.0"?>
141213
<robot name="test" version="1.0">
@@ -163,6 +235,29 @@ def test_link_multiple_visual(self):
163235
</robot>'''
164236
self.parse_and_compare(xml)
165237

238+
robot = urdf.Robot(name='test', version='1.0')
239+
link = urdf.Link(name='link')
240+
link.visual = urdf.Visual(geometry=urdf.Cylinder(length=1, radius=1),
241+
material=urdf.Material(name='mat'))
242+
link.visual = urdf.Visual(geometry=urdf.Cylinder(length=4, radius=0.5),
243+
material=urdf.Material(name='mat2'))
244+
robot.add_link(link)
245+
self.xml_and_compare(robot, xml)
246+
247+
def test_visual_with_name(self):
248+
xml = '''<?xml version="1.0"?>
249+
<robot name="test" version="1.0">
250+
<link name="link">
251+
<visual name="alice">
252+
<geometry>
253+
<cylinder length="1" radius="1"/>
254+
</geometry>
255+
<material name="mat"/>
256+
</visual>
257+
</link>
258+
</robot>'''
259+
self.parse_and_compare(xml)
260+
166261
def test_link_multiple_collision(self):
167262
xml = '''<?xml version="1.0"?>
168263
<robot name="test" version="1.0">
@@ -181,6 +276,13 @@ def test_link_multiple_collision(self):
181276
</robot>'''
182277
self.parse_and_compare(xml)
183278

279+
robot = urdf.Robot(name='test', version='1.0')
280+
link = urdf.Link(name='link')
281+
link.collision = urdf.Collision(geometry=urdf.Cylinder(length=1, radius=1))
282+
link.collision = urdf.Collision(geometry=urdf.Cylinder(length=4, radius=0.5))
283+
robot.add_link(link)
284+
self.xml_and_compare(robot, xml)
285+
184286
def test_version_attribute_not_enough_dots(self):
185287
xml = '''<?xml version="1.0"?>
186288
<robot name="test" version="1">
@@ -293,7 +395,7 @@ def test_robot_link_defaults_xyz_set(self):
293395
class LinkMultiVisualsAndCollisionsTest(unittest.TestCase):
294396

295397
xml = '''<?xml version="1.0"?>
296-
<robot name="test">
398+
<robot name="test" version="1.0">
297399
<link name="link">
298400
<visual>
299401
<geometry>
@@ -345,6 +447,41 @@ def test_multi_collision_access(self):
345447
robot.links[0].collision = dummyObject
346448
self.assertEqual(id(dummyObject), id(robot.links[0].collisions[0]))
347449

450+
def test_xml_and_urdfdom_robot_compatible_with_kinetic(self):
451+
robot = urdf.Robot(name='test', version='1.0')
452+
link = urdf.Link(name='link')
453+
link.visual = urdf.Visual(geometry=urdf.Cylinder(length=1, radius=1),
454+
material=urdf.Material(name='mat'))
455+
link.visual = urdf.Visual(geometry=urdf.Cylinder(length=4, radius=0.5),
456+
material=urdf.Material(name='mat2'))
457+
link.collision = urdf.Collision(geometry=urdf.Cylinder(length=1, radius=1))
458+
link.collision = urdf.Collision(geometry=urdf.Cylinder(length=4, radius=0.5))
459+
robot.add_link(link)
460+
link = urdf.Link(name='link2')
461+
robot.add_link(link)
462+
#
463+
robot_xml_string = robot.to_xml_string()
464+
robot_xml = minidom.parseString(robot_xml_string)
465+
orig_xml = minidom.parseString(self.xml)
466+
self.assertTrue(xml_matches(robot_xml, orig_xml))
467+
468+
def test_xml_and_urdfdom_robot_only_supported_since_melodic(self):
469+
robot = urdf.Robot(name='test', version='1.0')
470+
link = urdf.Link(name='link')
471+
link.add_aggregate('visual', urdf.Visual(geometry=urdf.Cylinder(length=1, radius=1),
472+
material=urdf.Material(name='mat')))
473+
link.add_aggregate('visual', urdf.Visual(geometry=urdf.Cylinder(length=4, radius=0.5),
474+
material=urdf.Material(name='mat2')))
475+
link.add_aggregate('collision', urdf.Collision(geometry=urdf.Cylinder(length=1, radius=1)))
476+
link.add_aggregate('collision', urdf.Collision(geometry=urdf.Cylinder(length=4, radius=0.5)))
477+
robot.add_link(link)
478+
link = urdf.Link(name='link2')
479+
robot.add_link(link)
480+
#
481+
robot_xml_string = robot.to_xml_string()
482+
robot_xml = minidom.parseString(robot_xml_string)
483+
orig_xml = minidom.parseString(self.xml)
484+
self.assertTrue(xml_matches(robot_xml, orig_xml))
348485

349486
class TestCreateNew(unittest.TestCase):
350487
def test_new_urdf(self):

0 commit comments

Comments
 (0)