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 257
|
#include "Aria.h"
#include "ArNetworking.h"
/** @example serverDemo.cpp Example ArNetworking server providing teleoperation,
* sonar data, control the camera, etc.
*
* This is a basic ArNetworking server. It connects to a robot or simulator,
* including, if available, IRs, gyro, and bumpers. Give the option
* "-connectLaser" on the command line to enable the laser rangefinder,
* if available.
*
* Run "./serverDemo -help" for a full list of command line options.
*
* Once running, connect to this server with a a client such as
* MobileEyes.
*
* This server provides the following services:
* - User login (optional)
* - Basic robot telemetry information
* - Range sensor data values (not used by MobileEyes)
* - Graphics representing range sensor reading positions
* - Teleoperation modes (including safe/unsafe drive modes)
* - Wander mode
* - Various advanced "custom" commands to control logging, debugging, etc.
* - If an ACTS or SAV server is running, forward the video stream
* - Camera control (pan/tilt/zoom) if cameras are available
*
* Note that this program requires a terminal to run -- i.e. you can't run
* it in the background in Linux. To modify it to allow that, remove the key
* handler code in main().
*/
int main(int argc, char **argv)
{
// mandatory init
Aria::init();
//ArLog::init(ArLog::StdOut, ArLog::Verbose);
// set up our parser
ArArgumentParser parser(&argc, argv);
// load the default arguments
parser.loadDefaultArguments();
// robot
ArRobot robot;
// set up our simple connector
ArRobotConnector robotConnector(&parser, &robot);
// add a gyro, it'll see if it should attach to the robot or not
ArAnalogGyro gyro(&robot);
// set up the robot for connecting
if (!robotConnector.connectRobot())
{
printf("Could not connect to robot... exiting\n");
Aria::exit(1);
}
ArDataLogger dataLogger(&robot, "dataLog.txt");
dataLogger.addToConfig(Aria::getConfig());
// our base server object
ArServerBase server;
ArLaserConnector laserConnector(&parser, &robot, &robotConnector);
ArServerSimpleOpener simpleOpener(&parser);
ArClientSwitchManager clientSwitchManager(&server, &parser);
// parse the command line... fail and print the help if the parsing fails
// or if the help was requested
if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
{
Aria::logOptions();
Aria::exit(1);
}
// Set up where we'll look for files such as user/password
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("Bad user/password/permissions file\n");
else
printf("Could not open server port\n");
exit(1);
}
// Range devices:
ArSonarDevice sonarDev;
robot.addRangeDevice(&sonarDev);
ArIRs irs;
robot.addRangeDevice(&irs);
ArBumpers bumpers;
robot.addRangeDevice(&bumpers);
// attach services to the server
ArServerInfoRobot serverInfoRobot(&server, &robot);
ArServerInfoSensor serverInfoSensor(&server, &robot);
ArServerInfoDrawings drawings(&server);
// modes for controlling robot movement
ArServerModeStop modeStop(&server, &robot);
ArServerModeRatioDrive modeRatioDrive(&server, &robot);
ArServerModeWander modeWander(&server, &robot);
modeStop.addAsDefaultMode();
modeStop.activate();
// set up the simple commands
ArServerHandlerCommands commands(&server);
ArServerSimpleComUC uCCommands(&commands, &robot); // send commands directly to microcontroller
ArServerSimpleComMovementLogging loggingCommands(&commands, &robot); // control debug logging
ArServerSimpleComGyro gyroCommands(&commands, &robot, &gyro); // configure gyro
ArServerSimpleComLogRobotConfig configCommands(&commands, &robot); // control more debug logging
ArServerSimpleServerCommands serverCommands(&commands, &server); // control ArNetworking debug logging
ArServerSimpleLogRobotDebugPackets logRobotDebugPackets(&commands, &robot, "."); // debugging tool
// ArServerModeDrive is an older drive mode. ArServerModeRatioDrive is newer and generally performs better,
// but you can use this for old clients if neccesary.
//ArServerModeDrive modeDrive(&server, &robot);
//modeDrive.addControlCommands(&commands); // configure the drive modes (e.g. enable/disable safe drive)
ArServerHandlerConfig serverHandlerConfig(&server, Aria::getConfig()); // make a config handler
ArLog::addToConfig(Aria::getConfig()); // let people configure logging
modeRatioDrive.addToConfig(Aria::getConfig(), "Teleop settings"); // able to configure teleop settings
modeRatioDrive.addControlCommands(&commands);
// Forward video if either ACTS or SAV server are running.
// You can find out more about SAV and ACTS on our website
// http://robots.activmedia.com. ACTS is for color tracking and is
// a separate product. SAV just does software A/V transmitting and is
// free to all our customers. Just run ACTS or SAV server before you
// start this program and this class here will forward video from the
// server to the client.
ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070);
// Control a pan/tilt/zoom camera, if one is installed, and the video
// forwarder was enabled above.
ArPTZ *camera = NULL;
ArServerHandlerCamera *handlerCamera = NULL;
ArCameraCollection *cameraCollection = NULL;
if (videoForwarder.isForwardingVideo())
{
bool invertedCamera = false;
camera = new ArVCC4(&robot, invertedCamera,
ArVCC4::COMM_UNKNOWN, true, true);
camera->init();
cameraCollection = new ArCameraCollection();
cameraCollection->addCamera("Cam1", "VCC4", "Camera", "VCC4");
handlerCamera = new ArServerHandlerCamera("Cam1",
&server,
&robot,
camera,
cameraCollection);
}
// You can use this class to send a set of arbitrary strings
// for MobileEyes to display, this is just a small example
ArServerInfoStrings stringInfo(&server);
Aria::getInfoGroup()->addAddStringCallback(stringInfo.getAddStringFunctor());
Aria::getInfoGroup()->addStringInt(
"Motor Packet Count", 10,
new ArConstRetFunctorC<int, ArRobot>(&robot,
&ArRobot::getMotorPacCount));
/*
Aria::getInfoGroup()->addStringInt(
"Laser Packet Count", 10,
new ArRetFunctorC<int, ArSick>(&sick,
&ArSick::getSickPacCount));
*/
// start the robot running, true means that if we lose connection the run thread stops
robot.runAsync(true);
// connect the laser(s) if it was requested
if (!laserConnector.connectLasers())
{
printf("Could not connect to lasers... exiting\n");
Aria::exit(2);
}
drawings.addRobotsRangeDevices(&robot);
// log whatever we wanted to before the runAsync
simpleOpener.checkAndLog();
// now let it spin off in its own thread
server.runAsync();
printf("Server is now running...\n");
// Add a key handler so that you can exit by pressing
// escape. Note that a key handler prevents you from running
// a program in the background on Linux, since it expects an
// active terminal to read keys from; remove this if you want
// to run it in the background.
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");
}
// Read in parameter files.
std::string configFile = "serverDemoConfig.txt";
Aria::getConfig()->setBaseDirectory("./");
if (Aria::getConfig()->parseFile(configFile.c_str(), true, true))
{
ArLog::log(ArLog::Normal, "Loaded config file %s", configFile.c_str());
}
else
{
if (ArUtil::findFile(configFile.c_str()))
{
ArLog::log(ArLog::Normal,
"Trouble loading configuration file %s, continuing",
configFile.c_str());
}
else
{
ArLog::log(ArLog::Normal,
"No configuration file %s, will try to create if config used",
configFile.c_str());
}
}
clientSwitchManager.runAsync();
robot.lock();
robot.enableMotors();
robot.unlock();
robot.waitForRunExit();
Aria::exit(0);
}
|