00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 import numpy as np
00033
00034 import roslib
00035 roslib.load_manifest("pykdl_utils")
00036 import PyKDL as kdl
00037
00038 from urdf_parser_py.urdf import URDF
00039
00040 def euler_to_quat(r, p, y):
00041 sr, sp, sy = np.sin(r/2.0), np.sin(p/2.0), np.sin(y/2.0)
00042 cr, cp, cy = np.cos(r/2.0), np.cos(p/2.0), np.cos(y/2.0)
00043 return [sr*cp*cy - cr*sp*sy,
00044 cr*sp*cy + sr*cp*sy,
00045 cr*cp*sy - sr*sp*cy,
00046 cr*cp*cy + sr*sp*sy]
00047
00048 def urdf_pose_to_kdl_frame(pose):
00049 pos = [0., 0., 0.]
00050 rot = [0., 0., 0.]
00051 if pose is not None:
00052 if pose.position is not None:
00053 pos = pose.position
00054 if pose.rotation is not None:
00055 rot = pose.rotation
00056 return kdl.Frame(kdl.Rotation.Quaternion(*euler_to_quat(*rot)),
00057 kdl.Vector(*pos))
00058
00059 def urdf_joint_to_kdl_joint(jnt):
00060 origin_frame = urdf_pose_to_kdl_frame(jnt.origin)
00061 if jnt.joint_type == 'fixed':
00062 return kdl.Joint(jnt.name, kdl.Joint.None)
00063 axis = kdl.Vector(*[float(s) for s in jnt.axis.split()])
00064 if jnt.joint_type == 'revolute':
00065 return kdl.Joint(jnt.name, origin_frame.p,
00066 origin_frame.M * axis, kdl.Joint.RotAxis)
00067 if jnt.joint_type == 'continuous':
00068 return kdl.Joint(jnt.name, origin_frame.p,
00069 origin_frame.M * axis, kdl.Joint.RotAxis)
00070 if jnt.joint_type == 'prismatic':
00071 return kdl.Joint(jnt.name, origin_frame.p,
00072 origin_frame.M * axis, kdl.Joint.TransAxis)
00073 print "Unknown joint type: %s." % jnt.joint_type
00074 return kdl.Joint(jnt.name, kdl.Joint.None)
00075
00076 def urdf_inertial_to_kdl_rbi(i):
00077 origin = urdf_pose_to_kdl_frame(i.origin)
00078 rbi = kdl.RigidBodyInertia(i.mass, origin.p,
00079 kdl.RotationalInertia(i.matrix['ixx'],
00080 i.matrix['iyy'],
00081 i.matrix['izz'],
00082 i.matrix['ixy'],
00083 i.matrix['ixz'],
00084 i.matrix['iyz']))
00085 return origin.M * rbi
00086
00087
00088
00089 def kdl_tree_from_urdf_model(urdf):
00090 root = urdf.get_root()
00091 tree = kdl.Tree(root)
00092 def add_children_to_tree(parent):
00093 if parent in urdf.child_map:
00094 for joint, child_name in urdf.child_map[parent]:
00095 child = urdf.links[child_name]
00096 if child.inertial is not None:
00097 kdl_inert = urdf_inertial_to_kdl_rbi(child.inertial)
00098 else:
00099 kdl_inert = kdl.RigidBodyInertia()
00100 kdl_jnt = urdf_joint_to_kdl_joint(urdf.joints[joint])
00101 kdl_origin = urdf_pose_to_kdl_frame(urdf.joints[joint].origin)
00102 kdl_sgm = kdl.Segment(child_name, kdl_jnt,
00103 kdl_origin, kdl_inert)
00104 tree.addSegment(kdl_sgm, parent)
00105 add_children_to_tree(child_name)
00106 add_children_to_tree(root)
00107 return tree
00108
00109 def main():
00110 import sys
00111 def usage():
00112 print("Tests for kdl_parser:\n")
00113 print("kdl_parser <urdf file>")
00114 print("\tLoad the URDF from file.")
00115 print("kdl_parser")
00116 print("\tLoad the URDF from the parameter server.")
00117 sys.exit(1)
00118
00119 if len(sys.argv) > 2:
00120 usage()
00121 if len(sys.argv) == 2 and (sys.argv[1] == "-h" or sys.argv[1] == "--help"):
00122 usage()
00123 if (len(sys.argv) == 1):
00124 robot = URDF.load_from_parameter_server(verbose=False)
00125 else:
00126 robot = URDF.load_xml_file(sys.argv[1], verbose=False)
00127 tree = kdl_tree_from_urdf_model(robot)
00128 num_non_fixed_joints = 0
00129 for j in robot.joints:
00130 if robot.joints[j].joint_type != 'fixed':
00131 num_non_fixed_joints += 1
00132 print "URDF non-fixed joints: %d;" % num_non_fixed_joints,
00133 print "KDL joints: %d" % tree.getNrOfJoints()
00134 print "URDF joints: %d; KDL segments: %d" %(len(robot.joints),
00135 tree.getNrofSegments())
00136 import random
00137 base_link = robot.get_root()
00138 end_link = robot.links.keys()[random.randint(0, len(robot.links)-1)]
00139 chain = tree.getChain(base_link, end_link)
00140 print "Root link: %s; Random end link: %s" % (base_link, end_link)
00141 for i in range(chain.getNrOfSegments()):
00142 print chain.getSegment(i).getName()
00143
00144 if __name__ == "__main__":
00145 main()