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

ArVCC4.cpp

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

Generated on Tue Feb 20 10:51:42 2007 for Aria by  doxygen 1.4.0