• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/F2/Lens.cpp

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     // Public methods
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     // Private methods
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     // Static member function helper to launch a thread-running method.
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             // To start, let's see if anyone wants us to do anything
00281             // over the next 200 ms
00282             bool cmdReady;
00283             cmdReady = cmdQueue.wait(200000);
00284             if (!cmdReady) {
00285                 dprintf(5,"LCT: idle\n");
00286                 if (getState() == NotInitialized) continue;
00287                 // Idle processing, then, if the lens is initialized
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         // Should handle lens re-detection here
00346         if (getState() != Ready) {
00347             //eprintf("getZoom: Lens not ready!\n");
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                 // Update mapping
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         // Linear interpolation between two entries, in diopter space
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     // Diopter->encoder conversions for focus distance
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     // Needed forward declaration of template specialization
00494     template<>
00495     void Lens::read(std::string &val);
00496 
00498     // Primary initialization for the lens
00499 
00500     void Lens::init() {
00502         // Open serial port device
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         // Configure port communication parameters
00513 
00514         // reads will block
00515         fcntl(serial_fd, F_SETFL, 0);
00516 
00517         struct termios opts;
00518         tcgetattr(serial_fd, &opts);
00519         // set speed to 19200 8n1
00520         opts.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
00521         opts.c_lflag = 0;
00522         opts.c_iflag = 0;
00523         opts.c_oflag = 0;
00524         // set the read timeout to 0.1 seconds
00525         opts.c_cc[VMIN] = 0;
00526         opts.c_cc[VTIME] = 1;
00527         // write the opts struct
00528         tcflush(serial_fd, TCIFLUSH);
00529         tcsetattr(serial_fd, TCSANOW, &opts);
00530 
00531         // Set lens starting parameters
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     // Detect and measure lens parameters
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             // Find lens in database, or create a new entry for it 
00560             currentLens = lensDB.find(focalMin, focalMax);
00561 
00562             // Focus near, and reset lens focus distance encoder 
00563             cmd_DoFocusAtZero();
00564             cmd_SetFocusEncoder(0);
00565       
00566             // Find minimum focus distance if not known
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                     // Can't find out what the minimum focus distance for this lens is
00574                     // And we don't have it in the DB, either.
00575                     // This results in a lot of buggy math down the line, FIXME
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             // Find maximum focus encoder count, assume that's infinity
00586             // Note - that assumption is a bit dangerous, should really calibrate better
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                 // Roughly measure focusing speed
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                 // Get median speed, more or less
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                 // Minimal entry for min aperture/focal length mapping
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     // Individual command executers
00669 
00670     std::string Lens::cmd_GetID() {
00671         send("id");
00672         expect("OK");
00673         read(buf); // Expecting a string of form "NNmm,fNN"
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"); // Get lens zoom range
00701         expect("OK");
00702         read(buf); // Expecting a string of form "NNmm,NNmm"
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"); // See if we can get a focus distance bracket here at zero focus
00714         expect("OK");
00715         read(buf); // Expecting NNcm,NNcm
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); // Expecting DONE<steps>,f<f_number*10>
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         // Aperture position encoded as 1/4-stops from fully-open
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); // Expecting DONE<step>,f<f_number*10>
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); // Expecting DONE<steps>,f<f_number*10>
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"); // Set lens focus distance to nearest
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"); // Set lens focus distance to infinity
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"); // Read encoder value at focus position
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     // Basic serial communication primitives
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 }}

Generated on Thu Jul 15 2010 17:51:28 for FCam by  doxygen 1.7.1