00001 """-------------------------------------------------------------------- 00002 COPYRIGHT 2013 SEGWAY Inc. 00003 00004 Software License Agreement: 00005 00006 The software supplied herewith by Segway Inc. (the "Company") for its 00007 RMP Robotic Platforms is intended and supplied to you, the Company's 00008 customer, for use solely and exclusively with Segway products. The 00009 software is owned by the Company and/or its supplier, and is protected 00010 under applicable copyright laws. All rights are reserved. Any use in 00011 violation of the foregoing restrictions may subject the user to criminal 00012 sanctions under applicable laws, as well as to civil liability for the 00013 breach of the terms and conditions of this license. The Company may 00014 immediately terminate this Agreement upon your use of the software with 00015 any products that are not Segway products. 00016 00017 The software was written using Python programming language. Your use 00018 of the software is therefore subject to the terms and conditions of the 00019 OSI- approved open source license viewable at http://www.python.org/. 00020 You are solely responsible for ensuring your compliance with the Python 00021 open source license. 00022 00023 You shall indemnify, defend and hold the Company harmless from any claims, 00024 demands, liabilities or expenses, including reasonable attorneys fees, incurred 00025 by the Company as a result of any claim or proceeding against the Company 00026 arising out of or based upon: 00027 00028 (i) The combination, operation or use of the software by you with any hardware, 00029 products, programs or data not supplied or approved in writing by the Company, 00030 if such claim or proceeding would have been avoided but for such combination, 00031 operation or use. 00032 00033 (ii) The modification of the software by or on behalf of you 00034 00035 (iii) Your use of the software. 00036 00037 THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, 00038 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED 00039 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00040 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, 00041 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR 00042 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 00043 00044 \file user_event_handlers.py 00045 00046 \brief This module allows the user to define how to handle events generated 00047 in rmp_interface.py. 00048 00049 \Platform: Cross Platform 00050 --------------------------------------------------------------------""" 00051 from system_defines import * 00052 00053 import time,sys,os, Queue 00054 00055 """ 00056 Define some general parameters for the example like various commands 00057 """ 00058 RMP_CMD_NO_MOTION = [RMP_MOTION_CMD_ID,0.0,0.0] 00059 RMP_FORCE_FEEDBACK = [RMP_CFG_CMD_ID,RMP_CMD_NONE,0.0] 00060 RMP_SET_TRACTOR = [RMP_CFG_CMD_ID,RMP_CMD_SET_OPERATIONAL_MODE,TRACTOR_REQUEST] 00061 RMP_SET_STANDBY = [RMP_CFG_CMD_ID,RMP_CMD_SET_OPERATIONAL_MODE,STANDBY_REQUEST] 00062 00063 RMP_STOP_SONG = [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_NO_SONG,MOTOR_AUDIO_PLAY_NO_SONG] 00064 RMP_SONGS = [[RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_POWER_ON_SONG], 00065 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_POWER_OFF_SONG], 00066 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_ALARM_SONG], 00067 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_MODE_UP_SONG], 00068 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_MODE_DOWN_SONG], 00069 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_ENTER_ALARM_SONG], 00070 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_EXIT_ALARM_SONG], 00071 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_FINAL_SHUTDOWN_SONG], 00072 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_CORRECT_ISSUE], 00073 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_ISSUE_CORRECTED], 00074 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_CORRECT_ISSUE_REPEATING], 00075 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_BEGINNER_ACK], 00076 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_PLAY_EXPERT_ACK], 00077 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_ENTER_FOLLOW], 00078 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_TEST_SWEEP], 00079 [RMP_CFG_CMD_ID,RMP_CMD_SET_AUDIO_COMMAND,MOTOR_AUDIO_SIMULATE_MOTOR_NOISE]] 00080 00081 """ 00082 This is the class that defines how to handle events passed up by the RMP class. 00083 These events currently include: 00084 RMP_IS_DEAD: The main loop should recongize that the RMP thread is no longer alive 00085 and should try and respawn or kill the main loop 00086 00087 RMP_TX_RDY: The RMP class can accept a new command. Commands sent before this event 00088 will be queued and executed asyncronously. The user should only post new 00089 commands once this event has been triggered 00090 00091 RMP_RSP_DATA_RDY: A response packet is ready for the user. 00092 """ 00093 class RMPEventHandlers: 00094 def __init__(self,cmd,rsp,inflags,rmpExchange): 00095 00096 print "Initializing event handlers" 00097 00098 """ 00099 Flag to run the loop 00100 """ 00101 self._continue = True 00102 self.start_time = time.time() 00103 self.song_playing = False 00104 self.idx = 0 00105 self.cmd_queue = cmd 00106 self.rsp_queue = rsp 00107 self.inflags = inflags 00108 00109 """ 00110 Listeners for feedback 00111 """ 00112 self.feedback_listeners = [] 00113 00114 """ 00115 This is the dictionary that the outflags get passed to. Each one can be 00116 redefined to be passed to whatever user function you would like 00117 """ 00118 self.handle_event = dict({RMP_KILL:sys.exit, 00119 RMP_INIT_FAILED:self.InitFailedExit, 00120 RMP_IS_DEAD:self.Kill_loop, 00121 RMP_TX_RDY:self.Send_Cmd, 00122 RMP_RSP_DATA_RDY:self.Get_Rsp, 00123 RMP_GOTO_STANDBY:self.GotoStandby, 00124 RMP_GOTO_TRACTOR:self.GotoTractor}) 00125 """ 00126 Called when the robot requests a command 00127 """ 00128 def Send_Cmd(self): 00129 if self.cmd_queue.empty(): 00130 self.cmd_queue.put(RMP_FORCE_FEEDBACK) 00131 00132 """ 00133 Called when feedback from the robot is received 00134 """ 00135 def Get_Rsp(self): 00136 fb_dict = self.rsp_queue.get() 00137 for listener in self.feedback_listeners: 00138 listener(fb_dict) 00139 00140 """ 00141 Add a feedback listener. 00142 """ 00143 def AddListener(self, callback): 00144 self.feedback_listeners.append(callback) 00145 00146 """ 00147 Sets the robot to Standby mode 00148 """ 00149 def GotoStandby(self): 00150 self.cmd_queue.put(RMP_SET_STANDBY) 00151 00152 """ 00153 Sets the robot to Tractor mode 00154 """ 00155 def GotoTractor(self): 00156 self.cmd_queue.put(RMP_SET_TRACTOR) 00157 00158 """ 00159 Adds a command to the queue for the robot 00160 """ 00161 def AddCommand(self,command): 00162 self.cmd_queue.put(command) 00163 00164 """ 00165 Failure procedure 00166 """ 00167 def InitFailedExit(self): 00168 print "RMP initialization failed...." 00169 print "exiting....." 00170 self.inflags.put(RMP_KILL) 00171 self._continue = False 00172 00173 """ 00174 Termination procedure 00175 """ 00176 def Kill_loop(self): 00177 print "Loop terminated, killing RMP thread and exiting....." 00178 self.inflags.put(RMP_KILL) 00179 self._continue = False