00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
00056
00057
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
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
00250 setLeftEyePan(leftEyeMovePan);
00251 setLeftEyeTilt(leftEyeMoveTilt);
00252 setRightEyePan(leftEyeMovePan);
00253 setRightEyeTilt(leftEyeMoveTilt);
00254
00255 setHeadPan(moveHeadPan);
00256
00257
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
00277
00278 itsPololu->setParam(LEFT_EYE_PAN, 1, 0, 13);
00279 itsPololu->setNeutral(LEFT_EYE_PAN,2850);
00280
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
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
00307
00308
00309