franka_robot_urdf.py
Go to the documentation of this file.
1 import os
2 import sys
3 import subprocess
4 from unittest import TestCase
5 from parameterized import parameterized_class
6 from .urdf_test_case import UrdfTestCase, PKG
7 from urdf_parser_py.urdf import URDF, Mesh, Cylinder, Sphere
8 
9 
10 @parameterized_class(('robot',), [("panda",), ("fr3",)])
12 
13  @property
14  def file(self):
15  return os.path.join(self.robot, self.robot + '.urdf.xacro')
16 
18  self.xacro(self.file) # does not throw
19 
21  arm_id = self.robot
22  urdf = self.xacro(self.file)
23  for i in range(0, 9):
24  self.assertContainsLink(urdf, '%s_link%s' % (arm_id, i))
25 
27  arm_id = self.robot
28  urdf = self.xacro(self.file)
29  for i in range(1, 9):
30  joint = 'panda_joint%s' % i
31  self.assertContainsJoint(urdf, '%s_joint%s' % (arm_id, i))
32 
34  urdf = self.xacro(self.file)
35  self.assertFalse(
36  self.links_with(urdf, lambda link: 'hand' in link), # should be empty
37  'Found one or more links containing "hand", probably URDF contains a franka_gripper'
38  )
39  self.assertFalse(
40  self.joints_with(urdf, lambda joint: 'hand' in joint), # should be empty
41  'Found one or more joints containing "hand", probably URDF contains a franka_gripper'
42  )
43 
45  arm_id = self.robot
46  urdf = self.xacro(self.file)
47  for i in range(0, 8):
48  link = '%s_link%s' % (arm_id, i)
49  collisions = self.collision_geometries(urdf, link)
50  self.assertGreaterEqual(len(collisions), 1, "Link '%s' does not have any collision meshes assigned to it" % link)
51  self.assertIsInstance(
52  collisions[0], Mesh,
53  "Link '%s' is expected to have mesh geometries in <collision> not '%s'" % (link, collisions[0].__class__.__name__)
54  )
55 
57  urdf = self.xacro(self.file)
58  for name in urdf.link_map:
59  if not name.endswith('_sc'): continue
60  geometries = self.collision_geometries(urdf, name)
61  for geometry in geometries:
62  self.assertIsInstance(
63  geometry, (Cylinder, Sphere),
64  "Link '%s' is expected to define only a capsule <collision> geometry (made from Cylinders and Spheres, not '%s')" % (name, geometry.__class__.__name__)
65  )
66 
68  urdf = self.xacro(self.file)
69  for name, link in urdf.link_map.items():
70  self.assertIsNone(
71  link.inertial,
72  "Link '%s' is expected to have no <inertial> defined but actually has one:\n%s" % (name, link.inertial)
73  )
74 
76  urdf = self.xacro(self.file, args='hand:=true')
77  for name, link in urdf.link_map.items():
78  self.assertIsNone(
79  link.inertial,
80  "Link '%s' is expected to have no <inertial> defined but actually has one:\n%s" % (name, link.inertial)
81  )
82 
84  arm_id = 'foo'
85  urdf = self.xacro(self.file, args='arm_id:=%s' % arm_id)
86  for link in urdf.link_map.keys():
87  self.assertIn(arm_id, link)
88 
90  arm_id = 'foo'
91  urdf = self.xacro(self.file, args='arm_id:=%s' % arm_id)
92  for joint in urdf.joint_map.keys():
93  self.assertIn(arm_id, joint)
94 
96  arm_id = self.robot
97  urdf = self.xacro(self.file, args='hand:=true')
98  for name in ['hand', 'hand_tcp', 'leftfinger', 'rightfinger']:
99  link = '%s_%s' % (arm_id, name)
100  self.assertContainsLink(urdf, link)
101 
102  for name in ['hand_joint', 'hand_tcp_joint', 'finger_joint1', 'finger_joint2']:
103  joint = '%s_%s' % (arm_id, name)
104  self.assertContainsJoint(urdf, joint)
105 
107  arm_id = 'foo'
108  urdf = self.xacro(self.file, args='arm_id:=%s hand:=true' % arm_id)
109  for name in ['hand', 'hand_tcp', 'leftfinger', 'rightfinger']:
110  link = '%s_%s' % (arm_id, name)
111  self.assertContainsLink(urdf, link)
112 
113  for name in ['hand_joint', 'hand_tcp_joint', 'finger_joint1', 'finger_joint2']:
114  joint = '%s_%s' % (arm_id, name)
115  self.assertContainsJoint(urdf, joint)
116 
118  arm_id = self.robot
119  urdf = self.xacro(self.file, args='gazebo:=true')
120 
121  # Check if the world link exists
122  self.assertEqual('world', urdf.get_root())
123 
124  # Check if robot is directly connected to the world link
125  self.assertJointBetween(urdf, 'world', arm_id + '_link0', type="fixed")
126 
128  urdf = self.xacro(self.file, args='gazebo:=true')
129 
130  for gazebo in urdf.gazebos:
131  for child in gazebo:
132  if child.tag == 'plugin':
133  self.assertIn('name', child.attrib, '<plugin> tag does not have a "name" attribute')
134  self.assertEqual('gazebo_ros_control', child.attrib['name'])
135  # Successfully found plugin, break out of all loops
136  break
137  else:
138  # Inner loop not broken, continue with next gazebo tag
139  continue
140  # Inner loop was broken, break also outer loop
141  break
142  else:
143  # Outer loop not broken -> no valid plugin found!
144  self.fail('No <plugin name="gazebo_ros_control"> found in URDF')
145 
147  arm_id = self.robot
148  urdf = self.xacro(self.file, args='gazebo:=true')
149  for joint in ['%s_joint%s' % (arm_id, i) for i in range(1,8)]:
150  self.assertJointHasTransmission(urdf, joint, 'hardware_interface/PositionJointInterface')
151 
153  arm_id = self.robot
154  urdf = self.xacro(self.file, args='gazebo:=true')
155  for joint in ['%s_joint%s' % (arm_id, i) for i in range(1,8)]:
156  self.assertJointHasTransmission(urdf, joint, 'hardware_interface/VelocityJointInterface')
157 
159  arm_id = self.robot
160  urdf = self.xacro(self.file, args='gazebo:=true')
161  for joint in ['%s_joint%s' % (arm_id, i) for i in range(1,8)]:
162  self.assertJointHasTransmission(urdf, joint, 'hardware_interface/EffortJointInterface')
163 
165  arm_id = self.robot
166  urdf = self.xacro(self.file, 'gazebo:=true')
167  for transmission in urdf.transmissions:
168  if transmission.type == 'franka_hw/FrankaStateInterface':
169  self.assertListEqual(
170  ['%s_joint%s' % (arm_id, i) for i in range(1,8)],
171  [joint.name for joint in transmission.joints]
172  )
173  break
174  else:
175  # Didn't break out of loop -> no state interface found
176  self.fail('No franka_hw/FrankaStateInterface found in URDF')
177 
179  arm_id = self.robot
180  urdf = self.xacro(self.file, args='gazebo:=true')
181  for transmission in urdf.transmissions:
182  if transmission.type == 'franka_hw/FrankaModelInterface':
183  self.assertEqual(
184  arm_id + '_joint1', transmission.joints[0].name,
185  "First joint in the FrankaModelInterface transmission must be the root of the chain, i.e. '$(arm_id)_joint1' not '%s'" % transmission.joints[0].name
186  )
187  self.assertEqual(
188  arm_id + '_joint8', transmission.joints[1].name,
189  "Second joint in the FrankaModelInterface transmission must be the tip of the chain, i.e. '$(arm_id)_joint8' not '%s'" % transmission.joints[1].name
190  )
191  break
192  else:
193  # Didn't break out of loop -> no model interface found
194  self.fail('No franka_hw/FrankaModelInterface found in URDF')
195 
197  arm_id = self.robot
198  urdf = self.xacro(self.file, args='gazebo:=true hand:=true')
199  for joint in [arm_id + '_finger_joint1', arm_id + '_finger_joint2']:
200  self.assertJointHasTransmission(urdf, joint, 'hardware_interface/EffortJointInterface')
201 
203  urdf = self.xacro(self.file, args='gazebo:=true')
204  for name, link in urdf.link_map.items():
205  if not name.endswith('_sc'): continue
206  self.assertEqual(
207  len(link.collisions), 0,
208  "Link '%s' is expected to have no <collision> tags defined but has %s" % (name, len(link.collisions))
209  )
210 
212  urdf = self.xacro(self.file, args='gazebo:=true hand:=true')
213  for name, link in urdf.link_map.items():
214  if not name.endswith('_sc'): continue
215  self.assertEqual(
216  len(link.collisions), 0,
217  "Link '%s' is expected to have no <collision> tags defined but has %s" % (name, len(link.collisions))
218  )
219 
221  arm_id = self.robot
222  urdf = self.xacro(self.file, args='hand:=true')
223  joint = urdf.joint_map[arm_id + '_hand_tcp_joint']
224  self.assertListEqual(joint.origin.xyz, [0, 0, 0.1034])
225  self.assertListEqual(joint.origin.rpy, [0, 0, 0])
226 
228  arm_id = self.robot
229  urdf = self.xacro(self.file, args='hand:=true tcp_xyz:="1 2 3"')
230  joint = urdf.joint_map[arm_id + '_hand_tcp_joint']
231  self.assertListEqual(joint.origin.xyz, [1, 2, 3])
232 
234  arm_id = self.robot
235  urdf = self.xacro(self.file, args='hand:=true tcp_rpy:="3.1415 0.123 42"')
236  joint = urdf.joint_map[arm_id + '_hand_tcp_joint']
237  self.assertListEqual(joint.origin.rpy, [3.1415, 0.123, 42])
238 
239 if __name__ == '__main__':
240  import rosunit
241  rosunit.unitrun(PKG, 'URDF', FrankaRobotUrdfTest)
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_without_xacro_args_uses_coarse_collision_models_for_sc_links
def test_generate_urdf_without_xacro_args_uses_coarse_collision_models_for_sc_links(self)
Definition: franka_robot_urdf.py:56
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_with_hand_puts_franka_gripper_into_urdf
def test_generate_urdf_with_hand_puts_franka_gripper_into_urdf(self)
Definition: franka_robot_urdf.py:95
test.franka_robot_urdf.FrankaRobotUrdfTest.test_custom_arm_id_renames_joints
def test_custom_arm_id_renames_joints(self)
Definition: franka_robot_urdf.py:89
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_without_tcp_args_uses_default_10_34_cm_hand_tcp_offset
def test_generate_urdf_without_tcp_args_uses_default_10_34_cm_hand_tcp_offset(self)
Definition: franka_robot_urdf.py:220
test.urdf_test_case.UrdfTestCase.collision_geometries
def collision_geometries(self, urdf, link)
Definition: urdf_test_case.py:63
test.franka_robot_urdf.FrankaRobotUrdfTest.test_setting_gazebo_arg_with_hand_forces_to_have_no_geometries_inside_sc_links
def test_setting_gazebo_arg_with_hand_forces_to_have_no_geometries_inside_sc_links(self)
Definition: franka_robot_urdf.py:211
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_without_xacro_args_contains_joint1_up_to_joint8
def test_generate_urdf_without_xacro_args_contains_joint1_up_to_joint8(self)
Definition: franka_robot_urdf.py:26
test.urdf_test_case.UrdfTestCase.assertContainsJoint
def assertContainsJoint(self, urdf, joint)
Definition: urdf_test_case.py:34
test.urdf_test_case.UrdfTestCase.joints_with
def joints_with(self, urdf, predicate)
Definition: urdf_test_case.py:53
test.franka_robot_urdf.FrankaRobotUrdfTest.test_gazebo_arg_and_hand_will_insert_effort_interfaces_for_fingers
def test_gazebo_arg_and_hand_will_insert_effort_interfaces_for_fingers(self)
Definition: franka_robot_urdf.py:196
test.urdf_test_case.UrdfTestCase.assertJointHasTransmission
def assertJointHasTransmission(self, urdf, joint, type)
Definition: urdf_test_case.py:94
test.franka_robot_urdf.FrankaRobotUrdfTest.test_gazebo_arg_will_insert_gazebo_ros_control_plugin
def test_gazebo_arg_will_insert_gazebo_ros_control_plugin(self)
Definition: franka_robot_urdf.py:127
test.franka_robot_urdf.FrankaRobotUrdfTest.test_gazebo_arg_will_insert_franka_state_interface
def test_gazebo_arg_will_insert_franka_state_interface(self)
Definition: franka_robot_urdf.py:164
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_without_xacro_args_uses_fine_collision_models
def test_generate_urdf_without_xacro_args_uses_fine_collision_models(self)
Definition: franka_robot_urdf.py:44
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_without_xacro_args_contains_link0_up_to_link8
def test_generate_urdf_without_xacro_args_contains_link0_up_to_link8(self)
Definition: franka_robot_urdf.py:20
test.franka_robot_urdf.FrankaRobotUrdfTest.test_gazebo_arg_will_add_top_level_world_link
def test_gazebo_arg_will_add_top_level_world_link(self)
Definition: franka_robot_urdf.py:117
test.franka_robot_urdf.FrankaRobotUrdfTest
Definition: franka_robot_urdf.py:11
test.franka_robot_urdf.FrankaRobotUrdfTest.test_gazebo_arg_will_insert_velocity_interfaces
def test_gazebo_arg_will_insert_velocity_interfaces(self)
Definition: franka_robot_urdf.py:152
test.franka_robot_urdf.FrankaRobotUrdfTest.test_setting_tcp_xyz_arg_moves_the_hand_tcp_link
def test_setting_tcp_xyz_arg_moves_the_hand_tcp_link(self)
Definition: franka_robot_urdf.py:227
test.franka_robot_urdf.FrankaRobotUrdfTest.test_gazebo_arg_will_insert_effort_interfaces
def test_gazebo_arg_will_insert_effort_interfaces(self)
Definition: franka_robot_urdf.py:158
test.franka_robot_urdf.FrankaRobotUrdfTest.test_gazebo_arg_will_insert_position_interfaces
def test_gazebo_arg_will_insert_position_interfaces(self)
Definition: franka_robot_urdf.py:146
test.franka_robot_urdf.FrankaRobotUrdfTest.file
def file(self)
Definition: franka_robot_urdf.py:14
test.franka_robot_urdf.FrankaRobotUrdfTest.test_custom_arm_id_renames_links
def test_custom_arm_id_renames_links(self)
Definition: franka_robot_urdf.py:83
test.franka_robot_urdf.FrankaRobotUrdfTest.test_custom_arm_id_with_hand_renames_hand_joints_and_links
def test_custom_arm_id_with_hand_renames_hand_joints_and_links(self)
Definition: franka_robot_urdf.py:106
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_without_xacro_args_dont_use_gripper
def test_generate_urdf_without_xacro_args_dont_use_gripper(self)
Definition: franka_robot_urdf.py:33
test.urdf_test_case.UrdfTestCase.assertContainsLink
def assertContainsLink(self, urdf, link)
Definition: urdf_test_case.py:25
test.urdf_test_case.UrdfTestCase.xacro
def xacro(self, file, args='')
Definition: urdf_test_case.py:9
test.urdf_test_case.UrdfTestCase
Definition: urdf_test_case.py:8
test.urdf_test_case.UrdfTestCase.assertJointBetween
def assertJointBetween(self, urdf, parent, child, type=None)
Definition: urdf_test_case.py:74
test.urdf_test_case.UrdfTestCase.links_with
def links_with(self, urdf, predicate)
Definition: urdf_test_case.py:43
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_with_hand_but_not_gazebo_doesnt_insert_inertial_tags_for_any_link
def test_generate_urdf_with_hand_but_not_gazebo_doesnt_insert_inertial_tags_for_any_link(self)
Definition: franka_robot_urdf.py:75
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_without_xacro_args_doesnt_insert_inertial_tags_for_any_link
def test_generate_urdf_without_xacro_args_doesnt_insert_inertial_tags_for_any_link(self)
Definition: franka_robot_urdf.py:67
test.franka_robot_urdf.FrankaRobotUrdfTest.test_gazebo_arg_will_insert_franka_model_interface
def test_gazebo_arg_will_insert_franka_model_interface(self)
Definition: franka_robot_urdf.py:178
test.franka_robot_urdf.FrankaRobotUrdfTest.test_generate_urdf_without_xacro_args_is_possible
def test_generate_urdf_without_xacro_args_is_possible(self)
Definition: franka_robot_urdf.py:17
test.franka_robot_urdf.FrankaRobotUrdfTest.test_setting_gazebo_arg_forces_to_have_no_geometries_inside_sc_links
def test_setting_gazebo_arg_forces_to_have_no_geometries_inside_sc_links(self)
Definition: franka_robot_urdf.py:202
test.franka_robot_urdf.FrankaRobotUrdfTest.test_setting_tcp_rpy_arg_rotates_the_hand_tcp_link
def test_setting_tcp_rpy_arg_rotates_the_hand_tcp_link(self)
Definition: franka_robot_urdf.py:233


franka_description
Author(s): Franka Emika GmbH
autogenerated on Mon Sep 19 2022 02:33:19