Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

ArVCC4.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 
00025 */
00026 
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArVCC4.h"
00030 #include "ArCommands.h"
00031 #include "ArRobot.h"
00032 
00033 
00034 ArVCC4Packet::ArVCC4Packet(ArTypes::UByte2 bufferSize) :
00035   ArBasePacket(bufferSize, 0)
00036 {
00037 }
00038 
00039 ArVCC4Packet::~ArVCC4Packet()
00040 {
00041 
00042 }
00043 
00044 
00045 void ArVCC4Packet::byte2ToBuf(ArTypes::Byte4 val)
00046 {
00047   int i;
00048   char buf[5];
00049   if (myLength + 4 > myMaxLength)
00050   {
00051     ArLog::log(ArLog::Terse, "ArVCC4Packet::uByte2ToBuf: Trying to add beyond length of buffer.");
00052     return;
00053   }
00054 
00055   sprintf(buf, "%X", val);
00056   for (i=0;i<(int)strlen(buf);i++)
00057   {
00058     myBuf[myLength] = buf[i];
00059     ++myLength;
00060   }
00061 }
00062 
00063 
00064 /* Automatically tacks on footer char */
00065 void ArVCC4Packet::finalizePacket(void)
00066 {
00067   uByteToBuf(ArVCC4Commands::FOOTER);
00068 }
00069 
00070 
00071 /*
00072 Creates new packet with default header, device id, and delimeter - FE 30 30 00
00073 */
00074 void ArVCC4::preparePacket(ArVCC4Packet *myPacket)              
00075 {
00076   myPacket->uByteToBuf(ArVCC4Commands::HEADER);
00077   myPacket->uByteToBuf(ArVCC4Commands::DEVICEID);
00078   myPacket->uByteToBuf(ArVCC4Commands::DEVICEID);
00079   myPacket->uByteToBuf(ArVCC4Commands::DELIM);
00080 
00081   myPacketTime.setToNow();
00082   
00083   if (myAutoUpdate)
00084     myIdleTime.setToNow();
00085 }
00086 
00087 
00114 ArVCC4::ArVCC4(ArRobot *robot, bool inverted, CommState commDirection, bool autoUpdate, bool disableLED, CameraType cameraType) :
00115   ArPTZ(robot),
00116   myTaskCB(this, &ArVCC4::camTask)
00117 {
00118   myConn = NULL;
00119   myInverted = inverted;
00120   myRobot = robot;
00121   myError = CAM_ERROR_NONE;
00122   myCommType = commDirection;
00123 
00124   myCameraType = cameraType;
00125 
00126   // the spec is 300ms, but give 400ms because of processing time for the loop
00127   myPacketTimeout = 400;
00128 
00129   myIdleTime.setToNow();
00130 
00131   myAutoUpdate = autoUpdate;
00132   myAutoUpdateCycle = 1;
00133   myWasError = false;
00134   myWaitingOnStop = false;
00135   myBytesLeft = 0;
00136 
00137   // set the state timeout based on the type of communication
00138   if (myCommType == COMM_BIDIRECTIONAL || myCommType == COMM_UNKNOWN)
00139   {
00140     myStateTimeout = BIDIRECTIONAL_TIMEOUT;
00141     ArLog::log(ArLog::Verbose,"ArVCC4::ArVCC4: Using bidirectional communication.");
00142   }
00143   else
00144   {
00145     ArLog::log(ArLog::Verbose,"ArVCC4::ArVCC4: Using unidirectional communication.");
00146     myStateTimeout = UNIDIRECTIONAL_TIMEOUT;
00147   }
00148 
00149   // Set these to TOLERANCE +1 and desired's to 0, so it will be automatically
00150   // zero out during the first first passes through the state machine
00151   myPan = TOLERANCE + 1;
00152   myTilt = TOLERANCE + 1;
00153   myZoom = TOLERANCE + 1;
00154   myPanSlew = 0;
00155   myTiltSlew = 0;
00156   myFocusMode = -1;
00157 
00158   if (myCameraType == CAMERA_C50I)
00159     myDigitalZoom = -1;
00160   else
00161     myDigitalZoom = 0;
00162 
00163   if (disableLED)
00164     myDesiredLEDControlMode = 2;
00165   else
00166     myDesiredLEDControlMode = -1;
00167 
00168   myIRLEDsEnabled = false;
00169   myDesiredIRLEDsMode = false;
00170   // if C50I then force it to turn off the filter
00171   if (myCameraType == CAMERA_C50I)
00172     myIRFilterModeEnabled = true;
00173   else
00174     myIRFilterModeEnabled = false;
00175   myDesiredIRFilterMode = false;
00176   myFocusModeDesired = 0;
00177 
00178   myPanDesired = 0;
00179   myTiltDesired = 0;
00180   myZoomDesired = 0;
00181   myDigitalZoomDesired = 0;
00182   myPanSlewDesired = getMaxPanSlew();
00183   myTiltSlewDesired = getMaxTiltSlew();
00184 
00185   myRequestProductName = false;
00186 
00187   myPacketBufLen = 0;
00188 
00189   // initialize the state variables
00190   myState = UNINITIALIZED;
00191   myPreviousState = UNINITIALIZED;
00192 
00193   // Initialize flags to false
00194   myResponseReceived = false;
00195   myCameraHasBeenInitted = false;
00196   myInitRequested = false;
00197   myCameraIsInitted = false;
00198   myRealPanTiltRequested = false;
00199   myRealZoomRequested = false;
00200 
00201   // add the user task if we have a valid robot
00202   if (myRobot != NULL)
00203     myRobot->addUserTask("vcc4", 50, &myTaskCB);
00204 }
00205 
00206 ArVCC4::~ArVCC4()
00207 {
00208   if (myRobot != NULL)
00209     myRobot->remUserTask(&myTaskCB);
00210 }
00211 
00212 void ArVCC4::connectHandler(void)
00213 {
00214 }
00215 
00216 /*
00217   This will send a request for a certain number of bytes if it's not using
00218   a computer serial port.  You can also send 0, which will flush the buffer.
00219 
00220   This will let you either request 0 bytes (flush the buffer), 6 bytes, or
00221   more than 6 bytes by first requesting 6, then requesting all the rest at
00222   one time.  This will not work with more than two requests for one packet
00223   of data (i.e. 6 bytes, then 4 bytes, then 2 bytes to get 12 bytes total)
00224 */
00225 void ArVCC4::requestBytes(int num)
00226 {
00227   // only send a request if we're not using a computer serial port
00228   if (myUsingAuxPort && myCommType != COMM_UNIDIRECTIONAL)
00229   {
00230     // send a request to the robot, because we're using an Aux port
00231     if (myBytesLeft == 0)
00232     {
00233       // We're not waiting for more bytes from the camera, so assume
00234       // that this is the first request for a response.  Responses start
00235       // as 6 bytes, then more if needed.  Start by asking for 6
00236       
00237       // sending 0 will flush the buffer
00238       if (num == 0)
00239       {
00240         myRobot->comInt(myAuxRxCmd,0);
00241         return;
00242       }
00243 
00244       // don't ask for fewer than 6 bytes, because we don't know
00245       // how to handle it
00246       if (num < 6)
00247       {
00248         ArLog::log(ArLog::Terse, "ArVCC4::requestBytes: Reqeuested fewer than 6 bytes total.  Not sending request.");
00249         return;
00250       }
00251 
00252       // we're not waiting for any bytes to come in, so request a full packet
00253       myRobot->comInt(myAuxRxCmd,6);
00254 
00255       // set the number of bytes left to 6 less than the request
00256       myBytesLeft = num - 6;
00257     }
00258     else
00259     {
00260       // request the rest of the bytes.  asumess num=myBytesLeft
00261       myRobot->comInt(myAuxRxCmd,num);
00262       myBytesLeft = 0;
00263     }
00264   }
00265 
00266   myWaitingOnPacket = true;
00267 
00268 }
00269 
00270 
00271 /*
00272 This is the user task for the camera.  It controls the state that the camera is in and responds accordingly.
00273 
00274 The POWERED_ON state will send commands as needed, and then switch the state into a state of waiting for a response.  If that state waits for too long without a response, it will timeout.  The states wait for a responseReceived flag, which says that a valid response packet was received back from the camera.  Based on that, it uses the myError variable to determine what the packet said.  If there is not responseReceived, or if operating in undirectional mode, the state will wait for a timeout, at which point it will fail if in bidirectional, or assume success in unidirectional mode.
00275 */
00276 void ArVCC4::camTask(void)
00277 {
00278 
00279   switch(myState)
00280   {
00281     // this is the case the camera starts in before being initialized
00282     case UNINITIALIZED:
00283       if (myConn == NULL)
00284         myConn = getDeviceConnection();
00285 
00286       // if myConn is still NULL then its an auxport
00287       if (myConn == NULL)
00288         myUsingAuxPort = true;
00289       else
00290         myUsingAuxPort = false;
00291 
00292       if (myInitRequested)
00293         switchState(STATE_UNKNOWN);
00294 
00295       break;
00296     // this case is the starting case, and fallback in case of error
00297     case STATE_UNKNOWN:
00298       ArLog::log(ArLog::Verbose,"ArVCC4::camTask: Attempting to power on and initialize.");
00299       myPowerStateDesired = true;
00300       myPowerState = false;
00301       myResponseReceived = false;
00302 
00303       // flush the buffer
00304       requestBytes(0);
00305       myBytesLeft = 0;
00306       myPacketBufLen = 0;
00307       switchState(AWAITING_INITIAL_POWERON);
00308       sendPower();
00309       break;
00310     // waiting for the camera to power on for the first time
00311     case AWAITING_INITIAL_POWERON:
00312       if (myResponseReceived == true)
00313       {
00314         if (myError == CAM_ERROR_NONE)
00315         {
00316           switchState(SETTING_CONTROL_MODE);
00317           myPowerState = true;
00318           myPowerStateDesired = true;
00319           setControlMode();
00320         }
00321         else if (myError == CAM_ERROR_BUSY)
00322         {
00323           sendPower();
00324         }
00325         else if (myError == CAM_ERROR_MODE)
00326         {
00327           switchState(SETTING_CONTROL_MODE);
00328           setControlMode();
00329           myPowerState = false;
00330           myPowerStateDesired = true;
00331         }
00332         else
00333         {
00334           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while executing a power command.");
00335           switchState(STATE_UNKNOWN);
00336         }
00337         myResponseReceived = false;
00338       }
00339       else if (timeout(4000))
00340       {
00341         if (myCommType == COMM_BIDIRECTIONAL)
00342         {
00343           ArLog::log(ArLog::Terse,"ArVCC4::camTask: No response from the camera.  Using unidirectional communication.");
00344           myCommType = COMM_UNIDIRECTIONAL;
00345           myStateTimeout = UNIDIRECTIONAL_TIMEOUT;
00346           myAutoUpdate = false;
00347           switchState(STATE_UNKNOWN);
00348         }
00349         else
00350         {
00351           if (myCommType == COMM_UNKNOWN)
00352           {
00353             ArLog::log(ArLog::Terse,"ArVCC4::camTask: No response from the camera.  Assuming unidirectional communications.");
00354             myCommType = COMM_UNIDIRECTIONAL;
00355             myStateTimeout = UNIDIRECTIONAL_TIMEOUT;
00356             myAutoUpdate = false;
00357           }
00358           switchState(SETTING_CONTROL_MODE);
00359           myPowerState = true;
00360           myPowerStateDesired = true;
00361           setControlMode();
00362         }
00363       }
00364       break;
00365     // waiting for the camera to initialize for the first time
00366     case AWAITING_INITIAL_INIT:
00367       if (myResponseReceived == true)
00368       {
00369         if (myError == CAM_ERROR_NONE)
00370         {
00371           switchState(SETTING_INIT_PAN_RATE);
00372           sendPanSlew();
00373         }
00374         // in the event of busy or mode error, keep trying, camera may be 
00375         // powering on
00376         else if (myError == CAM_ERROR_BUSY || myError == CAM_ERROR_MODE)
00377         {
00378           sendInit();
00379         }
00380         else
00381         {
00382           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while executing an init command.");
00383           switchState(STATE_UNKNOWN);
00384         }
00385         myResponseReceived = false;
00386       }
00387       else if (timeout(2500))
00388       {
00389         if (myCommType == COMM_BIDIRECTIONAL)
00390         {
00391           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out while executing an init command.");
00392           switchState(STATE_UNKNOWN);
00393         }
00394         else 
00395         {
00396           switchState(SETTING_INIT_PAN_RATE);
00397           sendPanSlew();
00398         }
00399       }
00400       break;
00401     // set the control mode to host mode, otherwise commands will be ignored
00402     case SETTING_CONTROL_MODE:
00403       if (myResponseReceived == true)
00404       {
00405         if (myError == CAM_ERROR_NONE)
00406         {
00407           sendInit();
00408           switchState(AWAITING_INITIAL_INIT);
00409         }
00410         else if (myError == CAM_ERROR_BUSY)
00411         {
00412           setControlMode();
00413         }
00414         else
00415         {
00416           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting the control mode.");
00417           switchState(STATE_UNKNOWN);
00418         }
00419         myResponseReceived = false;
00420       }
00421       else if (timeout())
00422       {
00423         if (myCommType == COMM_BIDIRECTIONAL)
00424         {
00425           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
00426           switchState(STATE_UNKNOWN);
00427         }
00428         else
00429         {
00430           sendInit();
00431           switchState(AWAITING_INITIAL_INIT);
00432         }
00433       }
00434       break;
00435     // setting the initial pan rate
00436     case SETTING_INIT_PAN_RATE:
00437       if (myResponseReceived == true)
00438       {
00439         if (myError == CAM_ERROR_NONE)
00440         {
00441           myPanSlew = myPanSlewSent;
00442           sendTiltSlew();
00443           switchState(SETTING_INIT_TILT_RATE);
00444         }
00445         else if (myError == CAM_ERROR_BUSY)
00446         {
00447           sendPanSlew();
00448         }
00449         else
00450         {
00451           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting the pan rates.");
00452           switchState(STATE_UNKNOWN);
00453         }
00454         myResponseReceived = false;
00455       }
00456       else if (timeout())
00457       {
00458         if (myCommType == COMM_BIDIRECTIONAL)
00459         {
00460           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding to an initialize pan slew command.");
00461           switchState(STATE_UNKNOWN);
00462         }
00463         else
00464         {
00465           myPanSlew = myPanSlewSent;
00466           sendTiltSlew();
00467           switchState(SETTING_INIT_TILT_RATE);
00468         }
00469       }
00470       break;
00471     // setting the initial tilt rate
00472     case SETTING_INIT_TILT_RATE:
00473       if (myResponseReceived == true)
00474       {
00475         if (myError == CAM_ERROR_NONE)
00476         {
00477           myTiltSlew = myTiltSlewSent;
00478           setDefaultRange();
00479           switchState(SETTING_INIT_RANGE);
00480         }
00481         else if (myError == CAM_ERROR_BUSY)
00482         {
00483           sendTiltSlew();
00484         }
00485         else
00486         {
00487           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting the tilt rate.");
00488           switchState(STATE_UNKNOWN);
00489         }
00490         myResponseReceived = false;
00491       }
00492       else if (timeout())
00493       {
00494         if (myCommType == COMM_BIDIRECTIONAL)
00495         {
00496           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
00497           switchState(STATE_UNKNOWN);
00498         }
00499         else
00500         {
00501           myTiltSlew = myTiltSlewSent;
00502           setDefaultRange();
00503           switchState(SETTING_INIT_RANGE);
00504         }
00505       }
00506       break;
00507     // setting the initial range so the camera will tilt the full amount
00508     case SETTING_INIT_RANGE:
00509       if (myResponseReceived == true)
00510       {
00511         if (myError == CAM_ERROR_NONE)
00512         {
00513           switchState(POWERED_ON);
00514           myCameraHasBeenInitted = true;
00515           myCameraIsInitted = true;
00516           ArLog::log(ArLog::Verbose,"ArVCC4::camTask: Camera initialized and ready.");
00517         }
00518         else if (myError == CAM_ERROR_BUSY)
00519         {
00520           setDefaultRange();
00521         }
00522         else
00523         {
00524           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting the default range.");
00525           // try to power off and see if we can recover
00526           myPowerStateDesired = false;
00527           sendPower();
00528           switchState(POWERING_OFF);
00529         }
00530         myResponseReceived = false;
00531       }
00532       else if (timeout())
00533       {
00534         if (myCommType == COMM_BIDIRECTIONAL)
00535         {
00536           // The camera sometimes responds with an error to this, or times out
00537           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding to a set range command.  Power cycle the camera.");
00538           myCameraHasBeenInitted = false;
00539           switchState(STATE_UNKNOWN);
00540         }
00541         else
00542         {
00543           ArLog::log(ArLog::Verbose,"ArVCC4::camTask: Camera initialized and ready.");
00544           myCameraHasBeenInitted = true;
00545           myCameraIsInitted = true;
00546           switchState(POWERED_ON);
00547         }
00548       }
00549       break;
00550     // initializing the camera
00551     case INITIALIZING:
00552       if (myResponseReceived == true)
00553       {
00554         if (myError == CAM_ERROR_NONE)
00555         {
00556           myCameraIsInitted = true;
00557           myInitRequested = false;
00558           // delay the state transition by 2500ms to allow init to take place
00559           switchState(POWERED_ON, 2500);
00560           ArLog::log(ArLog::Verbose,"ArVCC4::camTask: Camera initialized.");
00561         }
00562         else if (myError == CAM_ERROR_MODE)
00563         {
00564           setControlMode();
00565           switchState(SETTING_CONTROL_MODE);
00566         }
00567         else if (myError == CAM_ERROR_BUSY)
00568         {
00569           sendInit();
00570         }
00571         else
00572         {
00573           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while initializing the camera.");
00574           myCameraIsInitted = false;
00575           myInitRequested = false;
00576           switchState(STATE_UNKNOWN);
00577         }
00578         myResponseReceived = false;
00579       }
00580       else if (timeout(2000))
00581       {
00582         myInitRequested = false;
00583         if (myCommType == COMM_BIDIRECTIONAL)
00584         {
00585           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding to an initialization request.");
00586           myCameraIsInitted = false;
00587           switchState(STATE_UNKNOWN);
00588         }
00589         else
00590         {
00591           myCameraIsInitted = true;
00592           switchState(POWERED_ON);
00593         }
00594       }
00595       break;
00596     // waiting for the camera to power on
00597     case POWERING_ON:
00598       if (myResponseReceived == true)
00599       {
00600         if (myError == CAM_ERROR_NONE)
00601         {
00602           myPowerState = true;
00603           myPowerStateDesired = true;
00604           if (myCameraHasBeenInitted == false)
00605           {
00606             myPowerState = true;
00607             myPowerStateDesired = true;
00608             setControlMode();
00609             switchState(SETTING_CONTROL_MODE);
00610           }
00611           else
00612             switchState(POWERED_ON, 4500); // use a delay
00613         }
00614         else if (myError == CAM_ERROR_BUSY)
00615         {
00616           sendPower();
00617         }
00618         else
00619         {
00620           ArLog::log(ArLog::Terse, "ArVCC4::camTask: Error while executing power command.");
00621           switchState(POWERED_OFF);
00622         }
00623         myResponseReceived = false;
00624       }
00625       else if (timeout(4500))
00626       {
00627         if (myCommType == COMM_BIDIRECTIONAL)
00628         {
00629           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding to a power on command.");
00630           switchState(STATE_UNKNOWN);
00631         }
00632         else
00633         {
00634           myPowerState = true;
00635           myPowerStateDesired = true;
00636           switchState(POWERED_ON);
00637         }
00638       }
00639       break;
00640     // waiting for the camera to power on
00641     case POWERING_OFF:
00642       if (myResponseReceived == true)
00643       {
00644         if (myError == CAM_ERROR_NONE)
00645         {
00646           myPowerState = false;
00647           myPowerStateDesired = false;
00648           switchState(POWERED_OFF);
00649           ArLog::log(ArLog::Verbose, "ArVCC4::camTask: Camera powered off.");
00650         }
00651         else if (myError == CAM_ERROR_BUSY)
00652         {
00653           sendPower();
00654         }
00655         else
00656         {
00657           ArLog::log(ArLog::Terse, "ArVCC4::camTask: Error while executing power command.");
00658           switchState(POWERED_ON);
00659         }
00660         myResponseReceived = false;
00661       }
00662       else if (timeout(2000))
00663       {
00664         if (myCommType == COMM_BIDIRECTIONAL)
00665         {
00666           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
00667           switchState(STATE_UNKNOWN);
00668         }
00669         else
00670         {
00671           myPowerState = false;
00672           myPowerStateDesired = false;
00673           switchState(POWERED_OFF);
00674         }
00675       }
00676       break;
00677     // idle state.  This is the main state.  This will call other processes
00678     // in the event that a desired state doesn't match the current ones
00679     case POWERED_ON:
00680       if (myCameraHasBeenInitted == false || isInitted() == false)
00681       {
00682         ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera not initialized.");
00683         switchState(STATE_UNKNOWN);
00684       }
00685       else if (myPowerStateDesired == false)
00686       {
00687         sendPower();
00688         switchState(POWERING_OFF);
00689       }
00690       else if (myInitRequested == true)
00691       {
00692         sendInit();
00693         switchState(INITIALIZING);
00694       }
00695       else if (myRequestProductName == true)
00696       {
00697         sendProductNameRequest();
00698         switchState(AWAITING_PRODUCTNAME_REQUEST);
00699       }
00700       else if (myRealPanTiltRequested == true)
00701       {
00702         sendRealPanTiltRequest();
00703         switchState(AWAITING_POS_REQUEST);
00704       }
00705       else if (myRealZoomRequested == true)
00706       {
00707         sendRealZoomRequest();
00708         switchState(AWAITING_ZOOM_REQUEST);
00709       }
00710       else if (myHaltZoomRequested == true)
00711       {
00712         sendHaltZoom();
00713         switchState(AWAITING_STOP_ZOOM_RESPONSE);
00714       }
00715       else if (myHaltPanTiltRequested == true)
00716       {
00717         sendHaltPanTilt();
00718         switchState(AWAITING_STOP_PAN_TILT_RESPONSE);
00719       }
00720       else if (abs(myPan - myPanDesired) > TOLERANCE || abs(myTilt - myTiltDesired) > TOLERANCE)
00721       {
00722         // pan tilt sets its own state because it might stop first
00723         sendPanTilt();
00724       }
00725       else if (myZoom != myZoomDesired)
00726       {
00727         // zoom sets its own state because it might stop first
00728         sendZoom();
00729       }
00730       else if (myDigitalZoom != myDigitalZoomDesired)
00731       {
00732         if (myCameraType == CAMERA_C50I)
00733         {
00734           sendDigitalZoom();
00735           switchState(AWAITING_DIGITAL_ZOOM_RESPONSE);
00736         }
00737         else
00738         {
00739           ArLog::log(ArLog::Terse, "ArVCC4::camTask: Camera type does not support digital zoom.");
00740           myDigitalZoom = 0;
00741           myDigitalZoomDesired = 0;
00742         }
00743       }
00744       else if (myFocusMode != myFocusModeDesired)
00745       {
00746         sendFocus();
00747         switchState(AWAITING_FOCUS_RESPONSE);
00748       }
00749       else if (myPanSlewDesired != myPanSlew)
00750       {
00751         sendPanSlew();
00752         switchState(AWAITING_PAN_SLEW_RESPONSE);
00753       }
00754       else if (myTiltSlewDesired != myTiltSlew)
00755       {
00756         sendTiltSlew();
00757         switchState(AWAITING_TILT_SLEW_RESPONSE);
00758       }
00759       else if (myDesiredLEDControlMode != -1)
00760       {
00761         sendLEDControlMode();
00762         switchState(AWAITING_LED_CONTROL_RESPONSE);
00763       }
00764       else if (myDesiredIRFilterMode != myIRFilterModeEnabled)
00765       {
00766         if (myCameraType == CAMERA_C50I)
00767         {
00768           sendIRFilterControl();
00769           switchState(AWAITING_IRFILTER_RESPONSE);
00770         }
00771         else
00772         {
00773           ArLog::log(ArLog::Terse, "ArVCC4::camTask: Camera type does not support IR filtering.");
00774           myDesiredIRFilterMode = false;
00775         }
00776       }
00777       else if (myDesiredIRLEDsMode != myIRLEDsEnabled)
00778       {
00779         if (myCameraType == CAMERA_C50I)
00780         {
00781           if (myDesiredIRLEDsMode && !myIRFilterModeEnabled)
00782           {
00783             ArLog::log(ArLog::Terse, "ArVCC4::camTask: Need to first enable IR-filter before turning on InfraRed LEDs.");
00784             myDesiredIRLEDsMode = false;
00785           }
00786           else
00787           {
00788             sendIRLEDControl();
00789             switchState(AWAITING_IRLEDS_RESPONSE);
00790           }
00791         }
00792         else
00793         {
00794           ArLog::log(ArLog::Terse, "ArVCC4::camTask: Camera model does not support IR LED functions.");
00795           myDesiredIRLEDsMode = false;
00796         }
00797       }
00798       else if (myAutoUpdate &&
00799           myCommType == COMM_BIDIRECTIONAL &&
00800           myIdleTime.mSecSince() > AUTO_UPDATE_TIME)
00801       {
00802         switch (myAutoUpdateCycle)
00803         {
00804           case 1:
00805             sendRealPanTiltRequest();
00806             switchState(AWAITING_POS_REQUEST);
00807             break;
00808           case 2:
00809             sendRealZoomRequest();
00810             switchState(AWAITING_ZOOM_REQUEST);
00811             break;
00812           default:
00813             myAutoUpdateCycle = 0;
00814             break;
00815         }
00816         myAutoUpdateCycle++;
00817       }
00818       break;
00819     // camera is powered off
00820     case POWERED_OFF:
00821       if (myPowerStateDesired == true)
00822       {
00823         sendPower();
00824         switchState(POWERING_ON);
00825       }
00826       break;
00827     // waiting to hear back from the camera after a zoom command was sent
00828     case AWAITING_ZOOM_RESPONSE:
00829       if (myResponseReceived == true)
00830       {
00831         if (myError == CAM_ERROR_NONE)
00832         {
00833           myZoom = myZoomDesired;
00834           switchState(POWERED_ON);
00835         }
00836         else if (myError == CAM_ERROR_BUSY)
00837         {
00838           sendHaltZoom();
00839           // switch states, but don't reset the timer
00840           switchState(AWAITING_STOP_ZOOM_RESPONSE, false);
00841         }
00842         else
00843         {
00844           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while executing a zoom command.");
00845           myZoomDesired = myZoom;
00846           switchState(myPreviousState);
00847         }
00848         myResponseReceived = false;
00849       }
00850       else if (timeout())
00851       {
00852         if (myCommType == COMM_BIDIRECTIONAL)
00853         {
00854           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
00855           myZoomDesired = myZoom;
00856           switchState(myPreviousState);
00857         }
00858         else
00859         {
00860           myZoom = myZoomDesired;
00861           switchState(POWERED_ON);
00862         }
00863       }
00864       break;
00865     // waiting to hear back for verification from digital zoom command
00866     case AWAITING_DIGITAL_ZOOM_RESPONSE:
00867       if (myResponseReceived == true)
00868       {
00869         if (myError == CAM_ERROR_NONE)
00870         {
00871           myDigitalZoom = myDigitalZoomDesired;
00872           switchState(POWERED_ON);
00873         }
00874         else
00875         {
00876           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while executing a digital zoom command.");
00877           myDigitalZoomDesired = myDigitalZoom;
00878           switchState(myPreviousState);
00879         }
00880       }
00881       else if (timeout())
00882       {
00883         if (myCommType == COMM_BIDIRECTIONAL)
00884         {
00885           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
00886           myDigitalZoomDesired = myDigitalZoom;
00887           switchState(myPreviousState);
00888         }
00889         else
00890         {
00891           myDigitalZoom = myDigitalZoomDesired;
00892           switchState(POWERED_ON);
00893         }
00894       }
00895       break;
00896       // waiting to hear back for verification of a pan/tilt command
00897     case AWAITING_PAN_TILT_RESPONSE:
00898       if (myResponseReceived == true)
00899       {
00900         if (myError == CAM_ERROR_NONE)
00901         {
00902           myPan = myPanSent;
00903           myTilt = myTiltSent;
00904           switchState(POWERED_ON);
00905         }
00906         else if (myError == CAM_ERROR_BUSY)
00907         {
00908           sendHaltPanTilt();
00909           // switch states, but don't reset the timer
00910           switchState(AWAITING_STOP_PAN_TILT_RESPONSE, false);
00911         }
00912         else
00913         {
00914           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while executing a panTilt command.");
00915           myPanDesired = myPan;
00916           myTiltDesired = myTilt;
00917           switchState(myPreviousState);
00918         }
00919         myResponseReceived = false;
00920       }
00921       else if (timeout())
00922       {
00923         if (myCommType == COMM_BIDIRECTIONAL)
00924         {
00925           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
00926           myTiltDesired = myTilt;
00927           myPanDesired = myPan;
00928           if (myPowerState)
00929             switchState(POWERED_ON);
00930           else
00931             switchState(POWERED_OFF);
00932         }
00933         else
00934         {
00935           myTilt = myTiltSent;
00936           myPan = myPanSent;
00937           switchState(POWERED_ON);
00938         }
00939       }
00940       break;
00941     // waiting to hear back after requesting to stop pan/tilt movements
00942     case AWAITING_STOP_PAN_TILT_RESPONSE:
00943       if (myResponseReceived == true)
00944       {
00945         if (myError == CAM_ERROR_NONE)
00946         {
00947           myHaltPanTiltRequested = false;
00948           switchState(POWERED_ON);
00949         }
00950         else if (myError == CAM_ERROR_BUSY)
00951         {
00952           // A busy error is only generated when initializing. so just 
00953           // return to the previous state
00954           myHaltPanTiltRequested = false;
00955           switchState(myPreviousState);
00956         }
00957         else
00958         {
00959           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while stopping panTilt motion.");
00960           myHaltPanTiltRequested = false;
00961           switchState(myPreviousState);
00962         }
00963         myResponseReceived = false;
00964       }
00965       else if (timeout())
00966       {
00967         myHaltPanTiltRequested = false;
00968         if (myCommType == COMM_BIDIRECTIONAL)
00969         {
00970           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
00971           switchState(myPreviousState);
00972         }
00973         else
00974         {
00975           if (myWaitingOnStop == true)
00976           {
00977             sendPanTilt();
00978             myWaitingOnStop = false;
00979             switchState(AWAITING_PAN_TILT_RESPONSE);
00980           }
00981           else
00982             switchState(myPreviousState);
00983         }
00984       }
00985       break;
00986     // waiting to hear back about a stop zooming command
00987     case AWAITING_STOP_ZOOM_RESPONSE:
00988       if (myResponseReceived == true)
00989       {
00990         if (myError == CAM_ERROR_NONE)
00991         {
00992           myHaltZoomRequested = false;
00993           switchState(POWERED_ON);
00994         }
00995         else if (myError == CAM_ERROR_BUSY)
00996         {
00997           // A busy error is only generated when initializing. so just
00998           // return to the previous state
00999           myHaltZoomRequested = false;
01000           switchState(myPreviousState);
01001         }
01002         else
01003         {
01004           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while the zoom.");
01005           myHaltZoomRequested = false;
01006           switchState(myPreviousState);
01007         }
01008         myResponseReceived = false;
01009       }
01010       else if (timeout())
01011       {
01012         myHaltZoomRequested = false;
01013         if (myCommType == COMM_BIDIRECTIONAL)
01014         {
01015           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
01016           switchState(myPreviousState);
01017         }
01018         else
01019         {
01020           if (myWaitingOnStop == true)
01021           {
01022             sendZoom();
01023             myWaitingOnStop = false;
01024             switchState(AWAITING_ZOOM_RESPONSE);
01025           }
01026           else
01027             switchState(myPreviousState);
01028         }
01029       }
01030       break;
01031     // waiting to hear back about a pan speed setting
01032     case AWAITING_PAN_SLEW_RESPONSE:
01033       if (myResponseReceived == true)
01034       {
01035         if (myError == CAM_ERROR_NONE)
01036         {
01037           myPanSlew = myPanSlewSent;
01038           switchState(POWERED_ON);
01039         }
01040         else if (myError == CAM_ERROR_BUSY)
01041         {
01042           sendPanSlew();
01043         }
01044         else
01045         {
01046           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting pan slew.");
01047           myPanSlewDesired = myPanSlew;
01048           switchState(myPreviousState);
01049         }
01050         myResponseReceived = false;
01051       }
01052       else if (timeout())
01053       {
01054         if (myCommType == COMM_BIDIRECTIONAL)
01055         {
01056           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
01057           myPanSlewDesired = myPanSlew;
01058           switchState(myPreviousState);
01059         }
01060         else
01061         {
01062           myPanSlew = myPanSlewSent;
01063           switchState(POWERED_ON);
01064         }
01065       }
01066       break;
01067     // waiting to hear back about a tilt speed setting
01068     case AWAITING_TILT_SLEW_RESPONSE:
01069       if (myResponseReceived == true)
01070       {
01071         if (myError == CAM_ERROR_NONE)
01072         {
01073           myTiltSlew = myTiltSlewSent;
01074           switchState(POWERED_ON);
01075         }
01076         else if (myError == CAM_ERROR_BUSY)
01077         {
01078           sendTiltSlew();
01079         }
01080         else
01081         {                                               
01082           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting tilt slew.");
01083           myTiltSlewDesired = myTiltSlew;
01084           switchState(myPreviousState);
01085         } 
01086         myResponseReceived = false;
01087       }                                                     
01088       else if (timeout())
01089       {
01090         if (myCommType == COMM_BIDIRECTIONAL)
01091         {
01092           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
01093           myTiltSlewDesired = myTiltSlew;
01094           switchState(myPreviousState);
01095         }
01096         else
01097         {
01098           myTiltSlew = myTiltSlewSent;
01099           switchState(POWERED_ON);
01100         }
01101       }
01102       break;
01103     // waiting to hear back with pan/tilt information
01104     case AWAITING_POS_REQUEST:
01105       if (myResponseReceived == true)
01106       {
01107         if (myError == CAM_ERROR_NONE)
01108         {
01109           switchState(POWERED_ON);
01110           myPan = myPanResponse;
01111           myTilt = myTiltResponse;
01112           myRealPanTiltRequested = false;
01113         }
01114         else if (myError == CAM_ERROR_BUSY)
01115         {
01116           sendRealPanTiltRequest();
01117         }
01118         else
01119         {
01120           ArLog::log(ArLog::Terse,"ArVCC4::sendRealPanTiltRequest: Camera responded with an error while requesting pan/tilt information.");
01121           switchState(myPreviousState);
01122         }
01123         myResponseReceived = false;
01124       }
01125       else if (timeout())
01126       {
01127         myRealPanTiltRequested = false;
01128         if (myCommType == COMM_BIDIRECTIONAL)
01129         {
01130           ArLog::log(ArLog::Terse,"ArVCC4::sendRealPanTiltRequest: Camera timed out without responding.");
01131           switchState(myPreviousState);
01132         }
01133         else
01134         {
01135           switchState(POWERED_ON);
01136         }
01137       }
01138       break;
01139     // waiting to hear back with zoom information
01140     case AWAITING_ZOOM_REQUEST:
01141       if (myResponseReceived == true)
01142       {
01143         if (myError == CAM_ERROR_NONE)
01144         {
01145           switchState(POWERED_ON);
01146           myZoom = myZoomResponse;
01147           myRealZoomRequested = false;
01148         }
01149         else if (myError == CAM_ERROR_BUSY)
01150         {
01151           sendRealZoomRequest();
01152         }
01153         else
01154         {
01155           ArLog::log(ArLog::Terse,"ArVCC4::sendRealZoomRequest: Camera responded with an error while requesting zoom position.");
01156           switchState(myPreviousState);
01157         }
01158         myResponseReceived = false;
01159       }
01160       else if (timeout())
01161       {
01162         myRealZoomRequested = false;
01163         if (myCommType == COMM_BIDIRECTIONAL)
01164         {
01165           ArLog::log(ArLog::Terse,"ArVCC4::sendRealZoomRequest: Camera timed out without responding.");
01166           switchState(myPreviousState);
01167         }
01168         else
01169         {
01170           switchState(POWERED_ON);
01171         }
01172       }
01173       break;
01174     // sit in this state until the specified delay has occurred
01175     case AWAITING_LED_CONTROL_RESPONSE:
01176       if (myResponseReceived == true)
01177       {
01178         if (myError == CAM_ERROR_NONE)
01179         {
01180           myDesiredLEDControlMode = -1;
01181           switchState(POWERED_ON);
01182         }
01183         else if (myError == CAM_ERROR_BUSY)
01184         {
01185           sendLEDControlMode();
01186         }
01187         else
01188         {
01189           myDesiredLEDControlMode = -1;
01190           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting the LED control mode.");
01191           switchState(POWERED_ON);
01192         }
01193         myResponseReceived = false;
01194       }
01195       else if (timeout())
01196       {
01197         if (myCommType == COMM_BIDIRECTIONAL)
01198         {
01199           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
01200           switchState(STATE_UNKNOWN);
01201         }
01202         else
01203         {
01204           switchState(myPreviousState);
01205         }
01206       }
01207       break;
01208     case AWAITING_IRFILTER_RESPONSE:
01209       if (myResponseReceived == true)
01210       {
01211         if (myError == CAM_ERROR_NONE)
01212         {
01213           myIRFilterModeEnabled = myDesiredIRFilterMode;
01214 
01215           // the camera automatically shuts off the IR LEDs when removing
01216           // the filter
01217           if (!myIRFilterModeEnabled)
01218             myIRLEDsEnabled = false;
01219           switchState(POWERED_ON);
01220         }
01221         else if (myError == CAM_ERROR_BUSY)
01222         {
01223           sendIRFilterControl();
01224         }
01225         else
01226         {
01227           myIRFilterModeEnabled = myDesiredIRFilterMode;
01228           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting the infrared cutoff control.");
01229           switchState(POWERED_ON);
01230         }
01231         myResponseReceived = false;
01232       }
01233       else if (timeout())
01234       {
01235         myDesiredIRFilterMode = myIRFilterModeEnabled;
01236         if (myCommType == COMM_BIDIRECTIONAL)
01237         {
01238           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
01239           switchState(STATE_UNKNOWN);
01240         }
01241         else
01242         {
01243           switchState(myPreviousState);
01244         }
01245       }
01246       break;
01247     case AWAITING_IRLEDS_RESPONSE:
01248       if (myResponseReceived == true)
01249       {
01250         if (myError == CAM_ERROR_NONE)
01251         {
01252           myIRLEDsEnabled = myDesiredIRLEDsMode;
01253           switchState(POWERED_ON);
01254         }
01255         else if (myError == CAM_ERROR_BUSY)
01256         {
01257           sendIRLEDControl();
01258         }
01259         else
01260         {
01261           myDesiredIRLEDsMode = myIRLEDsEnabled;
01262           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera responded with an error while setting the infrared light.");
01263           switchState(POWERED_ON);
01264         }
01265         myResponseReceived = false;
01266       }
01267       else if (timeout())
01268       {
01269         myDesiredIRLEDsMode = myIRLEDsEnabled;
01270         if (myCommType == COMM_BIDIRECTIONAL)
01271         {
01272           ArLog::log(ArLog::Terse,"ArVCC4::camTask: Camera timed out without responding.");
01273           switchState(STATE_UNKNOWN);
01274         }
01275         else
01276         {
01277           switchState(myPreviousState);
01278         }
01279       }
01280       break;
01281     case AWAITING_PRODUCTNAME_REQUEST:
01282       if (myResponseReceived == true)
01283       {
01284         if (myError == CAM_ERROR_NONE)
01285         {
01286           switchState(POWERED_ON);
01287           myProductName = myProductNameResponse;
01288           myRequestProductName = false;
01289         }
01290         else if (myError == CAM_ERROR_BUSY)
01291         {
01292           sendProductNameRequest();
01293         }
01294         else
01295         {
01296           myRequestProductName = false;
01297           ArLog::log(ArLog::Terse,"ArVCC4::sendProductNameRequest: Camera responded with an error while requesting product name.");
01298           switchState(myPreviousState);
01299         }
01300         myResponseReceived = false;
01301       }
01302       else if (timeout())
01303       {
01304         myRequestProductName = false;
01305         if (myCommType == COMM_BIDIRECTIONAL)
01306         {
01307           ArLog::log(ArLog::Terse,"ArVCC4::sendProductNameRequest: Camera timed out without responding.");
01308           switchState(myPreviousState);
01309         }
01310         else
01311         {
01312           switchState(POWERED_ON);
01313         }
01314       }
01315       break;
01316     case AWAITING_FOCUS_RESPONSE:
01317       if (myResponseReceived == true)
01318       {
01319         if (myError == CAM_ERROR_NONE)
01320         {
01321           switchState(POWERED_ON);
01322           myFocusMode = myFocusModeDesired;
01323         }
01324         else
01325         {
01326           myFocusModeDesired = myFocusMode;
01327           ArLog::log(ArLog::Terse,"ArVCC4::sendFocus: Camera responded with an error while setting the focus.");
01328           switchState(myPreviousState);
01329         }
01330         myResponseReceived = false;
01331       }
01332       else if (timeout())
01333       {
01334         if (myCommType == COMM_BIDIRECTIONAL)
01335         {
01336           ArLog::log(ArLog::Terse,"ArVCC4::sendFocus: Camera timed out without responding.");
01337           switchState(myPreviousState);
01338         }
01339         else
01340         {
01341           switchState(POWERED_ON);
01342         }
01343       }
01344       break;
01345     case STATE_DELAYED_SWITCH:
01346       if (timeout(myStateDelayTime))
01347       {
01348         myState = myPreviousState;
01349         switchState(myNextState);
01350       }
01351       break;
01352     case STATE_ERROR:
01353     default:
01354       ArLog::log(ArLog::Terse,"ArVCC4::camTask: Unknown case in usertask.");
01355       break;
01356   }
01357 
01358   // if there were bad parameters, a control mode error, or an unknown error, 
01359   if (myWasError == false &&
01360       (myError == CAM_ERROR_PARAM || myError == CAM_ERROR_UNKNOWN ||
01361        myError == CAM_ERROR_MODE))
01362   {
01363     myWasError = true;
01364     throwError();
01365   }
01366   // turn off error flag if we're out of the error condition now
01367   else if (myWasError == true &&
01368       (myError == CAM_ERROR_NONE || myError == CAM_ERROR_BUSY))
01369     myWasError = false;
01370 
01371 }
01372 
01373 
01374 /*
01375    This performs the actual state switch.  In most cases it just switches
01376    from one state to another, and sets the state timer to keep track of
01377    how long it has been in a state.
01378 
01379    When you're requesting a pan/tilt movement, and the camera is busy,
01380    it will switch states to send a stop command, then send another pan/tilt
01381    command.  In doing so, you want the state timeout to be from the time the
01382    first pan/tilt request was sent, to the time that it succeeds, including
01383    any time spent telling the camera to stop it's movement.  In that case
01384    you want to send a false for the 'useTimer' parameter.
01385 
01386    The delayTime is useful for certain commands, like initialization, that
01387    even when the command is complete, the camera will still respond with
01388    busys for a certain period of time.  Use the delayTime to delay the state
01389    switch to the next state.
01390  */
01391 void ArVCC4::switchState(State state, int delayTime)
01392 {
01393   // if we're switching to a different state, then store the previous one
01394   if (state != myState)
01395     myPreviousState = myState;
01396 
01397   if (delayTime != 0)
01398   {
01399     myNextState = state;
01400     myStateDelayTime = delayTime;
01401     myState = STATE_DELAYED_SWITCH;
01402   }
01403   else
01404   {
01405     myStateTime.setToNow();
01406     myState = state;
01407   }
01408 }
01409 
01410 /*
01411    This checks for either a packet timeout or a state timeout.  A packet
01412   timeout is when the camera hasn't sent back a packet within the
01413   allotted amount of time.  The state timeout is when it takes too long 
01414   to transition from state to state, despite how many packets have or 
01415   haven't been received.  Passing an argument will check for a statetimeout
01416   greater than the argument.  The packet timeout is always the same, but
01417   does not exist for unidirecitonal communication
01418 */
01419 bool ArVCC4::timeout(int mSec)
01420 {
01421   bool stateTimeout;
01422   bool packetTimeout = false;
01423 
01424   if (mSec == 0)
01425     stateTimeout = (myStateTime.mSecSince() > myStateTimeout);
01426   else
01427     stateTimeout = (myStateTime.mSecSince() > mSec);
01428 
01429   if (myCommType != COMM_UNIDIRECTIONAL && myWaitingOnPacket)
01430     packetTimeout = myPacketTime.mSecSince() > myPacketTimeout;
01431 
01432   return (stateTimeout || packetTimeout);
01433 }
01434 
01435 /*
01436   This will read bytes from the computer serial port.  It will read until
01437   it finds a RESPONSE byte for the header, and then read until it doesn't
01438   get anymore, up to a max of the longest possible response packet.
01439 
01440   If it reads and gets a good header and footer, then it puts the data
01441   in a packet, so that packetHandler will be called.
01442 */
01443 ArBasePacket* ArVCC4::readPacket(void)
01444 {
01445   unsigned char data[MAX_RESPONSE_BYTES];
01446   unsigned char byte;
01447   int num;
01448   
01449   myPacketBufLen = 0;
01450 
01451   myWaitingOnPacket = false;
01452 
01453   // Check if the connection is NULL and exit if it is
01454   if (myConn == NULL)
01455   {
01456     ArLog::log(ArLog::Verbose,"ArVCC4::readPacket:  Error reading packet from serial port.  May not be open yet.");
01457     return NULL;
01458   }
01459 
01460   // Check for good header character -
01461   // Loop MAX_RESPONSE_BYTES times, then exit on the next loop
01462   // if we haven't gotten a RESPONSE header byte, yet
01463   for (num=0;num<=MAX_RESPONSE_BYTES + 1;num++)
01464   {
01465     // if we don't get any bytes, or if we've just exceeded the limit
01466     // then return null
01467     if (myConn->read((char *)&byte,1,1) <= 0 ||
01468         num == MAX_RESPONSE_BYTES + 1)
01469       return NULL;
01470     else if (byte == ArVCC4Commands::RESPONSE)
01471     {
01472       data[0] = byte;
01473       break;
01474     }
01475   }
01476 
01477   // we got the header character so keep reading bytes for MAX_RESPONSE_BYTES more
01478   for(num=1;num<=MAX_RESPONSE_BYTES;num++)
01479   {
01480     if (myConn->read((char *)&byte, 1, 1) <= 0)
01481     {
01482       // there are no more bytes, so check the last byte for the footer
01483       if (data[num-1] != ArVCC4Commands::FOOTER)
01484       {
01485         ArLog::log(ArLog::Terse, "ArVCC4::readPacket: Discarding bad packet.");
01486         return NULL;
01487       }
01488       else
01489         break;
01490     }
01491     else
01492       // add the byte to the array
01493       data[num] = byte;
01494     
01495   }
01496 
01497   // now put the data into a new packet so that it can be called by 
01498   // packet handlers
01499   myPacket.empty();
01500   myPacket.dataToBuf((char *)data, num);
01501   myPacket.resetRead();
01502   
01503   return &myPacket;
01504 }
01505 
01506 /*
01507   This will read packets from the VCC4 camera and determine whether or
01508   not we're going to need more bytes from the camera.  Trying to get
01509   pan/tilt or zoom position data from the camera generates a 6-byte 
01510   packet in event of an error, or a longer packet if no error.  This
01511   means we have to receive the first 6-bytes and see if there's a footer
01512   character.  If there is, then set myError to the error.  Otherwise
01513   request more bytes, put them all in a buffer, and call a function
01514   to process the buffer, depending on what type of response we were 
01515   waiting for.
01516 */
01517 bool ArVCC4::packetHandler(ArBasePacket *packet)
01518 {
01519   unsigned int errorCode;
01520 
01521   myWaitingOnPacket = false;
01522 
01523   // If we received a packet, then we can use bidirectional communications,
01524   // so enable if unless the user specified unidirectional
01525   if (myCommType == COMM_UNIDIRECTIONAL)
01526     return true;
01527   else if (myCommType == COMM_UNKNOWN)
01528   {
01529     ArLog::log(ArLog::Verbose,"ArVCC4::packetHandler: Using bidirectional communication.");
01530     myCommType = COMM_BIDIRECTIONAL;
01531     myStateTimeout = BIDIRECTIONAL_TIMEOUT;
01532   }
01533 
01534   // reset the packet time since we got a response from the packet
01535   myPacketTime.setToNow();
01536 
01537   if (myBytesLeft == 0)
01538   {
01539     // We've received all the expected bytes from the camera, so it's
01540     // either a 6-byte packet from an aux port, the second half of another
01541     // response packet from an aux port, or a complete packet from a
01542     // computer serial port
01543 
01544     if (myPacketBufLen == 0 && myUsingAuxPort)
01545     {
01546       // we don't have any data, so it's supposed to be a 6-byte packet
01547       // from an aux port
01548       myPacketBufLen = packet->getDataLength(); 
01549 
01550       if (myPacketBufLen != 6)
01551       {
01552         // we don't know what this is, so scrap it and exit
01553         ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Incorrect number of bytes in response packet.");
01554         myPacketBufLen = 0;
01555         myError = CAM_ERROR_UNKNOWN;
01556         requestBytes(0);
01557         return true;
01558       }
01559 
01560       packet->bufToData((char *)myPacketBuf, myPacketBufLen);
01561 
01562       // check the header and footer
01563       if (myPacketBuf[0] != ArVCC4Commands::RESPONSE ||
01564           myPacketBuf[5] != ArVCC4Commands::FOOTER)
01565       {
01566         ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Bad header or footer character in response packet.");
01567         myPacketBufLen = 0;
01568         myError = CAM_ERROR_UNKNOWN;
01569         requestBytes(0);
01570         return true;
01571       }
01572 
01573       // so far so good.  Set myError to the error byte
01574       errorCode = myPacketBuf[3];
01575 
01576       if (errorCode == CAM_ERROR_NONE ||
01577           errorCode == CAM_ERROR_BUSY ||
01578           errorCode == CAM_ERROR_PARAM ||
01579           errorCode == CAM_ERROR_MODE)
01580         myError = errorCode;
01581       else
01582       {
01583         ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Unrecognized error code sent from camera.");
01584         myError = CAM_ERROR_UNKNOWN;
01585         requestBytes(0);
01586         return true;
01587       }
01588 
01589       // Set the flag that says we had a valid response
01590       myResponseReceived = true;
01591 
01592       myPacketBufLen = 0;
01593 
01594     }
01595     else
01596     {
01597       // we already have some data, or it came in on the computer serial
01598       // port as one big packet, so add it to the rest of the buffer
01599 
01600       // only add up to the max number of bytes
01601       if ((myPacketBufLen + packet->getDataLength()) > MAX_RESPONSE_BYTES)
01602       {
01603         ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Too many bytes in response packet.  Truncating to maximum of %d.", MAX_RESPONSE_BYTES);
01604         requestBytes(0);
01605         packet->bufToData((char *)&myPacketBuf[myPacketBufLen],MAX_RESPONSE_BYTES - myPacketBufLen);
01606         myPacketBufLen = MAX_RESPONSE_BYTES;
01607       }
01608       else
01609       {
01610         packet->bufToData((char *)&myPacketBuf[myPacketBufLen],packet->getDataLength());
01611         myPacketBufLen += packet->getDataLength();
01612       }
01613 
01614 
01615       // now check the header and footer
01616       if (myPacketBuf[0] != ArVCC4Commands::RESPONSE ||
01617           myPacketBuf[myPacketBufLen-1] != ArVCC4Commands::FOOTER)
01618       {
01619         ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Bad header or footer character in long response packet.");
01620         myPacketBufLen = 0;
01621         myError = CAM_ERROR_UNKNOWN;
01622         requestBytes(0);
01623         return true;
01624       }
01625 
01626       // set the error to the error byte
01627       errorCode = myPacketBuf[3];
01628 
01629       if (errorCode == CAM_ERROR_NONE ||
01630           errorCode == CAM_ERROR_BUSY ||
01631           errorCode == CAM_ERROR_PARAM ||
01632           errorCode == CAM_ERROR_MODE)
01633         myError = errorCode;
01634       else
01635       {
01636         ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Unrecognized error code sent from camera.");
01637         myError = CAM_ERROR_UNKNOWN;
01638         requestBytes(0);
01639         return true;
01640       } 
01641 
01642       // We now have all the data for a long response packet, so process
01643       // if based on myState, and what type of response we're waiting for
01644       switch (myState)
01645       {
01646         case AWAITING_POS_REQUEST:
01647           processGetPanTiltResponse();
01648           break;
01649         case AWAITING_ZOOM_REQUEST:
01650           processGetZoomResponse();
01651           break;
01652         //case AWAITING_PRODUCTNAME_REQUEST:
01653         //  processGetProductNameResponse();
01654         //  break;
01655         default:
01656           myPacketBufLen = 0;
01657           break;
01658       }
01659 
01660       // Set the flag for a valid response
01661       myResponseReceived = true;
01662     }
01663   }
01664   else
01665   {
01666     // We're waiting for more bytes.  Check the header and error.
01667     // If they're okay, then ask for more bytes
01668 
01669     myPacketBufLen = packet->getDataLength();
01670 
01671     if (myPacketBufLen != 6)
01672     {
01673       // there should have been 6 bytes.  Scrap it and exit.
01674       ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Incorrect number of bytes in first part of long response packet.");
01675       myPacketBufLen = 0;
01676       myBytesLeft = 0;
01677       myError = CAM_ERROR_UNKNOWN;
01678       requestBytes(0);
01679       return true;
01680     }
01681 
01682     myPacketBufLen = packet->getDataLength();
01683     packet->bufToData((char *)myPacketBuf, myPacketBufLen);
01684 
01685     // check the header character
01686     if (myPacketBuf[0] != ArVCC4Commands::RESPONSE)
01687     {
01688       ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Bad header character in long response packet.");
01689       myPacketBufLen = 0;
01690       myBytesLeft = 0;
01691       myError = CAM_ERROR_UNKNOWN;
01692       requestBytes(0);
01693       return true;
01694     }
01695 
01696     if (myPacketBuf[5] != ArVCC4Commands::FOOTER)
01697     {
01698       // this means there is no error, and to expect more data
01699       requestBytes(myBytesLeft);
01700       myError = CAM_ERROR_NONE;
01701       return true;
01702     }
01703     else
01704     {
01705       // there was an error, so set the flags and exit
01706       errorCode = myPacketBuf[3];
01707       if (errorCode == CAM_ERROR_NONE ||
01708           errorCode == CAM_ERROR_BUSY ||
01709           errorCode == CAM_ERROR_PARAM ||
01710           errorCode == CAM_ERROR_MODE)
01711         myError = errorCode;
01712       else
01713       {
01714         ArLog::log(ArLog::Terse, "ArVCC4::packetHandler: Unrecognized error code sent from camera when expecting long response packet.");
01715         myError = CAM_ERROR_UNKNOWN;
01716         requestBytes(0);
01717       }
01718       myPacketBufLen = 0;
01719       myBytesLeft = 0;
01720 
01721       return true;
01722     }
01723   }
01724 
01725   return true;
01726 }
01727 
01728 /* This needs to eventually use digital zooming, too */
01729 int ArVCC4::getMaxZoom(void) const
01730 {
01731   if (myCameraType == CAMERA_C50I)
01732     return MAX_ZOOM_OPTIC;
01733   else
01734     return MAX_ZOOM_OPTIC;
01735 }
01736 
01737 bool ArVCC4::panTilt(int pdeg, int tdeg)
01738 {
01739   if (pdeg > getMaxPosPan())
01740     myPanDesired = getMaxPosPan();
01741   else if (pdeg < getMaxNegPan())
01742     myPanDesired = getMaxNegPan();
01743   else
01744     myPanDesired = pdeg;
01745 
01746   if (tdeg > getMaxPosTilt())
01747     myTiltDesired = getMaxPosTilt();
01748   else if (tdeg < getMaxNegTilt())
01749     myTiltDesired = getMaxNegTilt();
01750   else
01751     myTiltDesired = tdeg;
01752 
01753   return true;
01754 }
01755 
01756 bool ArVCC4::zoom(int deg)
01757 {
01758   if (deg > getMaxZoom())
01759     myZoomDesired = getMaxZoom();
01760   else if (deg < getMinZoom())
01761     myZoomDesired = getMinZoom();
01762   else
01763     myZoomDesired = deg;
01764 
01765   return true;
01766 }
01767 
01768 /* Is supposed to accept 1x, 2x, 4x, 8x, and 12x, but doesn't seem to work
01769  for 12x*/
01770 bool ArVCC4::digitalZoom(int deg)
01771 {
01772   if (deg < 0)
01773     myDigitalZoomDesired = 0;
01774   else if (deg > 3)
01775     myDigitalZoomDesired = 3;
01776   /* uncomment this if the 12x mode ever works */
01777   //else if (deg > 4)
01778   //  myDigitalZoomDesired = 4;
01779   else
01780     myDigitalZoomDesired = deg;
01781 
01782   return true;
01783 }
01784 
01785 /*
01786    This will process a response from the camera for where it thinks it
01787   is panned and tilted to.
01788 */
01789 void ArVCC4::processGetPanTiltResponse(void)
01790 {
01791   unsigned char buf[4];
01792   char byte;
01793   unsigned int valU;
01794   int val;
01795   int i;
01796 
01797   // remove the ascii encoding, and put into 4-byte array
01798   for (i=0;i<4;i++)
01799   {
01800     byte = myPacketBuf[i+5];
01801     if (byte < 0x40)
01802       byte = byte - 0x30;
01803     else
01804       byte = byte - 'A' + 10;
01805     buf[i] = byte;
01806   }
01807 
01808   // convert the 4-bytes into a number
01809   valU = buf[0]*0x1000 + buf[1]*0x100 + buf[2]*0x10 + buf[3];
01810 
01811   // convert the number to a value that's meaningful, based on camera specs
01812   val = (int)(((int)valU - (int)0x8000)*0.1125);
01813 
01814   // now set myPan to the response received for where the camera thinks it is
01815   myPanResponse = val;
01816 
01817   // repeat the steps for the tilt value
01818   for (i=0;i<4;i++)
01819   {
01820     byte = myPacketBuf[i+9];
01821     if (byte < 0x40)
01822       byte = byte - 0x30;
01823     else
01824       byte = byte - 'A' + 10;
01825     buf[i] = byte;
01826   }
01827   valU = buf[0]*0x1000 + buf[1]*0x100 + buf[2]*0x10 + buf[3];
01828   val =(int)(((int)valU  - (int)0x8000)*0.1125);
01829   myTiltResponse = val;
01830 
01831   myPacketBufLen = 0;
01832 }
01833 
01834 /*
01835   This will process the response from the camera when requesting to find
01836   out where it thinks it is zoomed to.
01837 */
01838 void ArVCC4::processGetZoomResponse(void)
01839 {
01840   unsigned char buf[4];
01841   char byte;
01842   unsigned int valU;
01843   int i;
01844 
01845   // Make sure we have the correct number of bytes
01846   if (myPacketBufLen != 10)
01847   {
01848     myPacketBufLen = 0;
01849     return;
01850   }
01851 
01852   // remove the ascii encoding, and put into 2 bytes
01853   for (i=0;i<4;i++)
01854   {
01855     byte = myPacketBuf[i+5];
01856     if (byte < 0x40)
01857       byte = byte - 0x30;
01858     else
01859       byte = byte - 'A' + 10;
01860     buf[i] = byte;
01861   }
01862 
01863   // convert the 2 bytes into a number
01864   valU = 0;
01865   for (i=0;i<4;i++)
01866     valU += buf[i]*(unsigned int)pow(16.0,(double)(3-i));
01867 
01868   myZoomResponse = (int)valU;
01869   
01870   myPacketBufLen = 0;
01871 }
01872 
01873 /* This is not implemented yet, but should eventually determine the product name
01874  */
01875 /*
01876 void ArVCC4::processGetProductNameResponse(void)
01877 {
01878   char byte;
01879   int i;
01880 
01881   if (myPacketBufLen != 10)
01882   {
01883     myPacketBufLen = 0;
01884     return;
01885   }
01886 }*/
01887 
01888 bool ArVCC4::sendPower(void)
01889 {
01890   myPacket.empty();
01891   preparePacket(&myPacket);
01892   myPacket.uByteToBuf(ArVCC4Commands::POWER);
01893   if (myPowerStateDesired)
01894   {
01895     ArLog::log(ArLog::Verbose,"ArVCC4::sendPower: sending power on packet\n");
01896     myPacket.uByteToBuf(ArVCC4Commands::DEVICEID + 1);
01897   }
01898   else
01899   {
01900     ArLog::log(ArLog::Verbose,"ArVCC4::sendPower: sending power off packet\n");
01901     myPacket.uByteToBuf(ArVCC4Commands::DEVICEID);
01902   }
01903 
01904 
01905   // The camera will return 6 bytes.  If busy, then resend
01906   requestBytes();
01907   return sendPacket(&myPacket);
01908 }
01909 
01910 bool ArVCC4::setControlMode(void)
01911 {
01912   ArLog::log(ArLog::Verbose,"ArVCC4::setControlMode: sending control mode packet\n");
01913   myPacket.empty();             //Send Control command
01914   preparePacket(&myPacket);
01915   myPacket.uByteToBuf(ArVCC4Commands::CONTROL);
01916   myPacket.uByteToBuf(ArVCC4Commands::DEVICEID);
01917 
01918   // The camera will return 6 bytes, which fail if menu is operational
01919   // If failure, then power-off and power-on
01920   requestBytes();
01921   return sendPacket(&myPacket);
01922 }
01923 
01924 void ArVCC4::addErrorCB(ArFunctor *functor, ArListPos::Pos position)
01925 {
01926   if (position == ArListPos::FIRST)
01927     myErrorCBList.push_front(functor);
01928   else if (position == ArListPos::LAST)
01929     myErrorCBList.push_back(functor);
01930   else
01931     ArLog::log(ArLog::Terse, "ArVCC4::addErrorCB: Invalid position.");
01932 }
01933 
01934 void ArVCC4::remErrorCB(ArFunctor *functor)
01935 {
01936   myErrorCBList.remove(functor);
01937 }
01938 
01939 void ArVCC4::throwError(void)
01940 {
01941   std::list<ArFunctor *>::iterator it;
01942 
01943   for (it = myErrorCBList.begin();
01944       it != myErrorCBList.end();
01945       it++)
01946     (*it)->invoke();
01947 
01948 }
01949 
01950 bool ArVCC4::sendInit(void)
01951 {
01952   ArLog::log(ArLog::Verbose,"ArVCC4::sendInit: sending init packet\n");
01953 
01954 
01955   myPacket.empty();             // Send Init command
01956   preparePacket(&myPacket);
01957   myPacket.uByteToBuf(ArVCC4Commands::INIT);
01958   myPacket.uByteToBuf(ArVCC4Commands::DEVICEID);
01959 
01960   // The camera will return 6 bytes.  If busy, resend
01961   // If error, then not initted or not in control mode
01962 
01963   requestBytes();
01964   return sendPacket(&myPacket);
01965 }
01966 
01967 
01968 /*
01969 It's necessary to set the default ranges, because the camera defaults to a max tilt range of +30, instead of +90.
01970 */
01971 bool ArVCC4::setDefaultRange(void)
01972 {
01973 
01974   ArLog::log(ArLog::Verbose,"ArVCC4::setDefaultRange: setting default range for camera movements");
01975 
01976   myPacket.empty();
01977   preparePacket(&myPacket);
01978 
01979   myPacket.uByteToBuf(ArVCC4Commands::SETRANGE);
01980   myPacket.uByteToBuf(ArVCC4Commands::DEVICEID + 1);
01981 
01982   // Note the conversion from degrees to camera units:
01983   //    units = degrees / 0.1125
01984 
01985   // Set min tilt range
01986   myPacket.byte2ToBuf((int) floor(MIN_TILT/.1125) + 0x8000);
01987 
01988   // Set max tilt range
01989   myPacket.byte2ToBuf((int) floor(MAX_TILT/.1125) + 0x8000);
01990 
01991   requestBytes();
01992   return sendPacket(&myPacket);
01993 }
01994 
01995 bool ArVCC4::sendPanTilt()
01996 {
01997   if (myCommType != COMM_BIDIRECTIONAL && myWaitingOnStop == false)
01998   {
01999     sendHaltPanTilt();
02000     myWaitingOnStop = true;
02001     switchState(AWAITING_STOP_PAN_TILT_RESPONSE);
02002     return true;
02003   }
02004 
02005   ArLog::log(ArLog::Verbose,"ArVCC4::sendPanTilt: sending panTilt packet");
02006 
02007   myPacket.empty();
02008   preparePacket(&myPacket);
02009   myPacket.uByteToBuf(ArVCC4Commands::PANTILT);
02010   myPacket.byte2ToBuf((int) floor(invert(myPanDesired)/.1125) + 0x8000);
02011   myPacket.byte2ToBuf((int) floor(invert(myTiltDesired)/.1125) + 0x8000);
02012 
02013   // set these so that we know what was sent if the command is successful
02014   myPanSent = myPanDesired;
02015   myTiltSent = myTiltDesired;
02016 
02017   switchState(AWAITING_PAN_TILT_RESPONSE);
02018 
02019   requestBytes();
02020   return sendPacket(&myPacket);
02021 }
02022 
02023 bool ArVCC4::sendZoom()
02024 {
02025   int i;
02026   if (myCommType != COMM_BIDIRECTIONAL && myWaitingOnStop == false)
02027   {
02028     sendHaltZoom();
02029     myWaitingOnStop = true;
02030     switchState(AWAITING_STOP_ZOOM_RESPONSE);
02031     return true;
02032   }
02033 
02034   ArLog::log(ArLog::Verbose,"ArVCC4::sendZoom: sending zoom packet");
02035 
02036   char buf[5];
02037 
02038   myPacket.empty();
02039   preparePacket(&myPacket);
02040   myPacket.uByteToBuf(ArVCC4Commands::ZOOM);
02041   sprintf(buf, "%4X", myZoomDesired);
02042 
02043   for (i=0;i<3;i++)
02044     if (buf[i] == ' ')
02045       buf[i] = '0';
02046 
02047   for (i=0;i<4;i++)
02048     myPacket.byteToBuf(buf[i]);
02049 
02050   // remember what value was sent
02051   myZoomSent = myZoomDesired;
02052 
02053   switchState(AWAITING_ZOOM_RESPONSE);
02054 
02055   requestBytes();
02056   return sendPacket(&myPacket);
02057 }
02058 
02059 /* This sends-
02060   0x30, 0x31 to turn off digital zooming
02061   0x30, 0x32 for 2x
02062   0x30, 0x34 for 4x
02063   0x30, 0x38 for 8x
02064   0x30, 0x3C for 12x
02065  */
02066 bool ArVCC4::sendDigitalZoom()
02067 {
02068   ArLog::log(ArLog::Verbose,"ArVCC4::sendDigitalZoom: sending digital zoom packet");
02069 
02070   myPacket.empty();
02071   preparePacket(&myPacket);
02072   myPacket.uByteToBuf(ArVCC4Commands::DIGITALZOOM);
02073 
02074   if (myDigitalZoomDesired < 4)
02075   {
02076     myPacket.uByteToBuf(0x30);
02077     myPacket.uByteToBuf(0x30 + (0x1 << myDigitalZoomDesired));
02078   }
02079   else
02080   {
02081     /* this currently never gets called because myDigitalZoomDesired is
02082      * always < 4.  The manual says 0x3C should work, but it doesn't */
02083     myPacket.uByteToBuf(0x30);
02084     myPacket.uByteToBuf(0x3C);
02085   }
02086 
02087   requestBytes();
02088   return sendPacket(&myPacket);
02089 }
02090 
02091 
02092 
02093 
02094 
02095 bool ArVCC4::sendHaltPanTilt(void)
02096 {
02097   ArLog::log(ArLog::Verbose,"ArVCC4::sendHaltPanTilt: sending halt pantilt packet");
02098   myPacket.empty();
02099   preparePacket(&myPacket);
02100   myPacket.uByteToBuf(ArVCC4Commands::STOP);
02101   myPacket.uByteToBuf(ArVCC4Commands::DEVICEID);
02102 
02103   requestBytes();
02104   return sendPacket(&myPacket);
02105 }
02106 
02107 
02108 bool ArVCC4::sendHaltZoom(void)
02109 {
02110   ArLog::log(ArLog::Verbose,"ArVCC4::sendHaltZoom: sending halt zoom packet");
02111   myPacket.empty();
02112   preparePacket(&myPacket);
02113   myPacket.uByteToBuf(ArVCC4Commands::ZOOMSTOP);
02114   myPacket.uByteToBuf(ArVCC4Commands::DEVICEID);
02115 
02116   requestBytes();
02117   return sendPacket(&myPacket);
02118 }
02119 
02120 
02121 bool ArVCC4::sendPanSlew(void)
02122 {
02123   char buf[4];
02124 
02125   if (myPanSlewDesired > getMaxPanSlew())
02126     myPanSlewDesired = getMaxPanSlew();
02127   if (myPanSlewDesired < getMinPanSlew())
02128     myPanSlewDesired = getMinPanSlew();
02129 
02130   if (myPanSlewDesired != myPanSlew)
02131   {
02132     ArLog::log(ArLog::Verbose,"ArVCC4::sendPanSlew: sending panSlew packet");
02133 
02134     myPacket.empty();
02135     preparePacket(&myPacket);
02136     myPacket.uByteToBuf(ArVCC4Commands::PANSLEW);
02137 
02138     sprintf(buf,"%3X", (int) floor(myPanSlewDesired/.1125));
02139 
02140     if (buf[0] < '0')
02141       buf[0] = '0';
02142     if (buf[1] < '0')
02143       buf[1] = '0';
02144     if (buf[2] < '0')
02145       buf[2] = '0';
02146 
02147     myPacket.byteToBuf(buf[0]);
02148     myPacket.byteToBuf(buf[1]);
02149     myPacket.byteToBuf(buf[2]);
02150 
02151     requestBytes();
02152     myPanSlewSent = myPanSlewDesired;
02153 
02154     return sendPacket(&myPacket);
02155   }
02156   return true;
02157 }
02158 
02159 
02160 bool ArVCC4::sendTiltSlew(void)
02161 {
02162   char buf[4];
02163 
02164   if (myTiltSlewDesired > getMaxTiltSlew())
02165     myTiltSlewDesired = getMaxTiltSlew();
02166   if (myTiltSlewDesired < getMinTiltSlew())
02167     myTiltSlewDesired = getMinTiltSlew();
02168 
02169   if (myTiltSlewDesired != myTiltSlew)
02170   {
02171     ArLog::log(ArLog::Verbose,"ArVCC4::sendTiltSlew: sending tiltSlew packet");
02172 
02173     myPacket.empty();
02174     preparePacket(&myPacket);
02175     myPacket.uByteToBuf(ArVCC4Commands::TILTSLEW);
02176 
02177     sprintf(buf,"%3X", (int) floor(myTiltSlewDesired/.1125));
02178 
02179     if (buf[0] == ' ')
02180       buf[0] = '0';
02181     if (buf[1] == ' ')
02182       buf[1] = '0';
02183 
02184     myPacket.byteToBuf(buf[0]);
02185     myPacket.byteToBuf(buf[1]);
02186     myPacket.byteToBuf(buf[2]);
02187 
02188     requestBytes();
02189     myTiltSlewSent = myTiltSlewDesired;
02190 
02191     return sendPacket(&myPacket);
02192   }
02193   return true;
02194 }
02195 
02196 bool ArVCC4::sendRealPanTiltRequest(void)
02197 {
02198   ArLog::log(ArLog::Verbose,"ArVCC4::sendRealPanTiltRequest: sending request for real pan/tilt information");
02199 
02200   myPacket.empty();
02201   preparePacket(&myPacket);
02202   myPacket.uByteToBuf(ArVCC4Commands::PANTILTREQ);
02203 
02204   // The camera will return 6 bytes in case of error
02205   // 9 bytes otherwise.
02206   requestBytes(14);
02207   return sendPacket(&myPacket);
02208 }
02209 
02210 
02211 bool ArVCC4::sendRealZoomRequest(void)
02212 {
02213   ArLog::log(ArLog::Verbose,"ArVCC4::sendRealZoomRequest: sending request for real zoom position.");
02214 
02215   myPacket.empty();
02216   preparePacket(&myPacket);
02217   myPacket.uByteToBuf(ArVCC4Commands::ZOOMREQ);
02218   myPacket.uByteToBuf(ArVCC4Commands::DEVICEID);
02219 
02220   // The camera will return 6 bytes in case of error
02221   // bytes othewise
02222   requestBytes(10);
02223   return sendPacket(&myPacket);
02224 }
02225 
02235 bool ArVCC4::sendLEDControlMode(void)
02236 {
02237   ArLog::log(ArLog::Verbose,"ArVCC4::sendLEDControlMode: sending LED control packet.");
02238 
02239   if (myDesiredLEDControlMode < 0 || myDesiredLEDControlMode > 4)
02240   {
02241     ArLog::log(ArLog::Terse,"ArVCC4::sendLEDControlMode: incorrect parameter.  Not sending packet.");
02242     myDesiredLEDControlMode = -1;
02243     return false;
02244   }
02245 
02246   myPacket.empty();
02247   preparePacket(&myPacket);
02248   myPacket.uByteToBuf(ArVCC4Commands::LEDCONTROL);
02249   myPacket.uByteToBuf(0x30 + (unsigned char) myDesiredLEDControlMode);
02250 
02251   requestBytes(6);
02252 
02253   return sendPacket(&myPacket);
02254 }
02255 
02256 bool ArVCC4::sendIRFilterControl(void)
02257 {
02258   ArLog::log(ArLog::Verbose,"ArVCC4::sendIRFilterControl: sending IR cut filter control packet.");
02259 
02260   myPacket.empty();
02261   preparePacket(&myPacket);
02262   myPacket.uByteToBuf(ArVCC4Commands::IRCUTFILTER);
02263 
02264   if (myDesiredIRFilterMode)
02265     myPacket.uByteToBuf(0x30);
02266   else
02267     myPacket.uByteToBuf(0x31);
02268 
02269   requestBytes(6);
02270 
02271   return sendPacket(&myPacket);
02272 }
02273                                                               
02274 /* The camera automatically shuts off the IR after some specified period of time.
02275  This command tells the camera to leave them on for the max of 6 hours.
02276  */
02277 bool ArVCC4::sendIRLEDControl(void)
02278 {
02279   ArLog::log(ArLog::Verbose,"ArVCC4::sendIRLEDControl: sending IR-LED control packet.");
02280 
02281   myPacket.empty();
02282   preparePacket(&myPacket);
02283   myPacket.uByteToBuf(ArVCC4Commands::INFRARED);
02284   if (myDesiredIRLEDsMode)
02285     myPacket.uByteToBuf(0x36);
02286   else
02287     myPacket.uByteToBuf(0x30);
02288 
02289   requestBytes(6);
02290 
02291   return sendPacket(&myPacket);
02292 }
02293 
02294 bool ArVCC4::sendProductNameRequest(void)
02295 {
02296   ArLog::log(ArLog::Verbose,"ArVCC4::sendProductNameRequest: sending request for product name.");
02297 
02298   myPacket.empty();
02299   preparePacket(&myPacket);
02300   myPacket.uByteToBuf(ArVCC4Commands::PRODUCTNAME);
02301 
02302   return sendPacket(&myPacket);
02303 }
02304 
02305 bool ArVCC4::sendFocus(void)
02306 {
02307   ArLog::log(ArLog::Verbose,"ArVCC4::sendFocus: sending focus control packet.");
02308 
02309   myPacket.empty();
02310   preparePacket(&myPacket);
02311   
02312   myPacket.uByteToBuf(ArVCC4Commands::AUTOFOCUS);
02313   myPacket.uByteToBuf(0x30 + (unsigned char) myFocusModeDesired);
02314 
02315   requestBytes(6);
02316 
02317   return sendPacket(&myPacket);
02318 }

Generated on Wed Oct 19 12:56:37 2005 for Aria by  doxygen 1.4.0