BeoMonkey.C

Go to the documentation of this file.
00001 /*!@file Devices/BeoMonkey.C Interfaces to robot monkey head, derived from
00002 BeoChip which is an to interface Brian Hudson's BeoChip .*/
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: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/BeoMonkey.C $
00035 // $Id: BeoMonkey.C 6795 2006-06-29 20:45:32Z rjpeters $
00036 //
00037 
00038 #include "Devices/BeoMonkey.H"
00039 #include "Component/OptionManager.H"
00040 #include "Util/Assert.H"
00041 #include "rutz/compat_snprintf.h"
00042 
00043 // ######################################################################
00044 BeoMonkey::BeoMonkey(OptionManager& mgr, const std::string& descrName,
00045                    const std::string& tagName) : BeoChip(mgr,descrName,tagName)
00046 {
00047   //setup Servos
00048   calibrateServo(H_EYE,H_EYE_MID,H_EYE_MIN,H_EYE_MAX);
00049   calibrateServo(V_EYE,V_EYE_MID,V_EYE_MIN,V_EYE_MAX);
00050   calibrateServo(H_HEAD,H_HEAD_MID,H_HEAD_MIN,H_HEAD_MAX);
00051   calibrateServo(V_HEAD,V_HEAD_MID,V_HEAD_MIN,V_HEAD_MAX);
00052   calibrateServo(EYELIDS,EYELIDS_MID,EYELIDS_MIN,EYELIDS_MAX);
00053   calibrateServo(EYEBROW,EYEBROW_MID,EYEBROW_MIN,EYEBROW_MAX);
00054   calibrateServo(MOUTH,MOUTH_MID,MOUTH_MIN,MOUTH_MAX);
00055   calibrateServo(MUZZLE,MUZZLE_MID,MUZZLE_MIN,MUZZLE_MAX);
00056 }
00057 
00058 
00059 // ######################################################################
00060 void BeoMonkey::setHEyePos(const float position,
00061                                        const int velocity)
00062 {
00063   setServo(H_EYE,position,velocity);
00064 }
00065 // ######################################################################
00066 std::deque<Position> BeoMonkey::getPathHEyePos(const float position,
00067                                        const int velocity,
00068                                                const float startpos)
00069 {
00070   return getPathServo(H_EYE,position,velocity,startpos);
00071 }
00072 
00073 // ######################################################################
00074 void BeoMonkey::setHEyePosRel(const float offset,
00075                                        const int velocity)
00076 {
00077    setHEyePos(getServo(H_EYE)+offset,velocity);
00078 
00079 }
00080 
00081 // ######################################################################
00082 void BeoMonkey::setVEyePos(const float position,
00083                                        const int velocity)
00084 {
00085    setServo(V_EYE,position,velocity);
00086 }
00087 
00088 // ######################################################################
00089 std::deque<Position> BeoMonkey::getPathVEyePos(const float position,
00090                                        const int velocity,
00091                                                const float startpos)
00092 {
00093   return getPathServo(V_EYE,position,velocity,startpos);
00094 }
00095 
00096 // ######################################################################
00097 void BeoMonkey::setVEyePosRel(const float offset,
00098                                        const int velocity)
00099 {
00100    setVEyePos(getServo(V_EYE)+offset,velocity);
00101 }
00102 
00103 // ######################################################################
00104 void BeoMonkey::setEyeLidsPos(const float position,
00105                                        const int velocity)
00106 {
00107    setServo(EYELIDS,position,velocity);
00108 }
00109 
00110 // ######################################################################
00111 std::deque<Position> BeoMonkey::getPathEyeLidsPos(const float position,
00112                                        const int velocity
00113 ,
00114                                                const float startpos)
00115 {
00116   return getPathServo(EYELIDS,position,velocity,startpos);
00117 }
00118 
00119 // ######################################################################
00120 void BeoMonkey::setEyeLidsRel(const float offset,
00121                                        const int velocity)
00122 {
00123    setEyeLidsPos(getServo(EYELIDS)+offset,velocity);
00124 }
00125 
00126 // ######################################################################
00127 void BeoMonkey::setEyeBrowPos(const float position,
00128                                        const int velocity)
00129 {
00130    setServo(EYEBROW,position,velocity);
00131 }
00132 
00133 // ######################################################################
00134 std::deque<Position> BeoMonkey::getPathEyeBrowPos(const float position,
00135                                        const int velocity,
00136                                                const float startpos)
00137 {
00138   return getPathServo(EYEBROW,position,velocity,startpos);
00139 }
00140 
00141 // ######################################################################
00142 void BeoMonkey::setEyeBrowPosRel(const float offset,
00143                                        const int velocity)
00144 {
00145    setEyeBrowPos(getServo(EYEBROW)+offset,velocity);
00146 }
00147 
00148 // ######################################################################
00149 void BeoMonkey::setMouthPos(const float position,
00150                                        const int velocity)
00151 {
00152    setServo(MOUTH,position,velocity);
00153 }
00154 
00155 // ######################################################################
00156 std::deque<Position> BeoMonkey::getPathMouthPos(const float position,
00157                                        const int velocity,
00158                                                const float startpos)
00159 {
00160   return getPathServo(MOUTH,position,velocity,startpos);
00161 }
00162 
00163 // ######################################################################
00164 void BeoMonkey::setMouthPosRel(const float offset,
00165                                        const int velocity)
00166 {
00167    setMouthPos(getServo(MOUTH)+offset,velocity);
00168 }
00169 
00170 // ######################################################################
00171 void BeoMonkey::setMuzzlePos(const float position,
00172                                        const int velocity)
00173 {
00174    setServo(MUZZLE,position,velocity);
00175 }
00176 
00177 // ######################################################################
00178 std::deque<Position> BeoMonkey::getPathMuzzlePos(const float position,
00179                                        const int velocity,
00180                                                const float startpos)
00181 {
00182   return getPathServo(MUZZLE,position,velocity,startpos);
00183 }
00184 
00185 // ######################################################################
00186 void BeoMonkey::setMuzzlePosRel(const float offset,
00187                                        const int velocity)
00188 {
00189    setMuzzlePos(getServo(MUZZLE)+offset,velocity);
00190 }
00191 
00192 // ######################################################################
00193 void BeoMonkey::setHHeadPos(const float position,
00194                                        const int velocity)
00195 {
00196    setServo(H_HEAD,position,velocity);
00197 }
00198 // ######################################################################
00199 std::deque<Position> BeoMonkey::getPathHHeadPos(const float position,
00200                                        const int velocity,
00201                                                const float startpos)
00202 {
00203   return getPathServo(H_HEAD,position,velocity,startpos);
00204 }
00205 
00206 // ######################################################################
00207 void BeoMonkey::setHHeadPosRel(const float offset,
00208                                        const int velocity)
00209 {
00210    setHHeadPos(getServo(H_HEAD)+offset,velocity);
00211 }
00212 
00213 
00214 
00215 // ######################################################################
00216 void BeoMonkey::setVHeadPos(const float position,
00217                                        const int velocity)
00218 {
00219    setServo(V_HEAD,position,velocity);
00220 }
00221 
00222 // ######################################################################
00223 std::deque<Position> BeoMonkey::getPathVHeadPos(const float position,
00224                                        const int velocity,
00225                                                const float startpos)
00226 {
00227   return getPathServo(V_HEAD,position,velocity,startpos);
00228 }
00229 
00230 // ######################################################################
00231 void BeoMonkey::setVHeadPosRel(const float offset,
00232                                        const int velocity)
00233 {
00234    setVHeadPos(getServo(V_HEAD)+offset,velocity);
00235 }
00236 
00237 // ######################################################################
00238 void BeoMonkey::start2()
00239 {
00240         initializeServos();
00241 }
00242 
00243 // ######################################################################
00244 void BeoMonkey::initializeServos()
00245 {
00246   LINFO("Initializing Servos...");
00247   //set servos to center
00248   setServo(H_EYE,0.0F,1);
00249   setServo(V_EYE,0.0F,1);
00250   setServo(H_HEAD,0.0F,1);
00251   setServo(V_HEAD,0.0F,1);
00252   setServo(EYELIDS,0.0F,1);
00253   setServo(EYEBROW,0.0F,1);
00254   setServo(MOUTH,0.0F,1);
00255   setServo(MUZZLE,0.0F,1);
00256   nextTimeStep();
00257   LINFO("Initialization Complete");
00258 }
00259 
00260 //set the servos and add blend to the current movement que
00261 //#######################################################################
00262 void BeoMonkey::setServo(const byte servo, const float position,
00263                          const int velocity)
00264 {
00265   addSequence(getPathServo(servo,position,velocity));
00266 }
00267 
00268 //return the path created from setting a servo to a particular pos and vel
00269 //#######################################################################
00270 std::deque<Position> BeoMonkey::getPathServo(const byte servo,
00271                                           const float position,
00272                                           const int velocity,
00273                                           const float startpos)
00274 
00275 {
00276   std::deque<Position> pos;
00277   float cur;
00278   if (startpos > -999)
00279     cur = startpos;
00280   else
00281     {
00282       cur = isServoInQue(servo); //shhould switch this burdain to add toend?
00283       if (cur < -2)
00284         cur = getServo(servo);
00285     }
00286 
00287   float step = (position - cur)/(float)velocity;
00288   for (int ii = 1; ii <= velocity; ii++)
00289     {
00290       Position p(servo,cur+step*ii,ii);
00291       pos.push_back(p);
00292     }
00293   //should add a function to change the velocty profile so its smooth
00294   return pos;
00295 }
00296 
00297 //add sequence and blend with current movement que
00298 //#######################################################################
00299 void BeoMonkey::addSequence(const byte servo,
00300                             std::deque<float> sequence)
00301 {
00302   addSequence(getSequence(servo,sequence));
00303 }
00304 
00305 //add sequencey and blend to current movement que
00306 //#######################################################################
00307 void BeoMonkey::addSequence(std::deque<Position> element)
00308 {
00309   moveQue = blend(moveQue,element);
00310 }
00311 
00312 //add sequencey to the end of the movement que
00313 //#######################################################################
00314 void BeoMonkey::addEndSequence(std::deque<Position> pos)
00315 {
00316     std::deque<Position>::iterator ii;
00317   if (moveQue.empty())
00318     moveQue = pos;
00319   else
00320     {
00321       for (ii = pos.begin(); ii != pos.end(); ii++)
00322         ii->time+= moveQue.back().time;
00323       moveQue.insert(moveQue.end(),pos.begin(),pos.end());
00324     }
00325 }
00326 
00327 //add sequencey to the end of the movement que
00328 //#######################################################################
00329 std::deque<Position> BeoMonkey::addEndSequence(std::deque<Position> seq,
00330                                std::deque<Position> pos)
00331 {
00332   std::deque<Position>::iterator ii;
00333   if (seq.empty())
00334     seq = pos;
00335   else
00336     {
00337       for (ii = pos.begin(); ii != pos.end(); ii++)
00338         ii->time+= seq.back().time;
00339       seq.insert(seq.end(),pos.begin(),pos.end());
00340     }
00341   return seq;
00342 }
00343 
00344 //create a position sequence from a deque of servo positions
00345 //#######################################################################
00346 std::deque<Position> BeoMonkey::getSequence(const byte servo,
00347                                              std::deque<float> sequence)
00348 {
00349   std::deque<Position> out;
00350   std::deque<float>::iterator ii;
00351   int time = 1;
00352   for(ii = sequence.begin(); ii != sequence.end(); ii++)
00353     {
00354       Position p(servo,*(ii),time);
00355       out.push_back(p);
00356       time++;
00357     }
00358   return out;
00359 }
00360 
00361 //take a deque of sequences and blend them togeather them with the current que
00362 //#######################################################################
00363 void BeoMonkey::blendSequence(std::deque< std::deque<Position> > elements)
00364 {
00365   elements.push_back(moveQue);
00366   moveQue = getBlendSequence(elements);
00367 }
00368 
00369 //blend a series of sequences togeather and return a deque
00370 //fix this to use an iterator
00371 //#######################################################################
00372 std::deque<Position> BeoMonkey::getBlendSequence(std::deque<
00373                                                   std::deque<Position>
00374                                                   > elements)
00375 {
00376  std::deque<Position> b;
00377   if (elements.size() > 1)
00378    {
00379     b  = blend(elements.at(0),elements.at(1));
00380 
00381     for (uint ii = 2; ii < elements.size(); ii++)
00382       {
00383         b = blend(b,elements.at(ii));
00384       }
00385    }
00386  return b;
00387 }
00388 
00389 //blend two sequences
00390 //#######################################################################
00391 std::deque<Position> BeoMonkey::blend(std::deque<Position> p1,
00392                                      std::deque<Position> p2)
00393 {
00394   std::deque<Position> p;
00395   std::deque<Position>::iterator ii,jj;
00396   int time;
00397   if (p1.empty())
00398     {
00399       p1.insert(p1.end(),p2.begin(),p2.end());
00400       return p1;
00401     }
00402   else
00403     {
00404       time = p1.back().time;
00405       if (p2.back().time > time)
00406         time = p2.back().time;
00407       ii = p1.begin();
00408       jj = p2.begin();
00409 
00410       for (int k = 1; k <= time; k++)
00411         {
00412           for (; ii != p1.end(); ii++)
00413             {
00414               if (ii->time == k)
00415                 p.push_back(*ii);
00416               else
00417                 break;
00418             }
00419           for (; jj != p2.end(); jj++)
00420             {
00421               if (jj->time == k)
00422                 p.push_back(*jj);
00423               else
00424                 break;
00425             }
00426         }
00427     }
00428   return p;
00429 }
00430 
00431 //#######################################################################
00432 bool BeoMonkey::isQueEmpty()
00433 {
00434   return moveQue.empty();
00435 }
00436 
00437 //#######################################################################
00438 bool BeoMonkey::nextTimeStep()
00439 {
00440   if (moveQue.empty() )
00441     return false;
00442 
00443   else
00444     {
00445       while (moveQue.front().time == 1)
00446         {
00447           if (!BeoChip::setServo(moveQue.front().servo,
00448                                  moveQue.front().position))
00449             return false;
00450           moveQue.pop_front();
00451         }
00452       std::deque<Position>::iterator ii;
00453       for (ii = moveQue.begin(); ii != moveQue.end(); ii++)
00454         ii->time--;
00455     }
00456   return true;
00457 }
00458 
00459 //#######################################################################
00460 std::deque<Position> BeoMonkey::concatSequence(std::deque<
00461                                                 std::deque<Position> > e)
00462 {
00463   std::deque<Position> f;
00464   std::deque< std::deque<Position> >::iterator ii;
00465   for (ii = e.begin(); ii != e.end(); ii++)
00466     {
00467       if (f.size() > 0)
00468         for (std::deque<Position>::iterator jj = ii->begin();
00469              jj != ii->end(); jj++)
00470           jj->time+= f.back().time;
00471 
00472       f.insert(f.end(),ii->begin(),ii->end());
00473     }
00474   return f;
00475 }
00476 
00477 //#######################################################################
00478 void BeoMonkey::clearQue()
00479 {
00480   moveQue.clear();
00481 }
00482 
00483 std::deque<Position> BeoMonkey::getQue()
00484 {
00485   return moveQue;
00486 }
00487 
00488 void  BeoMonkey::removeServo(const byte servo)
00489 {
00490   //doesn't make sure times are all ok
00491   std::deque<Position>::iterator ii;
00492   for (ii = moveQue.begin(); ii != moveQue.end(); )
00493     {
00494       if (ii->servo == servo)
00495         ii =  moveQue.erase(ii);
00496       else
00497         ii++;
00498     }
00499 }
00500 
00501 //######################################################################
00502 void BeoMonkey::surpriseFace(float surprise)
00503 {
00504   //  setEyeLidsPos(1.0,25);
00505   //setEyeBrowPos(1.0,25);
00506 
00507   std::deque< std::deque<Position> > p;
00508   p.push_back(getPathMouthPos(-1.0,2));
00509   p.push_back(getPathMouthPos(1.0,4,-1.0));
00510   p.push_back(getPathMouthPos(-1.0,4,1.0));
00511   p.push_back(getPathMouthPos(.5,2,-1.0));
00512   addSequence(concatSequence(p));
00513 }
00514 
00515 //######################################################################
00516 void BeoMonkey::printPath(std::deque<Position> pr)
00517 {
00518   std::deque<Position>::iterator ii;
00519   for (ii = pr.begin(); ii != pr.end(); ii++)
00520           LINFO("Servo: %d Position: %f Time: %d\n",ii->servo,
00521                 ii->position,ii->time);
00522 }
00523 
00524 //######################################################################
00525 float BeoMonkey::isServoInQue(byte servo)
00526 {
00527   if (moveQue.empty())
00528     return -999;
00529 
00530   float temp = -999;
00531   std::deque<Position>::reverse_iterator ii;
00532 
00533   for (ii = moveQue.rbegin(); ii != moveQue.rend(); ii++)
00534     {
00535       if (ii->servo == servo)
00536         {
00537           temp = ii->position;
00538           return temp;
00539         }
00540     }
00541   return temp;
00542 
00543 }
00544 
00545 //######################################################################
00546 int BeoMonkey::queSize()
00547 {
00548 return moveQue.size();
00549 }
00550 
00551 // ######################################################################
00552 /* So things look consistent in everyone's emacs... */
00553 /* Local Variables: */
00554 /* indent-tabs-mode: nil */
00555 /* End: */
Generated on Sun May 8 08:40:37 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3