00001 /** 00002 \file Robots/LoBot/control/LoRemoteControl.H 00003 00004 \brief A behaviour for controlling getting the iRobot Roomba/Create 00005 using its remote. 00006 */ 00007 00008 // //////////////////////////////////////////////////////////////////// // 00009 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00010 // by the University of Southern California (USC) and the iLab at USC. // 00011 // See http://iLab.usc.edu for information about this project. // 00012 // //////////////////////////////////////////////////////////////////// // 00013 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00014 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00015 // in Visual Environments, and Applications'' by Christof Koch and // 00016 // Laurent Itti, California Institute of Technology, 2001 (patent // 00017 // pending; application number 09/912,225 filed July 23, 2001; see // 00018 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00019 // //////////////////////////////////////////////////////////////////// // 00020 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00023 // redistribute it and/or modify it under the terms of the GNU General // 00024 // Public License as published by the Free Software Foundation; either // 00025 // version 2 of the License, or (at your option) any later version. // 00026 // // 00027 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00028 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00029 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00030 // PURPOSE. See the GNU General Public License for more details. // 00031 // // 00032 // You should have received a copy of the GNU General Public License // 00033 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00034 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00035 // Boston, MA 02111-1307 USA. // 00036 // //////////////////////////////////////////////////////////////////// // 00037 // 00038 // Primary maintainer for this file: Manu Viswanathan <mviswana at usc dot edu> 00039 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/control/LoRemoteControl.H $ 00040 // $Id: LoRemoteControl.H 12708 2010-01-28 18:55:12Z mviswana $ 00041 // 00042 00043 #ifndef LOBOT_REMOTE_CONTROL_BEHAVIOUR_DOT_H 00044 #define LOBOT_REMOTE_CONTROL_BEHAVIOUR_DOT_H 00045 00046 //------------------------------ HEADERS -------------------------------- 00047 00048 // lobot headers 00049 #include "Robots/LoBot/control/LoBehavior.H" 00050 00051 #include "Robots/LoBot/misc/factory.hh" 00052 #include "Robots/LoBot/misc/singleton.hh" 00053 00054 //----------------------------- NAMESPACE ------------------------------- 00055 00056 namespace lobot { 00057 00058 //------------------------- CLASS DEFINITION ---------------------------- 00059 00060 /** 00061 \class lobot::RemoteControl 00062 00063 \brief A behaviour for controlling the iRobot Roomba/Create using its 00064 remote. 00065 00066 This class implements a behaviour that uses the Roomba Remote to drive 00067 lobot. This can be useful, for instance, if the robot is about to do 00068 something dangerous or if it is doing something stupid (e.g., 00069 repetetive failures to extricate from a corner). 00070 00071 The behaviour works by freezing the arbiters and then issuing drive 00072 and turn commands based on the sensor data sent by the robot. If the 00073 user does not supply any remote control commands for more than some 00074 (configured) timeout, the behaviour will release the arbiters so that 00075 the other behaviours can start working normally again. 00076 */ 00077 class RemoteControl : public Behavior { 00078 // Prevent copy and assignment 00079 RemoteControl(const RemoteControl&) ; 00080 RemoteControl& operator=(const RemoteControl&) ; 00081 00082 // Handy type to have around in a derived class 00083 typedef Behavior base ; 00084 00085 // Boilerplate code to make the generic factory design pattern work 00086 friend class subfactory<RemoteControl, base> ; 00087 typedef register_factory<RemoteControl, base> my_factory ; 00088 static my_factory register_me ; 00089 00090 /// The remote control behaviour operates in one of two states: either 00091 /// the robot is working autonomously or it is being remote 00092 /// controlled. The behaviour starts off in the autonomous state. When 00093 /// a remote control command is received, it freezes the arbiters and 00094 /// transitions to the remote control state. If no more remote control 00095 /// commands come in within the configured timeout, the behaviour will 00096 /// release the arbiters and return to the autonomous state. 00097 //@{ 00098 enum State { 00099 AUTONOMOUS, 00100 REMOTE_CONTROL, 00101 } ; 00102 State m_state ; 00103 long long m_time ; 00104 //@} 00105 00106 /// A private constructor because behaviours are instantiated with an 00107 /// object factory and not directly by clients. 00108 RemoteControl() ; 00109 00110 /// Some things to do before commencing regular action processing. 00111 void pre_run() ; 00112 00113 /// This method implements the behaviour's extrication strategy. As 00114 /// mentioned earlier, it works by determining the kind of structure 00115 /// from which the robot needs to escape and then issues appropriate 00116 /// motor command votes to get the robot unstuck from that structure. 00117 void action() ; 00118 00119 /// This is a helper method that executes the command specified by the 00120 /// remote control. 00121 void execute(int infrared_byte) ; 00122 00123 /// Clean-up. 00124 ~RemoteControl() ; 00125 00126 /// This inner class encapsulates various parameters that can be used 00127 /// to tweak different aspects of the remote control behaviour. 00128 class Params : public singleton<Params> { 00129 /// The remote control behaviour works by listening for remote 00130 /// control commands. These commands must be sent continuously for 00131 /// the behaviour to retain control, i.e., the user must keep 00132 /// pressing the buttons on the Roomba Remote in order to maintain 00133 /// manual control of the robot. When these commands stop coming 00134 /// in, the behaviour relinquishes control and lets the other 00135 /// behaviours function normally. 00136 /// 00137 /// This setting specifies the timeout between successive remote 00138 /// control commands. Thus, if the remote control behaviour does 00139 /// not sense any remote control commands for this much time, it 00140 /// will relinquish control of the robot. 00141 /// 00142 /// This setting should be a time expressed in milliseconds. 00143 int m_timeout ; 00144 00145 /// Users may specify the driving speed for remote control 00146 /// commands. The speed should be a positive floating point number 00147 /// not to exceed 0.5 (the Roomba's top speed). Its unit is m/s. 00148 float m_drive_speed ; 00149 00150 /// Remote control turn commands can use a different speed setting 00151 /// than the drive commands. This setting specifies the turn speed. 00152 /// It is expeted to be a positive floating point number whose unit 00153 /// is m/s and whose value should not exceed 0.5 (the Roomba's top 00154 /// speed). 00155 float m_turn_speed ; 00156 00157 /// Private constructor because this is a singleton. 00158 Params() ; 00159 00160 // Boilerplate code to make generic singleton design pattern work 00161 friend class singleton<Params> ; 00162 00163 public: 00164 /// Accessing the various parameters. 00165 //@{ 00166 static int timeout() {return instance().m_timeout ;} 00167 static float drive_speed() {return instance().m_drive_speed ;} 00168 static float turn_speed() {return instance().m_turn_speed ;} 00169 //@} 00170 00171 /// Clean-up. 00172 ~Params() ; 00173 } ; 00174 } ; 00175 00176 //----------------------------------------------------------------------- 00177 00178 } // end of namespace encapsulating this file's definitions 00179 00180 #endif 00181 00182 /* So things look consistent in everyone's emacs... */ 00183 /* Local Variables: */ 00184 /* indent-tabs-mode: nil */ 00185 /* End: */