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

ArSimpleConnector.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 "ArSimpleConnector.h"
00029 #include "ArRobot.h"
00030 #include "ArSick.h"
00031 #include "ariaInternal.h"
00032 
00033 AREXPORT ArSimpleConnector::ArSimpleConnector(int *argc, char **argv) :
00034   myParseArgsCB(this, &ArSimpleConnector::parseArgs),
00035   myLogOptionsCB(this, &ArSimpleConnector::logOptions)
00036 {
00037   reset();
00038   myParser = new ArArgumentParser(argc, argv);
00039   myOwnParser = true;
00040   myParseArgsCB.setName("ArSimpleConnector");
00041   Aria::addParseArgsCB(&myParseArgsCB, 75);
00042   myLogOptionsCB.setName("ArSimpleConnector");
00043   Aria::addLogOptionsCB(&myLogOptionsCB, 90);
00044 }
00045 
00046 AREXPORT ArSimpleConnector::ArSimpleConnector(ArArgumentBuilder *builder) :
00047   myParseArgsCB(this, &ArSimpleConnector::parseArgs),
00048   myLogOptionsCB(this, &ArSimpleConnector::logOptions)
00049 {
00050   reset();
00051   myParser = new ArArgumentParser(builder);
00052   myOwnParser = true;
00053   myParseArgsCB.setName("ArSimpleConnector");
00054   Aria::addParseArgsCB(&myParseArgsCB, 75);
00055   myLogOptionsCB.setName("ArSimpleConnector");
00056   Aria::addLogOptionsCB(&myLogOptionsCB, 90);
00057 }
00058 
00059 AREXPORT ArSimpleConnector::ArSimpleConnector(ArArgumentParser *parser) :
00060   myParseArgsCB(this, &ArSimpleConnector::parseArgs),
00061   myLogOptionsCB(this, &ArSimpleConnector::logOptions)
00062 {
00063   reset();
00064   myParser = parser;
00065   myOwnParser = false;
00066   myParseArgsCB.setName("ArSimpleConnector");
00067   Aria::addParseArgsCB(&myParseArgsCB, 75);
00068   myLogOptionsCB.setName("ArSimpleConnector");
00069   Aria::addLogOptionsCB(&myLogOptionsCB, 90);
00070 }
00071 
00072 AREXPORT ArSimpleConnector::~ArSimpleConnector(void)
00073 {
00074 
00075 }
00076 
00077 void ArSimpleConnector::reset(void)
00078 {
00079   myRobot = NULL;
00080   myRemoteHost = NULL;
00081   myRobotPort = NULL;
00082   myRemoteRobotTcpPort = 8101;
00083   myRobotBaud = 9600;
00084   myRemoteIsSim = false;
00085   setMaxNumLasers();
00086   ArUtil::deleteSet(myLasers.begin(), myLasers.end());
00087   myLasers.clear();
00088 }
00089 
00094 AREXPORT void ArSimpleConnector::setMaxNumLasers(int maxNumLasers) 
00095 {
00096   if (maxNumLasers > 0)
00097     myMaxNumLasers = maxNumLasers;
00098   else
00099     myMaxNumLasers = 0;
00100   ArUtil::deleteSet(myLasers.begin(), myLasers.end());
00101   myLasers.clear();
00102 }
00103 
00104 
00105 
00114 AREXPORT bool ArSimpleConnector::parseArgs(void)
00115 {
00116   return parseArgs(myParser);
00117 }
00118 
00201 AREXPORT bool ArSimpleConnector::parseArgs(ArArgumentParser *parser)
00202 {
00203   int i;
00204   if (myMaxNumLasers > 0)
00205   {
00206     for (i = 1; i <= myMaxNumLasers; i++)
00207       myLasers.push_front(new LaserData(i));
00208   }
00209 
00210   if (parser->checkArgument("-remoteIsSim") ||
00211       parser->checkArgument("-ris"))
00212     myRemoteIsSim = true;
00213 
00214   if (!parser->checkParameterArgumentString("-remoteHost", 
00215                          &myRemoteHost) ||
00216       !parser->checkParameterArgumentString("-rh", 
00217                          &myRemoteHost) ||
00218       !parser->checkParameterArgumentString("-robotPort",
00219                          &myRobotPort) ||
00220       !parser->checkParameterArgumentString("-rp",
00221                          &myRobotPort) ||
00222       !parser->checkParameterArgumentInteger("-remoteRobotTcpPort",
00223                           &myRemoteRobotTcpPort) ||
00224       !parser->checkParameterArgumentInteger("-rrtp",
00225                           &myRemoteRobotTcpPort) ||
00226       !parser->checkParameterArgumentInteger("-robotBaud",
00227                           &myRobotBaud) ||
00228       !parser->checkParameterArgumentInteger("-rb",
00229                          &myRobotBaud))
00230     return false;
00231   else
00232   {
00233     for (i = 1; i <= myMaxNumLasers; i++)
00234       if (!parseLaserArgs(parser, i))
00235     return false;
00236     return true;
00237   }
00238 
00239 }
00240 
00241 AREXPORT bool ArSimpleConnector::parseLaserArgs(ArArgumentParser *parser, 
00242                         int laserNumber)
00243 {
00244   char buf[512];
00245   std::list<LaserData *>::iterator it;
00246   LaserData *laserData = NULL;
00247     
00248   for (it = myLasers.begin(); it != myLasers.end(); it++)
00249   {
00250     if ((*it)->myNumber == laserNumber)
00251     {
00252       laserData = (*it);
00253       break;
00254     }
00255   }
00256   if (laserData == NULL)
00257   {
00258     ArLog::log(ArLog::Terse, "Do not have laser %d", laserNumber);
00259     return false;
00260   }
00261 
00262   if (laserData->myNumber == 1)
00263     buf[0] = '\0';
00264   else
00265     sprintf(buf, "%d", laserData->myNumber);
00266 
00267   if (parser->checkArgumentVar("-connectLaser%s", buf) || 
00268       parser->checkArgumentVar("-cl%s", buf))
00269   {
00270     laserData->myConnect = true;
00271   }
00272 
00273   if (!parser->checkParameterArgumentStringVar(NULL, &laserData->myPort, 
00274                            "-laserPort%s", buf) ||
00275       !parser->checkParameterArgumentStringVar(NULL, &laserData->myPort,
00276                         "-lp%s", buf) ||
00277       !parser->checkParameterArgumentIntegerVar(NULL,
00278           &laserData->myRemoteTcpPort, 
00279           "-remoteLaserTcpPort%s", buf) ||
00280       !parser->checkParameterArgumentIntegerVar(NULL,
00281           &laserData->myRemoteTcpPort,
00282           "-rltp%s", buf) ||
00283       !parser->checkParameterArgumentBoolVar(&laserData->myFlippedReallySet,
00284                          &laserData->myFlipped,
00285                          "-laserFlipped%s", buf) ||
00286       !parser->checkParameterArgumentBoolVar(&laserData->myFlippedReallySet,
00287                          &laserData->myFlipped,
00288                          "-lf%s", buf) ||
00289       !parser->checkParameterArgumentBoolVar(
00290           &laserData->myPowerControlledReallySet,
00291           &laserData->myPowerControlled,
00292           "-laserPowerControlled%s", buf) ||
00293       !parser->checkParameterArgumentBoolVar(
00294           &laserData->myPowerControlledReallySet,
00295           &laserData->myPowerControlled,
00296                          "-lpc%s", buf) ||
00297       !parser->checkParameterArgumentStringVar(NULL, &laserData->myDegrees,
00298                            "-laserDegrees%s", buf) ||
00299       !parser->checkParameterArgumentStringVar(NULL, &laserData->myDegrees,
00300                            "-ld%s", buf) ||
00301       !parser->checkParameterArgumentStringVar(NULL, &laserData->myIncrement,
00302                            "-laserIncrement%s", buf) ||
00303       !parser->checkParameterArgumentStringVar(NULL, &laserData->myIncrement,
00304                            "-li%s", buf) ||
00305       !parser->checkParameterArgumentStringVar(NULL, &laserData->myUnits,
00306                            "-laserUnits%s", buf) ||
00307       !parser->checkParameterArgumentStringVar(NULL, &laserData->myUnits,
00308                            "-lu%s", buf) ||
00309       !parser->checkParameterArgumentStringVar(NULL, &laserData->myBits,
00310                            "-laserReflectorBits%s", buf) ||
00311       !parser->checkParameterArgumentStringVar(NULL, &laserData->myBits,
00312                            "-lrb%s", buf))
00313   {
00314     return false;
00315   }
00316   if (laserData->myDegrees == NULL || laserData->myDegrees[0] == '\0')
00317     laserData->mySickDegrees = ArSick::DEGREES180;
00318   else if (strcasecmp(laserData->myDegrees, "180") == 0)
00319     laserData->mySickDegrees = ArSick::DEGREES180;
00320   else if (strcasecmp(laserData->myDegrees, "100") == 0)
00321     laserData->mySickDegrees = ArSick::DEGREES100;
00322   else
00323   {
00324     ArLog::log(ArLog::Normal, 
00325            "Could not set laserDegrees%s, it should be set to 180 or 100",
00326            buf);
00327     return false;
00328   }
00329   
00330   if (laserData->myIncrement == NULL || laserData->myIncrement[0] == '\0')
00331     laserData->mySickIncrement = ArSick::INCREMENT_ONE;
00332   else if (strcasecmp(laserData->myIncrement, "one") == 0)
00333     laserData->mySickIncrement = ArSick::INCREMENT_ONE;
00334   else if (strcasecmp(laserData->myIncrement, "half") == 0)
00335     laserData->mySickIncrement = ArSick::INCREMENT_HALF;
00336   else
00337   {
00338     ArLog::log(ArLog::Normal, 
00339     "Could not set laserIncrement%s, it should be set to 'one' or 'half'",
00340            buf);
00341     return false;
00342   }
00343 
00344   if (laserData->myUnits == NULL || laserData->myUnits[0] == '\0')
00345     laserData->mySickUnits = ArSick::UNITS_1MM;
00346   else if (strcasecmp(laserData->myUnits, "1mm") == 0)
00347     laserData->mySickUnits = ArSick::UNITS_1MM;
00348   else if (strcasecmp(laserData->myUnits, "1cm") == 0)
00349     laserData->mySickUnits = ArSick::UNITS_1CM;
00350   else if (strcasecmp(laserData->myUnits, "10cm") == 0)
00351     laserData->mySickUnits = ArSick::UNITS_10CM;
00352   else
00353   {
00354     ArLog::log(ArLog::Normal, 
00355            "Could not set laserUnits%s, it should be set to '1mm', '1cm', or '10cm'",
00356            buf);
00357     return false;
00358   }
00359 
00360   if (laserData->myBits == NULL || laserData->myBits[0] == '\0')
00361     laserData->mySickBits = ArSick::BITS_1REFLECTOR;
00362   else if (strcasecmp(laserData->myBits, "1ref") == 0)
00363     laserData->mySickBits = ArSick::BITS_1REFLECTOR;
00364   else if (strcasecmp(laserData->myBits, "2ref") == 0)
00365     laserData->mySickBits = ArSick::BITS_2REFLECTOR;
00366   else if (strcasecmp(laserData->myBits, "3ref") == 0)
00367     laserData->mySickBits = ArSick::BITS_3REFLECTOR;
00368   else
00369   {
00370     ArLog::log(ArLog::Normal, 
00371            "Could not set laserReflectorBits%s, it should be set to '1ref', '2ref', or '3ref'",
00372            buf);
00373     return false;
00374   }
00375 
00376   return true;
00377 }
00378 
00379 AREXPORT void ArSimpleConnector::logOptions(void) const
00380 {
00381   ArLog::log(ArLog::Terse, "Options for ArSimpleConnector (see docs for more details):");
00382   ArLog::log(ArLog::Terse, "");
00383   ArLog::log(ArLog::Terse, "Robot options:");
00384   ArLog::log(ArLog::Terse, "-remoteHost <remoteHostNameOrIP>");
00385   ArLog::log(ArLog::Terse, "-rh <remoteHostNameOrIP>");
00386   ArLog::log(ArLog::Terse, "-robotPort <robotSerialPort>");
00387   ArLog::log(ArLog::Terse, "-rp <robotSerialPort>");
00388   ArLog::log(ArLog::Terse, "-robotBaud <baud>");
00389   ArLog::log(ArLog::Terse, "-rb <baud>");
00390   ArLog::log(ArLog::Terse, "-remoteRobotTcpPort <remoteRobotTcpPort>");
00391   ArLog::log(ArLog::Terse, "-rrtp <remoteRobotTcpPort>");
00392   ArLog::log(ArLog::Terse, "-remoteIsSim");
00393   ArLog::log(ArLog::Terse, "-ris");
00394   
00395   for (int i = 1; i <= myMaxNumLasers; i++)
00396     logLaserOptions(i);
00397 }
00398 
00399 AREXPORT void ArSimpleConnector::logLaserOptions(
00400     unsigned int laserNumber) const
00401 {
00402   char buf[512];
00403   
00404   if (laserNumber == 1)
00405     buf[0] = '\0';
00406   else
00407     sprintf(buf, "%d", laserNumber);
00408 
00409   ArLog::log(ArLog::Terse, "");
00410   ArLog::log(ArLog::Terse, "Laser%s options:", buf);
00411   ArLog::log(ArLog::Terse, "-connectLaser%s", buf);
00412   ArLog::log(ArLog::Terse, "-cl%s", buf);
00413   ArLog::log(ArLog::Terse, "-laserPort%s <laserSerialPort>", buf);
00414   ArLog::log(ArLog::Terse, "-lp%s <laserSerialPort>", buf);
00415   ArLog::log(ArLog::Terse, "-remoteLaserTcpPort%s <remoteLaserTcpPort>", buf);
00416   ArLog::log(ArLog::Terse, "-rltp%s <remoteLaserTcpPort>", buf);  
00417   ArLog::log(ArLog::Terse, "-laserFlipped%s <true|false>", buf);
00418   ArLog::log(ArLog::Terse, "-lf%s <true|false>", buf);
00419   ArLog::log(ArLog::Terse, "-laserPowerControlled%s <true|false>", buf);
00420   ArLog::log(ArLog::Terse, "-lpc%s <true|false>", buf);
00421   ArLog::log(ArLog::Terse, "-laserDegrees%s <180|100>", buf);
00422   ArLog::log(ArLog::Terse, "-ld%s <180|100>", buf);
00423   ArLog::log(ArLog::Terse, "-laserIncrement%s <one|half>", buf);
00424   ArLog::log(ArLog::Terse, "-li%s <one|half>", buf);
00425   ArLog::log(ArLog::Terse, "-laserUnits%s <1mm|1cm|10cm>", buf);
00426   ArLog::log(ArLog::Terse, "-lu%s <1mm|1cm|10cm>", buf);
00427   ArLog::log(ArLog::Terse, "-laserReflectorBits%s <1ref|2ref|3ref>", buf);
00428   ArLog::log(ArLog::Terse, "-lrb%s <1ref|2ref|3ref>", buf);
00429 
00430 }
00431 
00432 
00433 
00434 
00452 AREXPORT bool ArSimpleConnector::setupRobot(ArRobot *robot)
00453 {
00454   myRobot = robot;
00455   // First we see if we can open the tcp connection, if we can we'll
00456   // assume we're connecting to the sim, and just go on...  if we
00457   // can't open the tcp it means the sim isn't there, so just try the
00458   // robot
00459 
00460   // see if we're doing remote host or not
00461   if (myRemoteHost != NULL)
00462     myRobotTcpConn.setPort(myRemoteHost, myRemoteRobotTcpPort);
00463   else
00464     myRobotTcpConn.setPort("localhost", myRemoteRobotTcpPort);
00465 
00466   // see if we can get to the simulator  (true is success)
00467   if (myRobotTcpConn.openSimple())
00468   {
00469     robot->setDeviceConnection(&myRobotTcpConn);
00470     // we could get to the sim, so set the robots device connection to the sim
00471     if (myRemoteHost != NULL)
00472     {
00473       ArLog::log(ArLog::Normal, "Connected to remote host %s through tcp.\n", 
00474          myRemoteHost);
00475       if (myRemoteIsSim)
00476     myUsingSim = true;
00477       else
00478     myUsingSim = false;
00479     }
00480     else
00481     {
00482       ArLog::log(ArLog::Normal, "Connecting to simulator through tcp.\n");
00483       myUsingSim = true;
00484     }
00485   }
00486   else
00487   {
00488     // if we were trying for a remote host and it failed, just exit
00489     if (myRemoteHost != NULL)
00490     {
00491       ArLog::log(ArLog::Terse, "Could not connect robot to remote host %s, port %d.\n", myRemoteHost, myRemoteRobotTcpPort);
00492       return false;
00493     }
00494     // we couldn't get to the sim, so set the port on the serial
00495     // connection and then set the serial connection as the robots
00496     // device
00497 
00498     myRobotSerConn.setPort(myRobotPort);
00499     myRobotSerConn.setBaud(myRobotBaud);
00500     ArLog::log(ArLog::Normal,
00501            "Could not connect to simulator, connecting to robot through serial port %s.", 
00502            myRobotSerConn.getPort());
00503     robot->setDeviceConnection(&myRobotSerConn);
00504     myUsingSim = false;
00505   }
00506   return true;
00507 }
00508 
00514 AREXPORT bool ArSimpleConnector::connectRobot(ArRobot *robot)
00515 {
00516   if (!setupRobot(robot))
00517     return false;
00518   else
00519     return robot->blockingConnect();
00520 }
00521 
00534 AREXPORT bool ArSimpleConnector::setupLaser(ArSick *sick)
00535 {
00536   return setupLaserArbitrary(sick, 1);
00537 }
00538 
00546 AREXPORT bool ArSimpleConnector::setupSecondLaser(ArSick *sick)
00547 {
00548   return setupLaserArbitrary(sick, 2);
00549 }
00550 
00551 AREXPORT bool ArSimpleConnector::setupLaserArbitrary(ArSick *sick, 
00552                             int laserNumber)
00553 {
00554   std::list<LaserData *>::iterator it;
00555   LaserData *laserData = NULL;
00556   const ArRobotParams *params;
00557     
00558   for (it = myLasers.begin(); it != myLasers.end(); it++)
00559   {
00560     if ((*it)->myNumber == laserNumber)
00561     {
00562       laserData = (*it);
00563       break;
00564     }
00565   }
00566   if (laserData == NULL)
00567   {
00568     ArLog::log(ArLog::Terse, "ArSimpleConnector::setupLaser: Do not have laser #%d (parseArgs not called or beyond maximum number of lasers allowed?)", laserNumber);
00569     return false;
00570   }
00571   
00572   if (laserData->myNumber == 1 && myRobot != NULL && 
00573       myRobot->isConnected())
00574   {
00575     params = myRobot->getRobotParams();
00576     if (!laserData->myFlippedReallySet)
00577       laserData->myFlipped = params->getLaserFlipped();
00578     if (!laserData->myPowerControlledReallySet)
00579       laserData->myPowerControlled = params->getLaserPowerControlled();
00580     if (laserData->myPort == NULL || laserData->myPort[0] == '\0')
00581     {
00582       if (strcmp(params->getLaserPort(), "COM1") == 0)
00583     laserData->myPort = ArUtil::COM1;
00584       else if (strcmp(params->getLaserPort(), "COM2") == 0)
00585     laserData->myPort = ArUtil::COM2;
00586       else if (strcmp(params->getLaserPort(), "COM3") == 0)
00587     laserData->myPort = ArUtil::COM3;
00588       else if (strcmp(params->getLaserPort(), "COM4") == 0)
00589     laserData->myPort = ArUtil::COM4;
00590       else
00591       {
00592     if (params->getLaserPort() != NULL)
00593       laserData->myPort = params->getLaserPort();
00594     else
00595       laserData->myPort = ArUtil::COM3;
00596     ArLog::log(ArLog::Normal,
00597            "Could not find LaserPort from robot parameters, using %s", 
00598            laserData->myPort);
00599 
00600       }
00601     }
00602     
00603   }
00604 
00605   if (laserData->myPort == NULL || strlen(laserData->myPort) == 0)
00606   {
00607     ArLog::log(ArLog::Normal, "There is no port defined for laser %d", 
00608            laserData->myNumber);
00609     return false;
00610   }
00611   sick->setRangeInformation(laserData->mySickBits, laserData->mySickUnits);
00612   if (!myUsingSim && myRemoteHost != NULL && strlen(myRemoteHost) > 0)
00613     sick->configure(myUsingSim, laserData->myPowerControlled,
00614             laserData->myFlipped,
00615             ArSick::BAUD9600, laserData->mySickDegrees, 
00616             laserData->mySickIncrement);
00617   else if (myUsingSim && laserData->myNumber != 1)
00618   {
00619     ArLog::log(ArLog::Normal, "Cannot use the simulator with multiple lasers");
00620     return false;
00621   }
00622   else
00623     sick->configure(myUsingSim, laserData->myPowerControlled,
00624             laserData->myFlipped,
00625             ArSick::BAUD38400, laserData->mySickDegrees, 
00626             laserData->mySickIncrement);
00627 
00628   // set the port, if we need to
00629   if (!myUsingSim)
00630   { 
00631     if (myRemoteHost != NULL && strlen(myRemoteHost) > 0)
00632     { 
00633       laserData->myTcpConn.setPort(myRemoteHost, 
00634                    laserData->myRemoteTcpPort);
00635       sick->setDeviceConnection(&laserData->myTcpConn);
00636       if (!laserData->myTcpConn.openSimple())
00637       { 
00638         ArLog::log(ArLog::Terse, "Could not connect laser to remote host %s.\n", myRemoteHost);
00639     return false; 
00640       } 
00641     } 
00642     else 
00643     { 
00644       laserData->mySerConn.setPort(laserData->myPort);
00645       sick->setDeviceConnection(&laserData->mySerConn); 
00646     } 
00647   }
00648   return true;
00649 
00650 }
00651 
00658 AREXPORT bool ArSimpleConnector::connectLaser(ArSick *sick)
00659 {
00660   return connectLaserArbitrary(sick, 1);
00661 }
00662 
00663 
00669 AREXPORT bool ArSimpleConnector::connectSecondLaser(ArSick *sick)
00670 {
00671   return connectLaserArbitrary(sick, 2);
00672 }
00673 
00674 AREXPORT bool ArSimpleConnector::connectLaserArbitrary(ArSick *sick,
00675                               int laserNumber)
00676 {
00677   std::list<LaserData *>::iterator it;
00678   LaserData *laserData = NULL;
00679   
00680   for (it = myLasers.begin(); it != myLasers.end(); it++)
00681   {
00682     if ((*it)->myNumber == laserNumber)
00683     {
00684       laserData = (*it);
00685       break;
00686     }
00687   }
00688   if (laserData == NULL)
00689   {
00690     ArLog::log(ArLog::Terse, "Do not have laser %d", laserNumber);
00691     return false;
00692   }
00693 
00694   sick->lockDevice();
00695   // set up the laser regardless
00696   setupLaserArbitrary(sick, laserNumber);
00697   sick->unlockDevice();
00698   // see if we want to connect
00699   if (!laserData->myConnect)
00700     return true;
00701   else
00702     return sick->blockingConnect();
00703 }

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