00001 /** 00002 \file Robots/LoBot/irccm/LoCliffs.c 00003 \brief Low-level reactions for cliff sensors. 00004 00005 This file defines the functions that implement the cliff sensor action 00006 and pending API for the low-level Robolocust control program meant to 00007 be run on the iRobot Create's Command Module. 00008 */ 00009 00010 /* 00011 ************************************************************************ 00012 * The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 * 00013 * by the University of Southern California (USC) and the iLab at USC. * 00014 * See http://iLab.usc.edu for information about this project. * 00015 * * 00016 * Major portions of the iLab Neuromorphic Vision Toolkit are protected * 00017 * under the U.S. patent ``Computation of Intrinsic Perceptual Saliency * 00018 * in Visual Environments, and Applications'' by Christof Koch and * 00019 * Laurent Itti, California Institute of Technology, 2001 (patent * 00020 * pending; application number 09/912,225 filed July 23, 2001; see * 00021 * http://pair.uspto.gov/cgi-bin/final/home.pl for current status). * 00022 ************************************************************************ 00023 * This file is part of the iLab Neuromorphic Vision C++ Toolkit. * 00024 * * 00025 * The iLab Neuromorphic Vision C++ Toolkit is free software; you can * 00026 * redistribute it and/or modify it under the terms of the GNU General * 00027 * Public License as published by the Free Software Foundation; either * 00028 * version 2 of the License, or (at your option) any later version. * 00029 * * 00030 * The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope * 00031 * that it will be useful, but WITHOUT ANY WARRANTY; without even the * 00032 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * 00033 * PURPOSE. See the GNU General Public License for more details. * 00034 * * 00035 * You should have received a copy of the GNU General Public License * 00036 * along with the iLab Neuromorphic Vision C++ Toolkit; if not, write * 00037 * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * 00038 * Boston, MA 02111-1307 USA. * 00039 ************************************************************************ 00040 */ 00041 00042 /* 00043 Primary maintainer for this file: mviswana usc edu 00044 $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/irccm/LoCliffs.c $ 00045 $Id: LoCliffs.c 13753 2010-08-03 15:59:25Z mviswana $ 00046 */ 00047 00048 /*------------------------------ HEADERS ------------------------------*/ 00049 00050 // lobot headers 00051 #include "LoCliffs.h" 00052 #include "LoDrive.h" 00053 #include "LoSensors.h" 00054 #include "LoIO.h" 00055 #include "LoUtils.h" 00056 #include "LoCMInterface.h" 00057 #include "LoOpenInterface.h" 00058 00059 /*------------------------------ GLOBALS ------------------------------*/ 00060 00061 // The data that accompanies an ACK_CLIFFS message is stored in this 00062 // array. 00063 // 00064 // DEVNOTE: Instead of using a separate variable to indicate that an 00065 // ACK_CLIFFS is pending, we simply use the bit flags for the cliff 00066 // sensors (stored in the first element of this array) as the pending 00067 // flag. If none of the cliff sensors are active, it means no action was 00068 // taken and, hence, no acknowledgement is pending. 00069 static char g_cliffs[LOBOT_CLIFFS_SIZE] ; 00070 00071 /*------------------------ REACTING TO CLIFFS -------------------------*/ 00072 00073 // This function retrieves the cliff sensors' states from the LoSensors 00074 // module and backs up and spins the robot a little bit in case any of 00075 // them are active. 00076 // 00077 // DEVNOTE: This function does not check to see if sensor data is 00078 // available before retrieving the cliff sensors' states. The main 00079 // program should take care of that, i.e., check that sensor data is 00080 // actually available before calling this function. We do it like this 00081 // because there are other low-level sensor reaction modules and all of 00082 // them would have to keep checking the same flag over and over again. 00083 // Much nicer if the main program checks the sensor data availability 00084 // flag once and then calls all the sensor reaction functions one-by-one. 00085 void lo_cliffs(void) 00086 { 00087 g_cliffs[LOBOT_CLIFFS_FLAGS] = 00088 (lo_get_sensor(LOBOT_SENSORS_CLIFF_LEFT) << 3) | 00089 (lo_get_sensor(LOBOT_SENSORS_CLIFF_FRONT_LEFT) << 2) | 00090 (lo_get_sensor(LOBOT_SENSORS_CLIFF_FRONT_RIGHT) << 1) | 00091 (lo_get_sensor(LOBOT_SENSORS_CLIFF_RIGHT)) ; 00092 00093 int backup = 0, spin = 0 ; 00094 switch (g_cliffs[LOBOT_CLIFFS_FLAGS]) 00095 { 00096 case 0x0: // no cliffs 00097 break ; 00098 case 0x1: // right cliff 00099 backup = -100 ; spin = 15 ; 00100 break ; 00101 case 0x2: // front right cliff 00102 backup = -125 ; spin = 30 ; 00103 case 0x3: // front right and right cliffs 00104 backup = -150 ; spin = 45 ; 00105 break ; 00106 case 0x4: // front left cliff 00107 backup = -125 ; spin = -30 ; 00108 break ; 00109 case 0x5: // front left and right cliffs 00110 backup = -175 ; spin = 60 ; 00111 break ; 00112 case 0x6: // front left and front right cliffs 00113 backup = -200 ; spin = 90 ; 00114 break ; 00115 case 0x7: // front left and front right and right cliffs 00116 backup = -150 ; spin = 75 ; 00117 break ; 00118 case 0x8: // left cliff 00119 backup = -100 ; spin = -15 ; 00120 break ; 00121 case 0x9: // left and right cliffs 00122 backup = -100 ; spin = 180 ; 00123 break ; 00124 case 0xA: // left and front right cliffs 00125 backup = -175 ; spin = -60 ; 00126 break ; 00127 case 0xB: // left and front right and right cliffs 00128 backup = -125 ; spin = 90 ; 00129 break ; 00130 case 0xC: // left and front left cliffs 00131 backup = -150 ; spin = -45 ; 00132 break ; 00133 case 0xD: // left and front left and right cliffs 00134 backup = -175 ; spin = -120 ; 00135 break ; 00136 case 0xE: // left and front left and front right cliffs 00137 backup = -150 ; spin = -75 ; 00138 break ; 00139 case 0xF: // all cliffs 00140 backup = -300 ; spin = 180 ; 00141 break ; 00142 } 00143 00144 if (backup) { 00145 backup = lo_backup(-225, backup) ; 00146 spin = lo_spin(150, spin) ; 00147 lo_update_odometry(backup, spin) ; 00148 } 00149 00150 g_cliffs[LOBOT_CLIFFS_DISTANCE_HI] = lo_hibyte(backup) ; 00151 g_cliffs[LOBOT_CLIFFS_DISTANCE_LO] = lo_lobyte(backup) ; 00152 g_cliffs[LOBOT_CLIFFS_ANGLE_HI] = lo_hibyte(spin) ; 00153 g_cliffs[LOBOT_CLIFFS_ANGLE_LO] = lo_lobyte(spin) ; 00154 } 00155 00156 /*------------------- CLIFF SENSOR ACKNOWLEDGEMENTS -------------------*/ 00157 00158 // Check if cliff sensor acknowledgement is pending so that main loop can 00159 // send out the ACK the next time it switches to talking to the high 00160 // level via the Command Module's USB port. 00161 char lo_cliffs_pending(void) 00162 { 00163 return g_cliffs[LOBOT_CLIFFS_FLAGS] ; 00164 } 00165 00166 // Send pending cliff sensor ACK to high level 00167 void lo_send_cliffs(void) 00168 { 00169 lo_tx(LOBOT_ACK_CLIFFS) ; 00170 for (unsigned char i = 0; i < LOBOT_CLIFFS_SIZE; ++i) 00171 lo_tx(g_cliffs[i]) ; 00172 }