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 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 # Returns a PyKDL.Tree generated from a urdf_parser_py.urdf.URDF object.
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()


pykdl_utils
Author(s): Kelsey Hawkins
autogenerated on Fri Aug 28 2015 11:05:34