gazeboUrdf.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 extends urdf parsing lib (urdf.py) to handle any kind of gazebo tag
19 
20 import string
21 from xml.dom.minidom import Document
22 from xml.dom import minidom
23 import sys
24 from numpy import array, pi
25 import re
26 import copy
27 
28 ZERO_THRESHOLD = 0.000000001
29 
30 
31 def reindent(s, numSpaces):
32  """Reindent a string for tree structure pretty printing."""
33  s = string.split(s, '\n')
34  s = [(numSpaces * ' ') + line for line in s]
35  s = string.join(s, '\n')
36  return s
37 
38 
39 def add(doc, base, element):
40  """Add an XML element for URDF export"""
41  if element is not None:
42  base.appendChild(element.to_xml(doc))
43 
44 
45 def add_openrave(doc, base, element):
46  """Add an XML element for OpenRAVE XML export"""
47  if element is not None:
48  # TODO: copy this iterable test elsewhere
49  newelements = element.to_openrave_xml(doc)
50  if hasattr(newelements, '__iter__'):
51  for e in newelements:
52  base.appendChild(e)
53  else:
54  base.appendChild(newelements)
55 
56 
57 def pfloat(x):
58  """Print float value as string"""
59  return "{0}".format(x).rstrip('.')
60 
61 
62 def to_string(data=None):
63  """Convert data fromvarious types to urdf string format"""
64  if data is None:
65  return None
66  if hasattr(data, '__iter__'):
67  outlist = []
68  for a in data:
69  try:
70  if abs(a) > ZERO_THRESHOLD:
71  outlist.append(pfloat(a))
72  else:
73  outlist.append("0")
74  except TypeError:
75  outlist.append(pfloat(a))
76  return ' '.join(outlist)
77 
78  elif type(data) == type(0.0):
79  return pfloat(data if abs(data) > ZERO_THRESHOLD else 0)
80  elif not isinstance(data, str):
81  return str(data)
82  return data
83 
84 
85 def set_attribute(node, name, value):
86  """Set an attribute on an XML node, converting data to string format"""
87  node.setAttribute(name, to_string(value))
88 
89 
90 def set_content(doc, node, data):
91  """Create a text node and add it to the current element"""
92  if data is None:
93  return
94  node.appendChild(doc.createTextNode(to_string(data)))
95 
96 
97 def short(doc, name, key, value):
98  element = doc.createElement(name)
99  set_attribute(element, key, value)
100  return element
101 
102 
103 def create_element(doc, name, contents=None, key=None, value=None):
104  element = doc.createElement(name)
105  if contents is not None:
106  set_content(doc, element, contents)
107  if key is not None:
108  set_attribute(element, key, value)
109 
110  return element
111 
112 
113 def create_child(doc, name, contents=None, key=None, value=None):
114  doc.appendChild(create_element(doc, name, contents=None, key=None,
115  value=None))
116 
117 
118 def children(node):
119  children = []
120  for child in node.childNodes:
121  if child.nodeType is node.TEXT_NODE \
122  or child.nodeType is node.COMMENT_NODE:
123  continue
124  else:
125  children.append(child)
126  return children
127 
128 ##################################
129 ############# Gazebo #############
130 ##################################
131 
132 
133 class Gazebo(object):
134  """
135  Represent any type of gazebo tag:
136  - global gazebo tag inside a robot tag
137  - gazebo tags referencing links
138  - gazebo tags instantiating plugins and sensors
139  """
140  ATTRIBUTE_NAMES = ['material', 'turnGravityOff', 'dampingFactor',
141  'maxVel', 'minDepth', 'mu1', 'mu2', 'fdir1', 'kp',
142  'kd', 'selfCollide', 'maxContacts', 'laserRetro']
143 
144  def __init__(self, reference=None, material=None, gravity=None,
145  dampingFactor=None, maxVel=None, minDepth=None, mu1=None,
146  mu2=None, fdir1=None, kp=None, kd=None, selfCollide=None,
147  maxContacts=None, laserRetro=None, plugin=[], sensor=[]):
148  self.reference = reference
149  self.material = material
150  self.gravity = gravity
151  self.dampingFactor = dampingFactor
152  self.maxVel = maxVel
153  self.minDepth = minDepth
154  self.mu1 = mu1
155  self.mu2 = mu2
156  self.fdir1 = fdir1
157  self.kp = kp
158  self.kd = kd
159  self.selfCollide = selfCollide
160  self.maxContacts = maxContacts
161  self.laserRetro = laserRetro
162  self.plugins = plugin
163  self.sensors = sensor
164 
165  @staticmethod
166  def parse(node, verbose=True):
167  gaze = Gazebo()
168  gaze.sensors = []
169  gaze.plugins = []
170  if node.hasAttribute('reference'):
171  gaze.reference = node.getAttribute('reference')
172  for child in children(node):
173  for attribute in gaze.ATTRIBUTE_NAMES:
174  if child.localName == attribute:
175  if attribute == 'sensor':
176  gaze.sensors.append(Sensor.parse(child, verbose))
177  else:
178  setattr(gaze, attribute,
179  str(child.childNodes[0].nodeValue))
180  else:
181  for child in children(node):
182  if child.localName == 'plugin':
183  gaze.plugins.append(BasePlugin.parse(child, verbose))
184  return gaze
185 
186  def to_xml(self, doc):
187  xml = doc.createElement('gazebo')
188  if self.reference is not None:
189  set_attribute(xml, 'reference', self.reference)
190  for attribute in self.ATTRIBUTE_NAMES:
191  value = getattr(self, attribute)
192  if value is not None:
193  xml.appendChild(createElement(doc, attribute, value))
194 
195  if len(self.sensors) != 0:
196  for sensor in self.sensors:
197  add(doc, xml, sensor)
198  else:
199  if len(self.plugins) != 0:
200  for plugin in self.plugins:
201  add(doc, xml, plugin)
202 
203  return xml
204 
205  def __str__(self):
206  s = ""
207  if self.reference is not None:
208  s += 'Reference: {0}\n'.format(self.reference)
209  for name in self.ATTRIBUTE_NAMES:
210  value = getattr(self, name)
211  if value is not None:
212  s += name.title() + ':\n'
213  s += reindent(str(value, 1)) + '\n'
214  for sensor in self.sensors:
215  s += 'Sensor'
216  s += reindent(str(sensor), 1) + '\n'
217  else:
218  for plugin in self.plugins:
219  s += 'Plugin'
220  s += reindent(str(plugin), 1) + '\n'
221  return s
222 
223 
224 ###############################################################################
225 ######################### PLUGINS CLASSES #####################################
226 ###############################################################################
227 class BasePlugin(object):
228  """
229  Abstract class used to parse plugin tags and instantiating
230  inherited plugin accordingly
231 
232  """
233  ATTRIBUTE_NAMES = []
234 
235  def __init__(self, name=None, filename=None, attributes=None):
236  self.name = name
237  self.filename = filename
238  self.attributes = attributes
239 
240  @classmethod
241  def parse(cls, node, verbose=True):
242  for child in children(node):
243  if child.localName == 'cameraName':
244  plug = CameraPlugin(node.getAttribute('name'),
245  node.getAttribute('filename'))
246  break
247  elif child.localName == 'bumperTopicName':
248  plug = BumperPlugin(node.getAttribute('name'),
249  node.getAttribute('filename'))
250  break
251  elif child.localName == 'leftFrontJoint':
252  plug = DrivePlugin(node.getAttribute('name'),
253  node.getAttribute('filename'))
254  break
255  elif child.localName == 'odometryTopic':
256  plug = OdometryPlugin(node.getAttribute('name'),
257  node.getAttribute('filename'))
258  break
259  elif child.localName == 'height':
260  plug = VideoPlugin(node.getAttribute('name'),
261  node.getAttribute('filename'))
262  break
263  elif child.localName == 'mimicJoint':
264  plug = MimicJointPlugin(node.getAttribute('name'),
265  node.getAttribute('filename'))
266  break
267  elif child.localName == 'robotSimType':
268  plug = SimuPlugin(node.getAttribute('name'),
269  node.getAttribute('filename'))
270  else:
271  plug = ImuLaserPlugin()
272  for child in children(node):
273  if child.localName in cls.ATTRIBUTE_NAMES:
274  setattr(plug, child.localName,
275  str(child.childNodes[0].nodeValue))
276  return plug
277 
278  def to_xml(self, doc):
279  xml = doc.createElement('plugin')
280  if self.name is not None:
281  set_attribute(xml, 'name', self.name)
282  if self.filename is not None:
283  set_attribute(xml, 'filename', self.filename)
284  for attribute in self.ATTRIBUTE_NAMES:
285  value = getattr(self, attribute)
286  if value is not None:
287  xml.appendChild(create_element(doc, attribute, value))
288  return xml
289 
290  def __str__(self):
291  if self.name is not None:
292  s = 'Name: {0}\n'.format(self.name)
293  if self.filename is not None:
294  s += 'Filename: {0}\n'.format(self.filename)
295  for attribute in self.ATTRIBUTE_NAMES:
296  value = getattr(self, attribute)
297  if value is not None:
298  s += name.title() + ":\n"
299  s += reindent(str(value), 1) + '\n'
300 
301 
303  """
304  Define the simulation plugin used to initialize simulation parameters in
305  gazebo plugin
306  robotNamespace
307  robotSimType
308  """
309  ATTRIBUTE_NAMES = ['robotNamespace', 'robotSimType']
310 
311  def __init__(self, name=None, filename=None, robot_namespace=None,
312  robot_sim_type=None):
313  super(SimuPlugin, self).__init__(name, filename,
314  {'robotNamespace': robot_namespace,
315  'robotSimType': robot_sim_type})
316 # self.filename = filename
317 
318 
320  """
321  Define the plugin used to define mimic joints
322 
323  (joint not commanded directly by an actuator
324  but depending on another joint position)
325  plugin
326  joint
327  mimicjoint
328  multiplier
329  offset
330  """
331  ATTRIBUTE_NAMES = ['joint', 'mimicJoint', 'multiplier', 'offset']
332 
333  def __init__(self, name=None, filename=None, joint=None, mimic_joint=None,
334  multiplier=None, offset=None):
335  super(MimicJointPlugin, self).__init__(name, filename,
336  {'joint': joint,
337  'mimicJoint': mimic_joint,
338  'multiplier': multiplier,
339  'offset': offset})
340 
341 
342 # Sensors Plugin
344  """
345  Class defining the plugin used to simulate bumpers on a robot
346  plugin
347  bumperTopicName
348  frameName
349  alwaysOn
350  updateRate
351  """
352  ATTRIBUTE_NAMES = ['bumperTopicName', 'frameName', 'alwaysOn',
353  'updateRate']
354 
355  def __init__(self, name=None, filename=None, bumper_topic_name=None,
356  frame_name=None, always_on=None, update_rate=None):
357  super(BumperPlugin, self).__init__(name, filename,
358  {'bumperTopicName': bumper_topic_name,
359  'frameName': frame_name,
360  'alwaysOn': always_on,
361  'updateRate': update_rate})
362 
363 
365  """
366  Class defining the plugin used to IMU on a robot
367  note: gazebo official IMU plugin has some weird behaviour
368 
369  plugin
370  robotNamespace
371  topicName
372  gaussianNoise
373  xyzOffset
374  rpyOffset
375  alwaysOn
376  updateRate
377  frameName
378  hokuyoMinIntensity
379  frameId
380  accelGaussianNoise
381  headingGaussianNoise
382  rateGaussianNoise
383  bodyName
384  """
385  ATTRIBUTE_NAMES = ['robotNamespace', 'topicName', 'gaussianNoise',
386  'xyzOffset', 'rpyOffset', 'alwaysOn', 'updateRate',
387  'frameName', 'hokuyoMinIntensity', 'frameId',
388  'accelGaussianNoise', 'headingGaussianNoise',
389  'rateGaussianNoise', 'bodyName']
390 
391  def __init__(self, name=None, filename=None, robot_namespace=None,
392  topic_name=None, gaussian_noise=None, xyz_offset=None,
393  rpy_offset=None, always_on=None, update_rate=None,
394  hokuyo_min_intensity=None, frame_id=None,
395  accel_gaussian_noise=None, heading_gaussian_noise=None,
396  rate_gaussian_noise=None, body_name=None):
397  super(ImuLaserPlugin, self).__init__(name, filename,
398  {'robotNamespace': robot_namespace,
399  'topicName': topic_name,
400  'gaussianNoise': gaussian_noise,
401  'xyzOffset': xyz_offset,
402  'rpyOffset': rpy_offset,
403  'alwaysOn': always_on,
404  'updateRate': update_rate,
405  'hokuyoMinIntensity': hokuyo_min_intensity,
406  'frameId': frame_id,
407  'accelGaussianNoise': accel_gaussian_noise,
408  'headingGaussianNoise': heading_gaussian_noise,
409  'rateGaussianNoise': rate_gaussian_noise,
410  'bodyName': body_name})
411 
412 
414  """
415  Class defining the plugin used to simulate video on a robot
416  plugin
417  topicName
418  height
419  width
420  alwaysOn
421  updateRate
422  """
423  ATTRIBUTE_NAMES = ['topicName', 'height', 'width', 'alwaysOn',
424  'updateRate']
425 
426  def __init__(self, name=None, filename=None, topic_name=None, height=None,
427  width=None, always_on=None, update_rate=None):
428  super(VideoPlugin, self).__init__(name, filename,
429  {'topicName': topic_name,
430  'height': height,
431  'width': width,
432  'alwaysOn': always_on,
433  'updateRate': update_rate})
434 
435 
437  """
438  Class defining the plugin used to odometry on a robot
439  plugin
440  commandTopic
441  odometryTopic
442  odometryFrame
443  odometryRate
444  robotBaseFrame
445  alwaysOn
446  update_rate
447  """
448  ATTRIBUTE_NAMES = ['commandTopic', 'odometryTopic', 'odometryFrame',
449  'odometryRate', 'robotBaseFrame', 'alwaysOn',
450  'updateRate']
451 
452  def __init__(self, name=None, filename=None, command_topic=None,
453  odometry_topic=None, odometry_frame=None, odometry_rate=None,
454  robot_base_frame=None, always_on=None, update_rate=None):
455  super(OdometryPlugin, self).__init__(name, filename,
456  {'commandTopic': command_topic,
457  'odometryTopic': odometry_topic,
458  'odometryFrame': odometry_frame,
459  'odometryRate': odometry_rate,
460  'robotBaseFrame': robot_base_frame,
461  'alwaysOn': always_on,
462  'updateRate': update_rate})
463 
464 
465 #################################
466 ###### SENSOR DECLARATION #######
467 #################################
468 
469 class Sensor(object):
470  """
471  Class defining the sensors and the related plugins
472  sensor
473  type
474  updateRate
475  camera
476  ...
477  plugin
478  ...
479  pose
480  visualize
481  ray
482  """
483  def __init__(self, name=None, type=None, update_rate=None, camera=[],
484  plugin=[], pose=None, visualize=None, ray=None):
485  self.name = name
486  self.type = type
487  self.update_rate = update_rate
488  self.cameras = camera
489  self.plugins = plugin
490  self.pose = pose
491  self.visualize = visualize
492  self.ray = ray
493 
494  @staticmethod
495  def parse(node, verbose=True):
496  sens = Sensor(node.getAttribute('name'), node.getAttribute('type'))
497  sens.plugins = []
498  sens.cameras = []
499  for child in children(node):
500  if child.localName == 'ray':
501  sens.ray = Ray.parse(child, verbose)
502  if child.localName == 'update_rate':
503  sens.update_rate = str(child.childNodes[0].nodeValue)
504  if child.localName == 'camera':
505  sens.cameras.append(CameraSensor.parse(child, verbose))
506  if child.localName == 'plugin':
507  sens.plugins.append(BasePlugin.parse(child, verbose))
508  if child.localName == 'pose':
509  sens.pose = array([float(x) for x in
510  child.childNodes[0].nodeValue.split(' ')])
511  if child.localName == 'visualize':
512  sens.visualize = str(child.childNodes[0].nodeValue)
513  return sens
514 
515  def to_xml(self, doc):
516  xml = doc.createElement('sensor')
517  set_attribute(xml, 'name', self.name)
518  set_attribute(xml, 'type', self.type)
519  if self.update_rate is not None:
520  xml.appendChild(create_element(doc, 'update_rate',
521  self.update_rate))
522  for camera in self.cameras:
523  add(doc, xml, camera)
524  for plugin in self.plugins:
525  add(doc, xml, plugin)
526  if self.pose is not None:
527  xml.appendChild(create_element(doc, 'pose', self.pose))
528  # add(doc,xml,self.pose)
529  if self.visualize is not None:
530  xml.appendChild(create_element(doc, 'visualize', self.visualize))
531  if self.ray is not None:
532  add(doc, xml, self.ray)
533  return xml
534 
535  def __str__(self):
536  s = ""
537  s += "Name: {0}\n".format(self.name)
538  s += "Type: {0}\n".format(self.type)
539  if self.update_rate is not None:
540  s += "Update_rate:\n"
541  s += reindent(str(self.update_rate), 1) + "\n"
542  for camera in self.cameras:
543  s += 'Camera'
544  s += reindent(str(camera), 1) + "\n"
545  for plugin in self.plugins:
546  s += 'Plugin'
547  s += reindent(str(plugin), 1) + "\n"
548 
549  if self.visualize is not None:
550  s += "Visualize:\n"
551  s += reindent(str(self.visualize), 1) + "\n"
552 
553  if self.ray is not None:
554  s += "Ray:\n"
555  s += reindent(str(self.ray), 1) + "\n"
556  return s
557 
558 
559 class CameraSensor(object):
560  """
561  Class defining the camera sensor.
562 
563  This can instantiate specific plugin according to the type of camera
564  (RGB,Stereo,Depth...) camera
565  horizontal_fov
566  image
567  clip
568  noise
569  """
570  def __init__(self, name=None, horizontal_fov=None, image=None, clip=None,
571  noise=None):
572  self.name = name
573  self.horizontal_fov = horizontal_fov
574  self.image = image
575  self.clip = clip
576  self.noise = noise
577 
578  @staticmethod
579  def parse(node, verbose=True):
580  sens = CameraSensor()
581  if node.hasAttribute('name'):
582  sens.name = node.getAttribute('name')
583  for child in children(node):
584  if child.localName == 'horizontal_fov':
585  sens.horizontal_fov = str(child.childNodes[0].nodeValue)
586  elif child.localName == 'image':
587  sens.image = Image.parse(child, verbose)
588  elif child.localName == 'clip':
589  sens.clip = Clip.parse(child, verbose)
590  elif child.localName == 'noise':
591  sens.noise = Noise.parse(child, verbose)
592  return sens
593 
594  def to_xml(self, doc):
595  xml = doc.createElement('camera')
596  if self.name is not None:
597  set_attribute(xml, 'name', self.name)
598  if self.horizontal_fov is not None:
599  xml.appendChild(create_element(doc, 'horizontal_fov',
600  self.horizontal_fov))
601  if self.image is not None:
602  add(doc, xml, self.image)
603  if self.clip is not None:
604  add(doc, xml, self.clip)
605  if self.noise is not None:
606  add(doc, xml, self.noise)
607  return xml
608 
609  def __str__(self):
610  s = ''
611  if self.name is not None:
612  s = "Name: {0}\n".format(self.name)
613  if self.horizontal_fov is not None:
614  s += "Horizontal_fov:\n"
615  s += reindent(str(self.horizontal_fov), 1) + '\n'
616  if self.image is not None:
617  s += "Image:\n"
618  s += reindent(str(self.image), 1) + '\n'
619  if self.clip is not None:
620  s += "Clip:\n"
621  s += reindent(str(self.clip), 1) + '\n'
622  if self.noise is not None:
623  s += "Noise:\n"
624  s += reindent(str(self.noise), 1) + '\n'
625  return s
626 
627 
628 ################################
629 ##### Auxiliary Elements #######
630 ################################
631 
632 class Clip(object):
633  """
634  Class defining the clip element used in sensors
635 
636  (for range or beaming sensors)
637  structure:
638  clip
639  near
640  far
641  """
642  def __init__(self, near=None, far=None):
643  self.near = near
644  self.far = far
645 
646  @staticmethod
647  def parse(node, verbose=True):
648  clip = Clip()
649  for child in children(node):
650  if child.localName == 'near':
651  clip.near = str(child.childNodes[0].nodeValue)
652  elif child.localName == 'far':
653  clip.far = str(child.childNodes[0].nodeValue)
654  return clip
655 
656  def to_xml(self, doc):
657  xml = doc.createElement('clip')
658  if self.near is not None:
659  xml.appendChild(create_element(doc, 'near', self.near))
660  if self.far is not None:
661  xml.appendChild(create_element(doc, 'far', self.far))
662  return xml
663 
664  def __str__(self):
665  s = ''
666  if self.near is not None:
667  s += "Near:\n"
668  s += reindent(str(self.near), 1) + '\n'
669  if self.far is not None:
670  s += "Far:\n"
671  s += reindent(str(self.far), 1) + '\n'
672  return s
673 
674 
675 class Image(object):
676  """
677  Class defining the image element used in camera sensor
678  image
679  height
680  width
681  format
682  """
683  def __init__(self, height=None, width=None, format=None):
684  self.height = height
685  self.width = width
686  self.format = format
687 
688  @staticmethod
689  def parse(node, verbose=True):
690  img = Image()
691  for child in children(node):
692  if child.localName == 'height':
693  img.height = str(child.childNodes[0].nodeValue)
694  elif child.localName == 'width':
695  img.width = str(child.childNodes[0].nodeValue)
696  elif child.localName == 'format':
697  img.format = str(child.childNodes[0].nodeValue)
698  return img
699 
700  def to_xml(self, doc):
701  xml = doc.createElement('image')
702  if self.height is not None:
703  xml.appendChild(create_element(doc, 'height', self.height))
704  if self.width is not None:
705  xml.appendChild(create_element(doc, 'width', self.width))
706  if self.format is not None:
707  xml.appendChild(create_element(doc, 'format', self.format))
708  return xml
709 
710  def __str__(self):
711  s = ''
712  if self.height is not None:
713  s += "Height:\n"
714  s += reindent(str(self.height), 1) + '\n'
715  if self.width is not None:
716  s += "Width:\n"
717  s += reindent(str(self.width), 1) + '\n'
718  if self.format is not None:
719  s += "Format:\n"
720  s += reindent(str(self.format), 1) + '\n'
721  return s
722 
723 
724 class Noise(object):
725  """
726  Class defining the noise element used in most sensors definition
727  noise
728  type
729  mean
730  stddev
731  """
732  def __init__(self, type=None, mean=None, stddev=None):
733  self.type = type
734  self.mean = mean
735  self.stddev = stddev
736 
737  @staticmethod
738  def parse(node, verbose=True):
739  noise = Noise()
740  for child in children(node):
741  if child.localName == 'type':
742  noise.type = str(child.childNodes[0].nodeValue)
743  elif child.localName == 'mean':
744  noise.mean = str(child.childNodes[0].nodeValue)
745  elif child.localName == 'stddev':
746  noise.stddev = str(child.childNodes[0].nodeValue)
747  return noise
748 
749  def to_xml(self, doc):
750  xml = doc.createElement('noise')
751  if self.type is not None:
752  xml.appendChild(create_element(doc, 'type', self.type))
753  if self.mean is not None:
754  xml.appendChild(create_element(doc, 'mean', self.mean))
755  if self.stddev is not None:
756  xml.appendChild(create_element(doc, 'stddev', self.stddev))
757  return xml
758 
759  def __str__(self):
760  s = ''
761  if self.type is not None:
762  s += "Type:\n"
763  s += reindent(str(self.type), 1) + '\n'
764  if self.mean is not None:
765  s += "Mean:\n"
766  s += reindent(str(self.mean), 1) + '\n'
767  if self.stddev is not None:
768  s += "Stddev:\n"
769  s += reindent(str(self.stddev), 1) + '\n'
770  return s
771 
772 
773 class Ray(object):
774  """
775  Class defining the ray element used in most range sensors
776  ray
777  scan
778  range
779  noise
780  """
781  def __init__(self, scan=None, range=None, noise=None):
782  self.scan = scan
783  self.range = range
784  self.noise = noise
785 
786  @staticmethod
787  def parse(node, verbose=True):
788  ray = Ray()
789  for child in children(node):
790  if child.localName == 'scan':
791  ray.scan = Scan.parse(child, verbose)
792  # str(child.childNodes[0].nodeValue)
793  elif child.localName == 'range':
794  ray.range = Range.parse(child, verbose)
795  # str(child.childNodes[0].nodeValue)
796  elif child.localName == 'noise':
797  ray.noise = Noise.parse(child, verbose)
798  return ray
799 
800  def to_xml(self, doc):
801  xml = doc.createElement('ray')
802  if self.scan is not None:
803  add(doc, xml, self.scan)
804  if self.range is not None:
805  add(doc, xml, self.range)
806  if self.noise is not None:
807  add(doc, xml, self.noise)
808  return xml
809 
810  def __str__(self):
811  s = ''
812  if self.scan is not None:
813  s += "Scan:\n"
814  s += reindent(str(self.scan), 1) + '\n'
815  if self.range is not None:
816  s += "Range:\n"
817  s += reindent(str(self.range), 1) + '\n'
818  if self.noise is not None:
819  s += "Noise:\n"
820  s += reindent(str(self.noise), 1) + '\n'
821  return s
822 
823 
824 class Range(object):
825  """
826  Class defining the range element used in most range sensors (mostly LASERs)
827  range:
828  min
829  max
830  resolution
831  """
832  def __init__(self, min=None, max=None, resolution=None):
833  self.min = min
834  self.max = max
835  self.resolution = resolution
836 
837  @staticmethod
838  def parse(node, verbose=True):
839  rang = Range()
840  for child in children(node):
841  if child.localName == 'min':
842  rang.min = str(child.childNodes[0].nodeValue)
843  elif child.localName == 'max':
844  rang.max = str(child.childNodes[0].nodeValue)
845  elif child.localName == 'resolution':
846  rang.resolution = str(child.childNodes[0].nodeValue)
847  return rang
848 
849  def to_xml(self, doc):
850  xml = doc.createElement('range')
851  if self.min is not None:
852  xml.appendChild(create_element(doc, 'min', self.min))
853  if self.max is not None:
854  xml.appendChild(create_element(doc, 'max', self.max))
855  if self.resolution is not None:
856  xml.appendChild(create_element(doc, 'resolution', self.resolution))
857  return xml
858 
859  def __str__(self):
860  s = ''
861  if self.min is not None:
862  s += "Min:\n"
863  s += reindent(str(self.min), 1) + '\n'
864  if self.max is not None:
865  s += "Max:\n"
866  s += reindent(str(self.max), 1) + '\n'
867  if self.resolution is not None:
868  s += "Resolution:\n"
869  s += reindent(str(self.resolution), 1) + '\n'
870  return s
871 
872 
873 class Scan(object):
874  """
875  Class defining the scan element used in most range sensors (mostly LASERs)
876  scan
877  horizontal
878  """
879  def __init__(self, horizontal=None):
880  self.horizontal = horizontal
881 
882  @staticmethod
883  def parse(node, verbose=True):
884  scan = Scan()
885  for child in children(node):
886  if child.localName == 'horizontal':
887  scan.horizontal = Horizontal.parse(child, verbose)
888  # str(child.childNodes[0].nodeValue)
889  return scan
890 
891  def to_xml(self, doc):
892  xml = doc.createElement('scan')
893  if self.horizontal is not None:
894  add(doc, xml, self.horizontal)
895  return xml
896 
897  def __str__(self):
898  s = ''
899  if self.horizontal is not None:
900  s += "Horizontal:\n"
901  s += reindent(str(self.horizontal), 1) + '\n'
902  return s
903 
904 
905 class Horizontal(object):
906  """
907  Class defining the horizontal element
908  used in most range sensors(mostly LASERs)
909  horizontal
910  samples
911  resolution
912  min_angle
913  max_angle
914  """
915  def __init__(self, samples=None, resolution=None, min_angle=None,
916  max_angle=None):
917  self.samples = samples
918  self.resolution = resolution
919  self.min_angle = min_angle
920  self.max_angle = max_angle
921 
922  @staticmethod
923  def parse(node, verbose=True):
924  hori = Horizontal()
925  for child in children(node):
926  if child.localName == 'samples':
927  hori.samples = str(child.childNodes[0].nodeValue)
928  elif child.localName == 'resolution':
929  hori.resolution = str(child.childNodes[0].nodeValue)
930  elif child.localName == 'min_angle':
931  hori.min_angle = str(child.childNodes[0].nodeValue)
932  # Noise.parse(child, verbose)
933  elif child.localName == 'max_angle':
934  hori.max_angle = str(child.childNodes[0].nodeValue)
935  return hori
936 
937  def to_xml(self, doc):
938  xml = doc.createElement('horizontal')
939  if self.samples is not None:
940  xml.appendChild(create_element(doc, 'samples', self.samples))
941  if self.resolution is not None:
942  xml.appendChild(create_element(doc, 'resolution', self.resolution))
943  if self.min_angle is not None:
944  xml.appendChild(create_element(doc, 'min_angle', self.min_angle))
945  if self.max_angle is not None:
946  xml.appendChild(create_element(doc, 'max_angle', self.samples))
947 
948  return xml
949 
950  def __str__(self):
951  s = ''
952  if self.samples is not None:
953  s += "Samples:\n"
954  s += reindent(str(self.samples), 1) + '\n'
955  if self.resolution is not None:
956  s += "Resolution:\n"
957  s += reindent(str(self.resolution), 1) + '\n'
958  if self.min_angle is not None:
959  s += "Min_angle:\n"
960  s += reindent(str(self.min_angle), 1) + '\n'
961  if self.max_angle is not None:
962  s += "Max_angle:\n"
963  s += reindent(str(self.max_angle), 1) + '\n'
964  return s
def __init__(self, name=None, filename=None, bumper_topic_name=None, frame_name=None, always_on=None, update_rate=None)
Definition: gazeboUrdf.py:356
def __init__(self, type=None, mean=None, stddev=None)
Definition: gazeboUrdf.py:732
def parse(node, verbose=True)
Definition: gazeboUrdf.py:787
def parse(node, verbose=True)
Definition: gazeboUrdf.py:647
def __init__(self, samples=None, resolution=None, min_angle=None, max_angle=None)
Definition: gazeboUrdf.py:916
def __init__(self, name=None, filename=None, robot_namespace=None, robot_sim_type=None)
Definition: gazeboUrdf.py:312
def parse(node, verbose=True)
Definition: gazeboUrdf.py:923
def create_child(doc, name, contents=None, key=None, value=None)
Definition: gazeboUrdf.py:113
def short(doc, name, key, value)
Definition: gazeboUrdf.py:97
def add(doc, base, element)
Definition: gazeboUrdf.py:39
def __init__(self, name=None, filename=None, attributes=None)
Definition: gazeboUrdf.py:235
def __init__(self, height=None, width=None, format=None)
Definition: gazeboUrdf.py:683
def __init__(self, name=None, horizontal_fov=None, image=None, clip=None, noise=None)
Definition: gazeboUrdf.py:571
def parse(node, verbose=True)
Definition: gazeboUrdf.py:495
def to_string(data=None)
Definition: gazeboUrdf.py:62
def __init__(self, name=None, filename=None, robot_namespace=None, topic_name=None, gaussian_noise=None, xyz_offset=None, rpy_offset=None, always_on=None, update_rate=None, hokuyo_min_intensity=None, frame_id=None, accel_gaussian_noise=None, heading_gaussian_noise=None, rate_gaussian_noise=None, body_name=None)
Definition: gazeboUrdf.py:396
def __init__(self, name=None, filename=None, command_topic=None, odometry_topic=None, odometry_frame=None, odometry_rate=None, robot_base_frame=None, always_on=None, update_rate=None)
Definition: gazeboUrdf.py:454
Gazebo #############.
Definition: gazeboUrdf.py:133
def __init__(self, reference=None, material=None, gravity=None, dampingFactor=None, maxVel=None, minDepth=None, mu1=None, mu2=None, fdir1=None, kp=None, kd=None, selfCollide=None, maxContacts=None, laserRetro=None, plugin=[], sensor=[])
Definition: gazeboUrdf.py:147
def parse(node, verbose=True)
Definition: gazeboUrdf.py:166
def parse(cls, node, verbose=True)
Definition: gazeboUrdf.py:241
def parse(node, verbose=True)
Definition: gazeboUrdf.py:689
def add_openrave(doc, base, element)
Definition: gazeboUrdf.py:45
def __init__(self, name=None, filename=None, joint=None, mimic_joint=None, multiplier=None, offset=None)
Definition: gazeboUrdf.py:334
def parse(node, verbose=True)
Definition: gazeboUrdf.py:838
def __init__(self, horizontal=None)
Definition: gazeboUrdf.py:879
def __init__(self, min=None, max=None, resolution=None)
Definition: gazeboUrdf.py:832
def __init__(self, scan=None, range=None, noise=None)
Definition: gazeboUrdf.py:781
def __init__(self, name=None, type=None, update_rate=None, camera=[], plugin=[], pose=None, visualize=None, ray=None)
Definition: gazeboUrdf.py:484
def parse(node, verbose=True)
Definition: gazeboUrdf.py:579
def __init__(self, near=None, far=None)
Definition: gazeboUrdf.py:642
def __init__(self, name=None, filename=None, topic_name=None, height=None, width=None, always_on=None, update_rate=None)
Definition: gazeboUrdf.py:427
def set_attribute(node, name, value)
Definition: gazeboUrdf.py:85
def set_content(doc, node, data)
Definition: gazeboUrdf.py:90
def reindent(s, numSpaces)
Definition: gazeboUrdf.py:31
def parse(node, verbose=True)
Definition: gazeboUrdf.py:883
def create_element(doc, name, contents=None, key=None, value=None)
Definition: gazeboUrdf.py:103
def parse(node, verbose=True)
Definition: gazeboUrdf.py:738


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