00001 /*!@file Devices/BeoHead.C Interfaces to robot head */ 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/Devices/BeoHead.C $ 00035 // $Id: BeoHead.C 9764 2008-05-12 16:02:35Z lior $ 00036 // 00037 00038 #include "Devices/BeoHead.H" 00039 #include "Component/OptionManager.H" 00040 #include "Util/MathFunctions.H" 00041 #include "Util/Assert.H" 00042 #include "rutz/compat_snprintf.h" 00043 00044 // ###################################################################### 00045 BeoHead::BeoHead(OptionManager& mgr, const std::string& descrName, 00046 const std::string& tagName) : 00047 ModelComponent(mgr, descrName, tagName), 00048 itsLeftEyePanPos(0), 00049 itsRightEyeTiltPos(0), 00050 itsRightEyePanPos(0), 00051 itsLeftEyeTiltPos(0), 00052 itsHeadPanPos(0), 00053 itsHeadTiltPos(0.67), 00054 itsHeadYawPos(0), 00055 //pidLeftPan(0.6, 0.002, 0.2, -1.0, 1.0), 00056 //pidLeftTilt(0.4, 0.002, 0.2, -1.0, 1.0), 00057 //pidHeadPan(0.1, 0, 0, -1.0, 1.0) 00058 pidLeftPan(0.2, 0, 0.4, -1.0, 1.0), 00059 pidLeftTilt(0.2, 0, 0.3, -1.0, 1.0), 00060 pidHeadPan(0.05, 0, 0, -1.0, 1.0), 00061 isNeckRelaxed(true) 00062 00063 { 00064 itsPololu = nub::soft_ref<Pololu>(new Pololu(mgr)); 00065 addSubComponent(itsPololu); 00066 00067 } 00068 00069 00070 // ###################################################################### 00071 bool BeoHead::setLeftEyePan(float pos) 00072 { 00073 if (pos > 1.0) pos = 1.0; 00074 if (pos < -1.0) pos = -1.0; 00075 itsLeftEyePanPos = pos; 00076 int rawPos = int(63.5*pos+63.5); 00077 return itsPololu->moveRaw(LEFT_EYE_PAN, rawPos); 00078 } 00079 00080 // ###################################################################### 00081 bool BeoHead::setLeftEyeTilt(float pos) 00082 { 00083 if (pos > 1.0) pos = 1.0; 00084 if (pos < -1.0) pos = -1.0; 00085 int rawPos = int(63.5*pos+63.5); 00086 itsLeftEyeTiltPos = pos; 00087 return itsPololu->moveRaw(LEFT_EYE_TILT, rawPos); 00088 } 00089 00090 // ###################################################################### 00091 bool BeoHead::setRightEyePan(float pos) 00092 { 00093 if (pos > 1.0) pos = 1.0; 00094 if (pos < -1.0) pos = -1.0; 00095 int rawPos = int(63.5*pos+63.5); 00096 itsRightEyePanPos = pos; 00097 return itsPololu->moveRaw(RIGHT_EYE_PAN, rawPos); 00098 } 00099 00100 // ###################################################################### 00101 bool BeoHead::setRightEyeTilt(float pos) 00102 { 00103 if (pos > 1.0) pos = 1.0; 00104 if (pos < -1.0) pos = -1.0; 00105 int rawPos = int(63.5*pos+63.5); 00106 itsRightEyeTiltPos = pos; 00107 return itsPololu->moveRaw(RIGHT_EYE_TILT, rawPos); 00108 } 00109 00110 // ###################################################################### 00111 bool BeoHead::setHeadPan(float pos) 00112 { 00113 if (isNeckRelaxed) return false; 00114 if (pos > 1.0) pos = 1.0; 00115 if (pos < -1.0) pos = -1.0; 00116 itsHeadPanPos = pos; 00117 int rawPos = int(63.5*pos+63.5); 00118 return itsPololu->moveRaw(HEAD_PAN, rawPos); 00119 } 00120 00121 // ###################################################################### 00122 bool BeoHead::setHeadTilt(float pos) 00123 { 00124 if (isNeckRelaxed) return false; 00125 if (pos > 1.0) pos = 1.0; 00126 if (pos < -1.0) pos = -1.0; 00127 int rawLeftPos = int(63.5*(pos+itsHeadYawPos)+63.5); 00128 int rawRightPos = int(63.5*(pos-itsHeadYawPos)+63.5); 00129 00130 itsHeadTiltPos = pos; 00131 00132 if (rawLeftPos > 0 && rawLeftPos < 127 && 00133 rawRightPos > 0 && rawRightPos < 127) 00134 { 00135 itsPololu->moveRaw(HEAD_LEFT, rawLeftPos); 00136 itsPololu->moveRaw(HEAD_RIGHT, rawRightPos); 00137 } 00138 00139 return true; 00140 } 00141 00142 // ###################################################################### 00143 bool BeoHead::setHeadYaw(float pos) 00144 { 00145 if (isNeckRelaxed) return false; 00146 00147 if (pos > 1.0) pos = 1.0; 00148 if (pos < -1.0) pos = -1.0; 00149 int rawLeftPos = int(63.5*(pos+itsHeadTiltPos)+63.5); 00150 int rawRightPos = int(-63.5*(pos-itsHeadTiltPos)+63.5); 00151 00152 itsHeadYawPos = pos; 00153 00154 if (rawLeftPos > 0 && rawLeftPos < 127 && 00155 rawRightPos > 0 && rawRightPos < 127) 00156 { 00157 itsPololu->moveRaw(HEAD_LEFT, rawLeftPos); 00158 itsPololu->moveRaw(HEAD_RIGHT, rawRightPos); 00159 } 00160 return true; 00161 } 00162 00163 bool BeoHead::relaxNeck() 00164 { 00165 if (!isNeckRelaxed) 00166 { 00167 setHeadPan(0); 00168 setHeadTilt(0.67); 00169 setHeadYaw(0); 00170 sleep(2); 00171 } 00172 00173 itsPololu->setParam(HEAD_PAN, 0, 0, 10); 00174 itsPololu->setParam(HEAD_RIGHT, 0, 0, 3); 00175 itsPololu->setParam(HEAD_LEFT, 0, 1, 3); 00176 isNeckRelaxed = true; 00177 return true; 00178 } 00179 00180 bool BeoHead::relaxHead() 00181 { 00182 itsPololu->setParam(LEFT_EYE_TILT, 0, 0, 13); 00183 itsPololu->setParam(LEFT_EYE_PAN, 0, 0, 13); 00184 itsPololu->setParam(RIGHT_EYE_TILT, 0, 1, 13); 00185 itsPololu->setParam(RIGHT_EYE_PAN, 0, 0, 13); 00186 00187 itsPololu->setParam(HEAD_PAN, 0, 0, 10); 00188 itsPololu->setParam(HEAD_RIGHT, 0, 0, 3); 00189 itsPololu->setParam(HEAD_LEFT, 0, 1, 3); 00190 00191 return true; 00192 } 00193 00194 bool BeoHead::moveRestPos() 00195 { 00196 isNeckRelaxed = false; 00197 00198 itsPololu->setParam(LEFT_EYE_TILT, 1, 0, 13); 00199 itsPololu->setNeutral(LEFT_EYE_TILT,3180); 00200 itsPololu->setParam(LEFT_EYE_PAN, 1, 0, 13); 00201 itsPololu->setNeutral(LEFT_EYE_PAN,2850); 00202 itsPololu->setParam(RIGHT_EYE_TILT, 1, 1, 13); 00203 itsPololu->setNeutral(RIGHT_EYE_TILT,3024); 00204 itsPololu->setParam(RIGHT_EYE_PAN, 1, 0, 13); 00205 itsPololu->setNeutral(RIGHT_EYE_PAN,3150); 00206 00207 00208 setLeftEyePan(0); 00209 setLeftEyeTilt(0); 00210 setRightEyePan(0); 00211 setRightEyeTilt(0); 00212 00213 itsPololu->setSpeed(HEAD_PAN, 1); 00214 itsPololu->setParam(HEAD_PAN, 0, 0, 10); 00215 itsPololu->setNeutral(HEAD_PAN,3024); 00216 itsPololu->setSpeed(HEAD_RIGHT, 1); 00217 itsPololu->setParam(HEAD_RIGHT, 0, 0, 3); 00218 itsPololu->setNeutral(HEAD_RIGHT,3624); 00219 itsPololu->setSpeed(HEAD_LEFT, 1); 00220 itsPololu->setParam(HEAD_LEFT, 0, 1, 3); 00221 itsPololu->setNeutral(HEAD_LEFT,2334); 00222 00223 setHeadPan(0); 00224 setHeadTilt(0.67); 00225 setHeadYaw(0); 00226 00227 itsPololu->setSpeed(HEAD_PAN, 20); 00228 itsPololu->setSpeed(HEAD_RIGHT, 20); 00229 itsPololu->setSpeed(HEAD_LEFT, 20); 00230 00231 isNeckRelaxed = false; 00232 return true; 00233 } 00234 00235 //input should be normalized from 0 to 1 00236 float BeoHead::trackTarget(float desiredVisualPosX, float desiredVisualPosY, 00237 float currentVisualPosX, float currentVisualPosY) 00238 { 00239 00240 float leftEyeMovePan = itsLeftEyePanPos + 00241 pidLeftPan.update(desiredVisualPosX, currentVisualPosX); 00242 00243 float leftEyeMoveTilt = itsLeftEyeTiltPos + 00244 pidLeftTilt.update(desiredVisualPosY, currentVisualPosY); 00245 00246 float moveHeadPan = itsHeadPanPos + 00247 pidHeadPan.update(0, leftEyeMovePan); 00248 00249 //make the movement 00250 setLeftEyePan(leftEyeMovePan); 00251 setLeftEyeTilt(leftEyeMoveTilt); 00252 setRightEyePan(leftEyeMovePan); 00253 setRightEyeTilt(leftEyeMoveTilt); 00254 00255 setHeadPan(moveHeadPan); 00256 00257 //the total error in position 00258 float err = fabs(desiredVisualPosX-currentVisualPosX) + 00259 fabs(desiredVisualPosY-currentVisualPosY); 00260 return err; 00261 } 00262 00263 00264 // ###################################################################### 00265 void BeoHead::start2() 00266 { 00267 initHead(); 00268 } 00269 00270 // ###################################################################### 00271 void BeoHead::initHead() 00272 { 00273 LINFO("Init Servos..."); 00274 itsPololu->setParam(LEFT_EYE_TILT, 1, 0, 13); 00275 itsPololu->setNeutral(LEFT_EYE_TILT,3180); 00276 //itsPololu->setSpeed(LEFT_EYE_TILT, 30); 00277 00278 itsPololu->setParam(LEFT_EYE_PAN, 1, 0, 13); 00279 itsPololu->setNeutral(LEFT_EYE_PAN,2850); 00280 //itsPololu->setSpeed(LEFT_EYE_PAN, 30); 00281 00282 itsPololu->setParam(RIGHT_EYE_TILT, 1, 1, 13); 00283 itsPololu->setNeutral(RIGHT_EYE_TILT,3024); 00284 00285 itsPololu->setParam(RIGHT_EYE_PAN, 1, 0, 13); 00286 itsPololu->setNeutral(RIGHT_EYE_PAN,3150); 00287 00288 //start with the neck off 00289 itsPololu->setSpeed(HEAD_PAN, 20); 00290 itsPololu->setParam(HEAD_PAN, 0, 0, 10); 00291 itsPololu->setNeutral(HEAD_PAN,3024); 00292 00293 00294 itsPololu->setSpeed(HEAD_RIGHT, 20); 00295 itsPololu->setParam(HEAD_RIGHT, 0, 0, 3); 00296 itsPololu->setNeutral(HEAD_RIGHT,3624); 00297 00298 itsPololu->setSpeed(HEAD_LEFT, 20); 00299 itsPololu->setParam(HEAD_LEFT, 0, 1, 3); 00300 itsPololu->setNeutral(HEAD_LEFT,2334); 00301 00302 } 00303 00304 00305 // ###################################################################### 00306 /* So things look consistent in everyone's emacs... */ 00307 /* Local Variables: */ 00308 /* indent-tabs-mode: nil */ 00309 /* End: */