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

ArSimpleConnector.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 
00025 */
00026 
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArSimpleConnector.h"
00030 #include "ArRobot.h"
00031 #include "ArSick.h"
00032 
00033 ArSimpleConnector::ArSimpleConnector(int *argc, char **argv) 
00034 {
00035   reset();
00036   myParser = new ArArgumentParser(argc, argv);
00037   myOwnParser = true;
00038 }
00039 
00040 ArSimpleConnector::ArSimpleConnector(ArArgumentBuilder *builder) 
00041 {
00042   reset();
00043   myParser = new ArArgumentParser(builder);
00044   myOwnParser = true;
00045 }
00046 
00047 ArSimpleConnector::ArSimpleConnector(ArArgumentParser *parser)
00048 {
00049   reset();
00050   myParser = parser;
00051   myOwnParser = false;
00052 }
00053 
00054 ArSimpleConnector::~ArSimpleConnector(void)
00055 {
00056 
00057 }
00058 
00059 void ArSimpleConnector::reset(void)
00060 {
00061   myRobot = NULL;
00062   myRemoteHost = NULL;
00063   myRobotPort = NULL;
00064   myRemoteRobotTcpPort = 8101;
00065   myRobotBaud = 9600;
00066   myRemoteIsSim = false;
00067   setMaxNumLasers();
00068   ArUtil::deleteSet(myLasers.begin(), myLasers.end());
00069   myLasers.clear();
00070 }
00071 
00076 void ArSimpleConnector::setMaxNumLasers(int maxNumLasers) 
00077 {
00078   if (maxNumLasers > 0)
00079     myMaxNumLasers = maxNumLasers;
00080   else
00081     myMaxNumLasers = 0;
00082   ArUtil::deleteSet(myLasers.begin(), myLasers.end());
00083   myLasers.clear();
00084 }
00085 
00086 
00087 
00092 bool ArSimpleConnector::parseArgs(void)
00093 {
00094   return parseArgs(myParser);
00095 }
00100 bool ArSimpleConnector::parseArgs(ArArgumentParser *parser)
00101 {
00102   int i;
00103   if (myMaxNumLasers > 0)
00104   {
00105     for (i = 1; i <= myMaxNumLasers; i++)
00106       myLasers.push_front(new LaserData(i));
00107   }
00108 
00109   if (parser->checkArgument("-remoteIsSim") ||
00110       parser->checkArgument("-ris"))
00111     myRemoteIsSim = true;
00112 
00113   if (!parser->checkParameterArgumentString("-remoteHost", 
00114                                              &myRemoteHost) ||
00115       !parser->checkParameterArgumentString("-rh", 
00116                                              &myRemoteHost) ||
00117       !parser->checkParameterArgumentString("-robotPort",
00118                                              &myRobotPort) ||
00119       !parser->checkParameterArgumentString("-rp",
00120                                              &myRobotPort) ||
00121       !parser->checkParameterArgumentInteger("-remoteRobotTcpPort",
00122                                               &myRemoteRobotTcpPort) ||
00123       !parser->checkParameterArgumentInteger("-rrtp",
00124                                               &myRemoteRobotTcpPort) ||
00125       !parser->checkParameterArgumentInteger("-robotBaud",
00126                                               &myRobotBaud) ||
00127       !parser->checkParameterArgumentInteger("-rb",
00128                                              &myRobotBaud))
00129     return false;
00130   else
00131   {
00132     for (i = 1; i <= myMaxNumLasers; i++)
00133       if (!parseLaserArgs(parser, i))
00134         return false;
00135     return true;
00136   }
00137 
00138 }
00139 
00140 bool ArSimpleConnector::parseLaserArgs(ArArgumentParser *parser, 
00141                                                 int laserNumber)
00142 {
00143   char buf[512];
00144   std::list<LaserData *>::iterator it;
00145   LaserData *laserData = NULL;
00146     
00147   for (it = myLasers.begin(); it != myLasers.end(); it++)
00148   {
00149     if ((*it)->myNumber == laserNumber)
00150     {
00151       laserData = (*it);
00152       break;
00153     }
00154   }
00155   if (laserData == NULL)
00156   {
00157     ArLog::log(ArLog::Terse, "Do not have laser %d", laserNumber);
00158     return false;
00159   }
00160 
00161   if (laserData->myNumber == 1)
00162     buf[0] = '\0';
00163   else
00164     sprintf(buf, "%d", laserData->myNumber);
00165 
00166   if (parser->checkArgumentVar("-connectLaser%s", buf) || 
00167       parser->checkArgumentVar("-cl%s", buf))
00168   {
00169     laserData->myConnect = true;
00170   }
00171 
00172   if (!parser->checkParameterArgumentStringVar(NULL, &laserData->myPort, 
00173                                                "-laserPort%s", buf) ||
00174       !parser->checkParameterArgumentStringVar(NULL, &laserData->myPort,
00175                                             "-lp%s", buf) ||
00176       !parser->checkParameterArgumentIntegerVar(NULL,
00177               &laserData->myRemoteTcpPort, 
00178               "-remoteLaserTcpPort%s", buf) ||
00179       !parser->checkParameterArgumentIntegerVar(NULL,
00180               &laserData->myRemoteTcpPort,
00181               "-rltp%s", buf) ||
00182       !parser->checkParameterArgumentBoolVar(&laserData->myFlippedReallySet,
00183                                              &laserData->myFlipped,
00184                                              "-laserFlipped%s", buf) ||
00185       !parser->checkParameterArgumentBoolVar(&laserData->myFlippedReallySet,
00186                                              &laserData->myFlipped,
00187                                              "-lf%s", buf) ||
00188       !parser->checkParameterArgumentBoolVar(
00189               &laserData->myPowerControlledReallySet,
00190               &laserData->myPowerControlled,
00191               "-laserPowerControlled%s", buf) ||
00192       !parser->checkParameterArgumentBoolVar(
00193               &laserData->myPowerControlledReallySet,
00194               &laserData->myPowerControlled,
00195                                              "-lpc%s", buf) ||
00196       !parser->checkParameterArgumentStringVar(NULL, &laserData->myDegrees,
00197                                                "-laserDegrees%s", buf) ||
00198       !parser->checkParameterArgumentStringVar(NULL, &laserData->myDegrees,
00199                                                "-ld%s", buf) ||
00200       !parser->checkParameterArgumentStringVar(NULL, &laserData->myIncrement,
00201                                                "-laserIncrement%s", buf) ||
00202       !parser->checkParameterArgumentStringVar(NULL, &laserData->myIncrement,
00203                                                "-li%s", buf))
00204   {
00205     return false;
00206   }
00207   if (laserData->myDegrees == NULL || laserData->myDegrees[0] == '\0')
00208     laserData->mySickDegrees = ArSick::DEGREES180;
00209   else if (strcasecmp(laserData->myDegrees, "180") == 0)
00210     laserData->mySickDegrees = ArSick::DEGREES180;
00211   else if (strcasecmp(laserData->myDegrees, "100") == 0)
00212     laserData->mySickDegrees = ArSick::DEGREES100;
00213   else
00214   {
00215     ArLog::log(ArLog::Normal, 
00216                "Could not set laserDegrees%s, it should be set to 180 or 100",
00217                buf);
00218     return false;
00219   }
00220   
00221   if (laserData->myIncrement == NULL || laserData->myIncrement[0] == '\0')
00222     laserData->mySickIncrement = ArSick::INCREMENT_ONE;
00223   else if (strcasecmp(laserData->myIncrement, "one") == 0)
00224     laserData->mySickIncrement = ArSick::INCREMENT_ONE;
00225   else if (strcasecmp(laserData->myIncrement, "half") == 0)
00226     laserData->mySickIncrement = ArSick::INCREMENT_HALF;
00227   else
00228   {
00229     ArLog::log(ArLog::Normal, 
00230         "Could not set laserIncrement%s, it should be set to 'one' or 'half'",
00231                buf);
00232     return false;
00233   }
00234 
00235   return true;
00236 }
00237 
00238 void ArSimpleConnector::logOptions(void) const
00239 {
00240   ArLog::log(ArLog::Terse, "Options for ArSimpleConnector (see docs for more details):");
00241   ArLog::log(ArLog::Terse, "");
00242   ArLog::log(ArLog::Terse, "Robot options:");
00243   ArLog::log(ArLog::Terse, "-remoteHost <remoteHostNameOrIP>");
00244   ArLog::log(ArLog::Terse, "-rh <remoteHostNameOrIP>");
00245   ArLog::log(ArLog::Terse, "-robotPort <robotSerialPort>");
00246   ArLog::log(ArLog::Terse, "-rp <robotSerialPort>");
00247   ArLog::log(ArLog::Terse, "-robotBaud <baud>");
00248   ArLog::log(ArLog::Terse, "-rb <baud>");
00249   ArLog::log(ArLog::Terse, "-remoteRobotTcpPort <remoteRobotTcpPort>");
00250   ArLog::log(ArLog::Terse, "-rrtp <remoteRobotTcpPort>");
00251   ArLog::log(ArLog::Terse, "-remoteIsSim");
00252   ArLog::log(ArLog::Terse, "-ris");
00253   
00254   for (int i = 1; i <= myMaxNumLasers; i++)
00255     logLaserOptions(i);
00256 }
00257 
00258 void ArSimpleConnector::logLaserOptions(
00259         unsigned int laserNumber) const
00260 {
00261   char buf[512];
00262   
00263   if (laserNumber == 1)
00264     buf[0] = '\0';
00265   else
00266     sprintf(buf, "%d", laserNumber);
00267 
00268   ArLog::log(ArLog::Terse, "");
00269   ArLog::log(ArLog::Terse, "Laser%s options:", buf);
00270   ArLog::log(ArLog::Terse, "-connectLaser%s", buf);
00271   ArLog::log(ArLog::Terse, "-cl%s", buf);
00272   ArLog::log(ArLog::Terse, "-laserPort%s <laserSerialPort>", buf);
00273   ArLog::log(ArLog::Terse, "-lp%s <laserSerialPort>", buf);
00274   ArLog::log(ArLog::Terse, "-remoteLaserTcpPort%s <remoteLaserTcpPort>", buf);
00275   ArLog::log(ArLog::Terse, "-rltp%s <remoteLaserTcpPort>", buf);  
00276   ArLog::log(ArLog::Terse, "-laserFlipped%s <true|false>", buf);
00277   ArLog::log(ArLog::Terse, "-lf%s <true|false>", buf);
00278   ArLog::log(ArLog::Terse, "-laserPowerControlled%s <true|false>", buf);
00279   ArLog::log(ArLog::Terse, "-lpc%s <true|false>", buf);
00280   ArLog::log(ArLog::Terse, "-laserDegrees%s <180|100>", buf);
00281   ArLog::log(ArLog::Terse, "-ld%s <180|100>", buf);
00282   ArLog::log(ArLog::Terse, "-laserIncrement%s <one|half>", buf);
00283   ArLog::log(ArLog::Terse, "-li%s <one|half>", buf);
00284 
00285 }
00286 
00287 
00288 
00289 
00303 bool ArSimpleConnector::setupRobot(ArRobot *robot)
00304 {
00305   myRobot = robot;
00306   // First we see if we can open the tcp connection, if we can we'll
00307   // assume we're connecting to the sim, and just go on...  if we
00308   // can't open the tcp it means the sim isn't there, so just try the
00309   // robot
00310 
00311   // see if we're doing remote host or not
00312   if (myRemoteHost != NULL)
00313     myRobotTcpConn.setPort(myRemoteHost, myRemoteRobotTcpPort);
00314   else
00315     myRobotTcpConn.setPort("localhost", myRemoteRobotTcpPort);
00316 
00317   // see if we can get to the simulator  (true is success)
00318   if (myRobotTcpConn.openSimple())
00319   {
00320     robot->setDeviceConnection(&myRobotTcpConn);
00321     // we could get to the sim, so set the robots device connection to the sim
00322     if (myRemoteHost != NULL)
00323     {
00324       ArLog::log(ArLog::Normal, "Connected to remote host %s through tcp.\n", 
00325                  myRemoteHost);
00326       if (myRemoteIsSim)
00327         myUsingSim = true;
00328       else
00329         myUsingSim = false;
00330     }
00331     else
00332     {
00333       ArLog::log(ArLog::Normal, "Connecting to simulator through tcp.\n");
00334       myUsingSim = true;
00335     }
00336   }
00337   else
00338   {
00339     // if we were trying for a remote host and it failed, just exit
00340     if (myRemoteHost != NULL)
00341     {
00342       ArLog::log(ArLog::Terse, "Could not connect robot to remote host %s.\n", myRemoteHost);
00343       return false;
00344     }
00345     // we couldn't get to the sim, so set the port on the serial
00346     // connection and then set the serial connection as the robots
00347     // device
00348 
00349     myRobotSerConn.setPort(myRobotPort);
00350     myRobotSerConn.setBaud(myRobotBaud);
00351     ArLog::log(ArLog::Normal,
00352                "Could not connect to simulator, connecting to robot through serial port %s.", 
00353                myRobotSerConn.getPort());
00354     robot->setDeviceConnection(&myRobotSerConn);
00355     myUsingSim = false;
00356   }
00357   return true;
00358 }
00359 
00360 bool ArSimpleConnector::connectRobot(ArRobot *robot)
00361 {
00362   if (!setupRobot(robot))
00363     return false;
00364   else
00365     return robot->blockingConnect();
00366 }
00367 
00380 bool ArSimpleConnector::setupLaser(ArSick *sick)
00381 {
00382   return setupLaserArbitrary(sick, 1);
00383 }
00384 
00392 bool ArSimpleConnector::setupSecondLaser(ArSick *sick)
00393 {
00394   return setupLaserArbitrary(sick, 2);
00395 }
00396 
00397 bool ArSimpleConnector::setupLaserArbitrary(ArSick *sick, 
00398                                                     int laserNumber)
00399 {
00400   std::list<LaserData *>::iterator it;
00401   LaserData *laserData = NULL;
00402   const ArRobotParams *params;
00403     
00404   for (it = myLasers.begin(); it != myLasers.end(); it++)
00405   {
00406     if ((*it)->myNumber == laserNumber)
00407     {
00408       laserData = (*it);
00409       break;
00410     }
00411   }
00412   if (laserData == NULL)
00413   {
00414     ArLog::log(ArLog::Terse, "Do not have laser %d", laserNumber);
00415     return false;
00416   }
00417   
00418   if (laserData->myNumber == 1 && myRobot != NULL && 
00419       myRobot->isConnected())
00420   {
00421     params = myRobot->getRobotParams();
00422     if (!laserData->myFlippedReallySet)
00423       laserData->myFlipped = params->getLaserFlipped();
00424     if (!laserData->myPowerControlledReallySet)
00425       laserData->myPowerControlled = params->getLaserPowerControlled();
00426     if (laserData->myPort == NULL || laserData->myPort[0] == '\0')
00427     {
00428       if (strcmp(params->getLaserPort(), "COM1") == 0)
00429         laserData->myPort = ArUtil::COM1;
00430       else if (strcmp(params->getLaserPort(), "COM2") == 0)
00431         laserData->myPort = ArUtil::COM2;
00432       else if (strcmp(params->getLaserPort(), "COM3") == 0)
00433         laserData->myPort = ArUtil::COM3;
00434       else if (strcmp(params->getLaserPort(), "COM4") == 0)
00435         laserData->myPort = ArUtil::COM4;
00436       else
00437       {
00438         if (params->getLaserPort() != NULL)
00439           laserData->myPort = params->getLaserPort();
00440         else
00441           laserData->myPort = ArUtil::COM3;
00442         ArLog::log(ArLog::Normal,
00443                    "Could not find LaserPort from robot parameters, using %s", 
00444                    laserData->myPort);
00445 
00446       }
00447     }
00448     
00449   }
00450 
00451   if (laserData->myPort == NULL || strlen(laserData->myPort) == 0)
00452   {
00453     ArLog::log(ArLog::Normal, "There is no port defined for laser %d", 
00454                laserData->myNumber);
00455     return false;
00456   }
00457   if (!myUsingSim && myRemoteHost != NULL && strlen(myRemoteHost) > 0)
00458     sick->configure(myUsingSim, laserData->myPowerControlled,
00459                     laserData->myFlipped,
00460                     ArSick::BAUD9600, laserData->mySickDegrees, 
00461                     laserData->mySickIncrement);
00462   else if (myUsingSim && laserData->myNumber != 1)
00463   {
00464     ArLog::log(ArLog::Normal, "Cannot use the simulator with multiple lasers");
00465     return false;
00466   }
00467   else
00468     sick->configure(myUsingSim, laserData->myPowerControlled,
00469                     laserData->myFlipped,
00470                     ArSick::BAUD38400, laserData->mySickDegrees, 
00471                     laserData->mySickIncrement);
00472 
00473   // set the port, if we need to
00474   if (!myUsingSim)
00475   { 
00476     if (myRemoteHost != NULL && strlen(myRemoteHost) > 0)
00477     { 
00478       laserData->myTcpConn.setPort(myRemoteHost, 
00479                                    laserData->myRemoteTcpPort);
00480       sick->setDeviceConnection(&laserData->myTcpConn);
00481       if (!laserData->myTcpConn.openSimple())
00482       { 
00483         ArLog::log(ArLog::Terse, "Could not connect laser to remote host %s.\n", myRemoteHost);
00484         return false; 
00485       } 
00486     } 
00487     else 
00488     { 
00489       laserData->mySerConn.setPort(laserData->myPort);
00490       sick->setDeviceConnection(&laserData->mySerConn); 
00491     } 
00492   }
00493   return true;
00494 
00495 }
00496 
00503 bool ArSimpleConnector::connectLaser(ArSick *sick)
00504 {
00505   return connectLaserArbitrary(sick, 1);
00506 }
00507 
00508 
00514 bool ArSimpleConnector::connectSecondLaser(ArSick *sick)
00515 {
00516   return connectLaserArbitrary(sick, 2);
00517 }
00518 
00519 bool ArSimpleConnector::connectLaserArbitrary(ArSick *sick,
00520                                                       int laserNumber)
00521 {
00522   std::list<LaserData *>::iterator it;
00523   LaserData *laserData = NULL;
00524   
00525   for (it = myLasers.begin(); it != myLasers.end(); it++)
00526   {
00527     if ((*it)->myNumber == laserNumber)
00528     {
00529       laserData = (*it);
00530       break;
00531     }
00532   }
00533   if (laserData == NULL)
00534   {
00535     ArLog::log(ArLog::Terse, "Do not have laser %d", laserNumber);
00536     return false;
00537   }
00538 
00539   sick->lockDevice();
00540   // set up the laser regardless
00541   setupLaserArbitrary(sick, laserNumber);
00542   sick->unlockDevice();
00543   // see if we want to connect
00544   if (!laserData->myConnect)
00545     return true;
00546   else
00547     return sick->blockingConnect();
00548 }

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