00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 import roslib; roslib.load_manifest('pr2_doors_executive')
00033 import rospy
00034
00035 from actionlib import *
00036 from actionlib.msg import *
00037 import smach
00038 from smach import *
00039 from smach_ros import *
00040 from door_msgs.msg import *
00041 from move_base_msgs.msg import *
00042 from pr2_common_action_msgs.msg import *
00043 from pr2_mechanism_msgs.srv import SwitchController, SwitchControllerRequest
00044 from pr2_controllers_msgs.msg import *
00045 from std_msgs.msg import *
00046
00047 import threading
00048
00049 import door_functions
00050
00051 class SwitchControllersState(State):
00052 def __init__(self, stop_controllers, start_controllers):
00053 State.__init__(self, outcomes=['succeeded', 'aborted'])
00054 rospy.wait_for_service('pr2_controller_manager/switch_controller')
00055 self.srv = rospy.ServiceProxy('pr2_controller_manager/switch_controller', SwitchController)
00056 self.start_list = start_controllers
00057 self.stop_list = stop_controllers
00058
00059 def execute(self,ud):
00060 try:
00061 self.srv(self.start_list, self.stop_list, SwitchControllerRequest.STRICT)
00062 return 'succeeded'
00063 except rospy.ServiceException, e:
00064 return 'aborted'
00065
00066 def main():
00067 rospy.init_node('doors_executive')
00068
00069
00070 sm = StateMachine(
00071 ['succeeded', 'aborted', 'preempted'],
00072 input_keys = ['door'],
00073 output_keys = ['door'])
00074
00075 with sm:
00076 StateMachine.add('INIT_CONTROLLERS',
00077 SwitchControllersState(
00078 stop_controllers = ["r_arm_cartesian_tff_controller"],
00079 start_controllers = ["r_arm_controller"]),
00080 { 'succeeded':'TUCK_ARMS' })
00081 StateMachine.add('TUCK_ARMS',
00082 SimpleActionState('tuck_arms', TuckArmsAction, TuckArmsGoal(True, True)),
00083 { 'succeeded': 'DETECT_DOOR',
00084 'aborted': 'TUCK_ARMS'})
00085
00086 @smach.cb_interface(
00087 outcomes=['unlatched', 'closed', 'aborted'],
00088 output_keys=['door'])
00089 def detect_door_result_cb(ud, status, result):
00090 if status == GoalStatus.SUCCEEDED:
00091 ud.door = result.door
00092 if result.door.latch_state == Door.UNLATCHED:
00093 return 'unlatched'
00094 else:
00095 return 'closed'
00096 return 'aborted'
00097 StateMachine.add('DETECT_DOOR',
00098 SimpleActionState('detect_door',DoorAction,
00099 goal_slots = ['door'],
00100 result_cb = detect_door_result_cb),
00101 { 'closed': 'DETECT_HANDLE',
00102 'unlatched': 'aborted',
00103 'aborted': 'DETECT_DOOR'})
00104
00105
00106 @smach.cb_interface(output_keys=['door'])
00107 def detect_handle_result_cb(ud, status, result):
00108 if status == GoalStatus.SUCCEEDED:
00109 ud.door = result.door
00110 StateMachine.add('DETECT_HANDLE',
00111 SimpleActionState('detect_handle', DoorAction,
00112 goal_slots = ['door'],
00113 result_cb=detect_handle_result_cb),
00114 { 'succeeded': 'APPROACH_DOOR',
00115 'aborted': 'DETECT_HANDLE'})
00116
00117 @smach.cb_interface(input_keys=['door'])
00118 def get_approach_goal(userdata, goal):
00119 target_pose = door_functions.get_robot_pose(userdata.door, -0.7)
00120 return MoveBaseGoal(target_pose)
00121 StateMachine.add('APPROACH_DOOR',
00122 SimpleActionState('pr2_move_base_local', MoveBaseAction, goal_cb = get_approach_goal),
00123 { 'succeeded':'GRASP_HANDLE',
00124 'aborted':'APPROACH_DOOR'})
00125
00126 StateMachine.add('UNTUCK_FOR_GRASP',
00127 SimpleActionState('tuck_arms', TuckArmsAction, TuckArmsGoal(True, False)),
00128 { 'succeeded': 'GRASP_HANDLE',
00129 'aborted': 'aborted'})
00130
00131 open_gripper_goal = Pr2GripperCommandGoal()
00132 open_gripper_goal.command.position = 0.07
00133 open_gripper_goal.command.max_effort = 99999
00134 StateMachine.add('OPEN_GRIPPER',
00135 SimpleActionState('r_gripper_controller/gripper_action',
00136 Pr2GripperCommandAction,
00137 goal = open_gripper_goal),
00138 {'succeeded':'GRASP_HANDLE'})
00139
00140 StateMachine.add('GRASP_HANDLE',
00141 SimpleActionState('grasp_handle', DoorAction, goal_slots = ['door']),
00142 { 'succeeded':'TFF_START',
00143 'aborted':'RECOVER_RELEASE_HANDLE'})
00144
00145 StateMachine.add('RECOVER_RELEASE_HANDLE',
00146 SimpleActionState('release_handle',DoorAction,goal_slots = ['door']),
00147 { 'succeeded':'RECOVER_TUCK_ARMS',
00148 'aborted':'RECOVER_RELEASE_HANDLE'})
00149 StateMachine.add('RECOVER_TUCK_ARMS', SimpleActionState('tuck_arms', TuckArmsAction, TuckArmsGoal(True, True)),
00150 { 'succeeded': 'APPROACH_DETECT_POSE',
00151 'aborted': 'RECOVER_TUCK_ARMS'})
00152
00153 @smach.cb_interface(input_keys=['door'])
00154 def get_approach_detect_goal(userdata, goal):
00155 target_pose = door_functions.get_robot_pose(userdata.door, -1.5)
00156 return MoveBaseGoal(target_pose)
00157 StateMachine.add('APPROACH_DETECT_POSE',
00158 SimpleActionState('pr2_move_base_local', MoveBaseAction, goal_cb = get_approach_detect_goal),
00159 { 'succeeded':'DETECT_DOOR',
00160 'aborted':'APPROACH_DETECT_POSE'})
00161
00162
00163 StateMachine.add('TFF_START',
00164 SwitchControllersState(
00165 stop_controllers = ["r_arm_controller"],
00166 start_controllers = ["r_arm_cartesian_tff_controller"]),
00167 { 'succeeded':'TURN_HANDLE' })
00168
00169
00170
00171
00172
00173 StateMachine.add('TURN_HANDLE',
00174 SimpleActionState('unlatch_handle',DoorAction,goal_slots = ['door']),
00175 { 'succeeded':'OPEN_DOOR'})
00176
00177 open_door_cc = Concurrence(
00178 ['succeeded','aborted','preempted'],
00179 default_outcome = 'aborted',
00180 input_keys = ['door'],
00181 output_keys = ['door'],
00182 child_termination_cb = lambda so: True,
00183 outcome_map = {
00184 'succeeded':{'MOVE_THROUGH':'succeeded'},
00185 'aborted':{'MOVE_THROUGH':'aborted'},
00186 'preempted':{'MOVE_THROUGH':'preempted'}})
00187 StateMachine.add('OPEN_DOOR',open_door_cc,
00188 { 'succeeded':'TFF_STOP' })
00189 with open_door_cc:
00190 Concurrence.add('MOVE_THROUGH',SimpleActionState('move_base_door',DoorAction, goal_slots = ['door']))
00191 Concurrence.add('PUSH_DOOR',SimpleActionState('open_door',DoorAction, goal_slots = ['door']))
00192
00193 StateMachine.add('TFF_STOP',
00194 SwitchControllersState(
00195 stop_controllers = ["r_arm_cartesian_tff_controller"],
00196 start_controllers = ["r_arm_controller"]),
00197 { 'succeeded':'RELEASE_HANDLE' })
00198
00199 StateMachine.add('RELEASE_HANDLE',
00200 SimpleActionState('release_handle',DoorAction,goal_slots = ['door']),
00201 { 'succeeded':'FINISH_TUCK_ARMS'})
00202
00203 StateMachine.add('FINISH_TUCK_ARMS', SimpleActionState('tuck_arms', TuckArmsAction, TuckArmsGoal(True, True)),
00204 { 'succeeded': 'succeeded'})
00205
00206
00207 """
00208 # Sequence for pushing the door
00209 StateMachine.add('TOUCH_DOOR',
00210 SimpleActionState('touch_door', DoorAction, goal_slots = ['door']),
00211 {'succeeded':'PUSH_DOOR','aborted':'TOUCH_DOOR'})
00212
00213 push_door = Concurrence(['succeeded','aborted','preempted'])
00214 push_door.add(
00215 ('PUSH_DOOR',SimpleActionState('push_door',DoorAction, goal_slots = ['door'])),
00216 ('MOVE_THROUGH',SimpleActionState('move_base_door',DoorAction, goal_slots = ['door'])))
00217 push_door.set_slave_states('PUSH_DOOR')
00218 push_door.add_outcome_map(
00219 ({'MOVE_THROUGH':'succeeded'},'succeeded'),
00220 ({'MOVE_THROUGH':'aborted'},'aborted'),
00221 ({'MOVE_THROUGH':'preempted'},'preempted'))
00222 StateMachine.add('PUSH_DOOR',push_door,{})
00223 """
00224
00225
00226 intro_server = IntrospectionServer('doorman',sm,'/DOORMAN')
00227 intro_server.start()
00228
00229 if 'run' in rospy.myargv():
00230 sm_thread = threading.Thread(target=sm.execute)
00231 sm_thread.start()
00232 else:
00233 asw = ActionServerWrapper('move_through_door', DoorAction,
00234 wrapped_container = sm,
00235 goal_slots_map = {'door': 'door'},
00236 succeeded_outcomes = ['succeeded'],
00237 aborted_outcomes = ['aborted'],
00238 preempted_outcomes = ['preeempted'])
00239 asw.run_server()
00240
00241 rospy.spin()
00242
00243 intro_server.stop()
00244
00245 if __name__ == '__main__':
00246 main()
00247