1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
|
/*
Adept MobileRobots Robotics Interface for Applications (ARIA)
Copyright (C) 2004, 2005 ActivMedia Robotics LLC
Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc.
Copyright (C) 2011, 2012, 2013 Adept Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
If you wish to redistribute ARIA under different terms, contact
Adept MobileRobots for information about a commercial version of ARIA at
robots@mobilerobots.com or
Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960
*/
#include "Aria.h"
/*
Utility that forwards data back and forth from a tcp port to a serial
port. This can be used to run programs on your workstation instead
of the robot's onboard computer, or to bridge networks.
However, it can negatively impact performance, and may cause some things
to simply not work; we do not recommend or support using this program
other than for quick testing or development.
*/
void usage(char *progName)
{
printf("There are four ways to use %s\n", progName);
printf("%s\t\t\tUses a robot, port 8101 and %s\n", progName, ArUtil::COM1);
printf("%s laser\t\tUses a laser, port 8102 and %s\n", progName, ArUtil::COM3);
printf("%s <portNumberToForwardFrom> <portNameToForwardTo>\n", progName);
printf("%s <portNumberToForwardFrom> <portNameToForwardTo> laser\n", progName);
printf("-----------------------------------------------------------\n");
printf("portNumToForwardFrom: The tcp port to listen on.\n");
printf("portNameToForwardTo: The serial port name to open.\n");
printf("laser: option, if given it'll use laser packet receivers and not robot packet receivers.\n");
}
int main(int argc, char **argv)
{
// this is how long to wait after there's been no data to close the
// connection.. if its 0 and its using robot it'll set it to 5000 (5
// seconds), if its 0 and using laser, it'll set it to 60000 (60
// seconds, which is needed if the sick driver is controlling power
int timeout = 0;
// true will print out packets as they come and go, false won't
bool tracePackets = false;
// The socket objects
ArSocket masterSock, clientSock;
// The connections
ArTcpConnection clientConn;
ArSerialConnection robotConn;
// the receivers, first for the robot
ArRobotPacketReceiver clientRec(&clientConn);
ArRobotPacketReceiver robotRec(&robotConn);
// then for the laser
ArSickPacketReceiver clientSickRec(&clientConn, 0, false, true);
ArSickPacketReceiver robotSickRec(&robotConn);
// how about a packet
ArBasePacket *packet;
// our timer for how often we test the client
ArTime lastClientTest;
ArTime lastData;
// where we're forwarding from and to
int portNumber;
const char *portName;
// if we're using the robot or the laser
bool useRobot;
if (argc == 1)
{
printf("Using robot and port 8101 and serial connection %s, by default.\n", ArUtil::COM1);
useRobot = true;
portNumber = 8101;
portName = ArUtil::COM1;
}
else if (argc == 2)
{
// if laser isn't the last arg, somethings wrong
if (strcmp(argv[1], "laser") != 0)
{
usage(argv[0]);
return -1;
}
useRobot = false;
portNumber = 8102;
portName = ArUtil::COM3;
printf("Using laser and port %d and serial connection %s, by command line arguments.\n", portNumber, portName);
printf("(Note: Requests to change BAUD rate cannot be fulfilled; use 9600 rate only.)\n");
}
else if (argc == 3)
{
if ((portNumber = atoi(argv[1])) <= 0)
{
usage(argv[0]);
return -1;
}
portName = argv[2];
printf("Using robot and port %d and serial connection %s, by command line arguments.\n", portNumber, portName);
}
else if (argc == 4)
{
if ((portNumber = atoi(argv[1])) <= 0)
{
usage(argv[0]);
return -1;
}
// if laser isn't the last arg, somethings wrong
if (strcmp(argv[3], "laser") != 0)
{
usage(argv[0]);
return -1;
}
useRobot = false;
portName = argv[2];
printf("Using laser and port %d and serial connection %s, by command line arguments.\n", portNumber, portName);
printf("(Note: Requests to change BAUD rate cannot be fulfilled; use 9600 rate only.)\n");
}
else
{
usage(argv[0]);
return -1;
}
if (timeout == 0 && useRobot)
timeout = 5000;
else if (timeout == 0)
timeout = 60000;
// Initialize Aria. For Windows, this absolutely must be done. Because
// Windows does not initialize the socket layer for each program. Each
// program must initialize the sockets itself.
Aria::init(Aria::SIGHANDLE_NONE);
// Lets open the master socket
if (masterSock.open(portNumber, ArSocket::TCP))
printf("Opened the master port at %d\n", portNumber);
else
{
printf("Failed to open the master port at %d: %s\n",
portNumber, masterSock.getErrorStr().c_str());
return -1;
}
// just go forever
while (1)
{
// Lets wait for the client to connect to us.
if (masterSock.accept(&clientSock))
printf("Client has connected\n");
else
printf("Error in accepting a connection from the client: %s\n",
masterSock.getErrorStr().c_str());
// now set up our connection so our packet receivers work
clientConn.setSocket(&clientSock);
clientConn.setStatus(ArDeviceConnection::STATUS_OPEN);
lastClientTest.setToNow();
lastData.setToNow();
// open up the robot port
if (robotConn.open(portName) != 0)
{
printf("Could not open robot port %s.\n", portName);
return -1;
}
// while we're open, just read from one port and write to the other
while (clientSock.getFD() >= 0)
{
// get our packet
if (useRobot)
packet = clientRec.receivePacket(1);
else
packet = clientSickRec.receivePacket(1);
// see if we had one
if (packet != NULL)
{
if (tracePackets)
{
printf("Client ");
packet->log();
}
robotConn.writePacket(packet);
lastData.setToNow();
}
// get our packet
if (useRobot)
packet = robotRec.receivePacket(1);
else
packet = robotSickRec.receivePacket(1);
// see if we had one
if (packet != NULL)
{
if (tracePackets)
{
printf("Robot ");
packet->log();
}
clientConn.writePacket(packet);
lastData.setToNow();
}
ArUtil::sleep(1);
// If no datas gone by in timeout ms assume our connection is broken
if (lastData.mSecSince() > timeout)
{
printf("No data received in %d milliseconds, closing connection.\n",
timeout);
clientConn.close();
}
}
// Now lets close the connection to the client
clientConn.close();
printf("Socket to client closed\n");
robotConn.close();
}
// And lets close the master port
masterSock.close();
printf("Master socket closed and program exiting\n");
// Uninitialize Aria
Aria::uninit();
// All done
return(0);
}
|