00001 /*!@file Devices/BeeStemSim.C Simple interface to beestem */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/SeaBee/BeeStemSim.C $ 00035 // $Id: BeeStemSim.C 10794 2009-02-08 06:21:09Z itti $ 00036 // 00037 00038 #include "SeaBee/BeeStemSim.H" 00039 00040 #include "Component/OptionManager.H" 00041 #include "Devices/Serial.H" 00042 #include "Image/MatrixOps.H" 00043 #include <string> 00044 00045 #define BS_CMD_DELAY 5000000 00046 00047 namespace 00048 { 00049 class SubSimLoop : public JobWithSemaphore 00050 { 00051 public: 00052 SubSimLoop(BeeStemSim* beeStemSim) 00053 : 00054 itsBeeStemSim(beeStemSim), 00055 itsPriority(1), 00056 itsJobType("controllerLoop") 00057 {} 00058 00059 virtual ~SubSimLoop() {} 00060 00061 virtual void run() 00062 { 00063 ASSERT(itsBeeStemSim); 00064 while(1) 00065 { 00066 itsBeeStemSim->simLoop(); 00067 usleep(1000); 00068 } 00069 } 00070 00071 virtual const char* jobType() const 00072 { return itsJobType.c_str(); } 00073 00074 virtual int priority() const 00075 { return itsPriority; } 00076 00077 private: 00078 BeeStemSim* itsBeeStemSim; 00079 const int itsPriority; 00080 const std::string itsJobType; 00081 }; 00082 } 00083 00084 00085 00086 // ###################################################################### 00087 BeeStemSim::BeeStemSim(OptionManager& mgr, const std::string& descrName, 00088 const std::string& tagName) : 00089 ModelComponent(mgr, descrName, tagName), 00090 itsSubSim(new SubSim(mgr)) 00091 { 00092 // attach our port as a subcomponent: 00093 addSubComponent(itsSubSim); 00094 00095 for (int i=0; i<5; i++) 00096 itsLastMotorCmd[i] = 0; 00097 00098 initRandomNumbers(); 00099 } 00100 00101 // ###################################################################### 00102 BeeStemSim::~BeeStemSim() 00103 { 00104 } 00105 00106 void BeeStemSim::start2() 00107 { 00108 //setup pid loop thread 00109 itsThreadServer.reset(new WorkThreadServer("SubSim",1)); //start a single worker thread 00110 itsThreadServer->setFlushBeforeStopping(false); 00111 rutz::shared_ptr<SubSimLoop> j(new SubSimLoop(this)); 00112 itsThreadServer->enqueueJob(j); 00113 } 00114 00115 void BeeStemSim::simLoop() 00116 { 00117 itsSubSim->simLoop(); 00118 //itsForwardImg = itsSubSim->getFrame(1); 00119 //itsDownImg = itsSubSim->getFrame(2); 00120 00121 } 00122 00123 // ###################################################################### 00124 bool BeeStemSim::setThrusters(int &m1, int &m2, int &m3, 00125 int &m4, int &m5) 00126 { 00127 // Command Buffer: 00128 // [0] is start character 00129 // [1..5] is m1 m5 00130 00131 if (m1 > MOTOR_MAX) m1 = MOTOR_MAX; if (m1 < -MOTOR_MAX) m1 = -MOTOR_MAX; 00132 if (m2 > MOTOR_MAX) m2 = MOTOR_MAX; if (m2 < -MOTOR_MAX) m2 = -MOTOR_MAX; 00133 if (m3 > MOTOR_MAX) m3 = MOTOR_MAX; if (m3 < -MOTOR_MAX) m3 = -MOTOR_MAX; 00134 if (m4 > MOTOR_MAX) m4 = MOTOR_MAX; if (m4 < -MOTOR_MAX) m4 = -MOTOR_MAX; 00135 if (m5 > MOTOR_MAX) m5 = MOTOR_MAX; if (m5 < -MOTOR_MAX) m5 = -MOTOR_MAX; 00136 00137 00138 00139 if (abs(itsLastMotorCmd[0] - m1) > 60 && itsLastMotorCmd[0]*m1 < 0) m1 = 0; 00140 if (abs(itsLastMotorCmd[1] - m2) > 60 && itsLastMotorCmd[1]*m2 < 0) m2 = 0; 00141 if (abs(itsLastMotorCmd[2] - m3) > 60 && itsLastMotorCmd[2]*m3 < 0) m3 = 0; 00142 if (abs(itsLastMotorCmd[3] - m4) > 60 && itsLastMotorCmd[3]*m4 < 0) m4 = 0; 00143 if (abs(itsLastMotorCmd[4] - m5) > 60 && itsLastMotorCmd[4]*m5 < 0) m5 = 0; 00144 00145 00146 itsLastMotorCmd[0] = m1; 00147 itsLastMotorCmd[1] = m2; 00148 itsLastMotorCmd[2] = m3; 00149 itsLastMotorCmd[3] = m4; 00150 itsLastMotorCmd[4] = m5; 00151 00152 float pan = ((float(m2) - float(m4))/2) / 100.0; 00153 float tilt = 0; //((((float(m1) + float(m5))/2) - float(m3))/2.0)/100.0; 00154 float forward = -1*((float(m2) + float(m4))/2) / 100.0; 00155 float up = -1*((float(m1) + float(m3) + float(m5))/3.0)/100.0; 00156 00157 00158 itsSubSim->setTrusters(pan, tilt, forward, up); 00159 00160 00161 return true; 00162 00163 } 00164 00165 // ###################################################################### 00166 bool BeeStemSim::getSensors(int &heading, int &pitch, int &roll, int &ext_pressure, int &int_pressure) 00167 { 00168 float simxPos; 00169 float simyPos; 00170 float simdepth; 00171 float simroll; 00172 float simpitch; 00173 float simyaw; 00174 00175 int heading_noise = 0; 00176 int pitch_noise = randomUpToIncluding(6) - 3; 00177 int roll_noise = randomUpToIncluding(6) - 3; 00178 int ext_p_noise = randomUpToIncluding(6) - 3; 00179 int int_p_noise = randomUpToIncluding(6) - 3; 00180 00181 itsSubSim->getSensors(simxPos, simyPos, simdepth, 00182 simroll, simpitch, simyaw); 00183 00184 heading = (int)(simyaw*180/M_PI) + heading_noise; 00185 pitch = (int)(simpitch*180/M_PI) + pitch_noise; 00186 roll = (int)(simroll*180/M_PI) + roll_noise; 00187 00188 ext_pressure = (int)(simdepth*100) + ext_p_noise; 00189 00190 int_pressure = 90 + int_p_noise; 00191 00192 00193 return true; 00194 } 00195 00196 bool BeeStemSim::setHeartBeat() 00197 { 00198 return true; 00199 00200 } 00201 00202 Image<PixRGB<byte> > BeeStemSim::getImage(int camera) 00203 { 00204 // switch(camera) 00205 // { 00206 // case 1: return flipVertic(itsForwardImg); 00207 // case 2: return flipVertic(itsDownImg); 00208 // } 00209 00210 return flipVertic(itsSubSim->getFrame(camera)); 00211 00212 // return Image<PixRGB<byte> > (); 00213 } 00214 00215 // ###################################################################### 00216 /* So things look consistent in everyone's emacs... */ 00217 /* Local Variables: */ 00218 /* indent-tabs-mode: nil */ 00219 /* End: */