BeobotLauncher.C

Go to the documentation of this file.
00001 /*!@file Beobot/BeobotLauncher.C File template for developing a new class */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the 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: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Beobot/BeobotLauncher.C $
00035 // $Id: BeobotLauncher.C 13712 2010-07-28 21:00:40Z itti $
00036 //
00037 
00038 #include "Component/ModelManager.H"
00039 #include "Devices/BeoChip.H"
00040 
00041 #include <fcntl.h>
00042 #include <stdio.h>
00043 #include <sys/stat.h>
00044 #include <sys/types.h>
00045 #include <unistd.h>
00046 
00047 //! Description of applications which we handle:
00048 struct BeobotLauncherApp {
00049   char *descrip1, *descrip2;  // 20-char max each (one LCD line)
00050   char *name;                 // name to display at launch
00051   char *cmd;                  // command to run
00052 };
00053 
00054 //! List of applications which we handle
00055 BeobotLauncherApp apps[100];
00056 int napps = 0;
00057 
00058 //! Our own little BeoChipListener
00059 class BeobotLauncherListener : public BeoChipListener
00060 {
00061 public:
00062   BeobotLauncherListener(nub::soft_ref<BeoChip> beoc) :
00063     keepgoing(true), action(-1), idx(0), beochip(beoc) { }
00064 
00065   virtual ~BeobotLauncherListener() { }
00066 
00067   virtual void event(const BeoChipEventType t, const int valint,
00068                      const float valfloat)
00069   {
00070     if (t == KBD)
00071       {
00072         if ((valint & 0x1) == 0 && idx > 0) // leftmost key pressed
00073           display(--idx);
00074         if ((valint & 0x10) == 0 && idx < napps-1) // rtmost key pressed
00075           display(++idx);
00076         if ((valint & 0x4) == 0) { // middle key pressed
00077           LINFO("Launching: %s", apps[idx].cmd);
00078           // Tell user about what we are launching:
00079           beochip->lcdClear();
00080           beochip->lcdPrintf(0, 0, "     Launching:     ");
00081           beochip->lcdPrintf(0, 2, "%s", apps[idx].name);
00082           usleep(800000);
00083           action = idx; // main program will take it from here
00084         }
00085       }
00086   }
00087 
00088   virtual void display(const int i)
00089   {
00090     beochip->lcdPrintf(0, 1, "%s", apps[i].descrip1);
00091     beochip->lcdPrintf(0, 2, "%s", apps[i].descrip2);
00092     beochip->lcdPrintf(0, 3, "%s   Start!   %s",
00093                        i > 0 ? "<<<<" : "    ",
00094                        i < napps-1 ? ">>>>" : "    ");
00095   }
00096 
00097   volatile bool keepgoing;
00098   volatile int action;
00099   volatile int idx;
00100   nub::soft_ref<BeoChip> beochip;
00101 };
00102 
00103 //! Launch various programs on the Beobot
00104 /*! This launcher should be placed in a cron or init script so that it
00105   will permanently be running. To prevent multiple copies of it from
00106   running at the same time, we use an flock on a file in /tmp, as
00107   suggested on a linuxquestions.org post (so even if the launcher dies
00108   badly, which may leave the temp file behind, it will be unlocked and
00109   will not prevent a new instance from starting). Here we use the
00110   BeoChip to let the user decide what to run. Just before we launch
00111   and monitor a new program, we clear and release the BeoChip so that
00112   the launched program can use it. Once the launched program
00113   terminates, we take the BeoChip over again and show our launch
00114   menu. */
00115 int main(const int argc, const char **argv)
00116 {
00117   MYLOGVERB = LOG_INFO;
00118 
00119   // obtain a lock and check whether other instances of BeobotLauncher
00120   // are running; if so, abort:
00121   int fdlock; struct flock fl;
00122   fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET;
00123   fl.l_start = 0; fl.l_len = 1;
00124 
00125   if ( (fdlock = open("/tmp/BeobotLauncher.lock",
00126                       O_WRONLY | O_CREAT, 0666)) == -1 )
00127     PLFATAL("Cannot open /tmp/BeobotLauncher.lock");
00128   if (fcntl(fdlock, F_SETLK, &fl) == -1)
00129     PLFATAL("Cannot lock /tmp/BeobotLauncher.lock");
00130 
00131   // load our config file (list of possible actions):
00132   char buf[1000];
00133   FILE *f = fopen("/etc/BeobotLauncher.conf", "r");
00134   if (f == NULL) PLFATAL("Cannot open /etc/BeobotLauncher.conf");
00135   while(fgets(buf, 999, f)) {
00136     if (buf[0] == '#') continue;
00137     char *data = new char[strlen(buf)+1];
00138     strcpy(data, buf);
00139     apps[napps].descrip1 = data; data[20] = '\0';
00140     apps[napps].descrip2 = &data[21]; data[41] = '\0';
00141     apps[napps].name = &data[42]; data[62] = '\0';
00142     apps[napps].cmd = &data[63];
00143     napps ++;
00144   }
00145   fclose(f);
00146 
00147   // instantiate a model manager:
00148   ModelManager manager("Beobot Launcher");
00149 
00150   // Instantiate our various ModelComponents:
00151   nub::soft_ref<BeoChip> b(new BeoChip(manager));
00152   manager.addSubComponent(b);
00153 
00154   // Parse command-line:
00155   if (manager.parseCommandLine(argc, argv, "<serdev>", 1, 1) == false)
00156     return(1);
00157 
00158   // let's configure our serial device:
00159   b->setModelParamVal("BeoChipDeviceName", manager.getExtraArg(0));
00160 
00161   // let's register our listener:
00162   rutz::shared_ptr<BeobotLauncherListener> lis(new BeobotLauncherListener(b));
00163   rutz::shared_ptr<BeoChipListener> lis2; lis2.dynCastFrom(lis); // cast down
00164   b->setListener(lis2);
00165   bool blinkon = false;
00166 
00167   // let's get all our ModelComponent instances started:
00168   manager.start();
00169   b->lcdClear();
00170   b->lcdPrintf(0, 0, "-- BeobotLauncher --");
00171   b->debounceKeyboard(true);
00172   b->captureKeyboard(true);
00173   lis->display(0);
00174 
00175   // main loop:
00176   while(lis->keepgoing)
00177     {
00178       // wait for an action code or a termination condition while we
00179       // blink out tail lights:
00180       while(lis->action == -1 && lis->keepgoing == true)
00181         {
00182           if (blinkon)
00183             { b->setDigitalOut(2, false); b->setDigitalOut(3, false);
00184             blinkon = false; }
00185           else
00186             { b->setDigitalOut(2, true); b->setDigitalOut(3, true);
00187             blinkon = true; }
00188 
00189           usleep(250000);
00190         }
00191 
00192       // if it's an action, let's execute it:
00193       if (lis->action != -1)
00194         {
00195           // first stop the manager to release the beochip:
00196           b->lcdClear();
00197           b->setDigitalOut(2, false); b->setDigitalOut(3, false);
00198           manager.stop();
00199           lis->idx = 0;
00200 
00201           // now execute:
00202           if (system(apps[lis->action].cmd)) LERROR("Error in system()");
00203 
00204           // let's get all our ModelComponent instances re-started:
00205           manager.start();
00206           b->lcdClear();
00207           b->lcdPrintf(0, 0, "     Done with:     ");
00208           b->lcdPrintf(0, 2, "%s", apps[lis->action].name);
00209 
00210           usleep(800000);
00211 
00212           b->lcdClear();
00213           b->lcdPrintf(0, 0, "-- BeobotLauncher --");
00214           b->debounceKeyboard(true);
00215           b->captureKeyboard(true);
00216           lis->display(0);
00217 
00218           // done with this action:
00219           lis->action = -1;
00220           }
00221     }
00222 
00223   // release our lock:
00224   fl.l_type = F_UNLCK;
00225   if (fcntl(fdlock, F_SETLK, &fl) == -1)
00226     PLERROR("Error unlocking /tmp/BeobotLauncher.lock");
00227   if (close(fdlock) == -1)
00228     PLERROR("Error closing /tmp/BeobotLauncher.lock");
00229   if (unlink("/tmp/BeobotLauncher.lock") == -1)
00230     PLERROR("Error deleting /tmp/BeobotLauncher.lock");
00231   return 0;
00232 }
00233 
00234 // ######################################################################
00235 /* So things look consistent in everyone's emacs... */
00236 /* Local Variables: */
00237 /* indent-tabs-mode: nil */
00238 /* End: */
Generated on Sun May 8 08:04:29 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3