00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArServerModeRatioDrive.h"
00029 #include "ArServerHandlerCommands.h"
00030
00031 AREXPORT ArServerModeRatioDrive::ArServerModeRatioDrive(
00032 ArServerBase *server, ArRobot *robot, bool takeControlOnJoystick,
00033 bool useComputerJoystick, bool useRobotJoystick,
00034 bool useServerCommands, const char *name) :
00035 ArServerMode(robot, server, name),
00036 myRatioDriveGroup(robot),
00037 myJoyUserTaskCB(this, &ArServerModeRatioDrive::joyUserTask),
00038 myServerSetSafeDriveCB(this,
00039 &ArServerModeRatioDrive::serverSetSafeDrive),
00040 myServerGetSafeDriveCB(this,
00041 &ArServerModeRatioDrive::serverGetSafeDrive),
00042 myServerRatioDriveCB(this, &ArServerModeRatioDrive::serverRatioDrive),
00043 myRatioFireCB(this, &ArServerModeRatioDrive::ratioFireCallback),
00044 myServerSafeDrivingEnableCB(this,
00045 &ArServerModeRatioDrive::serverSafeDrivingEnable),
00046 myServerSafeDrivingDisableCB(this,
00047 &ArServerModeRatioDrive::serverSafeDrivingDisable)
00048 {
00049 myHandlerCommands = NULL;
00050 myDriveSafely = true;
00051 myTakeControlOnJoystick = takeControlOnJoystick;
00052 myUseComputerJoystick = useComputerJoystick;
00053 myUseRobotJoystick = useRobotJoystick;
00054 myUseServerCommands = useServerCommands;
00055 myUseLocationDependentDevices = true;
00056
00057
00058
00059
00060
00061 myRatioAction = new ArActionRatioInput;
00062 myRatioDriveGroup.addAction(myRatioAction, 50);
00063
00064 myLimiterForward = new ArActionDeceleratingLimiter(
00065 "DeceleratingLimiterForward", true);
00066 myRatioDriveGroup.addAction(myLimiterForward, 40);
00067
00068 myLimiterBackward = new ArActionDeceleratingLimiter(
00069 "DeceleratingLimiterBackward", false);
00070 myRatioDriveGroup.addAction(myLimiterBackward, 39);
00071
00072 myMovementParameters = new ArActionMovementParameters("TeleopMovementParameters", false);
00073 myRatioDriveGroup.addAction(myMovementParameters, 1);
00074
00075 myRatioFireCB.setName("ArServerModeRatioDrive");
00076 myRatioAction->addFireCallback(30, &myRatioFireCB);
00077
00078
00079
00080 if (myServer != NULL && myUseServerCommands)
00081 {
00082 addModeData("ratioDrive", "drives the robot as with a joystick",
00083 &myServerRatioDriveCB,
00084 "double: transRatio; double: rotRatio; double: throttleRatio ",
00085 "none", "Movement", "RETURN_NONE");
00086 myServer->addData("setSafeDrive",
00087 "sets whether we drive the robot safely or not",
00088 &myServerSetSafeDriveCB,
00089 "byte: 1 == drive safely, 0 == drive unsafely",
00090 "none", "UnsafeMovement", "RETURN_NONE");
00091 myServer->addData("getSafeDrive",
00092 "gets whether we drive the robot safely or not",
00093 &myServerGetSafeDriveCB,
00094 "none",
00095 "byte: 1 == driving safely, 0 == driving unsafely",
00096 "Movement", "RETURN_SINGLE");
00097 }
00098
00099 if (myUseComputerJoystick)
00100 {
00101 myJoydrive = new ArRatioInputJoydrive(robot, myRatioAction);
00102 if ((myJoyHandler = Aria::getJoyHandler()) == NULL)
00103 {
00104 myJoyHandler = new ArJoyHandler;
00105 myJoyHandler->init();
00106 Aria::setJoyHandler(myJoyHandler);
00107 }
00108 }
00109 if (myUseRobotJoystick)
00110 {
00111 myRobotJoydrive = new ArRatioInputRobotJoydrive(robot, myRatioAction);
00112 if ((myRobotJoyHandler = Aria::getRobotJoyHandler()) == NULL)
00113 {
00114 myRobotJoyHandler = new ArRobotJoyHandler(robot);
00115 Aria::setRobotJoyHandler(myRobotJoyHandler);
00116 }
00117 }
00118 if (myUseRobotJoystick || myUseComputerJoystick)
00119 {
00120 std::string taskName = name;
00121 taskName += "::joyUserTask";
00122 myRobot->addUserTask(taskName.c_str(), 75, &myJoyUserTaskCB);
00123 }
00124
00125 myPrinting = false;
00126 }
00127
00128 AREXPORT ArServerModeRatioDrive::~ArServerModeRatioDrive()
00129 {
00130
00131 }
00132
00133 AREXPORT void ArServerModeRatioDrive::addToConfig(ArConfig *config,
00134 const char *section)
00135 {
00136 myRatioAction->addToConfig(config, section);
00137 myLimiterForward->addToConfig(config, section, "Forward");
00138 myLimiterBackward->addToConfig(config, section, "Backward");
00139 myMovementParameters->addToConfig(config, section, "Teleop");
00140
00141 }
00142
00143 AREXPORT void ArServerModeRatioDrive::activate(void)
00144 {
00145 ratioDrive(0, 0, 100);
00146 }
00147
00148 AREXPORT void ArServerModeRatioDrive::deactivate(void)
00149 {
00150 myRatioDriveGroup.deactivate();
00151 baseDeactivate();
00152 }
00153
00154 AREXPORT void ArServerModeRatioDrive::setSafeDriving(bool safe, bool internal)
00155 {
00156 if (!internal)
00157 myRobot->lock();
00158
00159 if (safe != myDriveSafely)
00160 {
00161 if (safe)
00162 {
00163 ArLog::log(ArLog::Normal, "%s: Driving safely again", myName.c_str());
00164 }
00165 else
00166 {
00167 ArLog::log(ArLog::Normal, "%s: Driving UNSAFELY", myName.c_str());
00168 }
00169 myNewDriveSafely = true;
00170 }
00171 myDriveSafely = safe;
00172 if (isActive())
00173 ratioDrive(myRatioAction->getTransRatio(), myRatioAction->getRotRatio(),
00174 myRatioAction->getThrottleRatio());
00175 if (!internal)
00176 myRobot->unlock();
00177 }
00178
00179 AREXPORT bool ArServerModeRatioDrive::getSafeDriving(void)
00180 {
00181 return myDriveSafely;
00182 }
00183
00184 AREXPORT void ArServerModeRatioDrive::serverSafeDrivingEnable(void)
00185 {
00186 setSafeDriving(true);
00187 }
00188
00189 AREXPORT void ArServerModeRatioDrive::serverSafeDrivingDisable(void)
00190 {
00191 setSafeDriving(false);
00192 }
00193
00194 AREXPORT void ArServerModeRatioDrive::addControlCommands(ArServerHandlerCommands *handlerCommands)
00195 {
00196 if (!myUseServerCommands)
00197 {
00198 ArLog::log(ArLog::Normal,
00199 "ArServerModeRatioDrive::addControlCommands: Tried to add control commands to a ratio drive not using the server");
00200 return;
00201 }
00202 myHandlerCommands = handlerCommands;
00203 myHandlerCommands->addCommand(
00204 "safeRatioDrivingEnable",
00205 "Enables safe driving with ratioDrive, which will attempt to prevent collisions (default)",
00206 &myServerSafeDrivingEnableCB, "UnsafeMovement");
00207 myHandlerCommands->addCommand(
00208 "safeRatioDrivingDisable",
00209 "Disables safe driving with ratioDrive, this is UNSAFE and will let you drive your robot into things or down stairs, use at your own risk",
00210 &myServerSafeDrivingDisableCB, "UnsafeMovement");
00211 }
00212
00213 AREXPORT void ArServerModeRatioDrive::ratioDrive(double transRatio,
00214 double rotRatio,
00215 double throttleRatio)
00216 {
00217 bool wasActive;
00218 wasActive = isActive();
00219 if (!wasActive && !baseActivate())
00220 return;
00221 if (!wasActive || myNewDriveSafely)
00222 {
00223 myRobot->clearDirectMotion();
00224 if (myDriveSafely)
00225 {
00226 myRatioDriveGroup.activateExclusive();
00227 myMode = "Drive";
00228 ArLog::log(ArLog::Normal, "%s: Driving safely", myName.c_str());
00229 }
00230 else
00231 {
00232 myRobot->deactivateActions();
00233 myRatioAction->activate();
00234 myMode = "UNSAFE Drive";
00235 ArLog::log(ArLog::Normal, "%s: Driving unsafely", myName.c_str());
00236 }
00237 }
00238 myNewDriveSafely = false;
00239 myTransRatio = transRatio;
00240 myRotRatio = rotRatio;
00241 myThrottleRatio = throttleRatio;
00242 setActivityTimeToNow();
00243 if (myPrinting)
00244 printf("cmd %.0f %.0f %.0f\n", transRatio, rotRatio, throttleRatio);
00245
00246 }
00247
00248 AREXPORT void ArServerModeRatioDrive::serverRatioDrive(ArServerClient *client,
00249 ArNetPacket *packet)
00250 {
00251 double transRatio;
00252 double rotRatio;
00253 double throttleRatio;
00254 transRatio = packet->bufToDouble();
00255 rotRatio = packet->bufToDouble();
00256 throttleRatio = packet->bufToDouble();
00257 if (!myDriveSafely && !client->hasGroupAccess("UnsafeMovement"))
00258 serverSafeDrivingEnable();
00259 myRobot->lock();
00260 ratioDrive(transRatio, rotRatio, throttleRatio);
00261 myRobot->unlock();
00262 }
00263
00264 AREXPORT void ArServerModeRatioDrive::serverSetSafeDrive(
00265 ArServerClient *client, ArNetPacket *packet)
00266 {
00267 if (packet->bufToUByte() == 0)
00268 setSafeDriving(false);
00269 else
00270 setSafeDriving(true);
00271 }
00272
00273 AREXPORT void ArServerModeRatioDrive::serverGetSafeDrive(
00274 ArServerClient *client, ArNetPacket *packet)
00275 {
00276 ArNetPacket sendPacket;
00277 if (getSafeDriving())
00278 sendPacket.uByteToBuf(1);
00279 else
00280 sendPacket.uByteToBuf(0);
00281
00282 client->sendPacketTcp(&sendPacket);
00283 }
00284
00285
00286 AREXPORT void ArServerModeRatioDrive::joyUserTask(void)
00287 {
00288
00289
00290 if (myTakeControlOnJoystick && !isActive() &&
00291 ((myUseComputerJoystick && myJoyHandler->haveJoystick() &&
00292 myJoyHandler->getButton(1)) ||
00293 (myUseRobotJoystick && myRobotJoyHandler->gotData() &&
00294 myRobotJoyHandler->getButton1())))
00295 {
00296 if (ArServerMode::getActiveMode() != NULL)
00297 ArLog::log(ArLog::Normal,
00298 "%s: Activating instead of %s because of local joystick",
00299 ArServerMode::getActiveMode()->getName(),
00300 myName.c_str());
00301 else
00302 ArLog::log(ArLog::Normal,
00303 "%s: Activating because of local joystick",
00304 myName.c_str());
00305 activate();
00306 }
00307 }
00308
00309 AREXPORT void ArServerModeRatioDrive::userTask(void)
00310 {
00311
00312
00313 myRobot->forceTryingToMove();
00314
00315
00316
00317 if ((myUseComputerJoystick && myJoyHandler->haveJoystick() &&
00318 myJoyHandler->getButton(1)) ||
00319 (myUseRobotJoystick && myRobotJoyHandler->gotData() &&
00320 myRobotJoyHandler->getButton1()))
00321 {
00322 setActivityTimeToNow();
00323 }
00324
00325
00326 if (!myStatusSetThisCycle)
00327 {
00328 if (myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled())
00329 myStatus = "Stalled";
00330
00331
00332 else if (myRobot->getStallValue())
00333 myStatus = "Bumped";
00334 else if (ArMath::fabs(myRobot->getVel()) < 2 &&
00335 ArMath::fabs(myRobot->getRotVel()) < 2)
00336 myStatus = "Stopped";
00337 else
00338 myStatus = "Driving";
00339 }
00340
00341 myStatusSetThisCycle = false;
00342 }
00343
00344 AREXPORT void ArServerModeRatioDrive::ratioFireCallback(void)
00345 {
00346 if (myPrinting)
00347 printf("Doing %.0f %.0f %.0f\n", myTransRatio, myRotRatio,
00348 myThrottleRatio);
00349 myRatioAction->setRatios(myTransRatio, myRotRatio, myThrottleRatio);
00350 }
00351
00352 AREXPORT void ArServerModeRatioDrive::setUseLocationDependentDevices(
00353 bool useLocationDependentDevices, bool internal)
00354 {
00355 if (!internal)
00356 myRobot->lock();
00357
00358 if (useLocationDependentDevices != myUseLocationDependentDevices)
00359 {
00360 if (useLocationDependentDevices)
00361 {
00362 ArLog::log(ArLog::Normal, "%s: Using location dependent range devices",
00363 myName.c_str());
00364 }
00365 else
00366 {
00367 ArLog::log(ArLog::Normal,
00368 "%s: Not using location dependent range devices",
00369 myName.c_str());
00370 }
00371 myUseLocationDependentDevices = useLocationDependentDevices;
00372 myLimiterForward->setUseLocationDependentDevices(
00373 myUseLocationDependentDevices);
00374 myLimiterBackward->setUseLocationDependentDevices(
00375 myUseLocationDependentDevices);
00376 }
00377 if (!internal)
00378 myRobot->unlock();
00379 }
00380
00381 AREXPORT bool ArServerModeRatioDrive::getUseLocationDependentDevices(void)
00382 {
00383 return myUseLocationDependentDevices;
00384 }
00385
00386
00387
00388