door.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import roslib; roslib.load_manifest('door_perception')
00004 import rospy
00005 import numpy
00006 import tf
00007 import tf.transformations as tfm
00008 import sys
00009 
00010 from articulation_msgs.msg import *
00011 from articulation_msgs.srv import *
00012 from geometry_msgs.msg import Pose, PoseStamped, Point, Quaternion
00013 from sensor_msgs.msg import ChannelFloat32
00014 from std_srvs.srv import Empty, EmptyResponse
00015 from door_perception.srv import DoorSrvResponse, DoorSrv
00016 from door_perception.msg import Door 
00017 
00018 def door_from_articulation_model(model):
00019   new_door = Door()
00020   isdoor = False
00021   for p in model.params:
00022     if p.name == "rot_center.x":
00023       new_door.axis.position.x = p.value
00024       isdoor = True
00025     if p.name == "rot_center.y":
00026       new_door.axis.position.y = p.value
00027       isdoor = True
00028     if p.name == "rot_center.z":
00029       new_door.axis.position.z = p.value
00030       isdoor = True
00031     if p.name == "rot_axis.x":
00032       new_door.axis.orientation.x = p.value
00033       isdoor = True
00034     if p.name == "rot_axis.y":
00035       new_door.axis.orientation.y = p.value
00036       isdoor = True
00037     if p.name == "rot_axis.z":
00038       new_door.axis.orientation.z = p.value
00039       isdoor = True
00040     if p.name == "rot_axis.w":
00041       new_door.axis.orientation.w = p.value
00042       isdoor = True
00043     if p.name == "rot_radius":
00044       new_door.radius = p.value
00045       isdoor = True
00046     if p.name == "rot_orientation.x":
00047       pass
00048     if p.name == "rot_orientation.y":
00049       pass
00050     if p.name == "rot_orientation.z":
00051       pass
00052     if p.name == "rot_orientation.w":
00053       pass
00054     if p.name == "rot_mode":
00055       pass
00056   if isdoor:
00057     new_door.header = model.header #to copy frame_id
00058   return new_door
00059 
00060 def load_model(filename):
00061   result = ModelMsg()
00062   with open(filename, "r") as file:
00063     mystring = file.read()
00064     result.deserialize(mystring)
00065     rospy.loginfo("Deserialized Previous Model from " + filename)
00066   return result
00067 
00068 def save_model(model_msg, filename):
00069     with open(filename, "w") as file:
00070       model_msg.serialize(file)
00071 
00072 def set_model_prior(model):
00073   try:
00074     rospy.logdebug(str(model.params))
00075     model_prior_set = rospy.ServiceProxy('model_prior_set', SetModelPriorSrv)
00076     rospy.wait_for_service('model_prior_set', 10)
00077     request = SetModelPriorSrvRequest()
00078     request.model = [model]
00079     response = model_prior_set(request)
00080   except rospy.ServiceException, e:
00081     print "Service did not process request: %s"%str(e)
00082   except rospy.ROSException, e:
00083     print "Service did not come up: %s"%str(e)
00084 
00085 
00086 ##############################################################
00087 class DoorNode:
00088   def __init__(self):
00089     self.model = ModelMsg()
00090     self.door = Door()
00091     self.setup_ros_communication()
00092     #LOADING
00093     self.model_file = rospy.get_param('~model_file', "")
00094     self.fixed_frame = rospy.get_param('~fixed_frame', "/odom_combined")
00095     self.load_door_model(self.model_file)
00096   
00097 
00098   def load_door_model_callback(self, request):
00099     filename = "model.msg"
00100     self.load_door_model(filename)
00101     return EmptyResponse()
00102 
00103   def load_door_model(self, filename):
00104     try:
00105       loaded_model = load_model(filename)
00106       if len(loaded_model.track.pose) > 0:
00107         self.model = loaded_model
00108         self.model.header.stamp = rospy.get_rostime()
00109         self.model.id = 0
00110         rospy.loginfo("Setting Model")
00111         set_model_prior(self.model)
00112         self.pose_callback(None)
00113     except IOError as (errno, strerror):
00114       rospy.logwarn("I/O error({0}): {1} '".format(errno, strerror) + self.model_file +"'") 
00115 
00116     #END LOADING
00117 
00118   def save_door_model_callback(self, request):
00119     filename = "model.msg"
00120     self.save_door_model(filename)
00121     return EmptyResponse()
00122 
00123   def save_door_model(self, filename):
00124     if(filename == ''):
00125       return
00126     rospy.loginfo("Saving model to " + filename)
00127     save_model(self.model, filename)
00128 
00129   def pose_callback(self, pose_stamped):
00130     rospy.loginfo("Pose arrived")
00131 
00132     try:
00133       request = TrackModelSrvRequest()
00134       if pose_stamped != None:
00135         pose_stamped.header.frame_id = pose_stamped.header.frame_id
00136         ff_pose_stamped = self.tfros.transformPose(self.fixed_frame, pose_stamped)
00137 
00138         #Add pose to Track
00139         self.model.track.header = ff_pose_stamped.header
00140         self.model.track.pose.append( ff_pose_stamped.pose )
00141         self.model.track.pose_headers.append( ff_pose_stamped.header )
00142 
00143       try:      
00144           #Request a model from articulatin stack
00145           request.model = self.model
00146           response = self.model_select(request)
00147 
00148           #Extract stats
00149           loglikelihood = [entry.value for entry in response.model.params if entry.name=='loglikelihood'][0]
00150           q_min = [entry.value for entry in response.model.params if entry.name=='q_min[0]'][0]
00151           q_max = [entry.value for entry in response.model.params if entry.name=='q_max[0]'][0]
00152           rospy.loginfo("selected model: '%s' (n = %d, log LH = %f)" % (
00153               response.model.name, len(response.model.track.pose), loglikelihood))
00154           rospy.loginfo("Angular range: %f - %f" % (q_min, q_max))
00155 
00156           #If what we expect, process it further
00157           if response.model.name == 'rotational' and loglikelihood < 0.0: 
00158             self.model_pub.publish(response.model)
00159   
00160             #extract door specific information
00161             #Rotate the coordinate frame, s.t. the X axis points horizontally along the door
00162             door_raw = door_from_articulation_model(response.model)
00163             axis = PoseStamped()
00164             axis.pose = door_raw.axis
00165             axis.header = door_raw.header
00166             self.door_axis_pub2.publish(axis)
00167 
00168             q = door_raw.axis.orientation
00169             #if(q.z > 0.0):
00170             rot_to_min_q = tfm.quaternion_about_axis(-q_min, (0,0,1))
00171             zx_aligned = tfm.quaternion_multiply((q.x, q.y, q.z, q.w), rot_to_min_q)
00172             door_orientation = zx_aligned
00173             #align_y = tfm.quaternion_about_axis(-numpy.pi/2.0, (0,0,1))
00174             #door_orientation = tfm.quaternion_multiply(align_y, zx_aligned)
00175             #else:
00176             #  rot_to_min_q = tfm.quaternion_about_axis(q_min, (0,0,1))
00177             #  x_aligned = tfm.quaternion_multiply((q.x, q.y, q.z, q.w), rot_to_min_q)
00178             #  #flip_z_axis_up = tfm.quaternion_about_axis(numpy.pi, (1,0,0))
00179             #  #zx_aligned = tfm.quaternion_multiply(flip_z_axis_up, x_aligned)
00180             #  door_orientation = x_aligned
00181             #  #align_y = tfm.quaternion_about_axis(-numpy.pi/2.0, (0,0,1))
00182             #  #door_orientation = tfm.quaternion_multiply(align_y, zx_aligned)
00183             door_raw.axis.orientation.x = door_orientation[0]
00184             door_raw.axis.orientation.y = door_orientation[1]
00185             door_raw.axis.orientation.z = door_orientation[2]
00186             door_raw.axis.orientation.w = door_orientation[3]
00187             self.door = door_raw
00188             self.publish_door()
00189 
00190             t = door_raw.axis.position
00191             handle2axis = tfm.translation_matrix((0, door_raw.radius, 0))
00192             axis2fixed  = tfm.quaternion_matrix(door_orientation)
00193             axis2fixed[3,:] =(t.x, t.y, t.z, 1.0) 
00194             handle2fixed  = numpy.dot(axis2fixed , handle2axis)
00195 
00196 
00197             #rmat_q = tfm.rotation_matrix(q_min, (0,0,1))
00198             #handle
00199           #if response.model.name == 'rotational' and loglikelihood < -100.0: 
00200             #self.model.track.pose.pop()# =  self.model.track.pose[0:21]
00201             #self.model.track.pose_headers.pop()# =  self.model.track.pose_headers[0:20]
00202             #self.pose_subscriber.unregister()
00203           #self.model = response.model
00204 
00205       except rospy.ServiceException: 
00206           print "model selection failed"
00207           pass
00208 
00209     except tf.ExtrapolationException:
00210       rospy.loginfo("Skipped Pose, Transform from %s to %s not available"%(pose_stamped.header.frame_id, self.fixed_frame))
00211 
00212   def publish_door(self):
00213       #publish
00214       axis = PoseStamped()
00215       axis.pose = self.door.axis
00216       axis.header = self.door.header
00217       self.door_axis_pub.publish(axis)
00218     
00219   def door_service_callback(self, request):
00220     doors_response = DoorSrvResponse()
00221     doors_response.doors.append(self.door)
00222     return self.doors_response
00223 
00224   def setup_ros_communication(self):
00225       self.tfros = tf.TransformListener()
00226       self.pose_subscriber = rospy.Subscriber("pose0", PoseStamped, self.pose_callback)
00227 
00228       rospy.wait_for_service('model_select')
00229       self.model_select = rospy.ServiceProxy('model_select', TrackModelSrv)
00230       self.model_pub = rospy.Publisher('model', ModelMsg)
00231       self.door_axis_pub = rospy.Publisher('door_axis',PoseStamped)
00232       self.door_axis_pub2 = rospy.Publisher('door_axis2',PoseStamped)
00233       self.service = rospy.Service('door_description', DoorSrv, self.door_service_callback)
00234       self.service = rospy.Service('save_door_model', Empty, self.save_door_model_callback)
00235       self.service = rospy.Service('load_door_model', Empty, self.load_door_model_callback)
00236  
00237 
00238 if __name__ == '__main__':
00239   rospy.init_node('door_fitting')
00240   dn = DoorNode();
00241 
00242   #Process until the user kills the node
00243   r = rospy.Rate(10)
00244   while not rospy.is_shutdown():
00245     dn.publish_door()
00246 
00247   #dn.save_door_model_callback(Empty())
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


door_perception_old
Author(s): Felix Endres
autogenerated on Wed Dec 26 2012 15:56:10