door_functions.py
Go to the documentation of this file.
00001 
00002 import roslib; roslib.load_manifest('pr2_doors_executive')
00003 import rospy
00004 
00005 import math
00006 
00007 from geometry_msgs.msg import *
00008 from door_msgs.msg import *
00009 
00010 import tf
00011 import tf.transformations as transformations
00012 import conversions
00013 
00014 import PyKDL as kdl
00015 
00016 eps_angle = 5.0*math.pi/180.0
00017 gripper_height = 0.8
00018 
00019 def point2kdl(point):
00020   return kdl.Vector(point.x, point.y, point.z)
00021 
00022 def kdl2point(vector):
00023   return Point(vector.x, vector.y, vector.z)
00024 
00025 def get_door_angle(door):
00026   frame_vec = kdl.Vector(
00027     door.frame_p1.x-door.frame_p2.x,
00028     door.frame_p1.y-door.frame_p2.y,
00029     door.frame_p1.z-door.frame_p2.z)
00030   door_vec = kdl.Vector(
00031     door.door_p1.x-door.door_p2.x,
00032     door.door_p1.y-door.door_p2.y,
00033     door.door_p1.z-door.door_p2.z)
00034   
00035   angle = get_yaw_angle(frame_vec, door_vec)
00036 
00037   if door.rot_dir == Door.ROT_DIR_CLOCKWISE and angle > eps_angle:
00038     rospy.logdebug("Door angle is positive, but door message specifies it turns clockwise")
00039 
00040   if door.rot_dir == Door.ROT_DIR_COUNTERCLOCKWISE and angle < -eps_angle:
00041     rospy.logdebug("Door angle is negative, but door message specifies it turns counter-clockwise")
00042 
00043   return angle
00044 
00045 def get_door_normal(door):
00046   frame_normal = get_frame_normal(door)
00047   rot_frame_door = kdl.Rotation.RotZ(get_door_angle(door))
00048   return rot_frame_door * frame_normal
00049 
00050 def get_frame_normal(door):
00051   """Get the normal of the door frame.
00052   @type door: door_msgs.msg.Door
00053   @rtype: kdl.Vector
00054   """
00055   # normal on frame
00056   p12 = kdl.Vector(
00057       door.frame_p1.x - door.frame_p2.x,
00058       door.frame_p1.y - door.frame_p2.y,
00059       door.frame_p1.z - door.frame_p2.z)
00060 
00061   p12.Normalize()
00062   z_axis = kdl.Vector(0,0,1)
00063   normal = p12 * z_axis
00064 
00065   # make normal point in direction we travel through door
00066   direction = kdl.Vector(
00067       door.travel_dir.x,
00068       door.travel_dir.y,
00069       door.travel_dir.z)
00070 
00071   if kdl.dot(direction, normal) < 0:
00072     normal = normal * -1.0
00073 
00074   return normal
00075 
00076 def get_Frame_angle(door):
00077   if door.hinge == door.HINGE_P1:
00078     return math.atan2(door.frame_p2.y - door.frame_p1.y, door.frame_p2.x - door.frame_p1.x)
00079   else:
00080     return math.atan2(door.frame_p1.y - door.frame_p2.y, door.frame_p1.x - door.frame_p2.x)
00081 
00082 def get_door_dir(door):
00083   # get frame vector
00084   if door.hinge == Door.HINGE_P1:
00085     frame_vec = point2kdl(door.frame_p2) - point2kdl(door.frame_p1)
00086   elif door.hinge == Door.HINGE_P2:
00087     frame_vec = point2kdl(door.frame_p1) - point2kdl(door.frame_p2)
00088   else:
00089     rospy.logerr("Hinge side is not defined")
00090 
00091   # rotate frame vector
00092   if door.rot_dir == Door.ROT_DIR_CLOCKWISE:
00093     frame_vec = kdl.Rotation.RotZ(-math.pi/2) * frame_vec
00094   elif door.rot_dir == Door.ROT_DIR_COUNTERCLOCKWISE:
00095     frame_vec = kdl.Rotation.RotZ(math.pi/2) * frame_vec
00096   else:
00097     rospy.logerr("Rot dir is not defined")
00098 
00099   if kdl.dot(frame_vec, get_frame_normal(door)) < 0:
00100     return -1.0 
00101   else:
00102     return 1.0
00103 
00104 def get_handle_dir(door):
00105   frame_normal = get_frame_normal(door)
00106 
00107   if door.hinge == Door.HINGE_P1:
00108     frame_vec = point2kdl(door.frame_p2) - point2kdl(door.frame_p1)
00109   elif door.hinge == Door.HINGE_P2:
00110     frame_vec = point2kdl(door.frame_p1) - point2kdl(door.frame_p2)
00111   else:
00112     rospy.logerr("Hinge side is not defined")
00113 
00114   rot_vec = frame_vec * frame_normal
00115   if rot_vec[2] > 0:
00116     return -1.0
00117   else:
00118     return 1.0
00119 
00120 def get_yaw_angle(v1, v2):
00121   """Get the angle between the projections of v1 and v2 onto the XY plane.
00122   @type v1: kdl.Vector
00123   @type v2: kdl.Vector
00124   @rtype: double
00125   """
00126   vec1 = v1
00127   vec2 = v2
00128   vec1.Normalize()
00129   vec2.Normalize()
00130   dot      = vec2[0] * vec1[0] + vec2[1] * vec1[1]
00131   perp_dot = vec2[1] * vec1[0] - vec2[0] * vec1[1]
00132   return math.atan2(perp_dot, dot)
00133 
00134 def get_robot_pose(door, dist):
00135   """Get a robot pose some distance from the door.
00136   @type door: door_msgs.msg.Door
00137   @rtype: geometry_msgs.msg.PoseStamped
00138   """
00139   x_axis = kdl.Vector(1,0,0)
00140 
00141   frame_1 = kdl.Vector(door.frame_p1.x, door.frame_p1.y, door.frame_p1.z)
00142   frame_2 = kdl.Vector(door.frame_p2.x, door.frame_p2.y, door.frame_p2.z)
00143   frame_center = (frame_1+frame_2)/2.0
00144 
00145   frame_normal = get_frame_normal(door)
00146   robot_pos = frame_center + (frame_normal * dist)
00147 
00148   robot_pose = kdl.Frame(
00149       kdl.Rotation.RPY(0,0,get_yaw_angle(x_axis, frame_normal)),
00150       robot_pos)
00151 
00152   robot_pose_msg = PoseStamped() 
00153   robot_pose_msg.header.frame_id = door.header.frame_id
00154   robot_pose_msg.header.stamp = door.header.stamp
00155   robot_pose_msg.pose = conversions.toMsg(robot_pose)
00156   
00157   return robot_pose_msg
00158 
00159 def get_gripper_pose(door, angle, dist, side):
00160     x_axis = kdl.Vector(1,0,0)
00161     
00162     # get hinge point
00163     hinge = kdl.Vector()
00164     frame_vec = kdl.Vector()
00165 
00166     if door.hinge == Door.HINGE_P1:
00167       hinge = kdl.Vector(door.door_p1.x, door.door_p1.y, door.door_p1.z)
00168       frame_vec = kdl.Vector(
00169           door.frame_p2.x - door.frame_p1.x,
00170           door.frame_p2.y - door.frame_p1.y,
00171           door.frame_p2.z - door.frame_p1.z)
00172     elif door.hinge == Door.HINGE_P2:
00173       hinge = kdl.Vector(door.door_p2.x, door.door_p2.y, door.door_p2.z)
00174       frame_vec = kdl.Vector(
00175           door.frame_p1.x - door.frame_p2.x,
00176           door.frame_p1.y - door.frame_p2.y,
00177           door.frame_p1.z - door.frame_p2.z)
00178 
00179     # get gripper pos
00180     frame_vec.Normalize()
00181     frame_vec = frame_vec * dist
00182     rot_angle = kdl.Rotation.RotZ(angle)
00183     gripper_pos = hinge + (rot_angle * frame_vec)
00184     
00185     frame_normal = get_frame_normal(door)
00186 
00187     if side == DoorCmd.PULL:
00188       axis_sign = -1.0
00189     else:
00190       axis_sign = 1.0
00191 
00192     gripper_pose = kdl.Frame(
00193       kdl.Rotation.RPY(0,0,get_yaw_angle(axis_sign*x_axis, frame_normal)+angle),
00194       gripper_pos)
00195 
00196     gripper_pose_msg = PoseStamped()
00197     gripper_pose_msg.header.frame_id = door.header.frame_id
00198     gripper_pose_msg.header.stamp = door.header.stamp
00199     gripper_pose_msg.pose = gripper_pose
00200 
00201     return gripper_pose_msg
00202 
00203 def get_handle_pose(door, side):
00204   x_axis = kdl.Vector(1,0,0)
00205   
00206   dist = math.sqrt(
00207       math.pow(door.frame_p1.x - door.handle.x,2)
00208       +math.pow(door.frame_p1.y - door.handle.y,2))
00209 
00210   if door.hinge == Door.HINGE_P2:
00211     dist = math.sqrt(math.pow(door.frame_p2.x - door.handle.x,2)+math.pow(door.frame_p2.y - door.handle.y,2))
00212 
00213   angle = get_door_angle(door)
00214 
00215   # get hinge point
00216 
00217   if door.hinge == Door.HINGE_P1:
00218     hinge = point2kdl(door.door_p1)
00219     frame_vec = point2kdl(door.frame_p2) - point2kdl(door.frame_p1)
00220   else:
00221     hinge = point2kdl(door.door_p2)
00222     frame_vec = point2kdl(door.frame_p1) - point2kdl(door.frame_p2)
00223 
00224   # get gripper pos
00225   frame_vec.Normalize()
00226   frame_vec = frame_vec * dist
00227   rot_angle = kdl.Rotation.RotZ(angle)
00228   handle_pos = hinge + (rot_angle * frame_vec)
00229   
00230   # Construct handle pose
00231   frame_normal = get_frame_normal(door)
00232   if side == -1:
00233     frame_normal = -frame_normal
00234 
00235   handle_pose = kdl.Frame(
00236       kdl.Rotation.RPY(0,0,get_yaw_angle(x_axis, frame_normal)),
00237       handle_pos)
00238 
00239   gripper_rotate = kdl.Frame(
00240       kdl.Rotation.RPY(math.pi/2,0.0,0.0),
00241       kdl.Vector(0,0,0))
00242   
00243   handle_pose = handle_pose * gripper_rotate
00244 
00245   handle_pose_msg = PoseStamped()
00246   handle_pose_msg.header.frame_id = door.header.frame_id
00247   handle_pose_msg.header.stamp = door.header.stamp
00248   handle_pose_msg.pose = conversions.toMsg(handle_pose)
00249 
00250   return handle_pose_msg


pr2_doors_executive
Author(s): Wim Meeussen
autogenerated on Wed Dec 11 2013 14:17:59