LoRemoteControl.C

Go to the documentation of this file.
00001 /**
00002    \file  Robots/LoBot/control/LoRemoteControl.C
00003    \brief This file defines the non-inline member functions of the
00004    lobot::RemoteControl class.
00005 */
00006 
00007 // //////////////////////////////////////////////////////////////////// //
00008 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00009 // by the University of Southern California (USC) and the iLab at USC.  //
00010 // See http://iLab.usc.edu for information about this project.          //
00011 // //////////////////////////////////////////////////////////////////// //
00012 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00013 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00014 // in Visual Environments, and Applications'' by Christof Koch and      //
00015 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00016 // pending; application number 09/912,225 filed July 23, 2001; see      //
00017 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00018 // //////////////////////////////////////////////////////////////////// //
00019 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00020 //                                                                      //
00021 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00022 // redistribute it and/or modify it under the terms of the GNU General  //
00023 // Public License as published by the Free Software Foundation; either  //
00024 // version 2 of the License, or (at your option) any later version.     //
00025 //                                                                      //
00026 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00027 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00028 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00029 // PURPOSE.  See the GNU General Public License for more details.       //
00030 //                                                                      //
00031 // You should have received a copy of the GNU General Public License    //
00032 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00033 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00034 // Boston, MA 02111-1307 USA.                                           //
00035 // //////////////////////////////////////////////////////////////////// //
00036 //
00037 // Primary maintainer for this file: mviswana usc edu
00038 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/control/LoRemoteControl.C $
00039 // $Id: LoRemoteControl.C 13521 2010-06-06 14:23:03Z mviswana $
00040 //
00041 
00042 //------------------------------ HEADERS --------------------------------
00043 
00044 // lobot headers
00045 #include "Robots/LoBot/control/LoRemoteControl.H"
00046 #include "Robots/LoBot/control/LoTurnArbiter.H"
00047 #include "Robots/LoBot/control/LoSpeedArbiter.H"
00048 
00049 #include "Robots/LoBot/LoApp.H"
00050 #include "Robots/LoBot/io/LoRobot.H"
00051 #include "Robots/LoBot/config/LoConfigHelpers.H"
00052 #include "Robots/LoBot/thread/LoUpdateLock.H"
00053 
00054 #include "Robots/LoBot/misc/LoExcept.H"
00055 #include "Robots/LoBot/misc/LoRegistry.H"
00056 #include "Robots/LoBot/util/LoMath.H"
00057 #include "Robots/LoBot/util/LoTime.H"
00058 
00059 #include "Robots/LoBot/irccm/LoOpenInterface.h"
00060 
00061 //----------------------------- NAMESPACE -------------------------------
00062 
00063 namespace lobot {
00064 
00065 //--------------------------- LOCAL HELPERS -----------------------------
00066 
00067 // Retrieve settings from extricate section of config file
00068 template<typename T>
00069 static inline T conf(const std::string& key, const T& default_value)
00070 {
00071    return get_conf<T>(LOBE_REMOTE_CONTROL, key, default_value) ;
00072 }
00073 
00074 // Freeze the arbiters to the given behaviour's priority so that
00075 // behaviours with lower priority will be ignored.
00076 static inline void freeze_arbiters(const std::string& name)
00077 {
00078     TurnArbiter::instance().freeze(name) ;
00079    SpeedArbiter::instance().freeze(name) ;
00080 }
00081 
00082 // Unfreeze the arbiters so that other behaviours can resume having their
00083 // actions processed.
00084 static inline void unfreeze_arbiters(const std::string& name)
00085 {
00086     TurnArbiter::instance().unfreeze(name) ;
00087    SpeedArbiter::instance().unfreeze(name) ;
00088 }
00089 
00090 // Returns true if the remote control command code received from the
00091 // robot's sensors corresponds to one of the buttons this behaviour
00092 // recognizes.
00093 static bool supported_command(int c)
00094 {
00095    switch (c)
00096    {
00097       case LOBOT_OI_REMOTE_LEFT:
00098       case LOBOT_OI_REMOTE_RIGHT:
00099       case LOBOT_OI_REMOTE_PAUSE:
00100       case LOBOT_OI_REMOTE_CLEAN:
00101       case LOBOT_OI_REMOTE_FORWARD:
00102          return true ;
00103       default:
00104          return false ;
00105    }
00106 }
00107 
00108 //-------------------------- INITIALIZATION -----------------------------
00109 
00110 RemoteControl::RemoteControl()
00111    : base(clamp(conf("update_delay", 500), 1, 2500)),
00112      m_state(AUTONOMOUS),
00113      m_time(0)
00114 {
00115    start(LOBE_REMOTE_CONTROL) ;
00116 }
00117 
00118 void RemoteControl::pre_run()
00119 {
00120    if (! App::robot())
00121       throw behavior_error(MOTOR_SYSTEM_MISSING) ;
00122 }
00123 
00124 //---------------------- THE BEHAVIOUR'S ACTION -------------------------
00125 
00126 // The remote control behaviour works by checking the robot's sensors to
00127 // see if a remote control command has been sent. If so, it transitions
00128 // to the REMOTE_CONTROL state and executes the specified command. While
00129 // in the REMOTE_CONTROL state, if no more remote control commands come
00130 // in within the configured timeout, the behaviour releases the arbiters
00131 // and returns to the AUTONOMOUS state.
00132 void RemoteControl::action()
00133 {
00134    UpdateLock::begin_read() ;
00135       int ir = App::robot()->sensors().infrared() ; // remote control IR byte
00136    UpdateLock::end_read() ;
00137 
00138    switch (m_state)
00139    {
00140       case AUTONOMOUS:
00141          if (supported_command(ir))
00142          {
00143             freeze_arbiters(base::name) ;
00144             execute(ir) ;
00145             m_state = REMOTE_CONTROL ;
00146             m_time  = current_time() ;
00147          }
00148          break ;
00149       case REMOTE_CONTROL:
00150          if (current_time() - m_time <= Params::timeout())
00151          {
00152             if (supported_command(ir))
00153             {
00154                execute(ir) ;
00155                m_time = current_time() ;
00156             }
00157          }
00158          else // timed out without getting (valid) remote control command
00159          {
00160             m_state = AUTONOMOUS ;
00161             m_time  = 0 ;
00162             unfreeze_arbiters(base::name) ;
00163          }
00164          break ;
00165    }
00166 }
00167 
00168 // Execute the command specified by the remote control
00169 void RemoteControl::execute(int cmd)
00170 {
00171    switch (cmd)
00172    {
00173       case LOBOT_OI_REMOTE_FORWARD:
00174          TurnArbiter::instance().vote(base::name,
00175             new TurnArbiter::Vote(turn_vote_centered_at(0))) ;
00176          SpeedArbiter::instance().vote(base::name,
00177             new SpeedArbiter::Vote(Params::drive_speed(), 0)) ;
00178          break ;
00179 
00180       case LOBOT_OI_REMOTE_CLEAN: // use clean button for driving backwards
00181          TurnArbiter::instance().vote(base::name,
00182             new TurnArbiter::Vote(turn_vote_centered_at(0))) ;
00183          SpeedArbiter::instance().vote(base::name,
00184             new SpeedArbiter::Vote(-Params::drive_speed(), 0)) ;
00185          break ;
00186 
00187       case LOBOT_OI_REMOTE_PAUSE:
00188          TurnArbiter::instance().vote(base::name,
00189             new TurnArbiter::Vote(turn_vote_centered_at(0))) ;
00190          SpeedArbiter::instance().vote(base::name,
00191             new SpeedArbiter::Vote(0, 0)) ;
00192          break ;
00193 
00194       case LOBOT_OI_REMOTE_LEFT:
00195          TurnArbiter::instance().vote(base::name, new TurnArbiter::Vote(
00196             turn_vote_centered_at(TurnArbiter::turn_max()))) ;
00197          SpeedArbiter::instance().vote(base::name,
00198             new SpeedArbiter::Vote(Params::turn_speed(), 0)) ;
00199          break ;
00200 
00201       case LOBOT_OI_REMOTE_RIGHT:
00202          TurnArbiter::instance().vote(base::name, new TurnArbiter::Vote(
00203             turn_vote_centered_at(-TurnArbiter::turn_max()))) ;
00204          SpeedArbiter::instance().vote(base::name,
00205             new SpeedArbiter::Vote(Params::turn_speed(), 0)) ;
00206          break ;
00207    }
00208 }
00209 
00210 //----------------------------- CLEAN-UP --------------------------------
00211 
00212 RemoteControl::~RemoteControl(){}
00213 
00214 //-------------------------- KNOB TWIDDLING -----------------------------
00215 
00216 // Parameters initialization
00217 RemoteControl::Params::Params()
00218    : m_timeout(clamp(conf("timeout", 1000), 100, 5000)),
00219      m_drive_speed(clamp(conf("drive_speed", 0.3f), 0.1f, 0.5f)),
00220      m_turn_speed (clamp(conf("turn_speed",  0.2f), 0.1f, 0.5f))
00221 {}
00222 
00223 // Parameters clean-up
00224 RemoteControl::Params::~Params(){}
00225 
00226 //-----------------------------------------------------------------------
00227 
00228 } // end of namespace encapsulating this file's definitions
00229 
00230 /* So things look consistent in everyone's emacs... */
00231 /* Local Variables: */
00232 /* indent-tabs-mode: nil */
00233 /* End: */
Generated on Sun May 8 08:41:22 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3