pr2_arm_cart_base.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 #
00003 # Base class for interacting with a PR2 Cartesian realtime controller.
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 import copy
00034 
00035 import roslib
00036 roslib.load_manifest('hrl_pr2_arms')
00037 
00038 import rospy
00039 from std_msgs.msg import Float64MultiArray
00040 from geometry_msgs.msg import PoseStamped
00041 
00042 from ep_arm_base import EPArmBase, create_ep_arm
00043 from hrl_geom.pose_converter import PoseConv
00044 import hrl_geom.transformations as trans
00045 
00046 def extract_twist(msg):
00047     return np.array([msg.linear.x, msg.linear.y, msg.linear.z, 
00048                      msg.angular.x, msg.angular.y, msg.angular.z])
00049 
00050 ##
00051 # Base class for interacting with the Cartesian controllers on the PR2.
00052 # The equilibrium points are pose-like objects.
00053 class PR2ArmCartBase(EPArmBase):
00054     def __init__(self, arm_side, urdf, base_link='torso_lift_link', end_link='%s_gripper_tool_frame', 
00055                  controller_name='/%s_cart', kdl_tree=None, timeout=1.):
00056         super(PR2ArmCartBase, self).__init__(arm_side, urdf, base_link, end_link, 
00057                                              controller_name, kdl_tree, timeout)
00058         self.command_pose_pub = rospy.Publisher(self.controller_name + '/command_pose', PoseStamped)
00059 
00060     ##
00061     # Command the realtime controller to set its cartesian equilibrium
00062     # point to this pose.
00063     # @param Pose-like object
00064     def set_ep(self, pose):
00065         cep_pose_stmp = PoseConv.to_pose_stamped_msg('torso_lift_link', pose)
00066         self.command_pose_pub.publish(cep_pose_stmp)
00067 
00068     ##
00069     # Returns pairs of positions and rotations linearly interpolated between
00070     # the start and end position/orientations.  Rotations are found using slerp
00071     # @return List of (pos, rot) waypoints between start and end.
00072     def interpolate_ep(self, ep_a, ep_b, t_vals):
00073         pos_a, rot_a = ep_a
00074         pos_b, rot_b = ep_b
00075         num_samps = len(t_vals)
00076         pos_waypoints = (np.array(pos_a) + 
00077                          np.array(np.tile(pos_b - pos_a, (1, num_samps))) * np.array(t_vals))
00078         pos_waypoints = [np.mat(pos).T for pos in pos_waypoints.T]
00079         rot_homo_a, rot_homo_b = np.eye(4), np.eye(4)
00080         rot_homo_a[:3,:3] = rot_a
00081         rot_homo_b[:3,:3] = rot_b
00082         quat_a = trans.quaternion_from_matrix(rot_homo_a)
00083         quat_b = trans.quaternion_from_matrix(rot_homo_b)
00084         rot_waypoints = []
00085         for t in t_vals:
00086             cur_quat = trans.quaternion_slerp(quat_a, quat_b, t)
00087             rot_waypoints.append(np.mat(trans.quaternion_matrix(cur_quat))[:3,:3])
00088         return zip(pos_waypoints, rot_waypoints)
00089 
00090     ##
00091     # Gets the Cartesian difference in the two poses.
00092     def cart_error(self, ep_actual, ep_desired):
00093         pos_act, rot_act = PoseConv.to_pos_rot(ep_actual)
00094         pos_des, rot_des = PoseConv.to_pos_rot(ep_desired)
00095         err = np.mat(np.zeros((6, 1)))
00096         err[:3,0] = pos_act - pos_des
00097         err[3:6,0] = np.mat(trans.euler_from_matrix(rot_des.T * rot_act)).T
00098         return err
00099 
00100 ##
00101 # Class which extends the PR2ArmCartBase to provide functionality for changing the
00102 # posture.
00103 class PR2ArmCartPostureBase(PR2ArmCartBase):
00104     def __init__(self, arm_side, urdf, base_link='torso_lift_link', end_link='%s_gripper_tool_frame', 
00105                  controller_name='/%s_cart', kdl_tree=None, timeout=1.):
00106         super(PR2ArmCartPostureBase, self).__init__(arm_side, urdf, base_link, end_link, 
00107                                              controller_name, kdl_tree, timeout)
00108         self.command_posture_pub = rospy.Publisher(self.controller_name + '/command_posture', 
00109                                                    Float64MultiArray)
00110 
00111     ##
00112     # Sets the null-space posture the arm will attempt to reach with its
00113     # extra degree of freedom
00114     # @param List of joint angles representing the posture.  If any element is None,
00115     #        posture control is disabled for that joint. If posture is None, posture
00116     #        control is disabled for all joints.
00117     def set_posture(self, posture=None):
00118         if posture is None:
00119             posture = [None] * len(self.get_joint_names())
00120         posture = copy.copy(posture)
00121         for i, p in enumerate(posture):
00122             if p is None:
00123                 posture[i] = 9999
00124         msg = Float64MultiArray()
00125         msg.data = posture
00126         self.command_posture_pub.publish(msg)
00127 


hrl_pr2_arms
Author(s): Kelsey Hawkins, Advisor: Prof. Charlie Kemp, Lab: Healthcare Robotics Lab
autogenerated on Wed Nov 27 2013 11:41:30