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