drawingsExampleWithRobot.cpp

Example showing how to draw custom graphics in clients such as MobileEyes, and enable drawing of sensor readings as well.

This is an example server that shows how to draw arbitrary figures in a client (e.g. MobileEyes). It also uses the convenient built-in support for visualization built in to ArRobot, ArSick, ArSonarDevice, etc.

See also:
drawingsExample.cpp which does not include robot and sensor drawings
00001 #include "Aria.h"
00002 #include "ArNetworking.h"
00003 #include <math.h>
00004 
00017 /* These are callbacks that respond to client requests for the drawings' 
00018  * geometry data. */
00019 void exampleHomeDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt);
00020 void exampleDotsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt);
00021 void exampleXDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt);
00022 void exampleArrowsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt);
00023 
00024 int main(int argc, char **argv)
00025 {
00026   Aria::init();
00027   ArRobot robot;
00028   ArServerBase server;
00029 
00030   ArArgumentParser parser(&argc, argv);
00031   ArSimpleConnector simpleConnector(&parser);
00032   ArServerSimpleOpener simpleOpener(&parser);
00033 
00034 
00035   // parse the command line... fail and print the help if the parsing fails
00036   // or if help was requested
00037   parser.loadDefaultArguments();
00038   if (!simpleConnector.parseArgs() || !simpleOpener.parseArgs() || 
00039       !parser.checkHelpAndWarnUnparsed())
00040   {    
00041     simpleConnector.logOptions();
00042     simpleOpener.logOptions();
00043     exit(1);
00044   }
00045 
00046   // Set up where we'll look for files such as config file, user/password file,
00047   // etc.
00048   char fileDir[1024];
00049   ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(), 
00050                          "ArNetworking/examples");
00051 
00052   // first open the server up
00053   if (!simpleOpener.open(&server, fileDir, 240))
00054   {
00055     if (simpleOpener.wasUserFileBad())
00056       printf("Error: Bad user/password/permissions file.\n");
00057     else
00058       printf("Error: Could not open server port. Use -help to see options.\n");
00059     exit(1);
00060   }
00061 
00062 
00063   // Devices
00064   ArAnalogGyro gyro(&robot);
00065 
00066   ArSonarDevice sonarDev;
00067   robot.addRangeDevice(&sonarDev);
00068 
00069   ArIRs irs;
00070   robot.addRangeDevice(&irs);
00071 
00072   ArBumpers bumpers;
00073   robot.addRangeDevice(&bumpers);
00074 
00075   ArSick sick(361, 180);
00076   robot.addRangeDevice(&sick);  
00077   
00078 
00079   ArServerInfoRobot serverInfoRobot(&server, &robot);
00080   ArServerInfoSensor serverInfoSensor(&server, &robot);
00081 
00082   // This is the service that provides drawing data to the client.
00083   ArServerInfoDrawings drawings(&server);
00084 
00085   // Convenience function that sets up drawings for all the robot's current
00086   // range devices (using default shape and color info)
00087   drawings.addRobotsRangeDevices(&robot);
00088 
00089   // Add our custom drawings
00090   drawings.addDrawing(
00091       //                shape:      color:               size:   layer:
00092       new ArDrawingData("polyLine", ArColor(255, 0, 0),  2,      49),
00093       "exampleDrawing_Home", 
00094       new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleHomeDrawingNetCallback)
00095   );
00096   drawings.addDrawing(                                    
00097       new ArDrawingData("polyDots", ArColor(0, 255, 0), 250, 48),
00098       "exampleDrawing_Dots", 
00099       new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleDotsDrawingNetCallback)
00100   );
00101   drawings.addDrawing(
00102       new ArDrawingData("polySegments", ArColor(0, 0, 0), 4, 52),
00103       "exampleDrawing_XMarksTheSpot", 
00104       new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleXDrawingNetCallback)
00105   );
00106   drawings.addDrawing(
00107       new ArDrawingData("polyArrows", ArColor(255, 0, 255), 500, 100),
00108       "exampleDrawing_Arrows", 
00109       new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleArrowsDrawingNetCallback)
00110   );
00111 
00112   // modes for moving the robot
00113   ArServerModeStop modeStop(&server, &robot);
00114   ArServerModeDrive modeDrive(&server, &robot);
00115   ArServerModeRatioDrive modeRatioDrive(&server, &robot);
00116   ArServerModeWander modeWander(&server, &robot);
00117   modeStop.addAsDefaultMode();
00118   modeStop.activate();
00119 
00120   
00121 
00122   // Connect to the robot.
00123   if (!simpleConnector.connectRobot(&robot))
00124   {
00125     printf("Error: Could not connect to robot... exiting\n");
00126     Aria::shutdown();
00127     return 1;
00128   }
00129 
00130   // set up the laser before handing it to the laser mode
00131   simpleConnector.setupLaser(&sick);
00132 
00133   robot.enableMotors();
00134 
00135   // start the robot cycle running in a background thread
00136   robot.runAsync(true);
00137 
00138   // start the laser processing cycle in a background thread
00139   sick.runAsync();
00140 
00141   // connect the laser if it was requested
00142   if (!simpleConnector.connectLaser(&sick))
00143   {
00144     printf("Error: Could not connect to laser... exiting\n");
00145     Aria::shutdown();
00146     return 1;
00147   }
00148 
00149   // log whatever we wanted to before the runAsync
00150   simpleOpener.checkAndLog();
00151 
00152   // run the server thread in the background
00153   server.runAsync();
00154 
00155   printf("Server is now running...\n");
00156 
00157 
00158   // Add a key handler mostly that windows can exit by pressing
00159   // escape, note that the key handler prevents you from running this program
00160   // in the background on Linux.
00161   ArKeyHandler *keyHandler;
00162   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00163   {
00164     keyHandler = new ArKeyHandler;
00165     Aria::setKeyHandler(keyHandler);
00166     robot.lock();
00167     robot.attachKeyHandler(keyHandler);
00168     robot.unlock();
00169     printf("To exit, press escape.\n");
00170   }
00171 
00172   robot.waitForRunExit();
00173  
00174 
00175   Aria::shutdown();
00176   exit(0);  
00177 }
00178 
00179 
00180 
00181 
00182 // Network callbacks for drawings' current geometry data:
00183 
00184 void exampleHomeDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) {
00185   ArNetPacket reply;
00186 
00187   // 7 Vertices
00188   reply.byte4ToBuf(7);
00189 
00190   // Centered on 0,0.
00191   // X:                    Y:
00192   reply.byte4ToBuf(-500);  reply.byte4ToBuf(500);   // Vertex 1
00193   reply.byte4ToBuf(-500);  reply.byte4ToBuf(-500);  // Vertex 2
00194   reply.byte4ToBuf(500);   reply.byte4ToBuf(-500);  // Vertex 3
00195   reply.byte4ToBuf(500);   reply.byte4ToBuf(500);   // Vertex 4
00196   reply.byte4ToBuf(0);     reply.byte4ToBuf(1000);  // Vertex 5
00197   reply.byte4ToBuf(-500);  reply.byte4ToBuf(500);   // Vertex 6
00198   reply.byte4ToBuf(500);   reply.byte4ToBuf(500);   // Vertex 7
00199 
00200   client->sendPacketUdp(&reply);
00201 }
00202 
00203 void exampleDotsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) {
00204   ArNetPacket reply;
00205 
00206   unsigned int tik = ArUtil::getTime() % 200;
00207   double t = tik / 5.0;
00208 
00209   // Three dots
00210   reply.byte4ToBuf(3);
00211 
00212   // Dot 1:
00213   reply.byte4ToBuf(3000);  // X coordinate (mm)
00214   reply.byte4ToBuf((int) (sin(t) * 1000));// Y
00215 
00216   // Dot 2:
00217   reply.byte4ToBuf(3500);  // X
00218   reply.byte4ToBuf((int) (sin(t+500) * 1000));// Y
00219 
00220   // Dot 3:
00221   reply.byte4ToBuf(4000);  // X
00222   reply.byte4ToBuf((int) (sin(t+1000) * 1000));// Y
00223 
00224   client->sendPacketUdp(&reply);
00225 }
00226 
00227 void exampleXDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) {
00228   ArNetPacket reply;
00229 
00230   // X marks the spot. 2 line segments, so 4 vertices:
00231   reply.byte4ToBuf(4);
00232 
00233   // Segment 1:
00234   reply.byte4ToBuf(-4250); // X1
00235   reply.byte4ToBuf(250);   // Y1
00236   reply.byte4ToBuf(-3750); // X2
00237   reply.byte4ToBuf(-250);  // Y2
00238 
00239   // Segment 2:
00240   reply.byte4ToBuf(-4250); // X1
00241   reply.byte4ToBuf(-250);  // Y1
00242   reply.byte4ToBuf(-3750); // X2
00243   reply.byte4ToBuf(250);   // Y2
00244   
00245   client->sendPacketUdp(&reply);
00246 }
00247 
00248 void exampleArrowsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) {
00249   // 1 Arrow that points at the robot
00250   ArNetPacket reply;
00251   reply.byte4ToBuf(1);
00252   reply.byte4ToBuf(0);      // Pos. X
00253   reply.byte4ToBuf(700);   // Pos. Y
00254   client->sendPacketUdp(&reply);
00255 }
00256 

Generated on Fri Jul 31 12:37:28 2009 for ArNetworking by  doxygen 1.4.7