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

ipthru.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 /*
00030   Utility that forwards data back and forth from a tcp port to a serial
00031   port.  This can be used to run programs on your workstation instead
00032   of the robot's onboard computer, or to bridge networks.
00033   However, it can negatively impact performance, and may cause some things
00034   to simply not work; we do not recommend or support using this program
00035   other than for quick testing or development.
00036 */
00037 
00038 void usage(char *progName)
00039 {
00040   printf("There are four ways to use %s\n", progName);
00041   printf("%s\t\t\tUses a robot, port 8101 and %s\n", progName, ArUtil::COM1);
00042   printf("%s laser\t\tUses a laser, port 8102 and %s\n", progName, ArUtil::COM3);
00043   printf("%s <portNumberToForwardFrom> <portNameToForwardTo>\n",     progName);
00044   printf("%s <portNumberToForwardFrom> <portNameToForwardTo> laser\n",   progName);
00045   printf("-----------------------------------------------------------\n");
00046   printf("portNumToForwardFrom: The tcp port to listen on.\n");
00047   printf("portNameToForwardTo: The serial port name to open.\n");
00048   printf("laser: option, if given it'll use laser packet receivers and not robot packet receivers.\n");
00049 }
00050 
00051 int main(int argc, char **argv)
00052 {
00053   // this is how long to wait after there's been no data to close the
00054   // connection.. if its 0 and its using robot it'll set it to 5000 (5
00055   // seconds), if its 0 and using laser, it'll set it to 60000 (60
00056   // seconds, which is needed if the sick driver is controlling power
00057   int timeout = 0;
00058   // true will print out packets as they come and go, false won't
00059   bool tracePackets = false;
00060 
00061   // The socket objects
00062   ArSocket masterSock, clientSock;
00063   // The connections
00064   ArTcpConnection clientConn;
00065   ArSerialConnection robotConn;
00066   // the receivers, first for the robot
00067   ArRobotPacketReceiver clientRec(&clientConn);
00068   ArRobotPacketReceiver robotRec(&robotConn);
00069   // then for the laser
00070   ArSickPacketReceiver clientSickRec(&clientConn, 0, false, true);
00071   ArSickPacketReceiver robotSickRec(&robotConn);
00072   // how about a packet
00073   ArBasePacket *packet;
00074   // our timer for how often we test the client
00075   ArTime lastClientTest;
00076   ArTime lastData;
00077   // where we're forwarding from and to
00078   int portNumber;
00079   const char *portName;
00080   // if we're using the robot or the laser
00081   bool useRobot;
00082   
00083   if (argc == 1)
00084   {
00085     printf("Using robot and port 8101 and serial connection %s, by default.\n", ArUtil::COM1);
00086     useRobot = true;
00087     portNumber = 8101;
00088     portName = ArUtil::COM1;
00089   }
00090   else if (argc == 2)
00091   {
00092     // if laser isn't the last arg, somethings wrong
00093     if (strcmp(argv[1], "laser") != 0)
00094     {
00095       usage(argv[0]);
00096       return -1;
00097     }
00098     useRobot = false;
00099     portNumber = 8102;
00100     portName = ArUtil::COM3;
00101     printf("Using laser and port %d and serial connection %s, by command line arguments.\n", portNumber, portName);
00102     printf("(Note: Requests to change BAUD rate cannot be fulfilled; use 9600 rate only.)\n");
00103   }
00104   else if (argc == 3)
00105   {
00106     if ((portNumber = atoi(argv[1])) <= 0)
00107     {
00108       usage(argv[0]);
00109       return -1;
00110     }
00111     portName = argv[2];
00112     printf("Using robot and port %d and serial connection %s, by command line arguments.\n", portNumber, portName);
00113   }
00114   else if (argc == 4)
00115   {
00116     if ((portNumber = atoi(argv[1])) <= 0)
00117     {
00118       usage(argv[0]);
00119       return -1;
00120     }
00121     // if laser isn't the last arg, somethings wrong
00122     if (strcmp(argv[3], "laser") != 0)
00123     {
00124       usage(argv[0]);
00125       return -1;
00126     }
00127     useRobot = false;
00128     portName = argv[2];
00129     printf("Using laser and port %d and serial connection %s, by command line arguments.\n", portNumber, portName);
00130     printf("(Note: Requests to change BAUD rate cannot be fulfilled; use 9600 rate only.)\n");
00131   }
00132   else
00133   {
00134     usage(argv[0]);
00135     return -1;
00136   }
00137   if (timeout == 0 && useRobot)
00138     timeout = 5000;
00139   else if (timeout == 0)
00140     timeout = 60000;
00141 
00142   // Initialize Aria. For Windows, this absolutely must be done. Because
00143   // Windows does not initialize the socket layer for each program. Each
00144   // program must initialize the sockets itself.
00145   Aria::init(Aria::SIGHANDLE_NONE);
00146 
00147   // Lets open the master socket
00148   if (masterSock.open(portNumber, ArSocket::TCP))
00149     printf("Opened the master port at %d\n", portNumber);
00150   else
00151   {
00152     printf("Failed to open the master port at %d: %s\n",
00153        portNumber, masterSock.getErrorStr().c_str());
00154     return -1;
00155   }
00156 
00157   // just go forever
00158   while (1)
00159   {
00160     // Lets wait for the client to connect to us.
00161     if (masterSock.accept(&clientSock))
00162       printf("Client has connected\n");
00163     else
00164       printf("Error in accepting a connection from the client: %s\n",
00165          masterSock.getErrorStr().c_str());
00166    
00167     // now set up our connection so our packet receivers work
00168     clientConn.setSocket(&clientSock);
00169     clientConn.setStatus(ArDeviceConnection::STATUS_OPEN);
00170     lastClientTest.setToNow();
00171     lastData.setToNow();
00172     // open up the robot port
00173     if (robotConn.open(portName) != 0)
00174     {
00175       printf("Could not open robot port %s.\n", portName);
00176       return -1;
00177     }
00178 
00179     // while we're open, just read from one port and write to the other
00180     while (clientSock.getFD() >= 0)
00181     {
00182       // get our packet
00183       if (useRobot)
00184     packet = clientRec.receivePacket(1);
00185       else
00186     packet = clientSickRec.receivePacket(1);
00187       // see if we had one
00188       if (packet != NULL)
00189       {
00190     if (tracePackets)
00191     {
00192       printf("Client ");
00193       packet->log();
00194     }
00195     robotConn.writePacket(packet);
00196     lastData.setToNow();
00197       }
00198       // get our packet
00199       if (useRobot)
00200     packet = robotRec.receivePacket(1);
00201       else
00202     packet = robotSickRec.receivePacket(1);
00203       // see if we had one
00204       if (packet != NULL)
00205       {
00206     if (tracePackets)
00207     {
00208       printf("Robot ");
00209       packet->log();
00210     }
00211     clientConn.writePacket(packet);
00212     lastData.setToNow();
00213       }
00214       ArUtil::sleep(1);
00215       // If no datas gone by in timeout ms assume our connection is broken
00216       if (lastData.mSecSince() > timeout)
00217       {
00218     printf("No data received in %d milliseconds, closing connection.\n", 
00219            timeout);
00220     clientConn.close();
00221       }
00222     }
00223     // Now lets close the connection to the client
00224     clientConn.close();
00225     printf("Socket to client closed\n");
00226     robotConn.close();
00227   }
00228   // And lets close the master port
00229   masterSock.close();
00230   printf("Master socket closed and program exiting\n");
00231 
00232   // Uninitialize Aria
00233   Aria::uninit();
00234 
00235   // All done
00236   return(0);
00237 }

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