00001 /** 00002 \file Robots/LoBot/control/LoEmergencyStop.C 00003 \brief This file defines the non-inline member functions of the 00004 lobot::EmergencyStop 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/LoEmergencyStop.C $ 00039 // $Id: LoEmergencyStop.C 13620 2010-06-25 05:12:03Z mviswana $ 00040 // 00041 00042 //------------------------------ HEADERS -------------------------------- 00043 00044 // lobot headers 00045 #include "Robots/LoBot/control/LoEmergencyStop.H" 00046 #include "Robots/LoBot/control/LoMetrics.H" 00047 #include "Robots/LoBot/control/LoSpeedArbiter.H" 00048 00049 #include "Robots/LoBot/LoApp.H" 00050 #include "Robots/LoBot/slam/LoMap.H" 00051 00052 #include "Robots/LoBot/config/LoConfigHelpers.H" 00053 #include "Robots/LoBot/thread/LoUpdateLock.H" 00054 00055 #include "Robots/LoBot/misc/LoRegistry.H" 00056 #include "Robots/LoBot/util/LoGL.H" 00057 #include "Robots/LoBot/util/LoMath.H" 00058 00059 // OpenGL headers 00060 #ifdef INVT_HAVE_LIBGL 00061 #include <GL/gl.h> 00062 #endif 00063 00064 // Standard C++ headers 00065 #include <iomanip> 00066 #include <algorithm> 00067 #include <iterator> 00068 00069 //----------------------------- NAMESPACE ------------------------------- 00070 00071 namespace lobot { 00072 00073 //--------------------------- LOCAL HELPERS ----------------------------- 00074 00075 // Retrieve settings from emergency_stop section of config file 00076 template<typename T> 00077 static inline T conf(const std::string& key, const T& default_value) 00078 { 00079 return get_conf<T>(LOBE_EMERGENCY_STOP, key, default_value) ; 00080 } 00081 00082 //-------------------------- INITIALIZATION ----------------------------- 00083 00084 // DEVNOTE: It ought to be okay to use the DangerZone object without the 00085 // UpdateLock because, at this point, only the main thread should be 00086 // active. The other threads, even if they have been created, should be 00087 // waiting for the main thread to signal that initialization is complete. 00088 // See the lobot::App, lobot::Behavior and lobot::Arbiter class 00089 // implementations for the details. 00090 EmergencyStop::EmergencyStop() 00091 : base(clamp(conf("update_delay", 75), 1, 1000), 00092 LOBE_EMERGENCY_STOP, 00093 conf<std::string>("geometry", "480 140 140 140")) 00094 { 00095 m_blocks.reserve(DangerZone::num_blocks()) ; 00096 std::copy(DangerZone::begin(), DangerZone::end(), 00097 std::back_inserter(m_blocks)) ; 00098 start(LOBE_EMERGENCY_STOP) ; 00099 } 00100 00101 //---------------------- THE BEHAVIOUR'S ACTION ------------------------- 00102 00103 // The emergency stop behaviour monitors the robot's danger zone and 00104 // issues a stop command when things get too close. 00105 void EmergencyStop::action() 00106 { 00107 UpdateLock::begin_read() ; 00108 bool danger_zone_penetrated = DangerZone::penetrated() ; 00109 00110 viz_lock() ; 00111 std::copy(DangerZone::begin(), DangerZone::end(), m_blocks.begin()) ; 00112 viz_unlock() ; 00113 UpdateLock::end_read() ; 00114 00115 if (danger_zone_penetrated) { // stop the robot 00116 SpeedArbiter::instance(). 00117 vote(LOBE_EMERGENCY_STOP, new SpeedArbiter::Vote(0, 0)) ; 00118 00119 Metrics::Log log ; 00120 log << std::setw(Metrics::opw()) << std::left << "emergency stop" ; 00121 Map* M = App::map() ; 00122 if (M) 00123 log << M->current_pose() ; 00124 } 00125 } 00126 00127 //--------------------------- VISUALIZATION ----------------------------- 00128 00129 #ifdef INVT_HAVE_LIBGL 00130 00131 static void render_reading(const LRFData::Reading& R) 00132 { 00133 float d = R.distance()/DangerZone::max() ; 00134 glVertex2i(0, 0) ; 00135 glVertex2f(d * cos(R.angle()), d * sin(R.angle())) ; 00136 } 00137 00138 static void render_block(const DangerZone::Block& block) 00139 { 00140 std::for_each(block.danger_begin(), block.danger_end(), render_reading) ; 00141 } 00142 00143 void EmergencyStop::render_me() 00144 { 00145 // Make local copy so that emergency stop thread isn't held up waiting 00146 // for visualization thread to complete. 00147 viz_lock() ; 00148 Blocks blocks = m_blocks ; 00149 viz_unlock() ; 00150 00151 // Render the stop state visualization 00152 unit_view_volume() ; 00153 glBegin(GL_LINES) ; 00154 glColor3f(1, 0, 0) ; 00155 std::for_each(blocks.begin(), blocks.end(), render_block) ; 00156 glEnd() ; 00157 00158 // Label the visualization so that it is easy to tell which behaviour 00159 // is being visualized. 00160 restore_view_volume() ; 00161 text_view_volume() ; 00162 glColor3f(0, 1, 1) ; 00163 draw_label(3, 12, "Eme. Stop") ; 00164 00165 restore_view_volume() ; 00166 } 00167 00168 #endif 00169 00170 //----------------------------- CLEAN-UP -------------------------------- 00171 00172 EmergencyStop::~EmergencyStop(){} 00173 00174 //----------------------------------------------------------------------- 00175 00176 } // end of namespace encapsulating this file's definitions 00177 00178 /* So things look consistent in everyone's emacs... */ 00179 /* Local Variables: */ 00180 /* indent-tabs-mode: nil */ 00181 /* End: */