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

twoRobotWander.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 "Aria.h"
00027 
00028 /*
00029   Normally, a program will only connect to one robot, and will only have
00030   one ArRobot object.   However, it is possible to connect to more than
00031   one robot from the same program -- for example, this may be useful for doing 
00032   multirobot experiments in a simulator, or to control remote robots with
00033   wireless-serial bridge devices from an offboard computer. This program 
00034   demonstrates this by connecting to two robots over TCP connections. 
00035   (Old systems with dedicated serial-radio links for each robot would require 
00036   modifying this program to use serial connections instead.)
00037 
00038   Specify the hostnames of each robot with -rh1 and -rh2 command line arguments
00039   (defaults are "localhost" for each). Specify port numbers for each with
00040   -rp1 and -rp2 command line arguments (defaults are 8101 for each if 
00041   the hostnames are different, or 8101 and 8102 if the hostnames are the same).
00042 
00043   This program will just have two robots wander around, avoiding obstacles
00044   detected by the sonar, or otherwise moving forward at constant velocity.
00045   First it has one robot wander for a period of time, then it has the 
00046   second robot wander around.
00047 */
00048 
00049 int main(int argc, char** argv)
00050 {
00051   int ret;
00052   std::string str;
00053   int curRobot;
00054 
00055   // get hostnames and port numbers for connecting to the robots.
00056   ArArgumentParser argParser(&argc, argv);
00057   char* host1 = argParser.checkParameterArgument("-rh1");
00058   if(!host1) host1 = "localhost";
00059   char* host2 = argParser.checkParameterArgument("-rh2");
00060   if(!host2) host2 = "localhost";
00061 
00062   int port1 = 8101;
00063   int port2 = 8101;
00064   if(strcmp(host1, host2) == 0 )
00065   {
00066     // same host, it must be using two ports (but can still override below with -rp2)
00067     port2++;
00068   }
00069 
00070   bool argSet = false;
00071   argParser.checkParameterArgumentInteger("-rp1", &port1, &argSet);  
00072   if(!argSet) argParser.checkParameterArgumentInteger("-rrtp1", &port1);
00073   argSet = false;
00074   argParser.checkParameterArgumentInteger("-rp2", &port2, &argSet);
00075   if(!argSet) argParser.checkParameterArgumentInteger("-rrtp2", &port2);
00076   
00077   if(!argParser.checkHelpAndWarnUnparsed())
00078   {
00079     ArLog::log(ArLog::Terse, "Usage: twoRobotWander [-rh1 <hostname1>] [-rh2 <hostname2>] [-rp1 <port1>] [-rp2 <port2>]\n"\
00080       "\t<hostname1> Is the network host name of the first robot."\
00081           " Default is localhost (for the simulator).\n"\
00082       "\t<hostname2> Is the network host name of the second robot."\
00083           " Default is localhost (for the simulator).\n"\
00084       "\t<port1> Is the TCP port number of the first robot. Default is 8101.\n"\
00085       "\t<port2> Is the TCP port number of the second robot. Default is 8102 if"\
00086         " both robots have the same hostname, or 8101 if they differ.\n\n");
00087     return 1;
00088   }
00089 
00090   
00091 
00092   //
00093   // The first robot's objects
00094   //
00095   // the first robot connection
00096   ArTcpConnection con1;
00097   // the first robot
00098   ArRobot robot1;
00099   // sonar, must be added to the first robot
00100   ArSonarDevice sonar1;
00101   // the actions we'll use to wander for the first robot
00102   ArActionStallRecover recover1;
00103   ArActionBumpers bumpers1;
00104   ArActionAvoidFront avoidFront1;
00105   ArActionConstantVelocity constantVelocity1("Constant Velocity", 400);
00106 
00107   //
00108   // The second robot's objects
00109   //
00110   // the second robot connection
00111   ArTcpConnection con2;
00112   // the second robot
00113   ArRobot robot2;
00114   // sonar, must be added to the second robot
00115   ArSonarDevice sonar2;
00116   // the actions we'll use to wander for the second robot
00117   ArActionStallRecover recover2;
00118   ArActionBumpers bumpers2;
00119   ArActionAvoidFront avoidFront2;
00120   ArActionConstantVelocity constantVelocity2("Constant Velocity", 400);
00121 
00122   // mandatory init
00123   Aria::init();
00124 
00125   //
00126   // Lets get robot 1 going
00127   //
00128 
00129   // open the connection, if this fails exit
00130   ArLog::log(ArLog::Normal, "Connecting to first robot at %s:%d...", host1, port1);
00131   if ((ret = con1.open(host1, port1)) != 0)
00132   {
00133     str = con1.getOpenMessage(ret);
00134     printf("Open failed to robot 1: %s\n", str.c_str());
00135     Aria::shutdown();
00136     return 1;
00137   }
00138   
00139   // add the sonar to the robot
00140   robot1.addRangeDevice(&sonar1);
00141   
00142   // set the device connection on the robot
00143   robot1.setDeviceConnection(&con1);
00144   
00145   // try to connect, if we fail exit
00146   if (!robot1.blockingConnect())
00147   {
00148     printf("Could not connect to robot 1... exiting\n");
00149     Aria::shutdown();
00150     return 1;
00151   }
00152 
00153   // turn on the motors, turn off amigobot sounds
00154   robot1.comInt(ArCommands::ENABLE, 1);
00155   robot1.comInt(ArCommands::SOUNDTOG, 0);
00156 
00157   // add the actions
00158   robot1.addAction(&recover1, 100);
00159   robot1.addAction(&bumpers1, 75);
00160   robot1.addAction(&avoidFront1, 50);
00161   robot1.addAction(&constantVelocity1, 25);
00162 
00163 
00164   //
00165   // Lets get robot 2 going
00166   //
00167 
00168   // open the connection, if this fails exit
00169   ArLog::log(ArLog::Normal, "Connecting to second robot at %s:%d...", host2, port2);
00170   if ((ret = con2.open(host2, port2)) != 0)
00171   {
00172     str = con2.getOpenMessage(ret);
00173     printf("Open failed to robot 2: %s\n", str.c_str());
00174     Aria::shutdown();
00175     return 1;
00176   }
00177   
00178   // add the sonar to the robot
00179   robot2.addRangeDevice(&sonar2);
00180   
00181   // set the device connection on the robot
00182   robot2.setDeviceConnection(&con2);
00183   
00184   // try to connect, if we fail exit
00185   if (!robot2.blockingConnect())
00186   {
00187     printf("Could not connect to robot 2... exiting\n");
00188     Aria::shutdown();
00189     return 1;
00190   }
00191 
00192   // turn on the motors, turn off amigobot sounds
00193   robot2.comInt(ArCommands::ENABLE, 1);
00194   robot2.comInt(ArCommands::SOUNDTOG, 0);
00195 
00196   // add the actions
00197   robot2.addAction(&recover2, 100);
00198   robot2.addAction(&bumpers2, 75);
00199   robot2.addAction(&avoidFront2, 50);
00200   robot2.addAction(&constantVelocity2, 25);
00201   
00202   // start the robots running. true so that if we lose connection to either
00203   // robot, the run stops.
00204   robot1.runAsync(true);
00205   robot2.runAsync(true);
00206 
00207   // As long as both robot loops are running, lets alternate between the
00208   // two wandering around.
00209   curRobot=1;
00210   while (robot1.isRunning() && robot2.isRunning())
00211   {
00212     ArUtil::sleep(10000);
00213     if (curRobot == 1)
00214     {
00215       robot1.stop();
00216       robot2.clearDirectMotion();
00217       curRobot=2;
00218     }
00219     else
00220     {
00221       robot2.stop();
00222       robot1.clearDirectMotion();
00223       curRobot=1;
00224     }
00225   }
00226   
00227   // now exit
00228   Aria::shutdown();
00229   return 0;
00230 }

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