00001
00016 #include <controllers/positionControllers/defaultWheelController.h>
00017
00018 #include <controller/almControllers/sensorFusionComponent/associativeLearning/qLearning.h>
00019
00020 using namespace almendeSensorFusion;
00021
00022 using namespace srAlmende;
00023
00024 DefaultWheelController::DefaultWheelController(const std::string &name,
00025 srCore::RobotActorBase *robotActor): SubController(name, robotActor) {
00026 goalSpeedL = 0;
00027 goalSpeedR = 0;
00028 }
00029
00030 DefaultWheelController::~DefaultWheelController() {
00031
00032 }
00033
00034 CtrlMsg* DefaultWheelController::Act(CtrlMsg *message) {
00035 LOG_WARNING("Not yet implemented!");
00036 outgoingMsg.type = INVALID;
00037 return &outgoingMsg;
00038 }
00039
00046 bool DefaultWheelController::decreaseSpeedSlowly() {
00047
00048 LOG_WARNING("Not correctly implemented!");
00049 float lVel = 0;
00050 float rVel = 0;
00051 float decreaseLevel = 1;
00052 if(lVel != 0 && rVel != 0)
00053 {
00054 if(lVel >= decreaseLevel) lVel -= decreaseLevel;
00055 else if(lVel <= -decreaseLevel) lVel += decreaseLevel;
00056 else if(lVel < decreaseLevel && lVel > -decreaseLevel) lVel = 0;
00057
00058 if(rVel >= decreaseLevel) rVel -= decreaseLevel;
00059 else if(rVel <= -decreaseLevel) rVel += decreaseLevel;
00060 else if(rVel < decreaseLevel && rVel > -decreaseLevel) rVel = 0;
00061
00062
00063
00064 return false;
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 return false;
00076 }
00077
00078 void DefaultWheelController::wander() {
00079 goalSpeedL = QLearning::MAX_SPEED;
00080 goalSpeedR = goalSpeedL;
00081 }
00082
00083 #ifdef MAKE_IT_WORK_IN_THIS_CONTEXT
00084
00085
00086
00087
00088
00089
00090
00091
00092 void DefaultWheelController::driveToSalientLocation(float soundLocation, float imageLocation)
00093 {
00094
00095 int speedL = QLearning::MAX_SPEED;
00096 int speedR = QLearning::MAX_SPEED;
00097
00098 int classifyDistance = 100;
00099
00100 unsigned long sensorLeft;
00101 getSensor("Front Left DistanceSensor")->evaluate(MAKE_PARAMETER_VALUE(&sensorLeft));
00102
00103 unsigned long sensorRight;
00104 getSensor("Front Right DistanceSensor")->evaluate(MAKE_PARAMETER_VALUE(&sensorRight));
00105
00106
00107 sensorLeft = sensorLeft >> 16;
00108 sensorRight = sensorRight >> 16;
00109 bool objectIsGoal = true;
00110
00111
00112 int state = (float(imageLocation)+60.0)*(float(qLearn.NR_STATES)/120.0);
00113 int soundState = (float(soundLocation)+60.0)*(float(qLearn.NR_STATES)/120.0);
00114
00115
00116 if((imageLocation > -5 && imageLocation < 5 ) ||
00117 (imageLocation > -20 && imageLocation < 20 && cameraMotor.lastState == cameraMotor.goalState))
00118 state = cameraMotor.goalState;
00119
00120 osg::Vec3 rot = getRobotRotation();
00121
00122 if(imageLocation == DefaultWheelController::NO_LOCATION)
00123 fusionInput.image = NULL;
00124
00125
00126
00127
00128
00129
00130 if((sensorLeft < classifyDistance) && (sensorRight < classifyDistance))
00131 {
00132 fusionInput.imgRegionX = 0;
00133 fusionInput.imgRegionY = 0;
00134 fusionInput.imgRegionWidth = fusionInput.imageWidth-1;
00135 fusionInput.imgRegionHeight = fusionInput.imageHeight-1;
00136 }
00137 int energyValue = -1;
00138
00139
00140 if(soundLocation != NO_LOCATION && imageLocation != NO_LOCATION && state == soundState && useFusion)
00141 {
00142 energyValue = classifyObject(true);
00143 }
00144
00145 else if(soundLocation != NO_LOCATION && imageLocation != NO_LOCATION)
00146 {
00147
00148 float * tmpAudio = fusionInput.audio;
00149 fusionInput.audio = NULL;
00150 energyValue = classifyObject(true);
00151 fusionInput.audio = tmpAudio;
00152 if(energyValue != -1)
00153 {
00154 if(AVFusion.gotKeypoints() == -1)
00155 {
00156 imageLocation = NO_LOCATION;
00157 state = -3;
00158 energyValue = 0;
00159 }
00160 else if(!useAttention)
00161 state = AVFusion.gotKeypoints();
00162 }
00163
00164 if(energyValue == 1 && robotEnergy == 1)
00165 objectIsGoal = false;
00166 else if(energyValue == 2 && robotEnergy == 2)
00167 objectIsGoal = false;
00168 else if(energyValue == 0 && robotEnergy == 1)
00169 objectIsGoal = false;
00170 else if(energyValue == 0 && robotEnergy == 2)
00171 objectIsGoal = false;
00172 else if(energyValue == -1)
00173 objectIsGoal = false;
00174
00175 if(!objectIsGoal)
00176 {
00177
00178 unsigned char** tmpImage = fusionInput.image;
00179 fusionInput.image = NULL;
00180 int energyValue2 = classifyObject(true);
00181 fusionInput.image = tmpImage;
00182 objectIsGoal = true;
00183 if(energyValue2 == 1 && robotEnergy == 1)
00184 objectIsGoal = false;
00185 else if(energyValue2 == 2 && robotEnergy == 2)
00186 objectIsGoal = false;
00187 else if(energyValue2 == 0 && robotEnergy == 1)
00188 objectIsGoal = false;
00189 else if(energyValue == 0 && robotEnergy == 2)
00190 objectIsGoal = false;
00191 else if(energyValue2 == -1)
00192 objectIsGoal = false;
00193
00194
00195
00196
00197 if(objectIsGoal)
00198 {
00199 energyValue = energyValue2;
00200 state = soundState;
00201 }
00202 else if(energyValue2 == -1 && energyValue != -1)
00203 {
00204 energyValue = energyValue2;
00205 state = soundState;
00206 }
00207 else if(energyValue2 == -1 && energyValue == -1)
00208 {
00209 if(soundState == cameraMotor.goalState)
00210 {
00211 energyValue = energyValue2;
00212 state = soundState;
00213 }
00214 else
00215 {
00216 if(AVFusion.gotKeypoints() == -1 && (sensorLeft < classifyDistance) && (sensorRight < classifyDistance))
00217 {
00218 imageLocation = NO_LOCATION;
00219 state = -3;
00220 energyValue = 0;
00221 }
00222 }
00223 }
00224 else
00225 {
00226 if(AVFusion.gotKeypoints() == -1 && (sensorLeft < classifyDistance) && (sensorRight < classifyDistance))
00227 {
00228 imageLocation = NO_LOCATION;
00229 state = -3;
00230 energyValue = 0;
00231 }
00232 }
00233 }
00234 }
00235 else if(soundLocation != NO_LOCATION || imageLocation != NO_LOCATION)
00236 {
00237 energyValue = classifyObject(true);
00238 if(imageLocation == NO_LOCATION)
00239 state = soundState;
00240 if((!useAttention || soundLocation == NO_LOCATION) && energyValue != -1)
00241 {
00242 if(AVFusion.gotKeypoints() == -1 && (sensorLeft < classifyDistance) && (sensorRight < classifyDistance))
00243 {
00244 imageLocation = NO_LOCATION;
00245 state = -3;
00246 energyValue = 0;
00247 }
00248 else if(!useAttention)
00249 state = AVFusion.gotKeypoints();
00250 }
00251 }
00252
00253 if(soundLocation != NO_LOCATION || imageLocation != NO_LOCATION)
00254 if(robotEnergy == 1)
00255 cout << "My energy is low: ";
00256 else
00257 cout << "My energy is " << powerTime-(time(NULL)-energyTimer) << ": ";
00258
00259 if(energyValue == 1 && robotEnergy == 1)
00260 objectIsGoal = false;
00261 else if(energyValue == 2 && robotEnergy == 2)
00262 objectIsGoal = false;
00263 else if(energyValue == 0 && robotEnergy == 1)
00264 objectIsGoal = false;
00265 else if(energyValue == 0 && robotEnergy == 2)
00266 objectIsGoal = false;
00267 else if(energyValue == 2 && robotEnergy == 1)
00268 {
00269 objectIsGoal = true;
00270 cout << "Energy source found" << endl;
00271 }
00272 else if(energyValue == 1 && robotEnergy == 2)
00273 {
00274 objectIsGoal = true;
00275 cout << "Empty device found" << endl;
00276 }
00277 else if(soundLocation != NO_LOCATION || imageLocation != NO_LOCATION)
00278 {
00279 objectIsGoal = true;
00280 cout << "Unknown device found" << endl;
00281 }
00282 else
00283 objectIsGoal = false;
00284
00285 if(!objectIsGoal)
00286 {
00287 if(soundLocation != NO_LOCATION || imageLocation != NO_LOCATION)
00288 {
00289 if(robotEnergy == 2)
00290 std::cout << "Ignore object: doesn't need energy" << std::endl;
00291 if(robotEnergy == 1)
00292 std::cout << "Ignore object, has no energy" << std::endl;
00293 soundLocation = NO_LOCATION;
00294 imageLocation = NO_LOCATION;
00295 }
00296 }
00297
00298 if(soundDrive)
00299 {
00300 state = soundState;
00301 imageLocation = soundLocation;
00302 }
00303
00304
00305
00306 osg::Vec3 pos = getRobotPosition();
00307 if(rot[2] <= -90)
00308 {
00309
00310 resetRobotFlag = true;
00311 goalSpeedL = 0;
00312 goalSpeedR = 0;
00313 return;
00314 }
00315
00316 if(imageLocation != NO_LOCATION || soundLocation != NO_LOCATION)
00317 {
00318 std::cout << "state: " << state << std::endl;
00319
00320
00321 if(false)
00322 {
00323
00324 speedL = cameraMotor.IOStateMap[state].maxX;
00325 speedR = cameraMotor.IOStateMap[state].maxY;
00326 }
00327 else
00328 {
00329 float lVel = getActuator("LeftScrew")->getVel(getDeltaSimTime());
00330 float rVel = getActuator("RightScrew")->getVel(getDeltaSimTime());
00331 float accelValue = 0.4;
00332 if(state==0)
00333 {
00334 lVel = -fabs(lVel);
00335 rVel = -fabs(rVel);
00336 lVel -= accelValue;
00337 rVel += accelValue;
00338 if (rVel >= 0) rVel = -accelValue;
00339 if (rVel < -QLearning::MAX_SPEED) rVel = -QLearning::MAX_SPEED;
00340 if (lVel >= 0) lVel = -0.1;
00341 if (lVel < -QLearning::MAX_SPEED) lVel = -QLearning::MAX_SPEED;
00342
00343 rVel = -accelValue;
00344 lVel = -1;
00345 }
00346
00347 else
00348 {
00349 lVel = fabs(lVel);
00350 rVel = fabs(rVel);
00351 lVel += accelValue;
00352 rVel -= accelValue;
00353 if (rVel > QLearning::MAX_SPEED) rVel = QLearning::MAX_SPEED;
00354 if (rVel < 0) rVel = 0;
00355 if (lVel > QLearning::MAX_SPEED) lVel = QLearning::MAX_SPEED;
00356 if (lVel < 0) lVel = 0;
00357 rVel = 0;
00358 lVel = 1;
00359 }
00360 speedL = lVel;
00361 speedR = rVel;
00362 }
00363
00364
00365 if(state == cameraMotor.goalState)
00366 {
00367
00368 speedL = QLearning::MAX_SPEED;
00369 speedR = QLearning::MAX_SPEED;
00370 }
00371
00372 else
00373 {
00374
00375 if(false)
00376 {
00377 speedL -= QLearning::MAX_SPEED;
00378 speedR -= QLearning::MAX_SPEED;
00379 }
00380 }
00381
00382
00383
00384 goalSpeedL = speedL;
00385 goalSpeedR = speedR;
00386 trackTimer = time(NULL);
00387 }
00388
00389
00390
00391 if ((sensorLeft < classifyDistance) && (sensorRight < classifyDistance) && state == cameraMotor.goalState && objectIsGoal)
00392 {
00393 goalSpeedL = 0;
00394 goalSpeedR = 0;
00395
00396
00397
00398 if(soundState != cameraMotor.goalState || soundLocation == NO_LOCATION)
00399 {
00400 fusionInput.audio = NULL;
00401 if(AVFusion.gotKeypoints() == -1)
00402 return;
00403 }
00404
00405
00406 if(time(NULL) - otherRobotEnergyTimer > 1)
00407 {
00408
00409
00410 if(energyValue == 1 && energyAtPos(false) == 2 && robotEnergy == 2)
00411 experiment.setGaveNoEnergy();
00412 if(energyValue == 2 && energyAtPos(false) == 1 && robotEnergy == 1)
00413 experiment.setGotNoEnergy();
00414 classifyObject(false);
00415 }
00416 }
00417 }
00418
00419
00420 void DefaultWheelController::obstacleAvoidance()
00421 {
00422 float lVel = getActuator("LeftScrew")->getVel(getDeltaSimTime());
00423 float rVel = getActuator("RightScrew")->getVel(getDeltaSimTime());
00424
00425 unsigned long sensorLeft;
00426 getSensor("Front Left DistanceSensor")->evaluate(MAKE_PARAMETER_VALUE(&sensorLeft));
00427
00428 unsigned long sensorRight;
00429 getSensor("Front Right DistanceSensor")->evaluate(MAKE_PARAMETER_VALUE(&sensorRight));
00430
00431 unsigned long sensorFrontRight;
00432 getSensor("Right Front DistanceSensor")->evaluate(MAKE_PARAMETER_VALUE(&sensorFrontRight));
00433
00434 unsigned long sensorFrontLeft;
00435 getSensor("Left Front DistanceSensor")->evaluate(MAKE_PARAMETER_VALUE(&sensorFrontLeft));
00436
00437
00438 sensorLeft = sensorLeft >> 16;
00439 sensorRight = sensorRight >> 16;
00440 sensorFrontLeft = sensorFrontLeft >> 16;
00441 sensorFrontRight = sensorFrontRight >> 16;
00442
00443 float accelValue = 0.2;
00444 float distanceValue = 100;
00445 float maxSpeed = 2;
00446
00447 if ((sensorLeft > distanceValue) && (sensorRight > distanceValue) && sensorFrontLeft > 50 && sensorFrontRight > 50)
00448 {
00449 lVel = goalSpeedL;
00450 rVel = goalSpeedR;
00451 }
00452
00453 else if ((sensorLeft >= sensorRight) && sensorFrontLeft >= 95)
00454 {
00455 lVel = -fabs(lVel);
00456 rVel = -fabs(rVel);
00457 lVel -= accelValue;
00458 rVel += accelValue;
00459 if (rVel >= 0) rVel = -accelValue;
00460 if (rVel < -maxSpeed) rVel = -maxSpeed;
00461 if (lVel >= 0) lVel = -0.1;
00462 if (lVel < -maxSpeed) lVel = -maxSpeed;
00463 }
00464
00465 else if (sensorFrontRight >= 95)
00466 {
00467 lVel = fabs(lVel);
00468 rVel = fabs(rVel);
00469 lVel += accelValue;
00470 rVel -= accelValue;
00471 if (rVel > maxSpeed) rVel = maxSpeed;
00472 if (rVel < 0) rVel = 0;
00473 if (lVel > maxSpeed) lVel = maxSpeed;
00474 if (lVel < 0) lVel = 0;
00475 }
00476 else
00477 {
00478 srand( time(NULL) );
00479 cout << "random turn" << endl;
00480 if(rand()%2 == 0)
00481 {
00482 lVel = -qLearn.MAX_SPEED;
00483 rVel = -0.1;
00484 }
00485 else
00486 {
00487 lVel = qLearn.MAX_SPEED;
00488 rVel = 0;
00489 }
00490 }
00491 goalSpeedL = lVel;
00492 goalSpeedR = rVel;
00493 }
00494
00495
00496
00497
00498
00499 void DefaultWheelController::learnToDriveFunction(float soundLocation, float imageLocation)
00500 {
00501
00502 int speedL = QLearning::MAX_SPEED;
00503 int speedR = QLearning::MAX_SPEED;
00504
00505
00506 int state = (float(imageLocation)+60.0)*(float(qLearn.NR_STATES)/120.0);
00507
00508
00509
00510 osg::Vec3 rot = getRobotRotation();
00511 cout << " state: " << state << " ";
00512
00513
00514 if(cameraMotor.lastState == cameraMotor.goalState && state == cameraMotor.goalState)
00515 {
00516 cout << " Still at the goal state reset" << endl;
00517
00518 resetRobotFlag = true;
00519 goalSpeedL = 0;
00520 goalSpeedR = 0;
00521 return;
00522 }
00523
00524
00525
00526
00527 if(imageLocation > (cameraMotor.goalValue-5) && imageLocation < (cameraMotor.goalValue+5) )
00528 state = cameraMotor.goalState;
00529
00530
00531 if(rot[2] < -90)
00532 imageLocation = NO_LOCATION;
00533
00534
00535
00536 if(imageLocation != NO_LOCATION)
00537 {
00538 qLearn.learn(&cameraMotor, state, imageLocation, &speedL, &speedR);
00539 if(state == cameraMotor.goalState)
00540 {
00541 goalSpeedL = 0;
00542 goalSpeedR = 0;
00543 cout << "Goal found, speed to 0 speedL:" << speedL << " speedR:" << speedR << endl;
00544 }
00545 else
00546 {
00547 goalSpeedL = speedL-QLearning::MAX_SPEED;
00548 goalSpeedR = speedR-QLearning::MAX_SPEED;
00549 cout << "Use next speed values L:" << goalSpeedL << " R:" << goalSpeedR << endl;
00550 }
00551 }
00552
00553 else
00554 {
00555 qLearn.learn(&cameraMotor, -((QLearning::NR_STATES/2)+1), imageLocation, &speedL, &speedR);
00556 cout << "no image location reset" << endl;
00557
00558 resetRobotFlag = true;
00559 goalSpeedL = 0;
00560 goalSpeedR = 0;
00561 return;
00562 }
00563 }
00564
00565 void DetectRobotVisually::trackGoal()
00566 {
00567
00568
00569 int waitTime = 2;
00570 if((time(NULL) - trackTimer) < waitTime)
00571 {
00572 goalSpeedL = getActuator("LeftScrew")->getVel(getDeltaSimTime());
00573 goalSpeedR = getActuator("RightScrew")->getVel(getDeltaSimTime());
00574 }
00575
00576
00577
00578
00579
00580
00581
00582 }
00583
00584
00585 #endif
00586
00587