00001 /** 00002 \file Robots/LoBot/control/LoForward.H 00003 \brief A behaviour for driving the robot forward. 00004 */ 00005 00006 // //////////////////////////////////////////////////////////////////// // 00007 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00008 // by the University of Southern California (USC) and the iLab at USC. // 00009 // See http://iLab.usc.edu for information about this project. // 00010 // //////////////////////////////////////////////////////////////////// // 00011 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00012 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00013 // in Visual Environments, and Applications'' by Christof Koch and // 00014 // Laurent Itti, California Institute of Technology, 2001 (patent // 00015 // pending; application number 09/912,225 filed July 23, 2001; see // 00016 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00017 // //////////////////////////////////////////////////////////////////// // 00018 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00019 // // 00020 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00021 // redistribute it and/or modify it under the terms of the GNU General // 00022 // Public License as published by the Free Software Foundation; either // 00023 // version 2 of the License, or (at your option) any later version. // 00024 // // 00025 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00026 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00027 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00028 // PURPOSE. See the GNU General Public License for more details. // 00029 // // 00030 // You should have received a copy of the GNU General Public License // 00031 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00032 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00033 // Boston, MA 02111-1307 USA. // 00034 // //////////////////////////////////////////////////////////////////// // 00035 // 00036 // Primary maintainer for this file: mviswana usc edu 00037 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/control/LoForward.H $ 00038 // $Id: LoForward.H 13037 2010-03-23 01:00:53Z mviswana $ 00039 // 00040 00041 #ifndef LOBOT_FORWARD_BEHAVIOUR_DOT_H 00042 #define LOBOT_FORWARD_BEHAVIOUR_DOT_H 00043 00044 //------------------------------ HEADERS -------------------------------- 00045 00046 // lobot headers 00047 #include "Robots/LoBot/control/LoBehavior.H" 00048 #include "Robots/LoBot/control/LoTurnArbiter.H" 00049 #include "Robots/LoBot/control/LoSpeedArbiter.H" 00050 00051 #include "Robots/LoBot/io/LoLRFData.H" 00052 00053 #include "Robots/LoBot/misc/factory.hh" 00054 #include "Robots/LoBot/misc/singleton.hh" 00055 #include "Robots/LoBot/util/range.hh" 00056 00057 // Standard C++ headers 00058 #include <utility> 00059 00060 //----------------------------- NAMESPACE ------------------------------- 00061 00062 namespace lobot { 00063 00064 //------------------------- CLASS DEFINITION ---------------------------- 00065 00066 /** 00067 \class lobot::Forward 00068 \brief A behaviour for driving the robot forward. 00069 00070 This class implements a simple behaviour for driving the robot forward 00071 at the configured cruising speed. 00072 */ 00073 class Forward : public Behavior { 00074 // Prevent copy and assignment 00075 Forward(const Forward&) ; 00076 Forward& operator=(const Forward&) ; 00077 00078 // Handy type to have around in a derived class 00079 typedef Behavior base ; 00080 00081 // Boilerplate code to make the generic factory design pattern work 00082 friend class subfactory<Forward, base> ; 00083 typedef register_factory<Forward, base> my_factory ; 00084 static my_factory register_me ; 00085 00086 /// This behaviour features an adaptive mode, wherein it regulates the 00087 /// robot's speed based on the distance to the closest obstacle. To be 00088 /// able to properly visualize this mode of operation, it is useful to 00089 /// keep track of the particular reading that resulted in the adaptive 00090 /// speed value. This structure holds the distance reading plus speed 00091 /// vote together in one place. 00092 typedef std::pair<LRFData::Reading, SpeedArbiter::Vote*> SpeedInfo ; 00093 00094 /// To aid with development and debugging, this behaviour supports a 00095 /// visualization callback, which needs the most recent votes so that 00096 /// it can perform the proper visualization. 00097 //@{ 00098 TurnArbiter::Vote m_turn_vote ; 00099 SpeedArbiter::Vote m_speed_vote ; 00100 LRFData::Reading m_min_distance ; 00101 //@} 00102 00103 /// A private constructor because behaviours are instantiated with an 00104 /// object factory and not directly by clients. 00105 Forward() ; 00106 00107 /// Stuff to do before regular action processing begins. 00108 void pre_run() ; 00109 00110 /// These methods implement this behaviour's action. 00111 //@{ 00112 void action() ; 00113 SpeedInfo fixed_speed() const ; 00114 SpeedInfo adaptive_speed() const ; 00115 //@} 00116 00117 /// Visualization routines to aid with development and debugging. 00118 void render_me() ; 00119 00120 /// Clean-up. 00121 ~Forward() ; 00122 00123 /// This inner class encapsulates various parameters that can be used 00124 /// to tweak different aspects of the forward driving behaviour. 00125 class Params : public singleton<Params> { 00126 /// The forward behaviour always attempts to drive the robot 00127 /// forward at the specified cruising speed (specified in meters 00128 /// per second). 00129 float m_cruising_speed ; 00130 00131 /// If lobot is configured to ignore its RPM sensor, then speed 00132 /// related behaviours must specify their drive commands in terms 00133 /// of motor PWM values. Thus, in addition to a cruising speed, the 00134 /// forward behaviour must also be configured with a cruising PWM. 00135 int m_cruising_pwm ; 00136 00137 /// Instead of driving at a fixed (cruising) speed, the forward 00138 /// driving behaviour can be configured to regulate the robot's 00139 /// speed based on the distance to the closest obstacle. This flag 00140 /// turns on adaptive driving mode. 00141 bool m_adaptive_mode ; 00142 00143 /// In adaptive mode, the behaviour will consider the distance 00144 /// readings in the angular range specified by this setting. 00145 range<int> m_fov ; 00146 00147 /// Adaptive mode works by adjusting the robot's speed according to 00148 /// the minimum distance reading in the FOV specified by the above 00149 /// setting. However, the behaviour does not consider the "raw" 00150 /// distance readings; rather it averages the distance readings in 00151 /// a small block about each angle it considers, starting at the 00152 /// FOV's minimum and going up to the FOV maximum in steps 00153 /// specified by this setting. 00154 /// 00155 /// For example, if the FOV is [-30, 30] and the averaging block is 00156 /// 10, the forward behaviour will look at the average distances in 00157 /// the following blocks: [-35, -25], [-25, -15], [-5, -15], [-5, 5], 00158 /// [5, 15], [15, 25] and [25, 35]. 00159 int m_averaging_block ; 00160 00161 /// Once the minimum distance reading has been found, adaptive mode 00162 /// will compute a corresponding speed using a simple linear 00163 /// interpolation using the minimum distance reading, the distance 00164 /// range setting (see below) and the speed range (this setting's 00165 /// value). 00166 range<float> m_speed_range ; 00167 00168 /// Since all speed votes are required to work in terms of both PWM 00169 /// values and m/s speeds, we also need a PWM range so that 00170 /// adaptive mode can compute an appropriate PWM value using the 00171 /// same linear interpolation described above. 00172 range<int> m_pwm_range ; 00173 00174 /// To "convert" LRF distance readings into corresponding speed 00175 /// values, we use a linear interpolation that involves the 00176 /// minimum distance reading, the distance range (this setting) 00177 /// and the speed range (defined above). 00178 range<int> m_distance_range ; 00179 00180 /// Private constructor because this is a singleton. 00181 Params() ; 00182 00183 // Boilerplate code to make generic singleton design pattern work 00184 friend class singleton<Params> ; 00185 00186 public: 00187 /// Accessing the various parameters. 00188 //@{ 00189 static float cruising_speed() {return instance().m_cruising_speed ;} 00190 static int cruising_pwm() {return instance().m_cruising_pwm ;} 00191 static bool adaptive_mode() {return instance().m_adaptive_mode ;} 00192 static range<int> fov() {return instance().m_fov ;} 00193 static int averaging_block(){return instance().m_averaging_block;} 00194 static range<float> speed_range() {return instance().m_speed_range;} 00195 static range<int> pwm_range() {return instance().m_pwm_range ;} 00196 static range<int> distance_range(){return instance().m_distance_range ;} 00197 //@} 00198 00199 /// Clean-up. 00200 ~Params() ; 00201 } ; 00202 } ; 00203 00204 //----------------------------------------------------------------------- 00205 00206 } // end of namespace encapsulating this file's definitions 00207 00208 #endif 00209 00210 /* So things look consistent in everyone's emacs... */ 00211 /* Local Variables: */ 00212 /* indent-tabs-mode: nil */ 00213 /* End: */