kdl_parser.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # A parser for converting Python URDF objects into KDL Trees.
00004 #
00005 # Copyright (c) 2012, Georgia Tech Research Corporation
00006 # All rights reserved.
00007 #
00008 # Redistribution and use in source and binary forms, with or without
00009 # modification, are permitted provided that the following conditions are met:
00010 #     * Redistributions of source code must retain the above copyright
00011 #       notice, this list of conditions and the following disclaimer.
00012 #     * Redistributions in binary form must reproduce the above copyright
00013 #       notice, this list of conditions and the following disclaimer in the
00014 #       documentation and/or other materials provided with the distribution.
00015 #     * Neither the name of the Georgia Tech Research Corporation nor the
00016 #       names of its contributors may be used to endorse or promote products
00017 #       derived from this software without specific prior written permission.
00018 #
00019 # THIS SOFTWARE IS PROVIDED BY GEORGIA TECH RESEARCH CORPORATION ''AS IS'' AND
00020 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022 # DISCLAIMED. IN NO EVENT SHALL GEORGIA TECH BE LIABLE FOR ANY DIRECT, INDIRECT,
00023 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00024 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00025 # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00026 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00027 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 #
00030 # Author: Kelsey Hawkins
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 # Returns a PyKDL.Tree generated from a urdf_parser_py.urdf.URDF object.
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()


pykdl_utils
Author(s): Kelsey Hawkins / kphawkins@gatech.edu, Advisor: Prof. Charlie Kemp (Healthcare Robotics Lab at Georgia Tech)
autogenerated on Wed Nov 27 2013 11:37:37