generate_urdf.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2014 Aldebaran Robotics
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17 #
18 # This file takes the official URDF aldebaran files and convert them
19 # to rep120 compliant urdf files. It also includes the meshes from nao_meshes
20 # package allowing to display the model in RVIZ
21 #
22 # authors: Mikael Arguedas [mikael DOT arguedas AT gmail DOT com]
23 # TODO Get motor information from documentation and generate transmission tags
24 # automatically
25 # TODO Generate automatically gazebo tags for every sensor
26 # TODO Add toe frames for romeo (not supported yet by NAOqi)
27 
28 from __future__ import print_function
29 import sys
30 import argparse
31 from naoqi_tools.urdf import URDF
32 import copy
34 import naoqi_tools.urdf as ur
35 import naoqi_tools.nao_dictionaries as dico
36 import subprocess
37 import os
38 import math
39 from xml.dom.minidom import Document
40 
41 NAO_XACRO_DICO = {
42  'head': 'gaze',
43  'legs': 'sole',
44  'arms': 'gripper',
45  'torso': 'torso',
46  }
47 
48 ROMEO_XACRO_DICO = {
49  'head': 'gaze',
50  'legs': 'sole',
51  'arms': 'gripper',
52  'torso': 'body',
53  'eyes': 'Eye',
54  }
55 
56 PEPPER_XACRO_DICO = {
57  'head': 'Head',
58  'legs': 'base_footprint',
59  'arms': 'gripper',
60  'torso': 'torso',
61  }
62 
63 COLLISION_SUFFIX = '_0.10.stl'
64 
65 parser = argparse.ArgumentParser(usage='Load an URDF file')
66 parser.add_argument('-i', '--input', default='', help='URDF file to load')
67 parser.add_argument('-r', '--REP120', choices=['true', 'false'],
68  default='true', help='Rename the links to be REP120 compliant')
69 parser.add_argument('-x', '--xacro', choices=['urdf', 'robot'],
70 default='robot', help='Chose robot part to generate. choosing urdf create a'
71  'single urdf file with the entire robot. robot will OUTPUT a xacro file '
72  'for every kinematic chain on the robot')
73 
74 ####################
75 ##### FUNCTIONS ####
76 ####################
77 
78 
80  """Create a few materials.
81 
82  to display geometrical shapes in a given color.
83  """
84  global robot
85  robot.add_material(ur.Material('Black', ur.Color(0.1, 0.1, 0.1, 1)))
86  robot.add_material(ur.Material('LightGrey', ur.Color(0.9, 0.9, 0.9, 1)))
87  robot.add_material(ur.Material('Grey', ur.Color(0.6, 0.6, 0.6, 1)))
88  robot.add_material(ur.Material('DarkGrey', ur.Color(0.3, 0.3, 0.3, 1)))
89 
90 
92  """Add frames defined by ROS for humanoid robots.
93 
94  (REP120): http://www.ros.org/reps/rep-0120.html
95  """
96  # TODO Add toe frames for ROMEO (not supported by NAOqi yet)
97  global robot, NAME, MESH_VERSION, VERSION, LINKS_DICO, OFFSETS_DICO
98  print('creating and renaming joints & links to comply to REP120')
99 
100  # Rename links
101  for joint in robot.joints:
102  if robot.joints[joint].name.endswith('_joint'):
103  robot.joints[joint].name = robot.joints[joint].name[0:-6]
104  if robot.joints[joint].name.endswith('_actuator'):
105  robot.joints[joint].name = robot.joints[joint].name[0:-9]
106  if robot.joints[joint].mimic is not None:
107  if robot.joints[joint].mimic.joint_name.endswith('_actuator'):
108  robot.joints[joint].mimic.joint_name = \
109  robot.joints[joint].mimic.joint_name[0:-9]
110  if robot.joints[joint].mimic.joint_name.endswith('_joint'):
111  robot.joints[joint].mimic.joint_name = \
112  robot.joints[joint].mimic.joint_name[0:-6]
113  try:
114  robot.joints[joint].parent = LINKS_DICO[robot.joints[joint].parent]
115  except KeyError:
116  pass
117  try:
118  robot.joints[joint].child = LINKS_DICO[robot.joints[joint].child]
119  except KeyError:
120  pass
121  for link in robot.links.keys():
122  try:
123  robot.rename_link(link, LINKS_DICO[link])
124  except KeyError, ValueError:
125  pass
126 
127  if NAME == 'romeo':
128  robot.add_link(ur.Link('gaze'))
129  robot.add_joint(ur.Joint('gaze_joint', 'HeadRoll_link',
130  'gaze', 'fixed', None, ur.Pose(
131  (OFFSETS_DICO['CameraLeftEyeOffsetX'], 0,
132  OFFSETS_DICO['CameraLeftEyeOffsetZ']), (0, 0, 0))))
133  MESH_VERSION = ''
134 
135  elif NAME == 'nao':
136  robot.add_link(ur.Link('gaze'))
137  robot.add_joint(ur.Joint('gaze_joint', 'Head',
138  'gaze', 'fixed', None, ur.Pose(
139  (OFFSETS_DICO['CameraTopV4OffsetX'], 0,
140  OFFSETS_DICO['CameraTopV4OffsetZ']), (0, 0, 0))))
141  if VERSION == 'V32':
142  MESH_VERSION = VERSION
143  elif VERSION == 'V33' or VERSION == 'V40' or VERSION == 'V50':
144  MESH_VERSION = 'V40'
145 
146  elif NAME == 'pepper':
147  MESH_VERSION = VERSION
148  # add base_footprint frame
149  robot.add_link(ur.Link('base_footprint'))
150  robot.add_joint(ur.Joint('base_footprint_joint', 'Tibia',
151  'base_footprint', 'fixed', None, ur.Pose(
152  (OFFSETS_DICO['BaseFootprintOffsetX'],
153  OFFSETS_DICO['BaseFootprintOffsetY'],
154  OFFSETS_DICO['BaseFootprintOffsetZ']),
155  (OFFSETS_DICO['BaseFootprintRotX'],
156  OFFSETS_DICO['BaseFootprintRotY'],
157  OFFSETS_DICO['BaseFootprintRotZ']))))
158 
159  # rename the laser frames to sensor frames
160  # (they are actually not used for computation)
161  laser_links = [c for c in robot.links.keys()
162  if 'surrounding' in c.lower()]
163  for joint in robot.joints.values():
164  if joint.child in laser_links:
165  laser_frame = joint.child
166  laser_device_frame = laser_frame[:-5] + 'device_frame'
167  # get the old joint to have the device frame as a child
168  joint.child = laser_device_frame
169  # but also create a joint with the projected frame as a child
170  robot.add_link(ur.Link(laser_device_frame))
171  joint_new = copy.deepcopy(joint)
172  joint_new.name = joint.name[:-17] + \
173  'projected_sensor_fixedjoint'
174  joint_new.child = laser_frame
175  joint_new.origin.rotation[0] = 0
176  joint_new.origin.rotation[1] = 0
177  # set it on the ground
178  joint_new.origin.position[2] = -0.334
179  if 'left' in laser_frame.lower():
180  # the following line is a temporary fix
181  # that should be fixed upstream
182  joint_new.origin.rotation[2] = math.pi/2.0 + \
183  0.1864836732051034
184  elif 'right' in laser_frame.lower():
185  # the following line is a temporary fix
186  # that should be fixed upstream
187  joint.origin.position[0] = -0.018
188  joint_new.origin.position[0] = -0.018
189  # the following line is a temporary fix
190  # that should be fixed upstream
191  joint_new.origin.rotation[2] = -math.pi/2.0 \
192  - 0.1864836732051034
193  elif 'front' in laser_frame.lower():
194  joint_new.origin.rotation[2] = 0
195  robot.add_joint(joint_new)
196 
197  # add an optical frame for each robot
198  camera_frames = [c for c in robot.links.keys() if 'camera' in c.lower()]
199  for camera_frame in camera_frames:
200  camera_optical_frame = camera_frame[:-6] + '_optical_frame'
201  robot.add_link(ur.Link(camera_optical_frame))
202  robot.add_joint(ur.Joint('%s_fixedjoint' % camera_optical_frame,
203  camera_frame, camera_optical_frame, 'fixed', None,
204  ur.Pose((0, 0, 0), (-math.pi/2.0, 0, -math.pi/2.0))))
205 
206  # add dummy physics for gazebo simulation
207  add_dummy_inertia(['Finger', 'Thumb', 'gripper', 'Fsr'])
208  add_dummy_collision(['Fsr'])
209 
210 
212  """Should instanciate all transmission tags.
213 
214  - hardware interface
215  - mechanical reduction ratio for each motor
216  - joint and actuator to which the transmission tag reference
217  for now naoTransmission.xacro has been done by hand based on the work
218  of Konstantinos Chatzilygeroudis in his nao_dcm project
219  https://github.com/costashatz/nao_dcm
220  """
221  global robot
222  # TODO create all transmission elements : Cannot get them from the lib for now
223  return
224 
225 
227  """Should instanciate all gazebo tags.
228 
229  - sensor plugins
230  - mimic joints plugins
231  - ros_control plugin
232  - disable_links plugins
233  - gazebo reference for every link (ok)
234  for now naoGazebo.xacro has been done by hand based on the work of
235  Konstantinos Chatzilygeroudis in his nao_dcm project
236  https://github.com/costashatz/nao_dcm
237  """
238  global robot
239  # TODO instantiate plugins according to sensors present in input urdf
240  return
241 
242 
244  """Add a dummy Inertial tag to every links containing keyword in list."""
245  global robot
246  for string in list:
247  for link in robot.links:
248  if robot.links[link].name.find(string) != -1:
249  robot.links[link].inertial = ur.Inertial(1.1e-9, 0.0, 0.0,
250  1.1e-9, 0.0, 1.1e-9, 2e-06)
251 
252 
254  """Add a Box collision tag to every links containing keyword in list."""
255  global robot
256  for string in list:
257  for link in robot.links:
258  if robot.links[link].name.find(string) != -1:
259  robot.links[link].collision = ur.Collision(
260  ur.Box([0.01, 0.01, 0.005]),
261  ur.Pose((0, 0, 0), (0, 0, 0)))
262 
263 ##################
264 ##### Meshes #####
265 ##################
266 
267 
269  """Create a <ROBOT>_visual_collision.xacro file.
270 
271  with xacro macros for visual and collision tags of the urdf.
272  This function creates xacro macros for visualisation and collisions.
273  It checks if the meshes are on the computer and set the 'meshes_installed'
274  property accordingly
275  """
276  global robot
277  global OUTPUT
278  global MESH_VERSION
279  global NAME
280  global LINKS_DICO
281  global VISU_DICO
282  global OFFSETS_DICO
283  global MESHPKG
284  prefix = 'insert_visu_'
285  doc = Document()
286  root = doc.createElement('robot')
287  doc.appendChild(root)
288  root.setAttribute("xmlns:xacro", "http://www.ros.org/wiki/xacro")
289 
290  cmd = 'rospack find ' + NAME + MESHPKG
291  try:
292  path_mesh_pkg = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
293  shell=True)[:-1]
294  except:
295  print('unable to find ' + NAME + MESHPKG + ' package')
296  sys.exit(0)
297  # Set Mesh path
298  if NAME == 'nao':
299  node = ur.short(doc, 'xacro:property', 'name', 'PI_2')
300  node.setAttribute('value', str(math.pi/2.0))
301  root.appendChild(node)
302  node = ur.short(doc, 'xacro:property', 'name', 'meshes_installed')
303 
304  if os.path.isdir(os.path.join(path_mesh_pkg, 'meshes', MESH_VERSION)):
305  node.setAttribute('value', 'true')
306  else:
307  node.setAttribute('value', 'false')
308  root.appendChild(node)
309 
310  # Insert xacro macro
311  for link in robot.links:
312  (tempVisu, tempCol) = adjustMeshPath(path_mesh_pkg, link)
313  if robot.links[link].visual is not None:
314  robot.links[link].xacro = 'xacro:' + prefix + \
315  robot.links[link].name
316  node = ur.short(doc, 'xacro:macro', 'name', prefix +
317  robot.links[link].name)
318  if NAME == 'nao':
319  # add xacro condition macro to handle the absence of meshes
320  node2 = ur.short(doc, 'xacro:unless', 'value',
321  '${meshes_installed}')
322  if tempVisu is not None:
323  node2.appendChild(tempVisu.to_xml(doc))
324  if tempCol is not None:
325  node2.appendChild(tempCol.to_xml(doc))
326  node.appendChild(node2)
327  node3 = ur.short(doc, 'xacro:if', 'value', '${meshes_installed}')
328  node3.appendChild(robot.links[link].visual.to_xml(doc))
329  node3.appendChild(robot.links[link].collision.to_xml(doc))
330  node.appendChild(node3)
331  else:
332  node.appendChild(robot.links[link].visual.to_xml(doc))
333  node.appendChild(robot.links[link].collision.to_xml(doc))
334  root.appendChild(node)
335  robot.links[link].visual = None
336  robot.links[link].collision = None
337  filename = OUTPUT[0:OUTPUT.rfind('.')] + '_visual_collisions.xacro'
338  write_comments_in_xacro(doc, filename)
339 
340 
341 #################################
342 ######## XACRO FUNCTIONS ########
343 #################################
344 
345 
346 def export_robot_element(element):
347  """
348  Export the 'elements' related to the keyword 'element'.
349 
350  :param : element, string in ['Transmission', 'Gazebo', 'material']
351 
352  The output file is <ROBOT>_<element>.xacro
353  """
354  global robot, OUTPUT
355  doc = Document()
356  root = doc.createElement('robot')
357  doc.appendChild(root)
358  root.setAttribute("xmlns:xacro", "http://www.ros.org/wiki/xacro")
359  for i in robot.elements:
360  try:
361  if element == 'Transmission':
362  if i.name.find(element) != -1:
363  root.appendChild(i.to_xml(doc))
364  elif element == 'Gazebo':
365  if i.reference is not None:
366  root.appendChild(i.to_xml(doc))
367  elif i.plugins != []:
368  root.appendChild(i.to_xml(doc))
369  elif element == 'material':
371  root.appendChild(i.to_xml(doc))
372  except AttributeError:
373  pass
374  filename = OUTPUT[0:OUTPUT.rfind('.')] + '_' + str(element) + '.xacro'
375  print('exporting ' + element + ' xacro')
376  write_comments_in_xacro(doc, filename)
377 
378 
380  """
381  Export the entire 'robot' in several xacro files.
382 
383  One xacro file per kinematic chain (<ROBOT>_legs.xacro,
384  <ROBOT>_arms.xacro, <ROBOT>_torso.xacro...)
385  Xacro file for specific parts of the robot (<ROBOT>_fingers.xacro,
386  <ROBOT>_sensors.xacro)
387  One xacro file for visual elements (<ROBOT>_visual_collision.xacro,
388  <ROBOT>_material.xacro)
389  One xacro file per type of element needed for gazebo simulation
390  (<ROBOT>_Gazebo.xacro, <ROBOT>_Transmission.xacro)
391  One generic robot file which includes all the other ones
392  (<ROBOT>_robot.xacro)
393  """
394  global robot, OUTPUT, NAME
395  doc = Document()
396  root = doc.createElement('robot')
397  doc.appendChild(root)
398  root.setAttribute("xmlns:xacro", "http://www.ros.org/wiki/xacro")
399  root.setAttribute("name", robot.name)
400  root.appendChild(ur.short(doc, 'xacro:include', 'filename', NAME +
401  '_visual_collisions.xacro'))
403  for i in XACRO_DICO.keys():
404  print('exporting ' + NAME + '_' + i + '.xacro')
405  if i.find('eye') != -1:
406  export_kinematic_chain_to_xacro(i, 'HeadRoll_link',
407  'HeadRoll_link')
408  else:
410  filenamerobot = NAME + '_' + i + '.xacro'
411  root.appendChild(ur.short(doc, 'xacro:include', 'filename',
412  filenamerobot))
413  # Transmission elements not available from Aldebaran libraries yet
414  export_robot_element('Transmission')
415  root.appendChild(ur.short(doc, 'xacro:include', 'filename', NAME +
416  '_Transmission.xacro'))
417  # Gazebo Plugin not available from Aldebaran libraries yet
418  export_robot_element('Gazebo')
419  root.appendChild(ur.short(doc, 'xacro:include', 'filename', NAME +
420  '_Gazebo.xacro'))
421  root.appendChild(ur.short(doc, 'xacro:include', 'filename', NAME +
422  '_sensors.xacro'))
423  export_list_to_xacro(['_frame'], OUTPUT[0:OUTPUT.rfind('.')] +
424  '_sensors.xacro')
425  root.appendChild(ur.short(doc, 'xacro:include', 'filename', NAME +
426  '_fingers.xacro'))
427  export_list_to_xacro(['Finger', 'Thumb'], OUTPUT[0:OUTPUT.rfind('.')] +
428  '_fingers.xacro')
429  if NAME == 'pepper':
430  root.appendChild(ur.short(doc, 'xacro:include', 'filename', NAME +
431  '_wheels.xacro'))
432  export_list_to_xacro(['Wheel'], OUTPUT[0:OUTPUT.rfind('.')] +
433  '_wheels.xacro')
434  if NAME == 'romeo':
435  root.appendChild(ur.short(doc, 'xacro:include', 'filename',
436  'romeo_cap.xacro'))
437 
438  filename = OUTPUT[0:OUTPUT.rfind('.')] + '_robot.xacro'
439  write_comments_in_xacro(doc, filename)
440  print('output directory : ' + OUTPUT[0:OUTPUT.rfind('/') + 1])
441 
442 
443 def export_kinematic_chain_to_xacro(keyword, baseChain='base_link',
444  tipRefChain='default'):
445  """Export a specific kinematic chain to a xacro file.
446 
447  :param : keyword, string defining kinematic chains to export
448  (legs,arms,head,torso)
449  :param : baseChain, string representing the name of the link where
450  the reference chain starts
451  :param : tipRefChain, string representing the name of the link where
452  the reference chain ends
453  """
454  global robot, OUTPUT
455  if tipRefChain == 'default':
456  print('applying torso to end of ref chain')
457  tipRefChain = XACRO_DICO['torso']
458  chainRef = robot.get_chain(baseChain, tipRefChain)
459  print(chainRef)
460  doc = Document()
461  root = doc.createElement('robot')
462  doc.appendChild(root)
463  root.setAttribute('xmlns:xacro', 'http://www.ros.org/wiki/xacro')
464  chainNb = 0
465  try:
466  chain1 = robot.get_chain(baseChain, 'l_' + XACRO_DICO[keyword])
467  chain2 = robot.get_chain(baseChain, 'r_' + XACRO_DICO[keyword])
468  chainNb = 2
469  except KeyError:
470  try:
471  chain1 = robot.get_chain(baseChain, 'L' + XACRO_DICO[keyword])
472  chain2 = robot.get_chain(baseChain, 'R' + XACRO_DICO[keyword])
473  chainNb = 2
474  except KeyError:
475  try:
476  chain1 = robot.get_chain(baseChain, XACRO_DICO[keyword])
477  chainNb = 1
478  except KeyError:
479  print('the chain ' + keyword + ' cannot be found')
480 
481  if chainNb != 0:
482  duplicate = 0
483  for i in range(len(chain1)):
484  for j in range(len(chainRef)):
485  if chain1[i] == chainRef[j]:
486  duplicate = 1
487  if duplicate == 0 or keyword == 'torso':
488  try:
489  root.appendChild(robot.links[chain1[i]].to_xml(doc))
490  except KeyError:
491  try:
492  root.appendChild(robot.joints[chain1[i]].to_xml(doc))
493  except KeyError:
494  print('unknown element' + chain1[i])
495  else:
496  duplicate = 0
497  if chainNb == 2:
498  for i in range(len(chain2)):
499  for j in range(len(chainRef)):
500  if chain2[i] == chainRef[j]:
501  duplicate = 1
502  if duplicate == 0:
503  try:
504  root.appendChild(robot.links[chain2[i]].to_xml(doc))
505  except KeyError:
506  try:
507  root.appendChild(
508  robot.joints[chain2[i]].to_xml(doc))
509  except KeyError:
510  print('unknown element' + chain2[i])
511  else:
512  duplicate = 0
513  filename = OUTPUT[0:OUTPUT.rfind('.')] + '_' + keyword + str('.xacro')
514  write_comments_in_xacro(doc, filename)
515 
516 
517 def write_comments_in_xacro(doc, filename):
518  """
519  Write the content of the XML Document doc to a file named filename.
520 
521  Also add comments at the beginning of the file
522 
523  :param : doc, minidom Document to write
524  :param : filename, absolute path of the file to write to
525  """
526  if(not os.path.isdir(filename[0:filename.rfind('/') + 1])):
527  os.makedirs(filename[0:filename.rfind('/')])
528 
529  file = open(filename, 'w+')
530  file.write(doc.toprettyxml())
531  file.close()
532  file = open(filename, 'r')
533  firstline, remaining = file.readline(), file.read()
534  file.close()
535  file = open(filename, 'w')
536  file.write(firstline)
537  file.write(
538  '<!--**************************************************************\n'
539  ' **** File automatically generated by generate_urdf.py script ****\n'
540  ' **************************************************************-->\n')
541  file.write(remaining)
542  file.close()
543 
544 
545 def export_list_to_xacro(list, filename):
546  """Export all links containing a string and its parent joint.
547 
548  :param : list, list of strings to look for
549  :param : filename, absolute path of the file to write to
550  """
551  global robot, OUTPUT
552  doc = Document()
553  root = doc.createElement('robot')
554  doc.appendChild(root)
555  root.setAttribute("xmlns:xacro", "http://www.ros.org/wiki/xacro")
556  print ('exporting ' + os.path.basename(filename))
557  for string in list:
558  for link in robot.links:
559  if robot.links[link].name.find(string) != -1:
560  root.appendChild(robot.links[link].to_xml(doc))
561  for joint in robot.joints:
562  if robot.joints[joint].child == robot.links[link].name:
563  root.appendChild(robot.joints[joint].to_xml(doc))
564  write_comments_in_xacro(doc, filename)
565 
566 
567 def adjustMeshPath(path_mesh_pkg, link):
568  """
569  Find the path of a mesh according to the link definition.
570 
571  Set the visual and collision element of the given link
572 
573  :param : path_mesh_pkg, absolute path of the package where the meshes
574  should be located
575  :param : link, dictionary key of the link we want to set
576  visual and collision parameters
577 
578  :return : tempVisu, Visual element with the NAO visual geometrical shape
579  for people who don't have the meshes
580  :return : tempCol, Collision element with the NAO collision geometrical
581  shape for people who don't have the meshes
582  """
583  global robot, SCALE, MESHPKG, MESH_VERSION
584  tempVisu = None
585  tempVisuMesh = None
586  tempCol = None
587  tempColMesh = None
588  if robot.links[link].visual is not None:
589  try:
590  meshname = str(
591  LINKS_DICO.keys()[list(LINKS_DICO.values()).index(link)])
592  if meshname.endswith('_link'):
593  meshfile = meshname[0:-5]
594  else:
595  meshfile = meshname
596  except:
597  meshname = link
598  meshfile = link
599  pass
600  if meshfile.endswith('_link'):
601  meshfile = meshfile[0:-5]
602  tempVisuMesh = ur.Visual(ur.Mesh('', (SCALE, SCALE, SCALE)))
603  tempColMesh = ur.Collision(ur.Mesh('', (SCALE, SCALE, SCALE)))
604  tempVisuMesh.origin = robot.links[link].visual.origin
605  tempColMesh.origin = robot.links[link].visual.origin
606  if os.path.isfile(os.path.join(path_mesh_pkg, 'meshes', MESH_VERSION,
607  robot.links[link].visual.geometry.filename[
608  robot.links[link].visual.geometry.filename.rfind('/') + 1:])):
609  tempVisuMesh.geometry.filename = os.path.join(
610  'package://', NAME + MESHPKG, 'meshes', MESH_VERSION,
611  robot.links[link].visual.geometry.filename[
612  robot.links[link].visual.geometry.filename.rfind('/')+1:])
613  tempColMesh.geometry.filename = \
614  tempVisuMesh.geometry.filename[0:-4] + COLLISION_SUFFIX
615  else:
616  tempVisuMesh.geometry.filename = os.path.join(
617  'package://', NAME + MESHPKG, 'meshes', MESH_VERSION,
618  meshfile + '.dae')
619  tempColMesh.geometry.filename = \
620  tempVisuMesh.geometry.filename[0:-4] + COLLISION_SUFFIX
621 
622  if NAME == 'nao':
623  try:
624  tempVisu = ur.Visual(
625  VISU_DICO[meshname], ur.Material('LightGrey'),
626  dico.Nao_orig[meshname])
627  tempCol = ur.Collision(VISU_DICO[meshname],
628  dico.Nao_orig[meshname])
629  except KeyError:
630  tempVisu = None
631  tempCol = None
632  robot.links[link].visual = tempVisuMesh
633  robot.links[link].collision = tempColMesh
634  return (tempVisu, tempCol)
635 
636 ##############
637 #### Main ####
638 ##############
639 
640 args = parser.parse_args()
641 if args.input is '':
642  robot = URDF.from_parameter_server()
643 else:
644  robot = URDF.load_xml_file(args.input)
645 
646 if robot.name.find('V') != -1:
647  VERSION = robot.name[robot.name.find('V'):]
648 else:
649  VERSION = args.input[args.input.find('V'):args.input.find('V') + 3]
650 
651 if robot.name.lower().find('nao') != -1:
652  NAME = 'nao'
653  try:
654  import naoqi_tools.nao_dictionaries as dico
655  print('import nao dictionaries')
656  except:
657  print('unable to import nao dictionaries')
658  sys.exit(0)
659  LINKS_DICO = dico.Nao_links
660  VISU_DICO = dico.Nao_visu
661  OFFSETS_DICO = dico.Nao_offsets
662  XACRO_DICO = NAO_XACRO_DICO
663  MESHPKG = '_meshes'
664  SCALE = 0.1
665 elif robot.name.lower().find('romeo') != -1:
666  NAME = 'romeo'
667  try:
668  import naoqi_tools.romeo_dictionaries as dico
669  except:
670  print('unable to import romeo dictionaries')
671  sys.exit(0)
672  LINKS_DICO = dico.Romeo_links
673  OFFSETS_DICO = dico.Romeo_offsets
674  VISU_DICO = ''
675  XACRO_DICO = ROMEO_XACRO_DICO
676  MESHPKG = '_description'
677  SCALE = 1
678 
679 elif robot.name.lower().find('juliette') or robot.name.lower().find('pepper'):
680  NAME = 'pepper'
681  try:
682  import naoqi_tools.pepper_dictionaries as dico
683  except:
684  print('unable to import pepper dictionaries')
685  sys.exit(0)
686  LINKS_DICO = dico.Pepper_links
687  OFFSETS_DICO = dico.Pepper_offsets
688  VISU_DICO = ''
689  XACRO_DICO = PEPPER_XACRO_DICO
690  print('PROCESSING PEPPER ROBOT')
691  MESHPKG = '_meshes'
692  SCALE = 0.1
693  VERSION = '1.0'
694 
695 for element in robot.elements:
696  if type(element) == naoqi_tools.urdf.Material:
697  robot.elements.remove(element)
698 cmd = 'rospack find ' + NAME + '_description'
699 try:
700  pathdescription = subprocess.check_output(cmd,
701  stderr=subprocess.STDOUT, shell=True)[:-1]
702 except:
703  print('unable to find ' + NAME + '_description package')
704  sys.exit(0)
705 OUTPUT = os.path.join(pathdescription, 'urdf', NAME + VERSION +
706  '_generated_urdf', NAME + '.urdf')
707 print('processing ' + NAME + ' (' + VERSION + ") robot's urdf file in " +
708  OUTPUT)
709 cmd = 'rospack find ' + NAME + MESHPKG
710 try:
711  path_mesh_pkg = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
712  shell=True)[:-1]
713 except:
714  print('unable to find ' + NAME + MESHPKG + ' package')
715  sys.exit(0)
716 
718 if args.REP120 == 'true':
720 
721 for link in robot.links:
722  adjustMeshPath(path_mesh_pkg, link)
723 
724 if args.xacro == 'robot':
725  export_robot_element('material')
727 elif args.xacro == 'urdf':
728  robot.write_xml(OUTPUT)
729 else:
def export_kinematic_chain_to_xacro(keyword, baseChain='base_link', tipRefChain='default')
def export_robot_element(element)
XACRO FUNCTIONS ########.
def export_list_to_xacro(list, filename)
def add_dummy_inertia(list)
def write_comments_in_xacro(doc, filename)
def create_visual_xacro()
Meshes #####.
def REP120_compatibility()
def adjustMeshPath(path_mesh_pkg, link)
def define_materials()
FUNCTIONS ####.
def add_gazebo_tags()
def add_dummy_collision(list)
def add_transmission_tags()
def export_robot_to_xacro_files()


naoqi_tools
Author(s): Mikael Arguedas
autogenerated on Thu Jul 16 2020 03:18:36