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

ArServerHandlerCamera.cpp

Go to the documentation of this file.
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 "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArServerHandlerCamera.h"
00029 
00030 const char *ArServerHandlerCamera::CONTROL_COMMAND_GROUP = "CameraControl";
00031 const char *ArServerHandlerCamera::INFO_COMMAND_GROUP = "CameraInfo";
00032 const char *ArServerHandlerCamera::NO_ARGS = "None";
00033 
00034 //#define DEBUG_ARSERVERHANDLERCAMERA
00035 
00036 #if (defined(_DEBUG) && defined(DEBUG_ARSERVERHANDLERCAMERA))
00037 #define IFDEBUG(code) {code;}
00038 #else
00039 #define IFDEBUG(code)
00040 #endif 
00041 
00047 AREXPORT ArServerHandlerCamera::ArServerHandlerCamera(ArServerBase *server,
00048                                                                                           ArRobot *robot, 
00049                                                                                           ArPTZ *camera) : 
00050   ArCameraCollectionItem(),
00051   myRobot(robot),
00052   myServer(server),
00053   myCamera(camera),
00054   myCameraName(),
00055   myCameraCollection(NULL),
00056   myCommandToPacketNameMap(),
00057   myCommandToIntervalMap(),
00058   myCommandToCBMap(),
00059 
00060   myUserTaskCB(this, &ArServerHandlerCamera::userTask),
00061   myCameraCB(this, &ArServerHandlerCamera::camera),
00062   myCameraAbsCB(this, &ArServerHandlerCamera::cameraAbs),
00063   myCameraUpdateCB(this, &ArServerHandlerCamera::cameraUpdate),
00064   myCameraInfoCB(this, &ArServerHandlerCamera::cameraInfo)
00065 {
00066   init();
00067 }
00068 
00069 AREXPORT ArServerHandlerCamera::ArServerHandlerCamera
00070                                     (const char *cameraName,
00071                                      ArServerBase *server,
00072                                      ArRobot *robot,
00073                                      ArPTZ *camera,
00074                                      ArCameraCollection *collection) :
00075   ArCameraCollectionItem(),
00076   myRobot(robot),
00077   myServer(server),
00078   myCamera(camera),
00079   myCameraName(cameraName),
00080   myCameraCollection(collection),
00081   myCommandToPacketNameMap(),
00082   myCommandToIntervalMap(),
00083   myCommandToCBMap(),
00084 
00085   myModeMutex(),
00086   myCameraMode(CAMERA_MODE_POSITION),
00087   myCameraModeNameMap(),
00088   myCameraModePacket(),
00089   myLookAtPoint(),
00090   myPointResetZoom(false),
00091   myGoal(),
00092   myGoalAchieved(true),
00093   myGoalAchievedLast(false),
00094   myGoalResetZoom(false),
00095 
00096   myUserTaskCB(this, &ArServerHandlerCamera::userTask),
00097   myCameraCB(this, &ArServerHandlerCamera::camera),
00098   myCameraAbsCB(this, &ArServerHandlerCamera::cameraAbs),
00099   myCameraUpdateCB(this, &ArServerHandlerCamera::cameraUpdate),
00100   myCameraInfoCB(this, &ArServerHandlerCamera::cameraInfo)
00101 {
00102   init();
00103 
00104   if (myCameraCollection != NULL) {
00105     doAddToCameraCollection(*myCameraCollection);
00106   }
00107 } // end ctor
00108 
00109 AREXPORT ArServerHandlerCamera::~ArServerHandlerCamera()
00110 {
00111   for (std::map<std::string, ArFunctor2<ArServerClient *, ArNetPacket *> *>::iterator iter =
00112           myCommandToCBMap.begin();
00113        iter != myCommandToCBMap.end();
00114        iter++) {
00115 
00116      // TODO: REALLY should remove the callback from myServer (but there's currently
00117      // no way to do so...
00118 
00119      delete iter->second;
00120      iter->second = NULL;
00121 
00122   } // end for each callback
00123 
00124   myCommandToCBMap.clear();
00125 
00126 } // end dtor
00127   
00128 
00129 void ArServerHandlerCamera::init()
00130 {
00131   createCommandNames();
00132 
00133   createCommandCBs();
00134 
00135   addAllCommandsToServer();
00136 
00137   myCameraMode = CAMERA_MODE_POSITION;
00138   myGoalAchieved = true;
00139   myUserTaskCB.setName("ArServerHandlerCamera");
00140   if (myRobot != NULL)
00141     myRobot->addUserTask("ArServerHandlerCamera", 50, &myUserTaskCB);
00142 
00143   myCameraModeNameMap[CAMERA_MODE_POSITION] = "Position";
00144   myCameraModeNameMap[CAMERA_MODE_LOOK_AT_GOAL] = "LookAtGoal";
00145   myCameraModeNameMap[CAMERA_MODE_LOOK_AT_POINT] = "LookAtPoint";
00146 
00147 } // end method init
00148 
00149 
00150 AREXPORT const char *ArServerHandlerCamera::getCameraName()
00151 {
00152   return myCameraName.c_str();
00153 }
00154 
00155 void ArServerHandlerCamera::createCommandNames()
00156 {
00157   myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_DATA] = "getCameraData";
00158   myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_INFO] = "getCameraInfo";
00159   myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_ABS]  = "setCameraAbs";
00160   myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_PCT]  = "setCameraPct";
00161   myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_REL]  = "setCameraRel";
00162 
00163   myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_MODE_LIST]  = "getCameraModeList";
00164   myCommandToPacketNameMap[ArCameraCommands::CAMERA_MODE_UPDATED]  = "cameraModeUpdated";
00165   myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_MODE]  = "setCameraMode";
00166   myCommandToPacketNameMap[ArCameraCommands::RESET_CAMERA]  = "resetCamera";
00167         
00168   if (!myCameraName.empty()) {
00169   
00170     for (std::map<std::string, std::string>::iterator iter = myCommandToPacketNameMap.begin();
00171          iter != myCommandToPacketNameMap.end();
00172          iter++) {
00173 
00174       std::string baseCommandName = iter->second;
00175       iter->second = baseCommandName + myCameraName;
00176 
00177     } // end for each command
00178   } // end if camera name specified
00179 
00180 
00181   // Do these afterwards so that the name does NOT get mangled. (??)
00182   // This preserves some aspect of backwards compatibility...
00183 
00184         myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_DATA_INT] = "cameraUpdate";
00185   myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_INFO_INT] = "cameraInfo";
00186         myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_ABS_INT] = "cameraAbs";
00187         myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_REL_INT] = "camera";
00188         myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_PCT_INT] = "cameraPct";
00189 
00190 } // end method createCommandNames
00191 
00192 
00193 void ArServerHandlerCamera::createCommandCBs()
00194 {
00195 
00196   myCommandToCBMap[ArCameraCommands::GET_CAMERA_DATA] = 
00197     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00198           (this,
00199            &ArServerHandlerCamera::handleGetCameraData);
00200   // Default interval for requesting camera info
00201   myCommandToIntervalMap[ArCameraCommands::GET_CAMERA_DATA] = 100;
00202 
00203   myCommandToCBMap[ArCameraCommands::GET_CAMERA_INFO] = 
00204     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00205           (this,
00206            &ArServerHandlerCamera::handleGetCameraInfo);
00207 
00208         myCommandToCBMap[ArCameraCommands::SET_CAMERA_ABS] = 
00209     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00210           (this,
00211            &ArServerHandlerCamera::handleSetCameraAbs);
00212 
00213         myCommandToCBMap[ArCameraCommands::SET_CAMERA_PCT] = 
00214     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00215           (this,
00216            &ArServerHandlerCamera::handleSetCameraPct);
00217 
00218         myCommandToCBMap[ArCameraCommands::SET_CAMERA_REL] = 
00219     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00220           (this,
00221            &ArServerHandlerCamera::handleSetCameraRel);
00222 
00223         myCommandToCBMap[ArCameraCommands::GET_CAMERA_DATA_INT] = 
00224     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00225           (this,
00226            &ArServerHandlerCamera::cameraUpdate);
00227 
00228   myCommandToCBMap[ArCameraCommands::GET_CAMERA_INFO_INT] = 
00229     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00230           (this,
00231            &ArServerHandlerCamera::cameraInfo);
00232 
00233         myCommandToCBMap[ArCameraCommands::SET_CAMERA_ABS_INT] = 
00234     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00235           (this,
00236            &ArServerHandlerCamera::cameraAbs);
00237 
00238         myCommandToCBMap[ArCameraCommands::SET_CAMERA_REL_INT] = 
00239     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00240           (this,
00241            &ArServerHandlerCamera::camera);
00242 
00243         myCommandToCBMap[ArCameraCommands::SET_CAMERA_PCT_INT] = 
00244     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00245           (this,
00246            &ArServerHandlerCamera::cameraPct);
00247         
00248   myCommandToCBMap[ArCameraCommands::GET_CAMERA_MODE_LIST] = 
00249     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00250           (this,
00251            &ArServerHandlerCamera::handleGetCameraModeList);
00252   myCommandToCBMap[ArCameraCommands::CAMERA_MODE_UPDATED]  = 
00253     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00254           (this,
00255            &ArServerHandlerCamera::handleCameraModeUpdated);
00256   myCommandToCBMap[ArCameraCommands::SET_CAMERA_MODE]  = 
00257     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00258           (this,
00259            &ArServerHandlerCamera::handleSetCameraMode);
00260   myCommandToCBMap[ArCameraCommands::RESET_CAMERA]  = 
00261     new ArFunctor2C<ArServerHandlerCamera, ArServerClient *, ArNetPacket *>
00262           (this,
00263            &ArServerHandlerCamera::handleResetCamera);
00264 
00265 } // end method createCommandCBs
00266 
00267 
00268 void ArServerHandlerCamera::addAllCommandsToServer()
00269 {
00270   if (myServer == NULL) {
00271     ArLog::log(ArLog::Normal, 
00272                "ArServerHandlerCamera::addAllCommandsToServer() cannot add to NULL server");
00273     return;
00274   }
00275 
00276   // 
00277   addCommandToServer
00278      (ArCameraCommands::GET_CAMERA_DATA, 
00279             "Get \"double\" information about camera position. (factor == 100)",
00280             NO_ARGS, 
00281             "byte2: pan * factor, byte2: tilt * factor, byte2: zoomPercent * factor (optional)",
00282       INFO_COMMAND_GROUP);
00283 
00284   addCommandToServer
00285      (ArCameraCommands::GET_CAMERA_INFO, 
00286                   "Get (\"double\") information about the camera's pan, tilt, and (optional) zoom ranges. (factor == 100)",
00287                   NO_ARGS, 
00288                   "byte2: minPan * factor, byte2: maxPan * factor byte2: minTilt * factor, byte2: maxTilt * factor, byte2: minZoom * factor, byte2: maxZoom * factor, byte: isZoomAvailable",
00289       INFO_COMMAND_GROUP);
00290 
00291  addCommandToServer
00292      (ArCameraCommands::SET_CAMERA_ABS, 
00293       "Sends absolute (\"double\") pan, tilt, and zoom (optional) commands to the camera. (factor == 100)",
00294       NO_ARGS, 
00295       "byte2: pan * factor, byte2: tilt * factor, byte2: zoom * factor (optional)",
00296       CONTROL_COMMAND_GROUP);
00297 
00298  if ((myCamera != NULL) && (myCamera->canGetFOV())) {
00299     addCommandToServer
00300       (ArCameraCommands::SET_CAMERA_PCT, 
00301                     "Sends (\"double\") pan, tilt, and zoom (optional) commands to point camera, as percent of visible frame. (factor == 100)",
00302                     NO_ARGS,
00303                     "byte2: panOffset * factor, byte2: tiltOffset * factor, byte2: zoom * factor (optional)",
00304       CONTROL_COMMAND_GROUP);
00305  }
00306  else {
00307    removeCommand(ArCameraCommands::SET_CAMERA_PCT);
00308  }
00309 
00310  addCommandToServer
00311      (ArCameraCommands::SET_CAMERA_REL, 
00312                   "Sends (\"double\") pan, tilt, and zoom (optional) commands to the camera, relative to its current position. (factor == 100)",
00313                   NO_ARGS, 
00314                   "byte2: relPan * factor, byte2: relTilt * factor, byte2: relZoom * factor (optional)",
00315       CONTROL_COMMAND_GROUP);
00316 
00317  addCommandToServer(ArCameraCommands::GET_CAMERA_MODE_LIST,
00318                     "Gets the list of modes this camera supports",
00319                     NO_ARGS,
00320                     "ubyte2: numModes; <repeating numModes times> string: modeName",
00321         INFO_COMMAND_GROUP);
00322                     
00323 
00324  addCommandToServer(ArCameraCommands::CAMERA_MODE_UPDATED,
00325                     "Sent whenever the camera mode is updated",
00326                     NO_ARGS,
00327                     "string: modeName; <other data depends on mode>",
00328         INFO_COMMAND_GROUP);
00329 
00330  addCommandToServer(ArCameraCommands::SET_CAMERA_MODE,
00331                     "Sent whenever the camera mode is updated",
00332                     "string: modeName; <other data depends on mode>",
00333                     NO_ARGS,
00334         CONTROL_COMMAND_GROUP);             
00335 
00336  addCommandToServer(ArCameraCommands::RESET_CAMERA,
00337                     "Resets the camera to 0 0 0 and may reinitialize it (depending on camera)",
00338                     NO_ARGS,
00339                     NO_ARGS,
00340         CONTROL_COMMAND_GROUP);             
00341                     
00342 
00343   // Continue to support old-style integer commands for backward compatibility....
00344 
00345  addCommandToServer
00346    (ArCameraCommands::GET_CAMERA_DATA_INT, 
00347           "Get (integer) information about camera position",
00348           NO_ARGS, 
00349           "byte2: pan, byte2: tilt, byte2: zoom (optional)",
00350     INFO_COMMAND_GROUP);
00351 
00352  addCommandToServer
00353    (ArCameraCommands::GET_CAMERA_INFO_INT, 
00354                 "Get (integer) information about the camera's pan, tilt, and (optional) zoom ranges",
00355                 NO_ARGS, 
00356                 "byte2: minPan, byte2: maxPan byte2: minTilt, byte2: maxTilt, byte2: minZoom, byte2: maxZoom, byte: isZoomAvailable",
00357     INFO_COMMAND_GROUP);
00358 
00359  addCommandToServer
00360    (ArCameraCommands::SET_CAMERA_REL_INT, 
00361                 "Sends (integer) pan, tilt, and zoom (optional) commands to the camera, relative to its current position",
00362                 NO_ARGS, 
00363                 "byte: relPan, byte: relTilt, byte: relZoom (optional)",
00364     CONTROL_COMMAND_GROUP);
00365 
00366  addCommandToServer
00367    (ArCameraCommands::SET_CAMERA_ABS_INT, 
00368     "Sends absolute (integer) pan, tilt, and zoom (optional) commands to the camera",
00369     NO_ARGS, 
00370     "byte: pan, byte: tilt, byte: zoom (optional)",
00371     CONTROL_COMMAND_GROUP);
00372 
00373  addCommandToServer
00374    (ArCameraCommands::SET_CAMERA_PCT_INT, 
00375     "Sends (integer) pan, tilt commands to the camera, as percent of visible frame",
00376     NO_ARGS, 
00377     "byte: pan, byte: tilt, byte: zoom (optional)",
00378     CONTROL_COMMAND_GROUP);
00379 
00380 } // end method addToServer
00381 
00382 
00383 void ArServerHandlerCamera::addCommandToServer(const char *command, 
00384                                                const char *description,
00385                                                                        const char *argumentDescription,
00386                                                                        const char *returnDescription,
00387                                                const char *commandGroup)
00388 {
00389   if (command == NULL) {
00390     ArLog::log(ArLog::Normal, 
00391                "ArServerHandlerCamera::addCommandToServer() cannot add NULL command");
00392     return;
00393   }
00394 
00395   std::map<std::string, std::string>::iterator iter = 
00396     myCommandToPacketNameMap.find(command);
00397 
00398   if (iter == myCommandToPacketNameMap.end()) {
00399     ArLog::log(ArLog::Normal, 
00400                "ArServerHandlerCamera::addCommandToServer() cannot find packet name for command %s",
00401                command);
00402     return;
00403   }
00404   
00405   const char *packetName = iter->second.c_str();
00406   ArFunctor2<ArServerClient *, ArNetPacket *> *callback = NULL;
00407 
00408   std::map<std::string, ArFunctor2<ArServerClient *, ArNetPacket *> *>::iterator cbIter =
00409     myCommandToCBMap.find(command);
00410   if (cbIter != myCommandToCBMap.end()) {
00411     callback = cbIter->second;
00412   }
00413   if (callback == NULL) {
00414     ArLog::log(ArLog::Normal, 
00415                "ArServerHandlerCamera::addCommandToServer() cannot find callback for command %s",
00416                command);
00417   }
00418 
00419   bool isSuccess = true;
00420 
00433   if (isSuccess) {
00434     isSuccess = myServer->addData
00435                        (packetName, 
00436                                     description,
00437                                     callback,
00438                                     argumentDescription, 
00439                                     returnDescription,
00440                         commandGroup, "RETURN_SINGLE");
00441   }
00442   if (!isSuccess) {
00443     ArLog::log(ArLog::Normal, 
00444                "ArServerHandlerCamera::addCommandToServer() error adding server handler for packet %s",
00445                packetName);
00446     removeCommand(command);
00447   }
00448 
00449 } // end method addCommandToServer
00450 
00451 
00452 void ArServerHandlerCamera::doAddToCameraCollection(ArCameraCollection &collection)
00453 {
00454   if (myCameraName.empty()) {
00455   
00456     return;
00457   } // end if no camera name
00458 
00459   const char *cameraName = myCameraName.c_str();
00460   if (!collection.exists(cameraName)) {
00461 
00462     return;
00463   } // end if camera not yet created
00464 
00465   for (std::map<std::string, std::string>::iterator iter = myCommandToPacketNameMap.begin();
00466         iter != myCommandToPacketNameMap.end();
00467         iter++) {
00468 
00469     const char *command = iter->first.c_str();
00470     const char *packetName = iter->second.c_str();
00471 
00472     int requestInterval = -1; 
00473     std::map<std::string, int>::iterator nIter = myCommandToIntervalMap.find(command);
00474     if (nIter != myCommandToIntervalMap.end()) {
00475       requestInterval = nIter->second;
00476     }
00477 
00478     bool isSuccess = collection.addCameraCommand(cameraName,
00479                                                  command,
00480                                                  packetName,
00481                                                  requestInterval);
00482 
00483     if (!isSuccess) {
00484 
00485     } // end if error occurred
00486 
00487   } // end for each command
00488 } // end method doAddToCameraCollection
00489 
00490 
00491 void ArServerHandlerCamera::removeCommand(const char *command)
00492 {
00493   std::map<std::string, std::string>::iterator iter = myCommandToPacketNameMap.find(command);
00494   if (iter != myCommandToPacketNameMap.end()) {
00495     myCommandToPacketNameMap.erase(iter);
00496   }
00497 
00498   std::map<std::string, ArFunctor2<ArServerClient *, ArNetPacket *> *>::iterator cbIter =
00499     myCommandToCBMap.find(command);
00500   if (cbIter != myCommandToCBMap.end()) {
00501     delete cbIter->second;
00502     cbIter->second = NULL;
00503     myCommandToCBMap.erase(cbIter);
00504   }
00505 
00506 } // end method removeCommand
00507 
00508 
00509 AREXPORT void ArServerHandlerCamera::addToCameraCollection(ArCameraCollection &collection)
00510 {
00511   doAddToCameraCollection(collection);
00512 }
00513 
00514 // -----------------------------------------------------------------------------
00515 // Packet Handlers:
00516 // -----------------------------------------------------------------------------
00517 
00518 AREXPORT void ArServerHandlerCamera::handleGetCameraData(ArServerClient *client, 
00519                                                          ArNetPacket *packet)
00520 {
00521   if ((client == NULL) || (myRobot == NULL) || (myCamera == NULL)) {
00522     return;
00523   }
00524 
00525   ArNetPacket sendPacket;
00526 
00527   myRobot->lock();
00528   double pan = myCamera->getPan();
00529   double tilt = myCamera->getTilt();
00530   double zoom = (getCurrentZoomRatio() * 100.0);
00531 
00532   myRobot->unlock();
00533 
00534   addDoubleToPacket(pan, sendPacket);
00535   addDoubleToPacket(tilt, sendPacket);
00536   addDoubleToPacket(zoom, sendPacket);
00537 
00538   client->sendPacketUdp(&sendPacket);
00539 
00540 } // end method handleGetCameraData
00541 
00542 
00543 AREXPORT void ArServerHandlerCamera::handleGetCameraInfo(ArServerClient *client, 
00544                                                          ArNetPacket *packet)
00545 {
00546   if ((client == NULL) || (myRobot == NULL) || (myCamera == NULL)) {
00547     return;
00548   }
00549 
00550   ArNetPacket sendPacket;
00551 
00552   myRobot->lock();
00553 
00554   double minPan  = myCamera->getMaxNegPan();
00555   double maxPan  = myCamera->getMaxPosPan();
00556   double minTilt = myCamera->getMaxNegTilt();
00557   double maxTilt = myCamera->getMaxPosTilt();
00558   double minZoom = 0;
00559   double maxZoom = 100;
00560   bool isZoomAvailable = myCamera->canZoom();
00561 
00562   ArLog::log(ArLog::Normal, 
00563              "minPan %f maxPan %f minTilt %f maxTilt %f minZoom %f maxZoom %f isZoomAvailable %d", 
00564              minPan, maxPan, minTilt, maxTilt, minZoom, maxZoom, isZoomAvailable);
00565 
00566   myRobot->unlock();
00567 
00568   addDoubleToPacket(minPan, sendPacket);
00569   addDoubleToPacket(maxPan, sendPacket);
00570   addDoubleToPacket(minTilt, sendPacket);
00571   addDoubleToPacket(maxTilt, sendPacket);
00572   addDoubleToPacket(minZoom, sendPacket);
00573   addDoubleToPacket(maxZoom, sendPacket);
00574 
00575   sendPacket.byteToBuf(isZoomAvailable);
00576 
00577   client->sendPacketUdp(&sendPacket);
00578 
00579 } // end method handleGetCameraInfo
00580 
00581 
00582 AREXPORT void ArServerHandlerCamera::handleSetCameraAbs(ArServerClient *client, 
00583                                                         ArNetPacket *packet)
00584 {
00585   if ((packet == NULL) || (myRobot == NULL) || (myCamera == NULL)) {
00586     return;
00587   }
00588 
00589   double pan =  getDoubleFromPacket(*packet);
00590   double tilt = getDoubleFromPacket(*packet);
00591   double zoom = getDoubleFromPacket(*packet);
00592 
00593   setCameraAbs(pan, tilt, zoom);
00594 
00595 } // end method handleSetCameraAbs
00596 
00597 
00598 AREXPORT void ArServerHandlerCamera::handleSetCameraRel(ArServerClient *client, 
00599                                                         ArNetPacket *packet)
00600 {
00601   if (packet == NULL) {
00602     return;
00603   }
00604 
00605   //double invAtZoom = 1;
00606 
00607   double pan =  getDoubleFromPacket(*packet);
00608   double tilt = getDoubleFromPacket(*packet);
00609   double zoom = getDoubleFromPacket(*packet);
00610 
00611   setCameraRel(pan, tilt, zoom);
00612 
00613 } // end method handleSetCameraRel
00614 
00615 
00616 AREXPORT void ArServerHandlerCamera::handleSetCameraPct(ArServerClient *client, 
00617                                                                                                                           ArNetPacket *packet)
00618 {
00619 
00620   if (!myCamera->canGetFOV())
00621   {
00622     ArLog::log(ArLog::Normal, "ArServerHandlerCamera::cameraPct called when camera can't get the FOV");
00623     return;
00624   }
00625   // Values range -100 to 100.  0 indicates no change.
00626   //int panPct = packet->bufToByte();
00627   //int tiltPct = -packet->bufToByte();
00628 
00629   double panPct  = getDoubleFromPacket(*packet);
00630   double tiltPct = -(getDoubleFromPacket(*packet));
00631 
00632   setCameraPct(panPct, tiltPct);
00633 
00634 } // end method handleSetCameraPct
00635 
00636 
00637 // ----------------------------------------------------------------------------
00638 // Old Packet Handlers (integers, for backwards compatibility)
00639 // ----------------------------------------------------------------------------
00640 
00641 
00642 AREXPORT void ArServerHandlerCamera::camera(ArServerClient *client, 
00643                                                                           ArNetPacket *packet)
00644 {
00645 
00646   //double invAtZoom = 1;
00647 
00648   int pan = packet->bufToByte();
00649   int tilt = packet->bufToByte();
00650   int zoom = packet->bufToByte();
00651 
00652   setCameraRel(pan, tilt, zoom);
00653 
00654 } // end method camera
00655 
00656 
00657 AREXPORT void ArServerHandlerCamera::cameraAbs(ArServerClient *client, 
00658                                                                        ArNetPacket *packet)
00659 {
00660 
00661   int pan = packet->bufToByte();
00662   int tilt = packet->bufToByte();
00663   int zoom = packet->bufToByte();
00664 
00665   setCameraAbs(pan, tilt, zoom);
00666 
00667 } // end method cameraAbs
00668 
00669 
00670 AREXPORT void ArServerHandlerCamera::cameraPct(ArServerClient *client, 
00671                                                                                                                  ArNetPacket *packet)
00672 {
00673 
00674   if (!myCamera->canGetFOV())
00675   {
00676     ArLog::log(ArLog::Normal, "ArServerHandlerCamera::cameraPct called when camera can't get the FOV");
00677     return;
00678   }
00679   // Values range -100 to 100.  0 indicates no change.
00680   int panPct = packet->bufToByte();
00681   int tiltPct = -packet->bufToByte();
00682 
00683   setCameraPct(panPct, tiltPct);
00684 
00685 } // end method cameraPct
00686 
00687 
00688 AREXPORT void ArServerHandlerCamera::cameraUpdate(ArServerClient *client, 
00689                                                                           ArNetPacket *packet)
00690 {
00691   ArNetPacket send;
00692 
00693   myRobot->lock();
00694   int pan  = ArMath::roundInt(myCamera->getPan());
00695   int tilt = ArMath::roundInt(myCamera->getTilt());
00696   int zoom = ArMath::roundInt(myCamera->getZoom()/((double)(myCamera->getMaxZoom() - myCamera->getMinZoom()) + myCamera->getMinZoom()) * 100.0);
00697 
00698   myRobot->unlock();
00699 
00700   send.byte2ToBuf(pan);
00701   send.byte2ToBuf(tilt);
00702   send.byte2ToBuf(zoom);
00703   client->sendPacketUdp(&send);
00704 
00705 } // end method cameraUpdate
00706 
00707 
00708 AREXPORT void ArServerHandlerCamera::cameraInfo(ArServerClient *client, 
00709                                                                                                                         ArNetPacket *packet)
00710 {
00711   ArNetPacket send;
00712 
00713   myRobot->lock();
00714 
00715   int minPan = ArMath::roundInt(myCamera->getMaxNegPan());
00716   int maxPan = ArMath::roundInt(myCamera->getMaxPosPan());
00717   int minTilt = ArMath::roundInt(myCamera->getMaxNegTilt());
00718   int maxTilt = ArMath::roundInt(myCamera->getMaxPosTilt());
00719   int minZoom = 0;
00720   int maxZoom = 100;
00721   bool isZoomAvailable = myCamera->canZoom();
00722   //ArLog::log(ArLog::Normal, "minPan %d maxPan %d minTilt %d maxTilt %d minZoom %d maxZoom %d isZoomAvailable %d", minPan, maxPan, minTilt, maxTilt, minZoom, maxZoom, isZoomAvailable);
00723 
00724   myRobot->unlock();
00725 
00726   send.byte2ToBuf(minPan);
00727   send.byte2ToBuf(maxPan);
00728   send.byte2ToBuf(minTilt);
00729   send.byte2ToBuf(maxTilt);
00730   send.byte2ToBuf(minZoom);
00731   send.byte2ToBuf(maxZoom);
00732   send.byteToBuf(isZoomAvailable);
00733 
00734   client->sendPacketUdp(&send);
00735 
00736 } // end method cameraInfo
00737 
00738 
00746 AREXPORT void ArServerHandlerCamera::setCameraAbs(
00747         double pan, double tilt, double zoom, bool lockRobot)
00748 {
00749  if (zoom > 100)
00750     zoom = 100;
00751  else if (zoom < 0)
00752    zoom = 0;
00753  
00754  if (lockRobot)
00755    myRobot->lock();
00756  
00757  cameraModePosition();
00758  
00759  myCamera->panTilt(pan, tilt);
00760  
00761  double absZoom = myCamera->getMinZoom() + ((zoom / 100.0) * getZoomRange());
00762  
00763  IFDEBUG(ArLog::log(ArLog::Normal,
00764                     "ArServerHandlerCamera::handleSetCameraAbs() p = %f, t = %f, z = %f, calc absZoom = %f",
00765                     pan, tilt, zoom, absZoom));
00766  
00767  myCamera->zoom(ArMath::roundInt(absZoom));
00768  
00769  if (lockRobot)
00770    myRobot->unlock();
00771  
00772 } // end method doSetCameraAbs
00773 
00774 
00782 AREXPORT void ArServerHandlerCamera::setCameraRel(
00783         double pan, double tilt, double zoom, bool lockRobot)
00784 {
00785   if ((myRobot == NULL) || (myCamera == NULL)) {
00786     return;
00787   }
00788 
00789   IFDEBUG(ArLog::log(ArLog::Normal,
00790                     "ArServerHandlerCamera::doSetCameraRel() p = %f, t = %f, z = %f",
00791                     pan, tilt, zoom));
00792 
00793   // The camera mode is set to position only if the pan or tilt changed.
00794 
00795   double invAtZoom = 1;
00796 
00797   if (myCamera->getMaxZoom() - myCamera->getMinZoom() != 0)
00798   {
00799     // see what zoom we're at so we can modify total pan and tilt amounts by it
00800     invAtZoom = 1 - getCurrentZoomRatio();
00801 
00802     //totalPanAmount /= atZoom / (100 / (double) totalPanAmount);
00803     //totalTiltAmount /= atZoom / (100 / (double) totalTiltAmount);
00804     if (invAtZoom < .01)
00805       invAtZoom = .01;
00806     if (invAtZoom > 1.01)
00807       invAtZoom = 1;
00808   }
00809   else
00810   {
00811     invAtZoom = 1;
00812   }
00813 
00814   if (pan > 0)
00815     pan = ceil(pan * invAtZoom);
00816   else
00817     pan = floor(pan * invAtZoom);
00818 
00819   if (tilt > 0)
00820     tilt = ceil(tilt * invAtZoom);
00821   else
00822     tilt = floor(tilt * invAtZoom);
00823 
00824   if (lockRobot)
00825     myRobot->lock();
00826 
00827   if (zoom != 0)
00828   {
00829     double newZoomPct = (getCurrentZoomRatio() * 100.0) + zoom;
00830 
00831     double newAbsZoom = myCamera->getMinZoom() + ((newZoomPct / 100.0) * getZoomRange());
00832 
00833     IFDEBUG(ArLog::log(ArLog::Normal,
00834                       "ArServerHandlerCamera::handleSetCameraRel() newZoomPct = %f, newAbsZoom = %f",
00835                        newZoomPct, newAbsZoom));
00836 
00837     myCamera->zoom(ArMath::roundInt(newAbsZoom));
00838 
00839   } // end if zoom change
00840   
00841   // Only want to pan...
00842   if ((pan == 0) && (tilt != 0)) 
00843   {
00844     cameraModePosition();
00845     myCamera->tiltRel(tilt);
00846   }
00847   // Only want to tilt...
00848   else if ((pan != 0) && (tilt == 0)) 
00849   {
00850     cameraModePosition();
00851     myCamera->panRel(pan);
00852   }
00853   else if (pan != 0 && tilt != 0) 
00854   { // pan and tilt...
00855     cameraModePosition();
00856     myCamera->panTiltRel(pan, tilt);
00857   }
00858 
00859   if (lockRobot)
00860     myRobot->unlock();
00861 
00862 } // end method doSetCameraRel
00863 
00864 
00865 
00878 AREXPORT void ArServerHandlerCamera::setCameraPct(
00879         double panPct, double tiltPct, bool lockRobot)
00880 {
00881   cameraModePosition();
00882 
00883   double zoom = getCurrentZoomRatio();
00884   
00885   IFDEBUG(ArLog::log(ArLog::Normal,
00886                     "ArServerHandlerCamera::handleSetCameraPct() panPct = %f, tiltPct = %f curZoomRatio = %f",
00887                       panPct, tiltPct, zoom));
00888 
00889   /*
00890      So first we find the field of view we're at, this is interpolated
00891      from the max and min zooms... with an exponential factor (because
00892      empircally it seemed to be needed
00893   */
00894 
00895   double exponent = M_PI/2; // found this to be 1.6 so this seems a
00896                             // likely guess
00897   double fov = ((myCamera->getFOVAtMinZoom() - myCamera->getFOVAtMaxZoom()) * 
00898          pow((1 - zoom), exponent)  + 
00899                   myCamera->getFOVAtMaxZoom());
00900 
00901 
00902   double oldTilt = myCamera->getTilt();
00903   double oldPan = myCamera->getPan();
00904 
00905 
00906   /*
00907     So this whole thing is done as a vector calculations... so first
00908     we find where our old x, y, z value was to start with then we add
00909     in the x, y, z change from the left/right component of the image
00910     click and from the up/down component of the image click to find
00911     our final x, y, z and then we figure out the pan/tilt that points
00912     us there... this is basically all assuming a unit sphere (ie
00913     length 1)
00914 
00915     One thing that could be done to make it more accurate is to remove
00916     some of the error (ie right now from going straight right in the
00917     image at 0 all we do is add x, if we removed a little y too to
00918     normalize it on the unit sphere it'd be more accurate).
00919   **/
00920 
00921   /*
00922    
00923     Derivation of these equations (for finding the x, y, z from
00924     current pan tilt)
00925 
00926            |   ,
00927            |  /|z 
00928            | / |
00929            |/t |y
00930            -)--|-------
00931           / \)p|  /
00932          /  h\ | / x
00933         /     \|/
00934         
00935 
00936      Where pan and tilt are the values we're panned and tilted at now
00937      and x, y, and z are the coords in the unit sphere that we
00938      have... h is the hypoenuse of the line projected down into the
00939      x/y plane
00940 
00941 
00942      sin tilt = z / 1 (because its the unit sphere)   
00943 !    sin tilt = z                -,                  
00944                                   |                  
00945      tan tilt = z / hyp           |                
00946      tan tilt = sin tilt / hyp  <-'
00947      hyp = sin tilt / tan tilt            -,   -,
00948                                            |    | 
00949      sin pan = x / hyp                     |    | 
00950      sin pan * hyp = x                     |    |
00951      x = hyp * sin pan                     |    |
00952 !    x = (sin tilt/tan tilt) * sin pan   <-'    |
00953                                                 |
00954      cos pan = y / hyp                          |          
00955      cos pan * hyp = y                          |
00956      y = hyp * sin pan                          | 
00957 !    y = (sin tilt/tan tilt) * cos pan        <-'
00958      
00959 
00960    The old X here should be      sin(tilt)
00961                                  --------- * sin(pan)
00962                                  tan(tilt) 
00963 
00964    The old Y here should be      sin(tilt)
00965                                  --------- * cos(pan)
00966                                  tan(tilt) 
00967 
00968    The old z here should be      sin(tilt);
00969 
00970    The funkiness is because of divide by zeros and stuff, this is
00971    supposed to be the hypot though and so it can't really ever be 0 or
00972    infnity so just cap the thing
00973  **/
00974   double sinTiltOverTanTilt;
00975   if (fabs(oldTilt) < .01)
00976     sinTiltOverTanTilt = 1;
00977   else
00978     sinTiltOverTanTilt = ArMath::sin(oldTilt) / ArMath::tan(oldTilt);
00979   double oldX = sinTiltOverTanTilt * ArMath::sin(oldPan);
00980   double oldY = sinTiltOverTanTilt * ArMath::cos(oldPan);        
00981   double oldZ = ArMath::sin(oldTilt);
00982 
00983   // figure out the angle of the left/right point in the image
00984   double lr = panPct / 100.0 * fov/2.0;
00985 
01025   double lrDx = + ArMath::sin(lr) * ArMath::cos(oldPan);
01026   double lrDy =  - ArMath::sin(lr) * ArMath::sin(oldPan);
01027   double lrDz = 0;
01028 
01029   // the angle of the up/down point in the image
01030   double ud = tiltPct / 100.0 * fov/2.0 *.71;
01031 
01042   double udDx =  - (ArMath::sin(ud) * ArMath::sin(oldTilt) * 
01043                      ArMath::sin(oldPan));
01044   double udDy =  - (ArMath::sin(ud) * ArMath::sin(oldTilt) * 
01045                      ArMath::cos(oldPan));
01046   double udDz = ArMath::sin(ud) * ArMath::cos(oldTilt);
01047 
01048 
01053   double x = oldX + lrDx + udDx;
01054   double y = oldY + lrDy + udDy;
01055   double z = oldZ + lrDz + udDz;
01056 
01057 
01096   double newPan = ArMath::atan2(x, y);
01097   double tiltDenom;
01103   if (fabs(oldPan) < 1)
01104     tiltDenom = y / ArMath::cos(newPan);  
01105   else if (fabs(oldPan - 90) < 1)
01106     tiltDenom = x / ArMath::sin(newPan);  
01107   else
01108     tiltDenom = (y / ArMath::cos(newPan) + x / ArMath::sin(newPan)) / 2;
01109   double newTilt = ArMath::atan2(z, tiltDenom);
01110   if (lockRobot)
01111     myRobot->lock();
01112   myCamera->panTilt(newPan, newTilt);
01113   if (lockRobot)
01114     myRobot->unlock();
01115   /*
01116   ArLog::log(ArLog::Normal, "w %f h %f zoom %f fov %g oldPan %g oldTilt %g oldx %g oldy %g oldz %g x %g y %g z %g newPan %g newTilt %g",
01117              w, h, zoom, fov, oldPan, oldTilt, oldX, oldY, oldZ, x, y, z, newPan, newTilt);
01118   */
01119 
01120 } // end method doSetCameraPct
01121 
01122 // ----------------------------------------------------------------------------
01123 // Helper Methods
01124 // ----------------------------------------------------------------------------
01125 
01126 AREXPORT void ArServerHandlerCamera::handleGetCameraModeList(
01127         ArServerClient *client, ArNetPacket *packet)
01128 {
01129   ArNetPacket sending;
01130 
01131   myModeMutex.lock();
01132   sending.uByte2ToBuf(myCameraModeNameMap.size());
01133 
01134   std::map<CameraMode, std::string>::iterator it;
01135   for (it = myCameraModeNameMap.begin(); it != myCameraModeNameMap.end(); it++)
01136   {
01137     sending.strToBuf((*it).second.c_str());
01138   }
01139   myModeMutex.unlock();
01140   client->sendPacketTcp(&sending);
01141 }
01142 
01143 AREXPORT void ArServerHandlerCamera::handleCameraModeUpdated(
01144         ArServerClient *client, ArNetPacket *packet)
01145 {
01146   myModeMutex.lock();
01147   client->sendPacketTcp(&myCameraModePacket);
01148   myModeMutex.unlock();
01149 }
01150 
01151 AREXPORT void ArServerHandlerCamera::handleSetCameraMode(
01152         ArServerClient *client, ArNetPacket *packet)
01153 {
01154   char modeName[512];
01155   packet->bufToStr(modeName, sizeof(modeName));
01156 
01157 
01158   CameraMode newMode;
01159   std::map<CameraMode, std::string>::iterator it;
01160   ArPose lookPoint;
01161 
01162   for (it = myCameraModeNameMap.begin(); it != myCameraModeNameMap.end(); it++)
01163   {
01164     if (ArUtil::strcasecmp((*it).second, modeName) == 0)
01165     {
01166       newMode = (*it).first;
01167       if (newMode == CAMERA_MODE_POSITION)
01168       {
01169         cameraModePosition();
01170       }
01171       else if (newMode == CAMERA_MODE_LOOK_AT_GOAL)
01172       {
01173         cameraModeLookAtGoal();
01174       }
01175       else if (newMode == CAMERA_MODE_LOOK_AT_POINT)
01176       {
01177         lookPoint.setX(packet->bufToByte4());
01178         lookPoint.setY(packet->bufToByte4());
01179         cameraModeLookAtPoint(lookPoint);
01180       }
01181       return;
01182     }
01183   }
01184 
01185   ArLog::log(ArLog::Normal, 
01186              "ArServerHandlerCamera::%s: Could not find mode %s to switch to", 
01187              myCameraName.c_str(), modeName);
01188 }
01189 
01190 void ArServerHandlerCamera::userTask(void)
01191 {
01192   myModeMutex.lock();
01193   if (myCameraMode == CAMERA_MODE_LOOK_AT_GOAL)
01194   {
01195     if (!myGoalResetZoom)
01196     {
01197       myCamera->zoom(0);
01198       myGoalResetZoom = true;
01199     }
01200     if (!myGoalAchieved)
01201     {
01202       myCamera->panTilt(-myRobot->findDeltaHeadingTo(myGoal), 0);
01203     }
01204     else if (!myGoalAchievedLast)
01205     {
01206       myCamera->panTilt(0, 0);
01207       myGoalAchievedLast = true;
01208     }
01209   }
01210   if (myCameraMode == CAMERA_MODE_LOOK_AT_POINT)
01211   {
01212     if (!myPointResetZoom)
01213     {
01214       myCamera->zoom(0);
01215     }
01216     myCamera->panTilt(-myRobot->findDeltaHeadingTo(myLookAtPoint), 0);
01217   }
01218   myModeMutex.unlock();
01219 }
01220 
01221 void ArServerHandlerCamera::buildModePacket(void)
01222 {
01223   myCameraModePacket.empty();
01224 
01225   myCameraModePacket.strToBuf(myCameraModeNameMap[myCameraMode].c_str());
01226   if (myCameraMode == CAMERA_MODE_LOOK_AT_POINT)
01227   {
01228     myCameraModePacket.byte4ToBuf(
01229             ArMath::roundInt(myLookAtPoint.getX()));
01230     myCameraModePacket.byte4ToBuf(
01231             ArMath::roundInt(myLookAtPoint.getY()));
01232   }
01233 }
01234 
01235 AREXPORT void ArServerHandlerCamera::cameraModePosition(void)
01236 {
01237   myModeMutex.lock();
01238   if (myCameraMode != CAMERA_MODE_POSITION)
01239   {
01240     ArLog::log(ArLog::Normal, "Looking by position");
01241     myCameraMode = CAMERA_MODE_POSITION;
01242     buildModePacket();
01243     myServer->broadcastPacketTcp(
01244             &myCameraModePacket,
01245             myCommandToPacketNameMap[
01246                     ArCameraCommands::CAMERA_MODE_UPDATED].c_str());
01247             
01248   }
01249   myModeMutex.unlock();
01250 }
01251 
01252 AREXPORT void ArServerHandlerCamera::cameraModeLookAtGoal(void)
01253 {
01254   myModeMutex.lock();
01255   if (myCameraMode != CAMERA_MODE_LOOK_AT_GOAL)
01256   {
01257     ArLog::log(ArLog::Normal, "Looking at goal");
01258     myCameraMode = CAMERA_MODE_LOOK_AT_GOAL;
01259     myGoalAchievedLast = myGoalAchieved;
01260     myGoalResetZoom = false;
01261 
01262     buildModePacket();
01263     myServer->broadcastPacketTcp(
01264             &myCameraModePacket,
01265             myCommandToPacketNameMap[
01266                     ArCameraCommands::CAMERA_MODE_UPDATED].c_str());
01267   }
01268   myModeMutex.unlock();
01269 }
01270 
01271 AREXPORT void ArServerHandlerCamera::cameraModeLookAtPoint(ArPose pose)
01272 {
01273   myModeMutex.lock();
01274   if (myCameraMode != CAMERA_MODE_LOOK_AT_POINT || 
01275       myLookAtPoint.findDistanceTo(pose) > 1)
01276   {
01277     ArLog::log(ArLog::Normal, "Looking at point %.0f %.0f", 
01278                pose.getX(), pose.getY());
01279     if (myCameraMode != CAMERA_MODE_LOOK_AT_POINT)
01280       myPointResetZoom = false;
01281     myCameraMode = CAMERA_MODE_LOOK_AT_POINT;
01282     myLookAtPoint = pose;
01283     buildModePacket();
01284     myServer->broadcastPacketTcp(
01285             &myCameraModePacket,
01286             myCommandToPacketNameMap[
01287                     ArCameraCommands::CAMERA_MODE_UPDATED].c_str());
01288   }
01289   myModeMutex.unlock();
01290 }
01291 
01292 AREXPORT void ArServerHandlerCamera::cameraModeLookAtGoalSetGoal(ArPose pose)
01293 {
01294   myModeMutex.lock();
01295   myGoal = pose;
01296   myGoalAchieved = false;
01297   myGoalAchievedLast = false;
01298   myGoalResetZoom = false;
01299   myModeMutex.unlock();
01300 }
01301 
01302 AREXPORT void ArServerHandlerCamera::cameraModeLookAtGoalClearGoal(void)
01303 {
01304   myModeMutex.lock();
01305   myGoalAchieved = true;
01306   myModeMutex.unlock();
01307 }
01308 
01309 AREXPORT void ArServerHandlerCamera::handleResetCamera(
01310         ArServerClient *client, ArNetPacket *packet)
01311 {
01312   resetCamera();
01313 }
01314 
01315 AREXPORT void ArServerHandlerCamera::resetCamera(bool lockRobot)
01316 {
01317   if (lockRobot)
01318     myRobot->lock();
01319   myCamera->reset();
01320   if (lockRobot)
01321     myRobot->unlock();
01322   cameraModePosition();  
01323 }
01324 

Generated on Tue Feb 20 10:51:50 2007 for ArNetworking by  doxygen 1.4.0