This is a simple "central robot server": it uses ArCentralManager for ArNetworking to multiplex several ArNetworking connections through one ArNetworking server. Servers (e.g. guiServer) running on several robots can then be invoked with the "-centralServer" argument (and others), and they will accept client connections through this central server. Clients supporting multiple robots, such as recent version of MobileEyes, can connect to the central server.
The central server can also hold common configuration options and/or a common map.
You use this example program as-is, or add to it to implement multi-robot coordination etc.
Note, this server uses the default server port, 7272. Any other servers running on the same computer will need to use a different port (e.g. use the -serverPort argument).
00001 #include "Aria.h" 00002 #include "ArNetworking.h" 00003 #include "Arnl.h" 00004 00005 00033 // Called whenever a new robot server connects and a forwarder is created for 00034 // it. (Defined after main() below.) 00035 void robotForwarderAdded(ArCentralForwarder *forwarder); 00036 00037 int main(int argc, char **argv) 00038 { 00039 Aria::init(); 00040 ArArgumentParser parser(&argc, argv); 00041 00042 /* This server accepts connections from the several robot servers. It's port 00043 * number is set using the -<name>ServerPort argument, where <name> is given 00044 * here as "robot". (A default of 5000 set below, this number should always 00045 * be used). */ 00046 00047 ArServerSimpleOpener robotServersOpener(&parser, "robot"); 00048 ArServerBase robotServer(true, "RobotServer", false); 00049 00050 // Set robotServerPort to 5000, to avoid conflicting with the 00051 // server port used for clients, which will use the normal 00052 // default of 7272. 00053 parser.addDefaultArgument("-robotServerPort 5000", 1); 00054 00055 00056 /* This server accepts connections from clients: */ 00057 00058 ArServerSimpleOpener clientOpener(&parser, "client"); 00059 ArServerBase clientServer(true, "ClientServer", false, "", "", true); 00060 00061 // Load other defaults from files and environment 00062 parser.loadDefaultArguments(1); 00063 00064 00065 /* Parse arguments */ 00066 if(!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) 00067 { 00068 Aria::logOptions(); 00069 Aria::exit(0); 00070 } 00071 00072 /* Open servers */ 00073 00074 ArLog::log(ArLog::Normal, "Opening connection point for robot servers..."); 00075 if (!robotServersOpener.open(&robotServer, "", 120) || !robotServersOpener.checkAndLog()) 00076 { 00077 ArLog::log(ArLog::Terse, "Could not open connection point (server) for robot servers"); 00078 Aria::exit(1); 00079 } 00080 00081 ArLog::log(ArLog::Normal, "Opening server for clients..."); 00082 if (!clientOpener.open(&clientServer, "", 120) || !clientOpener.checkAndLog()) 00083 { 00084 ArLog::log(ArLog::Terse, "Could not open server for clients"); 00085 Aria::exit(1); 00086 } 00087 00088 00089 /* This keeps track of the several robot servers. When a robot server 00090 * connects to the robotsServer connection point, an ArCentralForwarder 00091 * object is created for that robot server. When a client 00092 * connects to the clientServer, it is informed of ports it can 00093 * connect to to reach the robot servers via the forwarder objects. 00094 */ 00095 ArCentralManager centralManager(&robotServer, &clientServer); 00096 00097 /* ArCentralManager also can invoke callbacks whenever a new robot server 00098 * connects and its ArCentralForwarder object is created. Commands can 00099 * be sent to the robots via these forwarders. 00100 * Here is an example: 00101 */ 00102 ArGlobalFunctor1<ArCentralForwarder*> exampleNewForwarderCB(&robotForwarderAdded); 00103 centralManager.addForwarderAddedCallback(&exampleNewForwarderCB); 00104 00105 /* Clients can send config requests to/from the robot servers, but 00106 * this allows you to also modify this central server's global configuration 00107 * (if you or any Aria class adds options to the global Aria ArConfig 00108 * object). 00109 */ 00110 ArServerHandlerConfig handlerConfig(&clientServer, Aria::getConfig()); 00111 00112 /* monitor communication between the server and client. */ 00113 ArServerHandlerCommMonitor commMonitor(&clientServer); 00114 00115 /* custom/simple commands, but give them different names than the robot 00116 * servers' simple commands: 00117 */ 00118 ArServerHandlerCommands commands(&clientServer); 00119 commands.setPrefix("CentralServer"); 00120 00121 ArServerSimpleServerCommands *serverCommands = NULL; 00122 serverCommands = new ArServerSimpleServerCommands(&commands, &clientServer); 00123 00124 /* Drawings for the client, used to draw information about multiple robots. */ 00125 ArServerInfoDrawings drawings(&clientServer); 00126 00127 /* Keep track of each robot, and send positions to other robots to use, and 00128 * drawings to clients showing points on the robots */ 00129 ArCentralMultiRobot *centralMultiRobot = NULL; 00130 centralMultiRobot = new ArCentralMultiRobot(¢ralManager, Aria::getConfig(), &drawings); 00131 00132 /* Load a config file if given */ 00133 /* 00134 char errorBuffer[1024]; 00135 if (!Aria::getConfig()->parseFile(parser.getArg(1), true, false, 00136 errorBuffer, sizeof(errorBuffer))) 00137 { 00138 ArLog::log(ArLog::Terse, "### Warning: Error loading configuration file \"%s\": %s", argv[1], errorBuffer); 00139 } 00140 00141 // write it back in case new items need to be added: 00142 Aria::getConfig()->writeFile(Aria::getConfig()->getFileName()); 00143 */ 00144 00145 /* Run servers */ 00146 clientServer.runAsync(); 00147 robotServer.run(); 00148 Aria::exit(0); 00149 } 00150 00151 00152 // Called whenever a new robot server connects and a forwarder is created for 00153 // it. 00154 void robotForwarderAdded(ArCentralForwarder *forwarder) 00155 { 00156 // Note that when a robot server connects to this central server, the central 00157 // server takes on the "client" role with respect to that server. So to send 00158 // requests or get information from a robot server, use the forwarder's 00159 // "client" object. (The forwarder's "server" object is the local port that 00160 // clients such as MobileEyes connect to.) 00161 ArLog::log(ArLog::Normal, "centralServerExample: New forwarder added for robot server named \"%s\" at host %s.", forwarder->getRobotName(), forwarder->getClient()->getHost()); 00162 }
1.4.7