$search
00001 #!/usr/bin/python 00002 ################################################################# 00003 ##\file 00004 # 00005 # \note 00006 # Copyright (c) 2011 \n 00007 # Cardiff University \n\n 00008 # 00009 ################################################################# 00010 # 00011 # \note 00012 # Project name: Multi-Role Shadow Robotic System for Independent Living 00013 # \note 00014 # ROS stack name: srs 00015 # \note 00016 # ROS package name: srs_decision_making 00017 # 00018 # \author 00019 # Author: Renxi Qiu, email: renxi.qiu@gmail.com 00020 # 00021 # \date Date of creation: Oct 2011 00022 # 00023 # \brief 00024 # Task coordination and interfacing for SRS decision making 00025 # 00026 ################################################################# 00027 # 00028 # Redistribution and use in source and binary forms, with or without 00029 # modification, are permitted provided that the following conditions are met: 00030 # 00031 # - Redistributions of source code must retain the above copyright 00032 # notice, this list of conditions and the following disclaimer. \n 00033 # 00034 # - Redistributions in binary form must reproduce the above copyright 00035 # notice, this list of conditions and the following disclaimer in the 00036 # documentation and/or other materials provided with the distribution. \n 00037 # 00038 # This program is free software: you can redistribute it and/or modify 00039 # it under the terms of the GNU Lesser General Public License LGPL as 00040 # published by the Free Software Foundation, either version 3 of the 00041 # License, or (at your option) any later version. 00042 # 00043 # This program is distributed in the hope that it will be useful, 00044 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00045 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00046 # GNU Lesser General Public License LGPL for more details. 00047 # 00048 # You should have received a copy of the GNU Lesser General Public 00049 # License LGPL along with this program. 00050 # If not, see <http://www.gnu.org/licenses/>. 00051 # 00052 ################################################################# 00053 # ROS imports 00054 00055 from srs_high_level_statemachines import * 00056 from smach import Concurrence 00057 00058 00059 """ 00060 This file contains concurrent state machines which provide parallel interruption checking during the operation. 00061 """ 00062 00063 #checking termination request for operation, the state will be terminated if: 00064 # 1 the current operation is stoppable 00065 # 2 and a termination request such as stop or customised_preempty is received or the main operation is completed (in this case, a preempty is triggered by the main operation) 00066 class state_checking_during_operation (smach.State): 00067 def __init__(self): 00068 smach.State.__init__(self , outcomes =['stopped', 'customised_preempted', 'paused', 'preempted']) 00069 #self.state_checking_outcome = 'preempted' #default outcome 00070 00071 def execute (self, userdata): 00072 global current_task_info 00073 self.state_checking_outcome = 'preempted' #reset the outcome to default 00074 _feedback=xmsg.ExecutionFeedback() 00075 00076 while (not self.preempt_requested()): 00077 00078 #rospy.sleep(1) 00079 time.sleep(1) 00080 00081 00082 #if stop command has been received 00083 if current_task_info.get_stop_required()==True: 00084 00085 #update the final outcome to stopped 00086 self.state_checking_outcome = 'stopped' 00087 00088 #if the current action can be stopped in the middle, terminate the checking and trigger preempty to the operation state 00089 #otherwise wait for the main operation which is not stoppable to be completed 00090 if current_task_info.stopable(): 00091 #acknowledge the request 00092 current_task_info.set_stop_acknowledged(True) 00093 try: 00094 sss.say([current_task_info.speaking_language['Stop']],False) 00095 _feedback.current_state = "the task has been stopped" 00096 _feedback.solution_required = False 00097 _feedback.exceptional_case_id = 0 00098 current_task_info._srs_as._as.publish_feedback(_feedback) 00099 except: 00100 print sys.exc_info() 00101 return 'stopped' 00102 00103 elif current_task_info.get_pause_required()==True: 00104 #update the final outcome to stopped 00105 self.state_checking_outcome = 'paused' 00106 try: 00107 _feedback.current_state = "the task has been paused" 00108 _feedback.solution_required = False 00109 _feedback.exceptional_case_id = 0 00110 current_task_info._srs_as._as.publish_feedback(_feedback) 00111 sss.say([current_task_info.speaking_language['Pause']],False) 00112 except: 00113 print sys.exc_info() 00114 return 'paused' 00115 00116 #if another command with higher priority received 00117 elif current_task_info.get_customised_preempt_required()==True: 00118 00119 #update the final outcome to customised_preempted 00120 self.state_checking_outcome = 'customised_preempted' 00121 #if the current action can be stopped in the middle, terminate the checking and trigger preempty to the operation state 00122 #otherwise wait for the main operation which is not stoppable to be completed 00123 if current_task_info.stopable(): 00124 try: 00125 _feedback.current_state = "the task has been replaced by another task request with higher priority" 00126 _feedback.solution_required = False 00127 _feedback.exceptional_case_id = 0 00128 current_task_info._srs_as._as.publish_feedback(_feedback) 00129 sss.say([current_task_info.speaking_language['Preempt']],False) 00130 #acknowledge the request 00131 except: 00132 print sys.exc_info() 00133 current_task_info.set_customised_preempt_acknowledged(True) 00134 return self.state_checking_outcome 00135 00136 #elif rospy.is_shutdown: 00137 # return 'preempted' 00138 00139 #preempted 00140 self.service_preempt() 00141 00142 if self.state_checking_outcome == 'stopped': 00143 try: 00144 sss.say([current_task_info.speaking_language['Stop']],False) 00145 _feedback.current_state = "the task has been stopped" 00146 _feedback.solution_required = False 00147 _feedback.exceptional_case_id = 0 00148 current_task_info._srs_as._as.publish_feedback(_feedback) 00149 current_task_info.set_stop_acknowledged(True) 00150 except: 00151 print sys.exc_info() 00152 if self.state_checking_outcome == 'customised_preempted': 00153 try: 00154 _feedback.current_state = "the task has been replaced by another task request with higher priority" 00155 _feedback.solution_required = False 00156 _feedback.exceptional_case_id = 0 00157 current_task_info._srs_as._as.publish_feedback(_feedback) 00158 sss.say([current_task_info.speaking_language['Preempt']],False) 00159 #acknowledge the request 00160 except: 00161 print sys.exc_info() 00162 current_task_info.set_customised_preempt_acknowledged(True) 00163 return self.state_checking_outcome 00164 00165 # gets called when ANY child state terminates 00166 def common_child_term_cb(outcome_map): 00167 00168 #checking if the termination is triggered by the completion of the main function 00169 #This will pre-empty the state_checking_during_operation state 00170 if outcome_map['MAIN_OPERATION'] is not None: 00171 return True 00172 00173 #termination is triggered by the checking state 00174 #stop command received 00175 if outcome_map['State_Checking_During_Operation'] == 'stopped': 00176 return True 00177 00178 #another command with higher priority received 00179 if outcome_map['State_Checking_During_Operation'] == 'customised_preempted': 00180 return True 00181 00182 #pause command received 00183 if outcome_map['State_Checking_During_Operation'] == 'paused': 00184 return True 00185 00186 #preempty or shutdown command received 00187 if outcome_map['State_Checking_During_Operation'] == 'preempted': 00188 return True 00189 00190 # in all other case, just keep running, don't terminate anything 00191 # There is no another case yet, just for complete 00192 return False 00193 00194 00195 # gets called when ALL child states are terminated 00196 def common_out_cb(outcome_map): 00197 00198 # Main operation is terminated before completion by checking state 00199 if outcome_map['MAIN_OPERATION'] == 'preempted' : 00200 00201 #operation terminated by external stop request 00202 if outcome_map['State_Checking_During_Operation'] == 'stopped': 00203 return 'stopped' 00204 00205 #pause is required 00206 elif outcome_map['State_Checking_During_Operation'] == 'paused': 00207 return 'paused' 00208 00209 else: 00210 #operation terminated by external high priority command, ctrl-c or preempty trigger by the client for the same goal 00211 return 'preempted' 00212 00213 #operation completed by the main operation. The outcome of the main operation is returned accordingly 00214 return outcome_map['MAIN_OPERATION'] 00215 00216 00217 00218 ################################################### 00219 # creating the concurrence state machine navigation 00220 00221 00222 co_sm_navigation = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'], 00223 default_outcome='failed', 00224 input_keys=['target_base_pose','semi_autonomous_mode'], 00225 child_termination_cb = common_child_term_cb, 00226 outcome_cb = common_out_cb) 00227 00228 with co_sm_navigation: 00229 smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation()) 00230 smach.Concurrence.add('MAIN_OPERATION', sm_srs_navigation(), 00231 remapping={'semi_autonomous_mode':'semi_autonomous_mode','target_base_pose':'target_base_pose'}) 00232 00233 00234 ################################################### 00235 # creating the concurrence state machine detection 00236 00237 00238 co_sm_detection = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'], 00239 default_outcome='failed', 00240 input_keys=['target_object_name','target_object_id', 'target_workspace_name','semi_autonomous_mode'], 00241 output_keys=['target_object','target_object_pose'], 00242 child_termination_cb = common_child_term_cb, 00243 outcome_cb = common_out_cb) 00244 00245 with co_sm_detection: 00246 smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation()) 00247 smach.Concurrence.add('MAIN_OPERATION', sm_srs_detection(), 00248 remapping={'target_object_name':'target_object_name', 00249 'target_object_id':'target_object_id', 00250 'target_workspace_name':'target_workspace_name', 00251 'semi_autonomous_mode':'semi_autonomous_mode', 00252 'target_object_pose':'target_object_pose', 00253 'target_object':'target_object'}) 00254 00255 00256 ################################################### 00257 # creating the concurrence state machine grasp 00258 00259 00260 co_sm_new_grasp = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'], 00261 default_outcome='failed', 00262 input_keys=['target_object_name','target_object_id','target_object','target_workspace_name','semi_autonomous_mode'], 00263 output_keys=['grasp_categorisation'], 00264 child_termination_cb = common_child_term_cb, 00265 outcome_cb = common_out_cb) 00266 00267 with co_sm_new_grasp: 00268 smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation()) 00269 smach.Concurrence.add('MAIN_OPERATION', sm_srs_new_grasp(), 00270 remapping={'target_object_name':'target_object_name', 00271 'semi_autonomous_mode':'semi_autonomous_mode', 00272 'target_object_id':'target_object_id', 00273 'target_object':'target_object', 00274 'target_workspace_name':'target_workspace_name', 00275 'grasp_categorisation':'grasp_categorisation'}) 00276 00277 00278 ################################################### 00279 # creating the concurrence state machine old grasp 00280 00281 00282 co_sm_old_grasp = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'], 00283 default_outcome='failed', 00284 input_keys=['target_object_name','target_object_id','target_object','semi_autonomous_mode'], 00285 output_keys=['grasp_categorisation'], 00286 child_termination_cb = common_child_term_cb, 00287 outcome_cb = common_out_cb) 00288 00289 with co_sm_old_grasp: 00290 smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation()) 00291 smach.Concurrence.add('MAIN_OPERATION', sm_srs_old_grasp(), 00292 remapping={'target_object_name':'target_object_name', 00293 'semi_autonomous_mode':'semi_autonomous_mode', 00294 'target_object_id':'target_object_id', 00295 'target_object':'target_object', 00296 'grasp_categorisation':'grasp_categorisation'}) 00297 00298 ################################################### 00299 # creating the concurrence state machine put object on tray 00300 # this process can be paused but not stoppable until object is on the tray, robot has to put the target in a stable position 00301 00302 co_sm_transfer_to_tray = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'], 00303 default_outcome='failed', 00304 input_keys=['grasp_categorisation'], 00305 child_termination_cb = common_child_term_cb, 00306 outcome_cb = common_out_cb) 00307 with co_sm_transfer_to_tray: 00308 smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation()) 00309 smach.Concurrence.add('MAIN_OPERATION', sm_srs_put_on_tray(), 00310 remapping={'grasp_categorisation':'grasp_categorisation'}) 00311 00312 00313 ################################################### 00314 # creating the concurrence state machine environment object update 00315 00316 00317 co_sm_enviroment_update = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'], 00318 default_outcome='failed', 00319 input_keys=['scan_pose_list'], 00320 child_termination_cb = common_child_term_cb, 00321 outcome_cb = common_out_cb) 00322 with co_sm_enviroment_update: 00323 smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation()) 00324 smach.Concurrence.add('MAIN_OPERATION', sm_enviroment_update(), 00325 remapping={'scan_pose_list':'scan_pose_list'}) 00326 00327 00328