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.
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
1.4.7