- Timestamp:
- May 31, 2010, 5:31:50 AM (15 years ago)
- Location:
- code/branches/presentation3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/presentation3
- Property svn:mergeinfo changed
/code/branches/ai (added) merged: 6592,6601,6640,6683,6695-6696,6782,6795,6832-6833,6847,6850,6854,6888,6891,6918-6919,6958,6978,6986,6991,6997,7029,7033
- Property svn:mergeinfo changed
-
code/branches/presentation3/src/orxonox/controllers/ArtificialController.cc
r7031 r7034 23 23 * Fabian 'x3n' Landau 24 24 * Co-authors: 25 * ...25 * Dominik Solenicki 26 26 * 27 27 */ … … 29 29 #include "ArtificialController.h" 30 30 31 #include <vector> 31 32 #include "core/CoreIncludes.h" 33 #include "core/XMLPort.h" 32 34 #include "worldentities/ControllableEntity.h" 33 35 #include "worldentities/pawns/Pawn.h" … … 36 38 #include "gametypes/Dynamicmatch.h" 37 39 #include "controllers/WaypointPatrolController.h" 40 #include "controllers/NewHumanController.h" 41 #include "controllers/DroneController.h" 42 #include "util/Math.h" 43 #include "core/ConsoleCommand.h" 38 44 39 45 namespace orxonox 40 46 { 47 SetConsoleCommand(ArtificialController, formationflight, true); 48 SetConsoleCommand(ArtificialController, masteraction, true); 49 SetConsoleCommand(ArtificialController, followme, true); 50 SetConsoleCommand(ArtificialController, passivebehaviour, true); 51 SetConsoleCommand(ArtificialController, formationsize, true); 52 53 static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7; 54 static const int FORMATION_LENGTH = 130; 55 static const int FORMATION_WIDTH = 110; 56 static const int FREEDOM_COUNT = 4; //seconds the slaves in a formation will be set free when master attacks an enemy 57 static const float SPEED_MASTER = 0.6f; 58 static const float ROTATEFACTOR_MASTER = 0.2f; 59 static const float SPEED_FREE = 0.8f; 60 static const float ROTATEFACTOR_FREE = 0.8f; 61 static const int SECONDS_TO_FOLLOW_HUMAN = 100; 62 41 63 ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator) 42 64 { … … 44 66 45 67 this->target_ = 0; 68 this->formationFlight_ = true; 69 this->passive_ = false; 70 this->maxFormationSize_ = STANDARD_MAX_FORMATION_SIZE; 71 this->myMaster_ = 0; 72 this->freedomCount_ = 0; 73 this->team_ = -1; 74 this->state_ = FREE; 75 this->specificMasterAction_ = NONE; 76 this->specificMasterActionHoldCount_ = 0; 46 77 this->bShooting_ = false; 47 78 this->bHasTargetPosition_ = false; 48 79 this->targetPosition_ = Vector3::ZERO; 80 this->humanToFollow_ = NULL; 49 81 50 82 this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this)); … … 54 86 { 55 87 } 88 89 void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode) 90 { 91 SUPER(ArtificialController, XMLPort, xmlelement, mode); 92 93 XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1); 94 XMLPortParam(ArtificialController, "formationflight", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(true); 95 XMLPortParam(ArtificialController, "formation_size", setFormationSize, getFormationSize, xmlelement, mode).defaultValues(STANDARD_MAX_FORMATION_SIZE); 96 } 97 98 // Documentation only here to get a faster overview for creating a useful documentation... 99 100 /** 101 @brief Activates / deactivates formationflight behaviour 102 @param form activate formflight if form is true 103 */ 104 void ArtificialController::formationflight(bool form) 105 { 106 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 107 { 108 if (!it->getController()) 109 continue; 110 111 ArtificialController *aiController = orxonox_cast<ArtificialController*>(it->getController()); 112 113 if(aiController) 114 { 115 aiController->formationFlight_ = form; 116 if(!form) 117 { 118 if(aiController->state_ == MASTER) aiController->freeSlaves(); 119 aiController->state_ = FREE; 120 } 121 } 122 } 123 } 124 125 /** 126 @brief Get all masters to do a "specific master action" 127 @param action which action to perform (integer, so it can be called with a console command (tmp solution)) 128 */ 129 void ArtificialController::masteraction(int action) 130 { 131 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 132 { 133 if (!it->getController()) 134 continue; 135 136 ArtificialController *aiController = orxonox_cast<ArtificialController*>(it->getController()); 137 138 if(aiController && aiController->state_ == MASTER) 139 { 140 if (action == 1) 141 aiController->spinInit(); 142 if (action == 2) 143 aiController->turn180Init(); 144 } 145 } 146 } 147 148 /** 149 @brief A human player gets followed by its nearest master. Initiated by console command, intended for demonstration puproses. Does not work at the moment. 150 */ 151 void ArtificialController::followme() 152 { 153 154 Pawn *humanPawn = NULL; 155 NewHumanController *currentHumanController = NULL; 156 std::vector<ArtificialController*> allMasters; 157 158 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 159 { 160 if (!it->getController()) 161 continue; 162 163 currentHumanController = orxonox_cast<NewHumanController*>(it->getController()); 164 165 if(currentHumanController) humanPawn = *it; 166 167 ArtificialController *aiController = orxonox_cast<ArtificialController*>(it->getController()); 168 169 if(aiController || aiController->state_ == MASTER) 170 allMasters.push_back(aiController); 171 172 } 173 174 if((humanPawn != NULL) && (allMasters.size() != 0)) 175 { 176 float posHuman = humanPawn->getPosition().length(); 177 float distance = 0.0f; 178 float minDistance = FLT_MAX; 179 int index = 0; 180 int i = 0; 181 182 for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++) 183 { 184 distance = posHuman - (*it)->getControllableEntity()->getPosition().length(); 185 if(distance < minDistance) index = i; 186 } 187 allMasters[index]->humanToFollow_ = humanPawn; 188 // allMasters[index]->followHuman(humanPawn, false); 189 } 190 191 } 192 193 /** 194 @brief Sets shooting behaviour of pawns. 195 @param passive if true, bots won't shoot. 196 */ 197 void ArtificialController::passivebehaviour(bool passive) 198 { 199 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 200 { 201 if (!it->getController()) 202 continue; 203 204 ArtificialController *aiController = orxonox_cast<ArtificialController*>(it->getController()); 205 206 if(aiController) 207 { 208 aiController->passive_ = passive; 209 } 210 } 211 } 212 213 214 /** 215 @brief Sets maximal formation size 216 @param size maximal formation size. 217 */ 218 void ArtificialController::formationsize(int size) 219 { 220 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 221 { 222 if (!it->getController()) 223 continue; 224 225 ArtificialController *aiController = orxonox_cast<ArtificialController*>(it->getController()); 226 227 if(aiController) 228 { 229 aiController->maxFormationSize_ = size; 230 } 231 } 232 } 233 234 /** 235 @brief Gets called when ControllableEntity is being changed. Resets the bot when it dies. 236 */ 237 void ArtificialController::changedControllableEntity() 238 { 239 if(!getControllableEntity()) 240 { 241 if (this->state_ == SLAVE) unregisterSlave(); 242 if (this->state_ == MASTER) setNewMasterWithinFormation(); 243 this->slaves_.clear(); 244 this->state_ = FREE; 245 246 } 247 } 248 56 249 57 250 void ArtificialController::moveToPosition(const Vector3& target) … … 63 256 float distance = (target - this->getControllableEntity()->getPosition()).length(); 64 257 65 if (this->target_ || distance > 10) 66 { 67 // Multiply with 0.8 to make them a bit slower 68 this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x); 69 this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y); 70 } 71 72 if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 73 this->getControllableEntity()->moveFrontBack(-0.5f); // They don't brake with full power to give the player a chance 74 else 75 this->getControllableEntity()->moveFrontBack(0.8f); 258 259 if(this->state_ == FREE) 260 { 261 if (this->target_ || distance > 10) 262 { 263 // Multiply with 0.8 to make them a bit slower 264 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x); 265 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y); 266 } 267 268 if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 269 { 270 this->getControllableEntity()->moveFrontBack(-0.05f); // They don't brake with full power to give the player a chance 271 } else this->getControllableEntity()->moveFrontBack(SPEED_FREE); 272 } 273 274 275 276 if(this->state_ == MASTER) 277 { 278 if (this->target_ || distance > 10) 279 { 280 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x); 281 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y); 282 } 283 284 if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 285 { 286 this->getControllableEntity()->moveFrontBack(-0.05f); 287 } else this->getControllableEntity()->moveFrontBack(SPEED_MASTER); 288 } 289 290 291 292 if(this->state_ == SLAVE) 293 { 294 295 this->getControllableEntity()->rotateYaw(-2.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x); 296 this->getControllableEntity()->rotatePitch(2.0f * ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y); 297 298 if (distance < 300) 299 { 300 if (distance < 40) 301 { 302 this->getControllableEntity()->moveFrontBack(0.8f*SPEED_MASTER); 303 } else this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER); 304 305 } else { 306 this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER + distance/300.0f); 307 } 308 } 76 309 } 77 310 … … 80 313 this->moveToPosition(this->targetPosition_); 81 314 } 315 316 int ArtificialController::getState() 317 { 318 return this->state_; 319 } 320 321 /** 322 @brief Unregisters a slave from its master. Called by a slave. 323 */ 324 void ArtificialController::unregisterSlave() { 325 if(myMaster_) 326 { 327 std::vector<ArtificialController*>::iterator it = std::find(myMaster_->slaves_.begin(), myMaster_->slaves_.end(), this); 328 if( it != myMaster_->slaves_.end() ) 329 myMaster_->slaves_.erase(it); 330 } 331 } 332 333 void ArtificialController::searchNewMaster() 334 { 335 336 if (!this->getControllableEntity()) 337 return; 338 339 this->targetPosition_ = this->getControllableEntity()->getPosition(); 340 this->forgetTarget(); 341 int teamSize = 0; 342 //go through all pawns 343 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 344 { 345 346 //same team? 347 if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype())) 348 continue; 349 350 //has it an ArtificialController? 351 if (!it->getController()) 352 continue; 353 354 //is pawn oneself? 355 if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity()) 356 continue; 357 358 teamSize++; 359 360 ArtificialController *newMaster = orxonox_cast<ArtificialController*>(it->getController()); 361 362 //is it a master? 363 if (!newMaster || newMaster->getState() != MASTER) 364 continue; 365 366 float distance = (it->getPosition() - this->getControllableEntity()->getPosition()).length(); 367 368 // is pawn in range? 369 if (distance < 5000) 370 { 371 if(newMaster->slaves_.size() > this->maxFormationSize_) continue; 372 373 for(std::vector<ArtificialController*>::iterator itSlave = this->slaves_.begin(); itSlave != this->slaves_.end(); itSlave++) 374 { 375 (*itSlave)->myMaster_ = newMaster; 376 newMaster->slaves_.push_back(*itSlave); 377 } 378 this->slaves_.clear(); 379 this->state_ = SLAVE; 380 381 this->myMaster_ = newMaster; 382 newMaster->slaves_.push_back(this); 383 384 break; 385 } 386 } 387 388 if (state_ != SLAVE && teamSize != 0) state_ = MASTER; 389 390 } 391 392 /** 393 @brief Commands the slaves of a master into a formation. Called by a master. 394 */ 395 void ArtificialController::commandSlaves() 396 { 397 if(this->state_ != MASTER) return; 398 399 Quaternion orient = this->getControllableEntity()->getOrientation(); 400 Vector3 dest = this->getControllableEntity()->getPosition(); 401 402 // 1 slave: follow 403 if (this->slaves_.size() == 1) 404 { 405 dest += 4*orient*WorldEntity::BACK; 406 this->slaves_.front()->setTargetPosition(dest); 407 } 408 else 409 { 410 dest += 1.0f*orient*WorldEntity::BACK; 411 Vector3 pos = Vector3::ZERO; 412 int i = 1; 413 414 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 415 { 416 pos = Vector3::ZERO; 417 if (i <= 1) pos += dest + FORMATION_WIDTH*(orient*WorldEntity::LEFT); 418 if (i == 2) pos += dest + FORMATION_WIDTH*(orient*WorldEntity::RIGHT); 419 if (i == 3) pos += dest + FORMATION_WIDTH*(orient*WorldEntity::UP); 420 if (i >= 4) 421 { 422 pos += dest + FORMATION_WIDTH*(orient*WorldEntity::DOWN); 423 i = 1; 424 dest += FORMATION_LENGTH*(orient*WorldEntity::BACK); 425 (*it)->setTargetPosition(pos); 426 continue; 427 } 428 i++; 429 (*it)->setTargetPosition(pos); 430 } 431 } 432 } 433 434 /** 435 @brief Sets a new master within the formation. Called by a master. 436 */ 437 void ArtificialController::setNewMasterWithinFormation() 438 { 439 if(this->state_ != MASTER) return; 440 441 if (this->slaves_.empty()) 442 return; 443 444 ArtificialController *newMaster = this->slaves_.back(); 445 this->slaves_.pop_back(); 446 447 if(!newMaster) return; 448 newMaster->state_ = MASTER; 449 newMaster->slaves_ = this->slaves_; 450 451 this->slaves_.clear(); 452 this->state_ = SLAVE; 453 this->myMaster_ = newMaster; 454 455 for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++) 456 { 457 (*it)->myMaster_ = newMaster; 458 } 459 460 } 461 462 /** 463 @brief Frees all slaves form a master. Called by a master. 464 */ 465 void ArtificialController::freeSlaves() 466 { 467 if(this->state_ != MASTER) return; 468 469 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 470 { 471 (*it)->state_ = FREE; 472 } 473 this->slaves_.clear(); 474 } 475 476 /** 477 @brief Master sets its slaves free for @var FREEDOM_COUNT seconds. 478 */ 479 void ArtificialController::forceFreeSlaves() 480 { 481 if(this->state_ != MASTER) return; 482 483 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 484 { 485 (*it)->state_ = FREE; 486 (*it)->forceFreedom(); 487 (*it)->targetPosition_ = this->targetPosition_; 488 (*it)->bShooting_ = true; 489 // (*it)->getControllableEntity()->fire(0);// fire once for fun 490 } 491 } 492 493 void ArtificialController::loseMasterState() 494 { 495 this->freeSlaves(); 496 this->state_ = FREE; 497 } 498 499 500 void ArtificialController::forceFreedom() 501 { 502 this->freedomCount_ = FREEDOM_COUNT; 503 } 504 505 /** 506 @brief Checks wether caller has been forced free, decrements time to stay forced free. 507 @return true if forced free. 508 */ 509 bool ArtificialController::forcedFree() 510 { 511 if(this->freedomCount_ > 0) 512 { 513 this->freedomCount_--; 514 return true; 515 } else return false; 516 } 517 518 /** 519 @brief Used to continue a "specific master action" for a certain time and resuming normal behaviour after. 520 */ 521 void ArtificialController::specificMasterActionHold() 522 { 523 if(this->state_ != MASTER) return; 524 525 if (specificMasterActionHoldCount_ == 0) 526 { 527 this->specificMasterAction_ = NONE; 528 this->searchNewTarget(); 529 } 530 else specificMasterActionHoldCount_--; 531 } 532 533 /** 534 @brief Master initializes a 180 degree turn. Leads to a "specific master action". 535 */ 536 void ArtificialController::turn180Init() 537 { 538 COUT(0) << "~turnInit" << std::endl; 539 if(this->state_ != MASTER) return; 540 541 Quaternion orient = this->getControllableEntity()->getOrientation(); 542 543 this->setTargetPosition(this->getControllableEntity()->getPosition() + 1000.0f*orient*WorldEntity::BACK); 544 545 this->specificMasterActionHoldCount_ = 4; 546 547 this->specificMasterAction_ = TURN180; 548 } 549 550 /** 551 @brief Execute the 180 degree turn. Called within tick. 552 */ 553 void ArtificialController::turn180() 554 { 555 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->targetPosition_); 556 557 this->getControllableEntity()->rotateYaw(-2.0f * sgn(coord.x) * coord.x*coord.x); 558 this->getControllableEntity()->rotatePitch(2.0f * sgn(coord.y) * coord.y*coord.y); 559 560 this->getControllableEntity()->moveFrontBack(SPEED_MASTER); 561 } 562 563 /** 564 @brief Master initializes a spin around its looking direction axis. Leads to a "specific master action". Not yet implemented. 565 */ 566 void ArtificialController::spinInit() 567 { 568 COUT(0) << "~spinInit" << std::endl; 569 if(this->state_ != MASTER) return; 570 this->specificMasterAction_ = SPIN; 571 this->specificMasterActionHoldCount_ = 10; 572 } 573 574 /** 575 @brief Execute the spin. Called within tick. 576 */ 577 void ArtificialController::spin() 578 { 579 this->moveToTargetPosition(); 580 this->getControllableEntity()->rotateRoll(0.8f); 581 } 582 583 /** 584 @brief Master begins to follow a human player. Is a "specific master action". 585 @param humanController human to follow. 586 @param alaways follows human forever if true, else it follows it for @var SECONDS_TO_FOLLOW_HUMAN seconds. 587 */ 588 void ArtificialController::followHumanInit(Pawn* human, bool always) 589 { 590 COUT(0) << "~followInit" << std::endl; 591 if (human == NULL || this->state_ != MASTER) 592 return; 593 594 this->specificMasterAction_ = FOLLOWHUMAN; 595 596 this->setTarget(human); 597 if (!always) 598 this->specificMasterActionHoldCount_ = SECONDS_TO_FOLLOW_HUMAN; 599 else 600 this->specificMasterActionHoldCount_ = INT_MAX; //for now... 601 602 } 603 604 /** 605 @brief Follows target with adjusted speed. Called within tick. 606 */ 607 void ArtificialController::follow() 608 { 609 this->moveToTargetPosition(); //standard position apprach for now. 610 } 611 612 82 613 83 614 void ArtificialController::setTargetPosition(const Vector3& target) … … 145 676 this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO); 146 677 147 Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());678 Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity()); 148 679 if (pawn) 149 680 pawn->setAimPosition(this->targetPosition_); … … 189 720 int team2 = -1; 190 721 191 if (entity1->getXMLController()) 192 { 193 WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity1->getXMLController()); 194 if (wpc) 195 team1 = wpc->getTeam(); 196 } 197 if (entity2->getXMLController()) 198 { 199 WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity2->getXMLController()); 200 if (wpc) 201 team2 = wpc->getTeam(); 722 Controller* controller = 0; 723 if (entity1->getController()) 724 controller = entity1->getController(); 725 else 726 controller = entity1->getXMLController(); 727 if (controller) 728 { 729 ArtificialController* ac = orxonox_cast<ArtificialController*>(controller); 730 if (ac) 731 team1 = ac->getTeam(); 732 } 733 734 if (entity1->getController()) 735 controller = entity1->getController(); 736 else 737 controller = entity1->getXMLController(); 738 if (controller) 739 { 740 ArtificialController* ac = orxonox_cast<ArtificialController*>(controller); 741 if (ac) 742 team2 = ac->getTeam(); 202 743 } 203 744 … … 246 787 } 247 788 789 DroneController* droneController = 0; 790 droneController = orxonox_cast<DroneController*>(entity1->getController()); 791 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2) 792 return true; 793 droneController = orxonox_cast<DroneController*>(entity2->getController()); 794 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1) 795 return true; 796 DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController()); 797 DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController()); 798 if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner()) 799 return true; 800 248 801 Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype); 249 802 if (dynamic)
Note: See TracChangeset
for help on using the changeset viewer.