Changeset 2860 for code/trunk/src/orxonox/objects
- Timestamp:
- Mar 27, 2009, 7:11:30 PM (16 years ago)
- Location:
- code/trunk/src/orxonox/objects/controllers
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/orxonox/objects/controllers/PongAI.cc
r2857 r2860 34 34 #include "objects/worldentities/ControllableEntity.h" 35 35 #include "objects/worldentities/PongBall.h" 36 #include "tools/Timer.h" 36 37 37 38 namespace orxonox … … 39 40 CreateUnloadableFactory(PongAI); 40 41 42 const static float MAX_REACTION_TIME = 0.4; 43 41 44 PongAI::PongAI(BaseObject* creator) : Controller(creator) 42 45 { … … 44 47 45 48 this->ball_ = 0; 49 this->ballDirection_ = Vector2::ZERO; 50 this->ballEndPosition_ = 0; 46 51 this->randomOffset_ = 0; 47 52 this->relHysteresisOffset_ = 0.02; 48 53 this->strength_ = 0.5; 54 this->movement_ = 0; 49 55 50 56 this->setConfigValues(); 57 58 // this->randomOffsetTimer_.setTimer(MAX_REACTION_TIME * (1 - this->strength_), false, this, createExecutor(createFunctor(&PongAI::calculateRandomOffset))); 59 // this->ballEndPositionTimer_.setTimer(MAX_REACTION_TIME * (1 - this->strength_), false, this, createExecutor(createFunctor(&PongAI::calculateBallEndPosition))); 60 // this->randomOffsetTimer_.stopTimer(); 61 // this->ballEndPositionTimer_.stopTimer(); 62 } 63 64 PongAI::~PongAI() 65 { 66 for (std::list<std::pair<Timer<PongAI>*, char> >::iterator it = this->reactionTimers_.begin(); it != this->reactionTimers_.end(); ++it) 67 delete (*it).first; 51 68 } 52 69 … … 61 78 return; 62 79 63 ControllableEntity* bat = this->getControllableEntity(); 64 65 Vector3 mypos = bat->getPosition(); 80 Vector3 mypos = this->getControllableEntity()->getPosition(); 66 81 Vector3 ballpos = this->ball_->getPosition(); 67 82 Vector3 ballvel = this->ball_->getVelocity(); 68 83 float hysteresisOffset = this->relHysteresisOffset_ * this->ball_->getFieldDimension().y; 69 84 85 char move = 0; 86 70 87 // Check in which direction the ball is flying 71 88 if ((mypos.x > 0 && ballvel.x < 0) || (mypos.x < 0 && ballvel.x > 0)) 72 89 { 73 90 // Ball is flying away 74 this->calculateRandomOffset(); 91 this->ballDirection_.x = -1; 92 this->ballDirection_.y = 0; 75 93 76 94 if (mypos.z > hysteresisOffset) 77 bat->moveFrontBack(1);95 move = 1; 78 96 else if (mypos.z < -hysteresisOffset) 79 bat->moveFrontBack(-1);97 move = -1; 80 98 } 81 99 else if (ballvel.x == 0) 82 100 { 83 101 // Ball is standing still 84 this->calculateRandomOffset(); 102 this->ballDirection_.x = 0; 103 this->ballDirection_.y = 0; 85 104 } 86 105 else 87 106 { 88 107 // Ball is approaching 89 float desiredZValue = ballpos.z + this->randomOffset_; 90 91 if (mypos.z > desiredZValue + hysteresisOffset) 92 bat->moveFrontBack(1); 93 else if (mypos.z < desiredZValue - hysteresisOffset) 94 bat->moveFrontBack(-1); 95 } 108 if (this->ballDirection_.x != 1) 109 { 110 this->ballDirection_.x = 1; 111 this->ballDirection_.y = sgn(ballvel.z); 112 this->ballEndPosition_ = 0; 113 this->randomOffset_ = 0; 114 115 this->calculateRandomOffset(); 116 this->calculateBallEndPosition(); 117 //this->randomOffsetTimer_.setInterval(MAX_REACTION_TIME * (1 - this->strength_)); 118 //this->ballEndPositionTimer_.setInterval(MAX_REACTION_TIME * (1 - this->strength_)); 119 //this->randomOffsetTimer_.startTimer(); 120 //this->ballEndPositionTimer_.startTimer(); 121 } 122 123 if (this->ballDirection_.y != sgn(ballvel.z)) 124 { 125 this->ballDirection_.y = sgn(ballvel.z); 126 127 this->calculateBallEndPosition(); 128 //this->ballEndPositionTimer_.startTimer(); 129 } 130 131 float desiredZValue = /*((1 - this->strength_) * ballpos.z) + */(/*this->strength_ * */this->ballEndPosition_) + this->randomOffset_; 132 133 if (mypos.z > desiredZValue + hysteresisOffset * (this->randomOffset_ < 0)) 134 move = 1; 135 else if (mypos.z < desiredZValue - hysteresisOffset * (this->randomOffset_ > 0)) 136 move = -1; 137 } 138 139 this->move(move); 140 this->getControllableEntity()->moveFrontBack(this->movement_); 96 141 } 97 142 … … 108 153 109 154 // The position shouln't be larger than 0.5 (50% of the bat-length from the middle is the end) 110 position *= 0.4 5;155 position *= 0.48; 111 156 112 157 // Both sides are equally probable … … 116 161 this->randomOffset_ = position * this->ball_->getBatLength() * this->ball_->getFieldDimension().y; 117 162 } 163 164 void PongAI::calculateBallEndPosition() 165 { 166 Vector3 position = this->ball_->getPosition(); 167 Vector3 velocity = this->ball_->getVelocity(); 168 Vector2 dimension = this->ball_->getFieldDimension(); 169 170 // calculate end-height: current height + slope * distance 171 this->ballEndPosition_ = position.z + velocity.z / velocity.x * (-position.x + dimension.x / 2 * sgn(velocity.x)); 172 173 // Calculate bounces 174 for (float limit = 0.35; limit < this->strength_ || this->strength_ > 0.99; limit += 0.4) 175 { 176 if (this->ballEndPosition_ > dimension.y / 2) 177 { 178 this->ballEndPosition_ = dimension.y - this->ballEndPosition_ + (rnd(-1, 1) * dimension.y * (1 - this->strength_)); 179 continue; 180 } 181 if (this->ballEndPosition_ < -dimension.y / 2) 182 { 183 this->ballEndPosition_ = -dimension.y - this->ballEndPosition_ + (rnd(-1, 1) * dimension.y * (1 - this->strength_)); 184 continue; 185 } 186 break; 187 } 188 } 189 190 void PongAI::move(char direction) 191 { 192 // The current direction is either what we're doing right now (movement_) or what is last in the queue 193 char currentDirection = this->movement_; 194 if (this->reactionTimers_.size() > 0) 195 currentDirection = this->reactionTimers_.back().second; 196 197 // Only add changes of direction 198 if (direction == currentDirection) 199 return; 200 201 // Calculate delay, but only to change direction or start moving (stop works without delay) 202 if (direction != 0) 203 { 204 float delay = MAX_REACTION_TIME * (1 - this->strength_); 205 206 // Add a new Timer 207 Timer<PongAI>* timer = new Timer<PongAI>(delay, false, this, createExecutor(createFunctor(&PongAI::delayedMove))); 208 this->reactionTimers_.push_back(std::pair<Timer<PongAI>*, char>(timer, direction)); 209 } 210 else 211 { 212 this->movement_ = 0; 213 } 214 } 215 216 void PongAI::delayedMove() 217 { 218 this->movement_ = this->reactionTimers_.front().second; 219 220 Timer<PongAI>* timer = this->reactionTimers_.front().first; 221 delete timer; 222 223 this->reactionTimers_.pop_front(); 224 } 118 225 } -
code/trunk/src/orxonox/objects/controllers/PongAI.h
r2857 r2860 32 32 #include "OrxonoxPrereqs.h" 33 33 34 #include <list> 35 34 36 #include "Controller.h" 35 37 #include "objects/Tickable.h" 38 #include "util/Math.h" 36 39 37 40 namespace orxonox … … 41 44 public: 42 45 PongAI(BaseObject* creator); 43 virtual ~PongAI() {}46 virtual ~PongAI(); 44 47 45 48 void setConfigValues(); … … 52 55 protected: 53 56 void calculateRandomOffset(); 57 void calculateBallEndPosition(); 58 void move(char direction); 59 void delayedMove(); 54 60 55 61 PongBall* ball_; 62 Vector2 ballDirection_; 63 float ballEndPosition_; 56 64 float randomOffset_; 57 65 float relHysteresisOffset_; 58 66 float strength_; 67 68 // Timer<PongAI> randomOffsetTimer_; 69 // Timer<PongAI> ballEndPositionTimer_; 70 std::list<std::pair<Timer<PongAI>*, char> > reactionTimers_; 71 char movement_; 59 72 }; 60 73 }
Note: See TracChangeset
for help on using the changeset viewer.