Skip to content
Snippets Groups Projects
Commit 0c988ea3 authored by Florent Lamiraux's avatar Florent Lamiraux
Browse files

Add python file to parse kxml files.

    * src/CMakeLists.txt,
    * src/dynamic_graph/sot/dynamics/__init__.py,
    * src/dynamic_graph/sot/dynamics/parser.py: new.
parent 9488b8e8
No related branches found
No related tags found
1 merge request!1[major][cpp] starting point to integrate pinocchio
...@@ -63,7 +63,9 @@ EXEC_PROGRAM(${PYTHON_EXECUTABLE} ARGS "-c \"from distutils import sysconfig; pr ...@@ -63,7 +63,9 @@ EXEC_PROGRAM(${PYTHON_EXECUTABLE} ARGS "-c \"from distutils import sysconfig; pr
) )
# Install empty __init__.py files in intermediate directories. # Install empty __init__.py files in intermediate directories.
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/sot/dynamics/__init__.py INSTALL(FILES
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/sot/dynamics/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/sot/dynamics/parser.py
DESTINATION ${PYTHON_SITELIB}/dynamic_graph/sot/dynamics DESTINATION ${PYTHON_SITELIB}/dynamic_graph/sot/dynamics
) )
......
import dynamic import dynamic
dynamic.Dynamic('') dynamic.Dynamic('')
# -*- coding: utf-8 -*-
import xml.dom.minidom as dom
from dynamic_graph.sot.dynamics.dynamic import Dynamic
class Parser (object):
"""
Parser to build dynamic_graph.sot.dynamics.dynamic.Dynamic entities.
Format is kxml, Kineo CAM robot description format.
"""
robotFloatProperties = ['GAZEORIGINX', 'GAZEORIGINY', 'GAZEORIGINZ',
'GAZEDIRECTIONX',
'GAZEDIRECTIONY',
'GAZEDIRECTIONZ',
'ANKLEPOSINLEFTFOOTFRAMEX',
'ANKLEPOSINLEFTFOOTFRAMEY',
'ANKLEPOSINLEFTFOOTFRAMEZ',
'SOLECENTERINLEFTFOOTFRAMEX',
'SOLECENTERINLEFTFOOTFRAMEY',
'SOLECENTERINLEFTFOOTFRAMEZ',
'SOLELENGTH', 'SOLEWIDTH',
'LEFTHANDCENTERX',
'LEFTHANDCENTERY',
'LEFTHANDCENTERZ',
'LEFTTHUMBAXISX',
'LEFTTHUMBAXISY',
'LEFTTHUMBAXISZ',
'LEFTFOREFINGERAXISX',
'LEFTFOREFINGERAXISY',
'LEFTFOREFINGERAXISZ',
'LEFTPALMNORMALX',
'LEFTPALMNORMALY',
'LEFTPALMNORMALZ']
robotStringProperties = ['WAIST', 'CHEST', 'LEFTWRIST',
'RIGHTWRIST', 'LEFTANKLE', 'RIGHTANKLE', 'GAZE']
jointFloatProperties = ['MASS', 'COM_X', 'COM_Y', 'COM_Z',
'INERTIA_MATRIX_XX', 'INERTIA_MATRIX_YY',
'INERTIA_MATRIX_ZZ', 'INERTIA_MATRIX_XY',
'INERTIA_MATRIX_XZ', 'INERTIA_MATRIX_YZ']
jointTypes = ['HPP_FREEFLYER_JOINT', 'HPP_ROTATION_JOINT',
'HPP_TRANSLATION_JOINT', 'HPP_ANCHOR_JOINT']
jointType = {'HPP_FREEFLYER_JOINT':'freeflyer',
'HPP_ROTATION_JOINT':'rotation',
'HPP_TRANSLATION_JOINT':'translation',
'HPP_ANCHOR_JOINT':'anchor'}
robotTag = "HPP_HUMANOID_ROBOT"
def __init__(self, entityName, filename):
self.entity = Dynamic(entityName)
self.filename = filename
def parse (self):
dom1 = dom.parse(self.filename)
hNode = dom1.getElementsByTagName(self.robotTag)[0]
for p in self.robotStringProperties:
value = self.findStringProperty(hNode, p)
setattr(self, p, value)
for p in self.robotFloatProperties:
value = self.findFloatProperty(hNode, p)
setattr(self, p, value)
self.entity.createRobot()
rootJointNode = self.findRootJoint(hNode)
self.createJoint(rootJointNode, hNode.nodeName)
# Set specific joints.
self.entity.setSpecificJoint(str(self.WAIST), 'waist')
self.entity.setSpecificJoint(str(self.CHEST), 'chest')
self.entity.setSpecificJoint(str(self.LEFTWRIST), 'left-wrist')
self.entity.setSpecificJoint(str(self.RIGHTWRIST), 'right-wrist')
self.entity.setSpecificJoint(str(self.LEFTANKLE), 'left-ankle')
self.entity.setSpecificJoint(str(self.RIGHTANKLE), 'right-ankle')
self.entity.setSpecificJoint(str(self.GAZE), 'gaze')
# Hand parameters.
handCenter = (self.LEFTHANDCENTERX,
self.LEFTHANDCENTERY,
self.LEFTHANDCENTERZ)
thumbAxis = (self.LEFTTHUMBAXISX,
self.LEFTTHUMBAXISY,
self.LEFTTHUMBAXISZ)
forefingerAxis = (self.LEFTFOREFINGERAXISX,
self.LEFTFOREFINGERAXISY,
self.LEFTFOREFINGERAXISZ)
palmNormal = (self.LEFTPALMNORMALX,
self.LEFTPALMNORMALY,
self.LEFTPALMNORMALZ)
self.entity.setHandParameters(False, handCenter, thumbAxis,
forefingerAxis, palmNormal)
self.entity.setHandParameters(True, handCenter, thumbAxis,
forefingerAxis, palmNormal)
# Foot parameters.
soleLength = self.SOLELENGTH
soleWidth = self.SOLEWIDTH
anklePosition = (self.ANKLEPOSINLEFTFOOTFRAMEX,
self.ANKLEPOSINLEFTFOOTFRAMEY,
self.ANKLEPOSINLEFTFOOTFRAMEZ)
self.entity.setFootParameters(False, soleLength, soleWidth,
anklePosition)
# Gaze parameters.
gazeOrigin = (self.GAZEORIGINX, self.GAZEORIGINY, self.GAZEORIGINZ)
gazeDirection = (self.GAZEDIRECTIONX, self.GAZEDIRECTIONY,
self.GAZEDIRECTIONZ)
self.entity.setGazeParameters(gazeOrigin, gazeDirection)
return self.entity
def createJoint (self, node, parentName):
sotJointType = self.jointType[node.nodeName]
jointName = self.findStringProperty(node, 'NAME')
print ('jointName = %s' % repr(jointName))
properties = {}
for p in self.jointFloatProperties:
try:
properties[p] = self.findFloatProperty(node, p)
except RunTimeError:
print ('warning: ' + p +
' property not specified, set to 0.')
properties[p] = 0.
position = self.findJointPosition(node)
bounds = self.findJointBounds(node, jointName)
self.entity.createJoint(jointName, sotJointType, position)
# set mass center of mass and inertia matrix of attached body
self.entity.setMass(jointName, properties['MASS'])
com = (properties['COM_X'], properties['COM_Y'], properties['COM_Z'])
self.entity.setLocalCenterOfMass(jointName, com)
ixx = properties['INERTIA_MATRIX_XX']
iyy = properties['INERTIA_MATRIX_YY']
izz = properties['INERTIA_MATRIX_ZZ']
ixy = properties['INERTIA_MATRIX_XY']
ixz = properties['INERTIA_MATRIX_XZ']
iyz = properties['INERTIA_MATRIX_YZ']
inertiaMatrix = ((ixx, ixy, ixz),
(ixy, iyy, iyz),
(ixz, iyz, izz))
self.entity.setInertiaMatrix(jointName, inertiaMatrix)
# set bounds of degrees of freedom
for index in range(len(bounds)):
bound = bounds[index]
self.entity.setDofBounds(jointName, index, bound[0], bound[1])
self.attachJointToParent(parentName, jointName)
# recursively create child joints
childJoints = filter(lambda n:n.nodeName in self.jointTypes,
node.childNodes)
for childJoint in childJoints:
self.createJoint(childJoint, jointName)
def attachJointToParent(self, parentName, jointName):
if parentName == self.robotTag:
self.entity.setRootJoint(jointName)
else:
self.entity.addJoint(parentName, jointName)
def findRootJoint (self, hNode):
rJoint = filter(lambda n:n.nodeName in self.jointTypes,
hNode.childNodes)
if len(rJoint) == 0:
raise RuntimeError("Robot should have at least one joint.")
if len(rJoint) > 1:
raise RuntimeError("Robot should have exactly one root joint.\n" +
"This one has " + str(len(rJoint)) + ".")
return rJoint[0]
def findJointBounds(self, node, jointName):
dofList = filter(lambda n: n.nodeName == 'DOF', node.childNodes)
bounds = []
for dof in dofList:
dofName = self.findStringProperty(dof, 'NAME')
minValue = -1e-6
maxValue = 1e-6
try:
minValue = self.findFloatProperty(dof, 'DOF_MIN_VALUE')
except RunTimeError:
print ("min value of dof %s of joint %s is not specified." %
(dofName, jointName))
print ("Set to -1e-6")
try:
maxValue = self.findFloatProperty(dof, 'DOF_MAX_VALUE')
except RunTimeError:
print ("max value of dof %s of joint %s is not specified." %
(dofName, jointName))
print ("Set to 1e-6")
bounds.append((minValue, maxValue))
return bounds
def findStringProperty (self, node, prop):
return self.findProperty(node, prop, str)
def findFloatProperty (self, node, prop):
return self.findProperty(node, prop, float)
def findIntProperty (self, node, prop):
return self.findProperty(node, prop, int)
def findProperty(self, node, prop, cast):
properties = filter(lambda n: n.nodeName == 'PROPERTY', node.childNodes)
theProperty = filter (lambda p: p._attrs['stringId'].nodeValue == prop,
properties)
#print ('THE PROPERTY: %s' % prop)
#print (theProperty)
if len(theProperty) != 1:
raise RuntimeError(prop +
' should be specified once and only once.')
theProperty = theProperty[0]
value = filter(lambda n:n.nodeType == n.TEXT_NODE,
theProperty.childNodes)
if len(value) != 1:
raise RuntimeError('One and only one name should be specified for '
+ prop)
value = value[0]
#print ('VALUE: %s' % value.data)
#print ('cast(VALUE): %s' % cast(value.data))
return cast(value.data)
def findJointPosition(self, node):
tag = 'CURRENT_POSITION'
posNode = filter(lambda n: n.nodeName == tag,
node.childNodes)
if len(posNode) == 0:
print ("Position of joint not specified: tag " + tag + ",")
print ("Setting to identity")
return ((1.,0.,0.,0.),(0.,1.,0.,0.),(0.,0.,1.,0.),(0.,0.,0.,1.))
if len(posNode) > 1:
raise RuntimeError("'CURRENT_POSITION' specified more than once")
posNode = posNode[0]
if len(posNode.childNodes) != 1 and (posNode.childNodes[0].typeNode ==
posNode.TEXT_NODE):
raise RunTimeError("Position matrix ill defined")
# Remove spurious characters at beginning and end of matrix string
data = posNode.childNodes[0].data.strip('\n\t ')
# Split by lines and remove spurious characters at begginning and end of
# each line.
lines = map (lambda l: l.strip('\t '), data.split('\n'))
# Split each line between spaces
matrix = map (lambda l: l.split(' '), lines)
# cast each matrix element into float
matrix = map (lambda l: map (float, l), matrix)
# transform list into tuple
return tuple (map (tuple, matrix))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment