foot_contact_monitor.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import rospy
00004 from geometry_msgs.msg import WrenchStamped, PoseStamped
00005 import message_filters
00006 import tf
00007 import numpy
00008 from tf.transformations import *
00009 import diagnostic_updater
00010 from diagnostic_msgs.msg import DiagnosticStatus
00011 
00012 g_contact_state = None
00013 
00014 def offsetPose(offset):
00015     pose = PoseStamped()
00016     pose.pose.position.x = offset[0]
00017     pose.pose.position.y = offset[1]
00018     pose.pose.position.z = offset[2]
00019     pose.pose.orientation.x = offset[3]
00020     pose.pose.orientation.y = offset[4]
00021     pose.pose.orientation.z = offset[5]
00022     pose.pose.orientation.w = offset[6]
00023     return pose
00024 
00025 def publishMidCoords(stamp):
00026     l_pose = computeEndCoords("left", stamp)
00027     r_pose = computeEndCoords("right", stamp)
00028     # compute the midcoords between l_pose and r_pose
00029     l_pos = numpy.array((l_pose.pose.position.x,
00030                          l_pose.pose.position.y,
00031                          l_pose.pose.position.z))
00032     r_pos = numpy.array((r_pose.pose.position.x,
00033                          r_pose.pose.position.y,
00034                          r_pose.pose.position.z))
00035     l_rot = numpy.array((l_pose.pose.orientation.x,
00036                          l_pose.pose.orientation.y,
00037                          l_pose.pose.orientation.z,
00038                          l_pose.pose.orientation.w))
00039     r_rot = numpy.array((r_pose.pose.orientation.x,
00040                          r_pose.pose.orientation.y,
00041                          r_pose.pose.orientation.z,
00042                          r_pose.pose.orientation.w))
00043     mid_pos = (l_pos + r_pos) / 2.0
00044     mid_rot = quaternion_slerp(l_rot, r_rot, 0.5)
00045     br = tf.TransformBroadcaster()
00046     br.sendTransform(mid_pos, mid_rot,
00047                      stamp,
00048                      ground_frame,
00049                      parent_frame)
00050 
00051 def computeEndCoords(leg, stamp):
00052     if leg == "left":
00053         foot_frame_id = lfoot_frame
00054         foot_offset_pose = offsetPose(lfoot_offset)
00055     elif leg == "right":
00056         foot_frame_id = rfoot_frame
00057         foot_offset_pose = offsetPose(rfoot_offset)
00058     else:
00059         raise Exception("unknown leg specified")
00060     foot_offset_pose.header.frame_id = foot_frame_id
00061     foot_offset_pose.header.stamp = stamp
00062     tf_listener.waitForTransform(parent_frame, foot_offset_pose.header.frame_id, 
00063                                  foot_offset_pose.header.stamp,
00064                                  rospy.Duration(1.0))
00065     pose_stamped = tf_listener.transformPose(parent_frame, foot_offset_pose)
00066     return pose_stamped
00067 
00068 def publishSingleCoords(leg, stamp):
00069     pose_stamped = computeEndCoords(leg, stamp)
00070     br = tf.TransformBroadcaster()
00071     br.sendTransform((pose_stamped.pose.position.x,
00072                       pose_stamped.pose.position.y,
00073                       pose_stamped.pose.position.z),
00074                      (pose_stamped.pose.orientation.x,
00075                       pose_stamped.pose.orientation.y,
00076                       pose_stamped.pose.orientation.z,
00077                       pose_stamped.pose.orientation.w),
00078                      pose_stamped.header.stamp,
00079                      ground_frame,
00080                      pose_stamped.header.frame_id)
00081 
00082 def callback(lfoot_force_msg, rfoot_force_msg):
00083     global force_thr, g_contact_state
00084     if lfoot_force_msg.wrench.force.z > force_thr:
00085         lfoot_contact = True
00086     else:
00087         lfoot_contact = False
00088     if rfoot_force_msg.wrench.force.z > force_thr:
00089         rfoot_contact = True
00090     else:
00091         rfoot_contact = False
00092     try:
00093         if lfoot_contact and rfoot_contact:
00094             g_contact_state = "both"
00095             publishMidCoords(lfoot_force_msg.header.stamp)
00096         elif lfoot_contact:
00097             g_contact_state = "lleg"
00098             publishSingleCoords("left", lfoot_force_msg.header.stamp)
00099         elif rfoot_contact:
00100             g_contact_state = "rleg"
00101             publishSingleCoords("right", rfoot_force_msg.header.stamp)
00102         else:
00103             g_contact_state = "air"
00104             publishMidCoords(lfoot_force_msg.header.stamp)
00105         updater.update()
00106     except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
00107         rospy.logerr("tf error, ignored")
00108 
00109 
00110 def contactStateDiagnostic(stats):
00111     if g_contact_state == "both":
00112         stats.summary(DiagnosticStatus.OK,
00113                       "BOTH legs on the floor")
00114     elif g_contact_state == "lleg":
00115         stats.summary(DiagnosticStatus.OK,
00116                       "LEFT leg on the floor")
00117     elif g_contact_state == "rleg":
00118         stats.summary(DiagnosticStatus.OK,
00119                       "RIGHT leg on the floor")
00120     elif g_contact_state == "air":
00121         stats.summary(DiagnosticStatus.WARN,
00122                       "robot on the AIR")
00123     else:
00124         stats.summary(DiagnosticStatus.ERROR,
00125                       "failed to estimate contact state")
00126     stats.add("contact state", g_contact_state)
00127 
00128 if __name__ == "__main__":
00129     rospy.init_node("foot_contact_monitor")
00130     tf_listener = tf.TransformListener()
00131     updater = diagnostic_updater.Updater()
00132     updater.setHardwareID(rospy.get_name())
00133     updater.add('ContactState', contactStateDiagnostic)
00134     force_thr = rospy.get_param('~force_thr', 100)
00135     ground_frame = rospy.get_param('~ground_frame', 'ground')
00136     parent_frame = rospy.get_param('~parent_frame', 'BODY')
00137     lfoot_frame = rospy.get_param('~lfoot_frame_id')
00138     rfoot_frame = rospy.get_param('~rfoot_frame_id')
00139     lfoot_offset = rospy.get_param('~lfoot_endcoords_offset')
00140     rfoot_offset = rospy.get_param('~rfoot_endcoords_offset')
00141     ground_parent_frame = rospy.get_param('')
00142     lfoot_sub = message_filters.Subscriber('/off_lfsensor', WrenchStamped)
00143     rfoot_sub = message_filters.Subscriber('/off_rfsensor', WrenchStamped)
00144     ts = message_filters.TimeSynchronizer([lfoot_sub, rfoot_sub], 100)
00145     ts.registerCallback(callback)
00146     rospy.spin()
00147 


jsk_footstep_controller
Author(s):
autogenerated on Mon Oct 6 2014 01:12:04