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 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
#include "Aria.h"
#include "ArNetworking.h"
#include <math.h>
/** @example 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.
*
* @sa drawingsExample.cpp which does not include robot and sensor drawings
*/
/* These are callbacks that respond to client requests for the drawings'
* geometry data. */
void exampleHomeDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt);
void exampleDotsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt);
void exampleXDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt);
void exampleArrowsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt);
int main(int argc, char **argv)
{
Aria::init();
ArRobot robot;
ArServerBase server;
ArArgumentParser parser(&argc, argv);
ArSimpleConnector simpleConnector(&parser);
ArServerSimpleOpener simpleOpener(&parser);
// parse the command line... fail and print the help if the parsing fails
// or if help was requested
parser.loadDefaultArguments();
if (!simpleConnector.parseArgs() || !simpleOpener.parseArgs() ||
!parser.checkHelpAndWarnUnparsed())
{
simpleConnector.logOptions();
simpleOpener.logOptions();
exit(1);
}
// Set up where we'll look for files such as config file, user/password file,
// etc.
char fileDir[1024];
ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(),
"ArNetworking/examples");
// first open the server up
if (!simpleOpener.open(&server, fileDir, 240))
{
if (simpleOpener.wasUserFileBad())
printf("Error: Bad user/password/permissions file.\n");
else
printf("Error: Could not open server port. Use -help to see options.\n");
exit(1);
}
// Devices
ArAnalogGyro gyro(&robot);
ArSonarDevice sonarDev;
robot.addRangeDevice(&sonarDev);
ArIRs irs;
robot.addRangeDevice(&irs);
ArBumpers bumpers;
robot.addRangeDevice(&bumpers);
ArSick sick(361, 180);
robot.addRangeDevice(&sick);
ArServerInfoRobot serverInfoRobot(&server, &robot);
ArServerInfoSensor serverInfoSensor(&server, &robot);
// This is the service that provides drawing data to the client.
ArServerInfoDrawings drawings(&server);
// Convenience function that sets up drawings for all the robot's current
// range devices (using default shape and color info)
drawings.addRobotsRangeDevices(&robot);
// Add our custom drawings
drawings.addDrawing(
// shape: color: size: layer:
new ArDrawingData("polyLine", ArColor(255, 0, 0), 2, 49),
"exampleDrawing_Home",
new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleHomeDrawingNetCallback)
);
drawings.addDrawing(
new ArDrawingData("polyDots", ArColor(0, 255, 0), 250, 48),
"exampleDrawing_Dots",
new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleDotsDrawingNetCallback)
);
drawings.addDrawing(
new ArDrawingData("polySegments", ArColor(0, 0, 0), 4, 52),
"exampleDrawing_XMarksTheSpot",
new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleXDrawingNetCallback)
);
drawings.addDrawing(
new ArDrawingData("polyArrows", ArColor(255, 0, 255), 500, 100),
"exampleDrawing_Arrows",
new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleArrowsDrawingNetCallback)
);
// modes for moving the robot
ArServerModeStop modeStop(&server, &robot);
ArServerModeDrive modeDrive(&server, &robot);
ArServerModeRatioDrive modeRatioDrive(&server, &robot);
ArServerModeWander modeWander(&server, &robot);
modeStop.addAsDefaultMode();
modeStop.activate();
// Connect to the robot.
if (!simpleConnector.connectRobot(&robot))
{
printf("Error: Could not connect to robot... exiting\n");
Aria::shutdown();
return 1;
}
// set up the laser before handing it to the laser mode
simpleConnector.setupLaser(&sick);
robot.enableMotors();
// start the robot cycle running in a background thread
robot.runAsync(true);
// start the laser processing cycle in a background thread
sick.runAsync();
// connect the laser if it was requested
if (!simpleConnector.connectLaser(&sick))
{
printf("Error: Could not connect to laser... exiting\n");
Aria::shutdown();
return 1;
}
// log whatever we wanted to before the runAsync
simpleOpener.checkAndLog();
// run the server thread in the background
server.runAsync();
printf("Server is now running...\n");
// Add a key handler mostly that windows can exit by pressing
// escape, note that the key handler prevents you from running this program
// in the background on Linux.
ArKeyHandler *keyHandler;
if ((keyHandler = Aria::getKeyHandler()) == NULL)
{
keyHandler = new ArKeyHandler;
Aria::setKeyHandler(keyHandler);
robot.lock();
robot.attachKeyHandler(keyHandler);
robot.unlock();
printf("To exit, press escape.\n");
}
robot.waitForRunExit();
Aria::shutdown();
exit(0);
}
// Network callbacks for drawings' current geometry data:
void exampleHomeDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) {
ArNetPacket reply;
// 7 Vertices
reply.byte4ToBuf(7);
// Centered on 0,0.
// X: Y:
reply.byte4ToBuf(-500); reply.byte4ToBuf(500); // Vertex 1
reply.byte4ToBuf(-500); reply.byte4ToBuf(-500); // Vertex 2
reply.byte4ToBuf(500); reply.byte4ToBuf(-500); // Vertex 3
reply.byte4ToBuf(500); reply.byte4ToBuf(500); // Vertex 4
reply.byte4ToBuf(0); reply.byte4ToBuf(1000); // Vertex 5
reply.byte4ToBuf(-500); reply.byte4ToBuf(500); // Vertex 6
reply.byte4ToBuf(500); reply.byte4ToBuf(500); // Vertex 7
client->sendPacketUdp(&reply);
}
void exampleDotsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) {
ArNetPacket reply;
unsigned int tik = ArUtil::getTime() % 200;
double t = tik / 5.0;
// Three dots
reply.byte4ToBuf(3);
// Dot 1:
reply.byte4ToBuf(3000); // X coordinate (mm)
reply.byte4ToBuf((int) (sin(t) * 1000));// Y
// Dot 2:
reply.byte4ToBuf(3500); // X
reply.byte4ToBuf((int) (sin(t+500) * 1000));// Y
// Dot 3:
reply.byte4ToBuf(4000); // X
reply.byte4ToBuf((int) (sin(t+1000) * 1000));// Y
client->sendPacketUdp(&reply);
}
void exampleXDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) {
ArNetPacket reply;
// X marks the spot. 2 line segments, so 4 vertices:
reply.byte4ToBuf(4);
// Segment 1:
reply.byte4ToBuf(-4250); // X1
reply.byte4ToBuf(250); // Y1
reply.byte4ToBuf(-3750); // X2
reply.byte4ToBuf(-250); // Y2
// Segment 2:
reply.byte4ToBuf(-4250); // X1
reply.byte4ToBuf(-250); // Y1
reply.byte4ToBuf(-3750); // X2
reply.byte4ToBuf(250); // Y2
client->sendPacketUdp(&reply);
}
void exampleArrowsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) {
// 1 Arrow that points at the robot
ArNetPacket reply;
reply.byte4ToBuf(1);
reply.byte4ToBuf(0); // Pos. X
reply.byte4ToBuf(700); // Pos. Y
client->sendPacketUdp(&reply);
}
|