00001 #include <stdexcept>
00002 #include <sstream>
00003 #include <vector>
00004 #include <algorithm>
00005
00006 #include <stdio.h>
00007 #include <errno.h>
00008 #include <termios.h>
00009 #include <fcntl.h>
00010 #include <unistd.h>
00011 #include <sys/time.h>
00012
00013 #include "FCam/F2/Lens.h"
00014 #include "FCam/Frame.h"
00015
00016 #include "../Debug.h"
00017
00022 #define eprintf(...) \
00023 fprintf(stderr,"EF232[%s]: ERROR! ", tty.c_str()); \
00024 fprintf(stderr, __VA_ARGS__);
00025
00026
00027 namespace FCam { namespace F2 {
00028
00030
00031
00032
00033 Lens::Lens(const std::string &tty_):
00034 tty(tty_),
00035 lensDB(),
00036 currentLens(NULL),
00037 state(NotInitialized),
00038 lensHistory(640),
00039 controlRunning(false)
00040 {
00041 launchControlThread();
00042 }
00043
00044 Lens::~Lens() {
00045 dprintf(DBG_MINOR,"Lens controller shutting down...\n");
00046 if (controlRunning) {
00047 LensOrder shutdown;
00048 shutdown.cmd = Shutdown;
00049 cmdQueue.push(shutdown);
00050 dprintf(DBG_MINOR,"Waiting for control thread to complete...\n");
00051 pthread_join(controlThread, NULL);
00052 }
00053 dprintf(DBG_MINOR,"Lens controller exit.\n");
00054 }
00055
00056 void Lens::setFocus(float diopters, float speed) {
00057 dprintf(DBG_MINOR,"Setting lens focus to %f\n", diopters);
00058 LensOrder ord = {SetFocus,
00059 diopToEncoder(diopters)};
00060 cmdQueue.push(ord);
00061 }
00062
00063 float Lens::getFocus() {
00064 int val;
00065 pthread_mutex_lock(&stateMutex);
00066 val = calcFocusDistance(Time::now());
00067 pthread_mutex_unlock(&stateMutex);
00068 return encToDiopter(val);
00069 }
00070
00071 float Lens::farFocus() {
00072 return 0;
00073 }
00074
00075 float Lens::nearFocus() {
00076 LensState s = getState();
00077 if (s == NotInitialized ||
00078 s == NoLens) {
00079 eprintf("maxFocus: Lens not ready!\n");
00080 return -1;
00081 }
00082 return 1000.0/currentLens->focusDistMin;
00083 }
00084
00085 bool Lens::focusChanging() {
00086 return getState() == MovingFocus;
00087 }
00088
00089 int Lens::focusLatency() {
00090 return 0;
00091 }
00092
00093 float Lens::minFocusSpeed() {
00094 LensState s = getState();
00095 if (s == NotInitialized ||
00096 s == NoLens) {
00097 eprintf("minFocusSpeed: Lens not ready!\n");
00098 return -1;
00099 }
00100 return currentLens->focusSpeed;
00101 }
00102
00103 float Lens::maxFocusSpeed() {
00104 LensState s = getState();
00105 if (s == NotInitialized ||
00106 s == NoLens) {
00107 eprintf("maxFocusSpeed: Lens not ready!\n");
00108 return -1;
00109 }
00110 return currentLens->focusSpeed;
00111 }
00112
00113 void Lens::setZoom(float focal_length_mm, float speed) {
00114 eprintf("setZoom: Manual zoom only, not zooming to %f\n", focal_length_mm);
00115 }
00116
00117 float Lens::getZoom() {
00118 int val;
00119 pthread_mutex_lock(&stateMutex);
00120 val = calcFocalLength(Time::now());
00121 pthread_mutex_unlock(&stateMutex);
00122 return val;
00123
00124 }
00125
00126 float Lens::minZoom() {
00127 LensState s = getState();
00128 if (s == NotInitialized ||
00129 s == NoLens) {
00130 eprintf("minZoom: Lens not ready!\n");
00131 return -1;
00132 }
00133 return currentLens->focalLengthMin;
00134 }
00135 float Lens::maxZoom() {
00136 LensState s = getState();
00137 if (s == NotInitialized ||
00138 s == NoLens) {
00139 eprintf("minZoom: Lens not ready!\n");
00140 return -1;
00141 }
00142 return currentLens->focalLengthMax;
00143 }
00144
00145 bool Lens::zoomChanging() {
00146 return false;
00147 }
00148
00149 float Lens::minZoomSpeed() {
00150 return 0;
00151 }
00152
00153 float Lens::maxZoomSpeed() {
00154 return 0;
00155 }
00156
00157 int Lens::zoomLatency() {
00158 return 0;
00159 }
00160
00161 void Lens::setAperture(float f_number, float speed) {
00162 dprintf(DBG_MINOR,"Setting lens aperture to %f\n", f_number);
00163 LensOrder ord = {SetAperture,
00164 f_number*10};
00165 cmdQueue.push(ord);
00166 }
00167
00168 float Lens::getAperture() {
00169 int val;
00170 pthread_mutex_lock(&stateMutex);
00171 val = calcAperture(Time::now());
00172 pthread_mutex_unlock(&stateMutex);
00173 return val/10.0;
00174 }
00175
00176 float Lens::wideAperture(float focal_length_mm) {
00177 LensState s = getState();
00178 if (s == NotInitialized ||
00179 s == NoLens) {
00180 eprintf("minAperture: Lens not ready!\n");
00181 return -1;
00182 }
00183
00184 return currentLens->minApertureAt(focal_length_mm)/10.0;
00185 }
00186
00187
00188 float Lens::narrowAperture(float focal_length_mm) {
00189 LensState s = getState();
00190 if (s == NotInitialized ||
00191 s == NoLens) {
00192 eprintf("maxAperture: Lens not ready!\n");
00193 return -1;
00194 }
00195 return currentLens->apertureMax/10.0;
00196 }
00197
00198 bool Lens::apertureChanging() {
00199 return getState() == MovingAperture;
00200 }
00201
00202 int Lens::apertureLatency() {
00203 return 0;
00204 }
00205
00206 float Lens::minApertureSpeed() {
00207 return 0;
00208 }
00209
00210 float Lens::maxApertureSpeed() {
00211 return 0;
00212 }
00213
00214 void Lens::reset() {
00215 LensOrder ord = {
00216 Initialize,
00217 0
00218 };
00219
00220 cmdQueue.push(ord);
00221 }
00222
00223 void Lens::tagFrame(FCam::Frame f) {
00224 pthread_mutex_lock(&stateMutex);
00225
00226 float initialFocus = encToDiopter(calcFocusDistance(f.exposureStartTime()));
00227 float finalFocus = encToDiopter(calcFocusDistance(f.exposureEndTime()));
00228 f["initialFocus"] = initialFocus;
00229 f["finalFocus"] = finalFocus;
00230 f["focus"] = (initialFocus + finalFocus)/2;
00231 f["focusSpeed"] = (1000000.0f * (finalFocus - initialFocus)/
00232 (f.exposureEndTime() - f.exposureStartTime()));
00233 dprintf(5, "Focus start %f, end %f\n", initialFocus, finalFocus);
00234
00235 float initialZoom = calcFocalLength(f.exposureStartTime());
00236 float finalZoom = calcFocalLength(f.exposureEndTime());
00237 f["initialZoom"] = initialZoom;
00238 f["finalZoom"] = finalZoom;
00239 f["zoom"] = (initialZoom + finalZoom)/2;
00240 f["zoomSpeed"] = 1e6 * (finalZoom - initialZoom)/
00241 (f.exposureEndTime() - f.exposureStartTime());
00242
00243 float initialAperture = 10*calcAperture(f.exposureStartTime());
00244 float finalAperture = 10*calcAperture(f.exposureEndTime());
00245 f["initialAperture"] = initialAperture;
00246 f["finalAperture"] = finalAperture;
00247 f["aperture"] = (initialAperture + finalAperture)/2.;
00248 f["apertureSpeed"] = 1e6*(finalAperture - initialAperture) /
00249 (f.exposureEndTime() - f.exposureStartTime());
00250
00251 pthread_mutex_unlock(&stateMutex);
00252 }
00253
00254
00256
00257
00258
00259 void Lens::launchControlThread() {
00260 pthread_mutex_init(&stateMutex, NULL);
00261 if (pthread_create(&controlThread, NULL, lensControlThread, this) != 0) {
00262 perror("Error creating lens control thread");
00263 } else {
00264 controlRunning = true;
00265 }
00266 }
00267
00268
00269 void *Lens::lensControlThread(void *arg) {
00270 Lens *l = (Lens *)arg;
00271 l->runLensControlThread();
00272 pthread_exit(NULL);
00273 }
00274
00275 void Lens::runLensControlThread() {
00276 bool done = false;
00277 dprintf(DBG_MINOR,"Lens control thread starting\n");
00278 init();
00279 while(!done) {
00280
00281
00282 bool cmdReady;
00283 cmdReady = cmdQueue.wait(200000);
00284 if (!cmdReady) {
00285 dprintf(5,"LCT: idle\n");
00286 if (getState() == NotInitialized) continue;
00287
00288 idleProcessing();
00289
00290 } else {
00291 LensOrder ord = cmdQueue.front();
00292 cmdQueue.pop();
00293 dprintf(5,"LCT: %d %d\n", ord.cmd, ord.val);
00294 switch(ord.cmd) {
00295 case Initialize:
00296 init();
00297 break;
00298 case Calibrate:
00299 calibrateLens();
00300 break;
00301 case SetAperture:
00302 {
00303 setState(MovingAperture);
00304 LensParams params;
00305 params.time=Time::now();
00306 params.focalLength = lensHistory[0].focalLength;
00307 params.aperture = lensHistory[0].aperture;
00308 params.focusDist = lensHistory[0].focusDist;
00309 lensHistory.push(params);
00310
00311 unsigned int newAperture = cmd_DoAperture(ord.val);
00312
00313 params.aperture = newAperture;
00314 params.time = Time::now();
00315 lensHistory.push(params);
00316 setState(Ready);
00317 } break;
00318 case SetFocus:
00319 {
00320 setState(MovingFocus);
00321 LensParams params;
00322 params.time=Time::now();
00323 params.focalLength = lensHistory[0].focalLength;
00324 params.aperture = lensHistory[0].aperture;
00325 params.focusDist = lensHistory[0].focusDist;
00326 lensHistory.push(params);
00327
00328 unsigned int newFocusDist = cmd_DoFocus(ord.val);
00329 params.focusDist = newFocusDist;
00330 params.time = Time::now();
00331 lensHistory.push(params);
00332 setState(Ready);
00333 } break;
00334 case Shutdown:
00335 done = true;
00336 break;
00337 }
00338 }
00339 }
00340 close(serial_fd);
00341 dprintf(DBG_MINOR,"Lens control thread shutting down\n");
00342 }
00343
00344 void Lens::idleProcessing() {
00345
00346 if (getState() != Ready) {
00347
00348 return;
00349 }
00350 setState(Busy);
00351 std::string idStr = cmd_GetID();
00352 unsigned int fl = cmd_GetFocalLength(idStr);
00353 if (fl != lensHistory[0].focalLength) {
00354 LensParams currentParams;
00355 currentParams.focalLength = fl;
00356 currentParams.focusDist = lensHistory[0].focusDist;
00357 currentParams.time = Time::now();
00358
00359 unsigned int minAperture = cmd_GetMinAperture(idStr);
00360 if (minAperture > lensHistory[0].aperture) {
00361 currentParams.aperture = minAperture;
00362 } else {
00363 currentParams.aperture = lensHistory[0].aperture;
00364 }
00365
00366 lensHistory.push(currentParams);
00367
00368 if (currentLens->minApertureAt(lensHistory[0].focalLength) != minAperture) {
00369 dprintf(5,"Adding entry to min aperture map: %d->%d, currently %d\n",
00370 lensHistory[0].focalLength, minAperture,
00371 currentLens->minApertureAt(lensHistory[0].focalLength));
00372
00373 EF232LensInfo updatedInfo = *currentLens;
00374 EF232LensInfo::minApertureListIter iter=
00375 updatedInfo.
00376 minApertureList.
00377 insert(updatedInfo.minApertureList.begin(),
00378 EF232LensInfo::apertureChange(lensHistory[0].focalLength,
00379 minAperture));
00380 iter++;
00381 while (iter != updatedInfo.minApertureList.end()) {
00382 if (iter->second == minAperture) {
00383 dprintf(5,"Removing redundant entry %d->%d\n", iter->first, iter->second);
00384 updatedInfo.minApertureList.erase(iter++);
00385 } else {
00386 iter++;
00387 }
00388 }
00389 currentLens = lensDB.update(updatedInfo);
00390 }
00391 }
00392 setState(Ready);
00393
00394 return;
00395 }
00396
00397 void Lens::setState(LensState newState) {
00398 pthread_mutex_lock(&stateMutex);
00399 state = newState;
00400 pthread_mutex_unlock(&stateMutex);
00401 }
00402
00403 Lens::LensState Lens::getState() {
00404 LensState curState;
00405 pthread_mutex_lock(&stateMutex);
00406 curState = state;
00407 pthread_mutex_unlock(&stateMutex);
00408 return curState;
00409 }
00410
00411
00412 int Lens::calcFocusDistance(const Time &t) const {
00413 unsigned int index =0;
00414 while (index < lensHistory.size() &&
00415 lensHistory[index].time >= t) {
00416 index++;
00417 }
00418 if (index == 0) {
00419 return lensHistory[0].focusDist;
00420 }
00421 if (index == lensHistory.size()) {
00422 return lensHistory[lensHistory.size()-1].focusDist;
00423 }
00424
00425 int fStart = lensHistory[index].focusDist;
00426 int fEnd = lensHistory[index-1].focusDist;
00427 if (fStart == fEnd) return fStart;
00428
00429 float tfrac = (t - lensHistory[index].time)
00430 / ((float) (lensHistory[index-1].time - lensHistory[index].time));
00431
00432 return fStart * tfrac + fEnd * (1-tfrac);
00433 }
00434
00435 int Lens::calcAperture(const Time &t) const {
00436 unsigned int index =0;
00437 while (index < lensHistory.size() &&
00438 lensHistory[index].time >= t) {
00439 index++;
00440 }
00441 if (index == 0) {
00442 return lensHistory[0].aperture;
00443 }
00444 if (index == lensHistory.size()) {
00445 return lensHistory[lensHistory.size()-1].aperture;
00446 }
00447
00448 int aStart = lensHistory[index].aperture;
00449 int aEnd = lensHistory[index-1].aperture;
00450 if (aStart == aEnd) return aStart;
00451
00452 float tfrac = (t - lensHistory[index].time)
00453 / ((float) (lensHistory[index-1].time - lensHistory[index].time));
00454
00455 return aStart * tfrac + aEnd * (1-tfrac);
00456 }
00457
00458 int Lens::calcFocalLength(const Time &t) const {
00459 unsigned int index =0;
00460 while (index < lensHistory.size() &&
00461 lensHistory[index].time >= t) {
00462 index++;
00463 }
00464 if (index == 0) {
00465 return lensHistory[0].focalLength;
00466 }
00467 if (index == lensHistory.size()) {
00468 return lensHistory[lensHistory.size()-1].focalLength;
00469 }
00470
00471 int fStart = lensHistory[index].focalLength;
00472 int fEnd = lensHistory[index-1].focalLength;
00473 if (fStart == fEnd) return fStart;
00474
00475 float tfrac = (t - lensHistory[index].time)
00476 / ((float) (lensHistory[index-1].time - lensHistory[index].time));
00477
00478 return fStart * tfrac + fEnd * (1-tfrac);
00479
00480 }
00481
00483
00484 float Lens::encToDiopter(unsigned int encoder) {
00485 return diopScaleFactor * (focusEncoderMax - encoder);
00486 }
00487
00488 unsigned int Lens::diopToEncoder(float diopters) {
00489 return focusEncoderMax - (diopters/diopScaleFactor);
00490 }
00491
00493
00494 template<>
00495 void Lens::read(std::string &val);
00496
00498
00499
00500 void Lens::init() {
00502
00503 serial_fd = open (tty.c_str(),
00504 O_RDWR | O_NOCTTY | O_NDELAY);
00505
00506 if (serial_fd < 0) {
00507 eprintf("Unable to open serial device!");
00508 return;
00509 }
00510
00512
00513
00514
00515 fcntl(serial_fd, F_SETFL, 0);
00516
00517 struct termios opts;
00518 tcgetattr(serial_fd, &opts);
00519
00520 opts.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
00521 opts.c_lflag = 0;
00522 opts.c_iflag = 0;
00523 opts.c_oflag = 0;
00524
00525 opts.c_cc[VMIN] = 0;
00526 opts.c_cc[VTIME] = 1;
00527
00528 tcflush(serial_fd, TCIFLUSH);
00529 tcsetattr(serial_fd, TCSANOW, &opts);
00530
00531
00532
00533 try {
00534 cmd_DoInitialize();
00535 cmd_DoApertureOpen();
00536
00537 state = NoLens;
00538 } catch (std::runtime_error err) {
00539 eprintf("Unable to initialize the lens controller!\n");
00540 close(serial_fd);
00541 state = NotInitialized;
00542 return;
00543 }
00544
00545 calibrateLens();
00546 }
00547
00549
00550
00551 void Lens::calibrateLens() {
00552 try {
00553 unsigned int focalMin, focalMax;
00554
00555 int focalLength = cmd_GetFocalLength();
00556
00557 cmd_GetZoomRange(focalMin, focalMax);
00558
00559
00560 currentLens = lensDB.find(focalMin, focalMax);
00561
00562
00563 cmd_DoFocusAtZero();
00564 cmd_SetFocusEncoder(0);
00565
00566
00567 if (currentLens->focusDistMin == 0) {
00568 dprintf(5,"Measuring minimum focus distance\n");
00569 unsigned int newFDMin, newFDMax;
00570
00571 cmd_GetFocusBracket(newFDMin, newFDMax);
00572 if (newFDMin == 0) {
00573
00574
00575
00576 eprintf("Unknown lens minimum focus distance, assuming 0mm!\n");
00577 } else {
00578 EF232LensInfo updatedInfo = *currentLens;
00579 updatedInfo.focusDistMin = newFDMin;
00580 currentLens = lensDB.update(updatedInfo);
00581 dprintf(5, "Updated focusDistMin to %d\n", currentLens->focusDistMin);
00582 }
00583 }
00584
00585
00586
00587 cmd_DoFocusAtInf();
00588
00589 focusEncoderMax = cmd_GetFocusEncoder();
00590 diopScaleFactor = 1000.0/(currentLens->focusDistMin
00591 * focusEncoderMax);
00592
00593 state = Ready;
00594
00595 if (currentLens->apertureMax == 0) {
00596 dprintf(DBG_MINOR,"Measuring max aperture...\n");
00597 unsigned int newApertureMax = cmd_DoApertureClose();
00598 EF232LensInfo updatedInfo = *currentLens;
00599 updatedInfo.apertureMax = newApertureMax;
00600 currentLens = lensDB.update(updatedInfo);
00601 }
00602
00603 if (currentLens->focusSpeed == 0) {
00604 dprintf(DBG_MINOR,"Measuring focus speed...\n");
00605
00606 std::vector<float> focusSpeeds;
00607 float maxDiop = 1000.0/currentLens->focusDistMin;
00608 for (unsigned int percent = 10; percent <= 100; percent+=20) {
00609 timeval startFocus, midFocus, endFocus;
00610 float destDiop = maxDiop*percent/100;
00611 gettimeofday(&startFocus, NULL);
00612 setFocus(destDiop);
00613 gettimeofday(&midFocus, NULL);
00614 setFocus(0);
00615 gettimeofday(&endFocus, NULL);
00616
00617 unsigned int infToZeroT = (midFocus.tv_sec - startFocus.tv_sec)*1000000
00618 + (midFocus.tv_usec - startFocus.tv_usec);
00619 unsigned int zeroToInfT = (endFocus.tv_sec - midFocus.tv_sec)*1000000
00620 + (endFocus.tv_usec - midFocus.tv_usec);
00621
00622 float infToZeroDPS = (destDiop/(float)infToZeroT)*1e6;
00623 float zeroToInfDPS = (destDiop/(float)zeroToInfT)*1e6;
00624 dprintf(5, "Focus Speed calib for 0 to %f diop: %f diop/sec inf-to-zero, %f diop/sec zero-to-inf\n", destDiop, infToZeroDPS, zeroToInfDPS);
00625 focusSpeeds.push_back(infToZeroDPS);
00626 focusSpeeds.push_back(zeroToInfDPS);
00627 }
00628
00629
00630 std::sort(focusSpeeds.begin(), focusSpeeds.end());
00631 float newFocusSpeed = focusSpeeds[(focusSpeeds.size()+1)/2];
00632 dprintf(5, "Setting focus speed to median: %f DPS\n", newFocusSpeed);
00633
00634 EF232LensInfo updatedInfo = *currentLens;
00635 updatedInfo.focusSpeed = newFocusSpeed;
00636 currentLens = lensDB.update(updatedInfo);
00637
00638 }
00639
00640 if (currentLens->minApertureList.size() == 0) {
00641 dprintf(DBG_MINOR,"Establishing minimal focal length->min aperture map\n");
00642
00643 unsigned int newFocalLength = cmd_GetFocalLength();
00644 unsigned int newMinAperture = cmd_GetMinAperture();
00645 EF232LensInfo updatedInfo = *currentLens;
00646 updatedInfo.minApertureList[newFocalLength] = newMinAperture;
00647 currentLens = lensDB.update(updatedInfo);
00648 }
00649
00650 int aperture = cmd_DoApertureOpen();
00651 int focusDistance = cmd_GetFocusEncoder();
00652
00653 LensParams calibParams;
00654 calibParams.time = Time::now();
00655 calibParams.focalLength = focalLength;
00656 calibParams.aperture = aperture;
00657 calibParams.focusDist= focusDistance;
00658 lensHistory.push(calibParams);
00659
00660
00661 } catch (std::runtime_error err) {
00662 eprintf("Unable to configure lens!\n");
00663 state = NoLens;
00664 }
00665 }
00666
00668
00669
00670 std::string Lens::cmd_GetID() {
00671 send("id");
00672 expect("OK");
00673 read(buf);
00674 dprintf(6,"* ID response: %s\n", buf.c_str());
00675 return buf;
00676 }
00677
00678 unsigned int Lens::cmd_GetFocalLength(std::string idStr) {
00679 std::stringstream parsebuf;
00680 if (idStr == "") idStr = cmd_GetID();
00681 parsebuf.str(idStr);
00682 unsigned int val;
00683 parsebuf >> val;
00684 return val;
00685 }
00686
00687 unsigned int Lens::cmd_GetMinAperture(std::string idStr) {
00688 std::stringstream parsebuf;
00689 if (idStr == "") idStr = cmd_GetID();
00690 parsebuf.str(idStr);
00691 unsigned int val;
00692 parsebuf.ignore(10,'f');
00693 parsebuf >> val;
00694 return val;
00695 }
00696
00697 void Lens::cmd_GetZoomRange(unsigned int &min,
00698 unsigned int &max) {
00699 std::stringstream parsebuf;
00700 send("dz");
00701 expect("OK");
00702 read(buf);
00703 parsebuf.str(buf);
00704 parsebuf >> min;
00705 parsebuf.ignore(10,',');
00706 parsebuf >> max;
00707 dprintf(6,"* DZ response: %s\n",buf.c_str());
00708 }
00709
00710 void Lens::cmd_GetFocusBracket(unsigned int &min,
00711 unsigned int &max) {
00712 std::stringstream parsebuf;
00713 send("fd");
00714 expect("OK");
00715 read(buf);
00716 parsebuf.str(buf);
00717 parsebuf >> min;
00718 parsebuf.ignore(10,',');
00719 parsebuf >> max;
00720 min*=10;
00721 max*=10;
00722 dprintf(6,"* FD response: %s\n", buf.c_str());
00723 }
00724
00725 Lens::LensError::e Lens::cmd_DoInitialize() {
00726 send("in");
00727 expect("OK");
00728 LensError::e err = errorCheck(buf);
00729 if (err == LensError::None) {
00730 dprintf(6,"* IN successful\n");
00731 } else {
00732 dprintf(6,"* IN Failure!\n");
00733 }
00734 return err;
00735 }
00736
00737 unsigned int Lens::cmd_DoApertureOpen() {
00738 std::stringstream parsebuf;
00739 unsigned int val;
00740 send("mo");
00741 expect("OK");
00742 expect("DONE", buf);
00743 dprintf(6,"* MO response: %s\n", buf.c_str());
00744 parsebuf.str(buf);
00745 parsebuf.ignore(10,'f');
00746 parsebuf >> val;
00747 return val;
00748 }
00749
00750 unsigned int Lens::cmd_DoAperture(unsigned int val) {
00751 std::stringstream parsebuf;
00752 unsigned int minAperture = currentLens->minApertureAt(lensHistory[0].focalLength);
00753 unsigned int newVal;
00754
00755
00756 unsigned int aperture_enc = (val-minAperture)*4/10;
00757 parsebuf << "ma" << aperture_enc;
00758 dprintf(6,"* MA send: %s\n", parsebuf.str().c_str());
00759 send(parsebuf.str());
00760 expect("OK");
00761 expect("DONE", buf);
00762
00763 dprintf(6,"* MA response: %s\n", buf.c_str());
00764 parsebuf.str(buf);
00765 parsebuf.ignore(10,'f');
00766 parsebuf >> newVal;
00767 return newVal;
00768 }
00769
00770 unsigned int Lens::cmd_DoApertureClose() {
00771 std::stringstream parsebuf;
00772 unsigned int val;
00773 send("mc");
00774 expect("OK");
00775 expect("DONE", buf);
00776 dprintf(6,"* MC response: %s\n", buf.c_str());
00777 parsebuf.str(buf);
00778 parsebuf.ignore(10,'f');
00779 parsebuf >> val;
00780 return val;
00781 }
00782
00783 void Lens::cmd_DoFocusAtZero() {
00784 send("mz");
00785 expect("OK");
00786 expect("DONE", buf);
00787 dprintf(6,"* MZ response: %s\n", buf.c_str());
00788 }
00789
00790 unsigned int Lens::cmd_DoFocus(unsigned int val) {
00791 std::stringstream parsebuf, parsebuf2;
00792 unsigned int encVal;
00793 parsebuf << "fa" << val;
00794 send(parsebuf.str());
00795 expect("OK");
00796 expect("DONE", buf);
00797 parsebuf2.str(buf);
00798 parsebuf2 >> encVal;
00799 dprintf(6,"* FA response: %s (%d)\n", buf.c_str(), encVal);
00800 return encVal;
00801 }
00802
00803 void Lens::cmd_DoFocusAtInf() {
00804 send("mi");
00805 expect("OK");
00806 expect("DONE", buf);
00807 dprintf(6,"* MI response: %s\n", buf.c_str());
00808 }
00809
00810 void Lens::cmd_SetFocusEncoder(unsigned int val) {
00811 std::stringstream parsebuf;
00812 parsebuf << "sf" << val;
00813 send(parsebuf.str());
00814 expect("OK");
00815 dprintf(6,"* SF successful\n");
00816 }
00817
00818 unsigned int Lens::cmd_GetFocusEncoder() {
00819 std::stringstream parsebuf;
00820 int val;
00821 send("pf");
00822 expect("OK");
00823 read(buf);
00824 dprintf(6,"* PF response: %s\n", buf.c_str());
00825 parsebuf.str(buf);
00826 parsebuf >> val;
00827 return val;
00828 }
00829
00831
00832
00833 void Lens::send(const std::string &str) {
00834 dprintf(7,"Sending: %s\n", str.c_str());
00835 char c = 13;
00836 usleep(1000);
00837 write(serial_fd, str.c_str(), str.size());
00838 write(serial_fd, &c, 1);
00839
00840 expect(str);
00841 }
00842
00843 template<>
00844 void Lens::read(std::string &str) {
00845 char nextC;
00846 int timeoutCounter = 0;
00847 str.clear();
00848 do {
00849 int ret = ::read(serial_fd, &nextC, 1);
00850 if (ret > 0 && nextC != 13) {
00851 str += nextC;
00852 } else if (ret < 0) {
00853 eprintf("Read returned %i\n", ret);
00854 return;
00855 } else {
00856 timeoutCounter++;
00857 if (timeoutCounter == 30) {
00858 eprintf("Lost comm with lens controller\n");
00859 throw std::runtime_error("timeout communicating with controller");
00860 }
00861 }
00862 } while (nextC != 13);
00863 dprintf(7,"Received: '%s'\n", str.c_str());
00864 }
00865
00866 template<typename T>
00867 void Lens::read(T &val) {
00868 std::stringstream str;
00869
00870 read(str.str());
00871 str >> val;
00872 }
00873
00874 void Lens::expect(const std::string &desired) {
00875 std::string buf;
00876 read(buf);
00877 dprintf(6,"Expect: Got '%s'\n", buf.c_str());
00878 if (buf.substr(0, desired.size()) == desired) return;
00879
00880 eprintf("Expected: '%s' Got: '%s'\n", desired.c_str(), buf.c_str());
00881 throw std::runtime_error("expect mismatch");
00882 }
00883
00884 Lens::LensError::e Lens::errorCheck(std::string &remainder) {
00885 std::string buf;
00886 read(buf);
00887 if (buf == "DONE") {
00888 remainder = buf.substr(4);
00889 return LensError::None;
00890 } else if (buf.substr(0,3) == "ERR") {
00891 std::stringstream errNumStr(buf.substr(4));
00892 int errNum;
00893 errNumStr >> errNum;
00894 return static_cast<LensError::e>(errNum);
00895 } else {
00896 return LensError::UnknownError;
00897 }
00898 }
00899
00900 void Lens::expect(const std::string &desired, std::string &remainder) {
00901 std::string buf;
00902 read(buf);
00903 if (buf.substr(0, desired.size()) == desired) {
00904 remainder = buf.substr(desired.size());
00905 return;
00906 }
00907
00908 eprintf("Expected: %s\n Got: %s\n", desired.c_str(), buf.c_str());
00909 throw std::runtime_error("expect mismatch");
00910 }
00911
00912 }}