srs_monitoring_statemachines.py
Go to the documentation of this file.
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','surface_distance'],
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                                         'surface_distance':'surface_distance'})
00277 
00278 
00279 ###################################################
00280 # creating the concurrence state machine old grasp
00281 
00282 
00283 co_sm_old_grasp = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'],
00284                  default_outcome='failed',
00285                  input_keys=['target_object_name','target_object_id','target_object','semi_autonomous_mode'],
00286                  output_keys=['grasp_categorisation','surface_distance'],
00287                  child_termination_cb = common_child_term_cb,
00288                  outcome_cb = common_out_cb)
00289 
00290 with co_sm_old_grasp:
00291             smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation())   
00292             smach.Concurrence.add('MAIN_OPERATION', sm_srs_old_grasp(),
00293                             remapping={'target_object_name':'target_object_name',
00294                                         'semi_autonomous_mode':'semi_autonomous_mode',
00295                                         'target_object_id':'target_object_id',
00296                                         'target_object':'target_object',
00297                                         'grasp_categorisation':'grasp_categorisation',
00298                                         'surface_distance':'surface_distance'})
00299 
00300 ###################################################
00301 # creating the concurrence state machine put object on tray
00302 # this process can be paused but not stoppable until object is on the tray, robot has to put the target  in a stable position
00303 
00304 co_sm_transfer_to_tray = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'],
00305                  default_outcome='failed',
00306                  input_keys=['grasp_categorisation','surface_distance'],
00307                  child_termination_cb = common_child_term_cb,
00308                  outcome_cb = common_out_cb)
00309 with co_sm_transfer_to_tray:
00310             smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation())   
00311             smach.Concurrence.add('MAIN_OPERATION', sm_srs_put_on_tray(),
00312                             remapping={'grasp_categorisation':'grasp_categorisation',
00313                                        'surface_distance':'surface_distance'})
00314 
00315 
00316 ###################################################
00317 # creating the concurrence state machine environment object update
00318 
00319 
00320 co_sm_enviroment_update = smach.Concurrence (outcomes=['succeeded', 'not_completed', 'failed', 'stopped', 'preempted', 'paused'],
00321                  default_outcome='failed',
00322                  input_keys=['scan_pose_list'],
00323                  child_termination_cb = common_child_term_cb,
00324                  outcome_cb = common_out_cb)
00325 with co_sm_enviroment_update:
00326             smach.Concurrence.add('State_Checking_During_Operation', state_checking_during_operation())   
00327             smach.Concurrence.add('MAIN_OPERATION', sm_enviroment_update(),
00328                             remapping={'scan_pose_list':'scan_pose_list'})
00329 
00330 
00331 


srs_decision_making
Author(s): Renxi Qiu
autogenerated on Mon Oct 6 2014 08:38:32