00001 #include "Lens.h"
00002
00003 #include <stdexcept>
00004 #include <sstream>
00005 #include <vector>
00006 #include <algorithm>
00007
00008 #include <stdio.h>
00009 #include <errno.h>
00010 #include <termios.h>
00011 #include <fcntl.h>
00012 #include <unistd.h>
00013 #include <sys/time.h>
00014
00015 #define EF232_DEBUG 1
00016
00017 #if defined(EF232_DEBUG)
00018 #define dprintf(...) \
00019 printf("EF232[%s]: ", tty.c_str()); \
00020 printf(__VA_ARGS__);
00021
00022 #if EF232_DEBUG > 0
00023 #define ddprintf(...) \
00024 printf("EF232[%s]: ", tty.c_str()); \
00025 printf(__VA_ARGS__);
00026 #else
00027 #define ddprintf(...)
00028 #endif
00029
00030 #else
00031 #define dprintf(...)
00032 #define ddprintf(...)
00033 #endif
00034
00035 #define eprintf(...) \
00036 fprintf(stderr,"EF232[%s]: ERROR! ", tty.c_str()); \
00037 fprintf(stderr, __VA_ARGS__);
00038
00039
00040 namespace FCam { namespace F2 {
00041
00043
00044
00045
00046 Lens::Lens():
00047 tty("/dev/ttyS2"),
00048 state(NOT_INITIALIZED),
00049 lensDB(),
00050 currentLens(NULL)
00051 {
00052 init();
00053 }
00054
00055 Lens::Lens(const std::string &tty_): tty(tty_), state(NOT_INITIALIZED) {
00056 init();
00057 }
00058
00059 Lens::~Lens() {
00060 close(serial_fd);
00061 }
00062
00063 void Lens::setFocus(float diopters, float speed) {
00064 if (state != READY) {
00065 eprintf("setFocus: Lens not ready!\n");
00066 return;
00067 }
00068 focusDist = cmd_DoFocus(diopToEncoder(diopters));
00069 }
00070
00071 float Lens::getFocus() {
00072 if (state != READY) {
00073 eprintf("getFocus: Lens not ready!\n");
00074 return -1;
00075 }
00076 return encToDiopter(focusDist);
00077 }
00078
00079 float Lens::farFocus() {
00080 return 0;
00081 }
00082
00083 float Lens::nearFocus() {
00084 if (state != READY) {
00085 eprintf("maxFocus: Lens not ready!\n");
00086 return -1;
00087 }
00088 return 1000.0/currentLens->focusDistMin;
00089 }
00090
00091 bool Lens::focusChanging() {
00092 return false;
00093 }
00094
00095 int Lens::focusLatency() {
00096 return 0;
00097 }
00098
00099 float Lens::minFocusSpeed() {
00100 if (state != READY) {
00101 eprintf("minFocusSpeed: Lens not ready!\n");
00102 return -1;
00103 }
00104 return currentLens->focusSpeed;
00105 }
00106
00107 float Lens::maxFocusSpeed() {
00108 if (state != READY) {
00109 eprintf("maxFocusSpeed: Lens not ready!\n");
00110 return -1;
00111 }
00112 return currentLens->focusSpeed;
00113 }
00114
00115 void Lens::setZoom(float focal_length_mm, float speed) {
00116 eprintf("setZoom: Manual zoom only, not zooming to %f\n", focal_length_mm);
00117 }
00118
00119 float Lens::getZoom() {
00120 if (state != READY) {
00121 eprintf("getZoom: Lens not ready!\n");
00122 return -1;
00123 }
00124 std::string idStr = cmd_GetID();
00125 unsigned int fl = cmd_GetFocalLength(idStr);
00126 if (fl != focalLength) {
00127 focalLength = fl;
00128 unsigned int minAperture = cmd_GetMinAperture(idStr);
00129 if (currentLens->minApertureAt(focalLength) != minAperture) {
00130 dprintf("Adding entry to min aperture map: %d->%d, currently %d\n", focalLength, minAperture, currentLens->minApertureAt(focalLength));
00131
00132 EF232LensInfo updatedInfo = *currentLens;
00133 EF232LensInfo::minApertureListIter iter=
00134 updatedInfo.minApertureList.insert(updatedInfo.minApertureList.begin(),
00135 EF232LensInfo::apertureChange(focalLength,
00136 minAperture));
00137 iter++;
00138 while (iter != updatedInfo.minApertureList.end()) {
00139 if (iter->second == minAperture) {
00140 dprintf("Removing redundant entry %d->%d\n", iter->first, iter->second);
00141 updatedInfo.minApertureList.erase(iter++);
00142 } else {
00143 iter++;
00144 }
00145 }
00146 currentLens = lensDB.update(updatedInfo);
00147 }
00148 }
00149 return focalLength;
00150 }
00151
00152 float Lens::minZoom() {
00153 if (state != READY) {
00154 eprintf("minZoom: Lens not ready!\n");
00155 return -1;
00156 }
00157 return currentLens->focalLengthMin;
00158 }
00159 float Lens::maxZoom() {
00160 if (state != READY) {
00161 eprintf("minZoom: Lens not ready!\n");
00162 return -1;
00163 }
00164 return currentLens->focalLengthMax;
00165 }
00166
00167 bool Lens::zoomChanging() {
00168 return false;
00169 }
00170
00171 float Lens::minZoomSpeed() {
00172 return 0;
00173 }
00174
00175 float Lens::maxZoomSpeed() {
00176 return 0;
00177 }
00178
00179 int Lens::zoomLatency() {
00180 return 0;
00181 }
00182
00183 void Lens::setAperture(float f_number, float speed) {
00184 if (state != READY) {
00185 eprintf("setAperture: Lens not ready!\n");
00186 return;
00187 }
00188 aperture = cmd_DoAperture(f_number*10);
00189 }
00190
00191 float Lens::getAperture() {
00192 if (state != READY) {
00193 eprintf("getAperture: Lens not ready!\n");
00194 return -1;
00195 }
00196 return aperture/10.0;
00197 }
00198
00199 float Lens::wideAperture(float focal_length_mm) {
00200 if (state != READY) {
00201 eprintf("minAperture: Lens not ready!\n");
00202 return -1;
00203 }
00204
00205 return currentLens->minApertureAt(focal_length_mm)/10.0;
00206 }
00207
00208
00209 float Lens::narrowAperture(float focal_length_mm) {
00210 if (state != READY) {
00211 eprintf("maxAperture: Lens not ready!\n");
00212 return -1;
00213 }
00214 return currentLens->apertureMax/10.0;
00215 }
00216
00217 bool Lens::apertureChanging() {
00218 return false;
00219 }
00220
00221 int Lens::apertureLatency() {
00222 return 0;
00223 }
00224
00225 float Lens::minApertureSpeed() {
00226 return 0;
00227 }
00228
00229 float Lens::maxApertureSpeed() {
00230 return 0;
00231 }
00232
00233
00234 void Lens::reset() {
00235 if (state == READY || state == BUSY) {
00236 close(serial_fd);
00237 }
00238 state = NOT_INITIALIZED;
00239 init();
00240 }
00241
00242 void Lens::tagFrame(FCam::Frame *) {
00243
00244 }
00245
00246
00248
00249
00250
00251
00253
00254 float Lens::encToDiopter(unsigned int encoder) {
00255 return diopScaleFactor * (focusEncoderMax - encoder);
00256 }
00257
00258 unsigned int Lens::diopToEncoder(float diopters) {
00259 return focusEncoderMax - (diopters/diopScaleFactor);
00260 }
00261
00263
00264 template<>
00265 void Lens::read(std::string &val);
00266
00268
00269
00270 void Lens::init() {
00272
00273 serial_fd = open (tty.c_str(),
00274 O_RDWR | O_NOCTTY | O_NDELAY);
00275
00276 if (serial_fd < 0) {
00277 eprintf("Unable to open serial device!");
00278 return;
00279 }
00280
00282
00283
00284
00285 fcntl(serial_fd, F_SETFL, 0);
00286
00287 struct termios opts;
00288 tcgetattr(serial_fd, &opts);
00289
00290 opts.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
00291 opts.c_lflag = 0;
00292 opts.c_iflag = 0;
00293 opts.c_oflag = 0;
00294
00295 opts.c_cc[VMIN] = 0;
00296 opts.c_cc[VTIME] = 1;
00297
00298 tcflush(serial_fd, TCIFLUSH);
00299 tcsetattr(serial_fd, TCSANOW, &opts);
00300
00301
00302
00303 try {
00304 cmd_DoInitialize();
00305 cmd_DoApertureOpen();
00306
00307 state = NO_LENS;
00308 } catch (std::runtime_error err) {
00309 eprintf("Unable to initialize the lens controller!\n");
00310 close(serial_fd);
00311 state = NOT_INITIALIZED;
00312 return;
00313 }
00314
00315 calibrateLens();
00316 }
00317
00319
00320
00321 void Lens::calibrateLens() {
00322 try {
00323 unsigned int focalMin, focalMax;
00324
00325 focalLength = cmd_GetFocalLength();
00326
00327 cmd_GetZoomRange(focalMin, focalMax);
00328
00329
00330 currentLens = lensDB.find(focalMin, focalMax);
00331
00332
00333 cmd_DoFocusAtZero();
00334 cmd_SetFocusEncoder(0);
00335
00336
00337 if (currentLens->focusDistMin == 0) {
00338 dprintf("Measuring minimum focus distance\n");
00339 unsigned int newFDMin, newFDMax;
00340
00341 cmd_GetFocusBracket(newFDMin, newFDMax);
00342 if (newFDMin == 0) {
00343
00344
00345
00346 eprintf("Unknown lens minimum focus distance, assuming 0mm!\n");
00347 } else {
00348 EF232LensInfo updatedInfo = *currentLens;
00349 updatedInfo.focusDistMin = newFDMin;
00350 currentLens = lensDB.update(updatedInfo);
00351 dprintf("Updated focusDistMin to %d\n", currentLens->focusDistMin);
00352 }
00353 }
00354
00355
00356
00357 cmd_DoFocusAtInf();
00358
00359 focusEncoderMax = cmd_GetFocusEncoder();
00360 diopScaleFactor = 1000.0/(currentLens->focusDistMin
00361 * focusEncoderMax);
00362
00363 state = READY;
00364
00365 if (currentLens->apertureMax == 0) {
00366 dprintf("Measuring max aperture...\n");
00367 unsigned int newApertureMax = cmd_DoApertureClose();
00368 EF232LensInfo updatedInfo = *currentLens;
00369 updatedInfo.apertureMax = newApertureMax;
00370 currentLens = lensDB.update(updatedInfo);
00371 }
00372
00373 if (currentLens->focusSpeed == 0) {
00374 dprintf("Measuring focus speed...\n");
00375
00376 std::vector<float> focusSpeeds;
00377 float maxDiop = 1000.0/currentLens->focusDistMin;
00378 for (unsigned int percent = 10; percent <= 100; percent+=20) {
00379 timeval startFocus, midFocus, endFocus;
00380 float destDiop = maxDiop*percent/100;
00381 gettimeofday(&startFocus, NULL);
00382 setFocus(destDiop);
00383 gettimeofday(&midFocus, NULL);
00384 setFocus(0);
00385 gettimeofday(&endFocus, NULL);
00386
00387 unsigned int infToZeroT = (midFocus.tv_sec - startFocus.tv_sec)*1000000
00388 + (midFocus.tv_usec - startFocus.tv_usec);
00389 unsigned int zeroToInfT = (endFocus.tv_sec - midFocus.tv_sec)*1000000
00390 + (endFocus.tv_usec - midFocus.tv_usec);
00391
00392 float infToZeroDPS = (destDiop/(float)infToZeroT)*1e6;
00393 float zeroToInfDPS = (destDiop/(float)zeroToInfT)*1e6;
00394 dprintf("Focus Speed calib for 0 to %f diop: %f diop/sec inf-to-zero, %f diop/sec zero-to-inf\n", destDiop, infToZeroDPS, zeroToInfDPS);
00395 focusSpeeds.push_back(infToZeroDPS);
00396 focusSpeeds.push_back(zeroToInfDPS);
00397 }
00398
00399
00400 std::sort(focusSpeeds.begin(), focusSpeeds.end());
00401 float newFocusSpeed = focusSpeeds[(focusSpeeds.size()+1)/2];
00402 dprintf("Setting focus speed to median: %f DPS\n", newFocusSpeed);
00403
00404 EF232LensInfo updatedInfo = *currentLens;
00405 updatedInfo.focusSpeed = newFocusSpeed;
00406 currentLens = lensDB.update(updatedInfo);
00407
00408 }
00409
00410 if (currentLens->minApertureList.size() == 0) {
00411 dprintf("Establishing minimal focal length->min aperture map\n");
00412
00413 unsigned int newFocalLength = cmd_GetFocalLength();
00414 unsigned int newMinAperture = cmd_GetMinAperture();
00415 EF232LensInfo updatedInfo = *currentLens;
00416 updatedInfo.minApertureList[newFocalLength] = newMinAperture;
00417 currentLens = lensDB.update(updatedInfo);
00418 }
00419
00420 aperture = cmd_DoApertureOpen();
00421
00422 } catch (std::runtime_error err) {
00423 eprintf("Unable to configure lens!\n");
00424 state = NO_LENS;
00425 }
00426 }
00427
00428
00429
00431
00432
00433 std::string Lens::cmd_GetID() {
00434 send("id");
00435 expect("OK");
00436 read(buf);
00437 dprintf("* ID response: %s\n", buf.c_str());
00438 return buf;
00439 }
00440
00441 unsigned int Lens::cmd_GetFocalLength(std::string idStr) {
00442 std::stringstream parsebuf;
00443 if (idStr == "") idStr = cmd_GetID();
00444 parsebuf.str(idStr);
00445 unsigned int val;
00446 parsebuf >> val;
00447 return val;
00448 }
00449
00450 unsigned int Lens::cmd_GetMinAperture(std::string idStr) {
00451 std::stringstream parsebuf;
00452 if (idStr == "") idStr = cmd_GetID();
00453 parsebuf.str(idStr);
00454 unsigned int val;
00455 parsebuf.ignore(10,'f');
00456 parsebuf >> val;
00457 return val;
00458 }
00459
00460 void Lens::cmd_GetZoomRange(unsigned int &min,
00461 unsigned int &max) {
00462 std::stringstream parsebuf;
00463 send("dz");
00464 expect("OK");
00465 read(buf);
00466 parsebuf.str(buf);
00467 parsebuf >> min;
00468 parsebuf.ignore(10,',');
00469 parsebuf >> max;
00470 dprintf("* DZ response: %s\n",buf.c_str());
00471 }
00472
00473 void Lens::cmd_GetFocusBracket(unsigned int &min,
00474 unsigned int &max) {
00475 std::stringstream parsebuf;
00476 send("fd");
00477 expect("OK");
00478 read(buf);
00479 parsebuf.str(buf);
00480 parsebuf >> min;
00481 parsebuf.ignore(10,',');
00482 parsebuf >> max;
00483 min*=10;
00484 max*=10;
00485 dprintf("* FD response: %s\n", buf.c_str());
00486 }
00487
00488 void Lens::cmd_DoInitialize() {
00489 send("in");
00490 expect("OK");
00491 expect("DONE");
00492 dprintf("* IN successful\n");
00493 }
00494
00495 unsigned int Lens::cmd_DoApertureOpen() {
00496 std::stringstream parsebuf;
00497 unsigned int val;
00498 send("mo");
00499 expect("OK");
00500 expect("DONE", buf);
00501 dprintf("* MO response: %s\n", buf.c_str());
00502 parsebuf.str(buf);
00503 parsebuf.ignore(10,'f');
00504 parsebuf >> val;
00505 return val;
00506 }
00507
00508 unsigned int Lens::cmd_DoAperture(unsigned int val) {
00509 std::stringstream parsebuf;
00510 unsigned int minAperture = currentLens->minApertureAt(focalLength);
00511 unsigned int newVal;
00512
00513
00514 unsigned int aperture_enc = (val-minAperture)*4/10;
00515 parsebuf << "ma" << aperture_enc;
00516 dprintf("* MA send: %s\n", parsebuf.str().c_str());
00517 send(parsebuf.str());
00518 expect("OK");
00519 expect("DONE", buf);
00520
00521 dprintf("* MA response: %s\n", buf.c_str());
00522 parsebuf.str(buf);
00523 parsebuf.ignore(10,'f');
00524 parsebuf >> newVal;
00525 return newVal;
00526 }
00527
00528 unsigned int Lens::cmd_DoApertureClose() {
00529 std::stringstream parsebuf;
00530 unsigned int val;
00531 send("mc");
00532 expect("OK");
00533 expect("DONE", buf);
00534 dprintf("* MC response: %s\n", buf.c_str());
00535 parsebuf.str(buf);
00536 parsebuf.ignore(10,'f');
00537 parsebuf >> val;
00538 return val;
00539 }
00540
00541 void Lens::cmd_DoFocusAtZero() {
00542 send("mz");
00543 expect("OK");
00544 expect("DONE", buf);
00545 dprintf("* MZ response: %s\n", buf.c_str());
00546 }
00547
00548 unsigned int Lens::cmd_DoFocus(unsigned int val) {
00549 std::stringstream parsebuf, parsebuf2;
00550 unsigned int encVal;
00551 parsebuf << "fa" << val;
00552 send(parsebuf.str());
00553 expect("OK");
00554 expect("DONE", buf);
00555 parsebuf2.str(buf);
00556 parsebuf2 >> encVal;
00557 dprintf("* FA response: %s (%d)\n", buf.c_str(), encVal);
00558 return encVal;
00559 }
00560
00561 void Lens::cmd_DoFocusAtInf() {
00562 send("mi");
00563 expect("OK");
00564 expect("DONE", buf);
00565 dprintf("* MI response: %s\n", buf.c_str());
00566 }
00567
00568 void Lens::cmd_SetFocusEncoder(unsigned int val) {
00569 std::stringstream parsebuf;
00570 parsebuf << "sf" << val;
00571 send(parsebuf.str());
00572 expect("OK");
00573 dprintf("* SF successful\n");
00574 }
00575
00576 unsigned int Lens::cmd_GetFocusEncoder() {
00577 std::stringstream parsebuf;
00578 int val;
00579 send("pf");
00580 expect("OK");
00581 read(buf);
00582 dprintf("* PF response: %s\n", buf.c_str());
00583 parsebuf.str(buf);
00584 parsebuf >> val;
00585 return val;
00586 }
00587
00589
00590
00591 void Lens::send(const std::string &str) {
00592 ddprintf("Sending: %s\n", str.c_str());
00593 char c = 13;
00594 usleep(1000);
00595 write(serial_fd, str.c_str(), str.size());
00596 write(serial_fd, &c, 1);
00597
00598 expect(str);
00599 }
00600
00601 template<>
00602 void Lens::read(std::string &str) {
00603 char nextC;
00604 int timeoutCounter = 0;
00605 str.clear();
00606 do {
00607 int ret = ::read(serial_fd, &nextC, 1);
00608 if (ret > 0 && nextC != 13) {
00609 str += nextC;
00610 } else if (ret < 0) {
00611 eprintf("Read returned %i\n", ret);
00612 return;
00613 } else {
00614 timeoutCounter++;
00615 if (timeoutCounter == 30) {
00616 eprintf("Lost comm with lens controller\n");
00617 throw std::runtime_error("timeout communicating with controller");
00618 }
00619 }
00620 } while (nextC != 13);
00621 ddprintf("Received: '%s'\n", str.c_str());
00622 }
00623
00624 template<typename T>
00625 void Lens::read(T &val) {
00626 std::stringstream str;
00627
00628 read(str.str());
00629 str >> val;
00630 }
00631
00632 void Lens::expect(const std::string &desired) {
00633 std::string buf;
00634 read(buf);
00635 ddprintf("Expect: Got '%s'\n", buf.c_str());
00636 if (buf.substr(0, desired.size()) == desired) return;
00637
00638 eprintf("Expected: '%s' Got: '%s'\n", desired.c_str(), buf.c_str());
00639 throw std::runtime_error("expect mismatch");
00640 }
00641
00642 void Lens::expect(const std::string &desired, std::string &remainder) {
00643 std::string buf;
00644 read(buf);
00645 if (buf.substr(0, desired.size()) == desired) {
00646 remainder = buf.substr(desired.size());
00647 return;
00648 }
00649
00650 eprintf("Expected: %s\n Got: %s\n", desired.c_str(), buf.c_str());
00651 throw std::runtime_error("expect mismatch");
00652 }
00653 }
00654 }