centralServerExample.cpp

Example of a central server which allows clients to communicate with multiple robot servers through one connection, and for the multiple robot servers to share information. 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(&centralManager, 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 }

Generated on Thu Aug 6 09:40:13 2009 for BaseArnl by  doxygen 1.5.1