[Orxonox-commit 215] r2885 - in trunk/src/orxonox/objects: controllers gametypes worldentities
landauf at orxonox.net
landauf at orxonox.net
Wed Apr 1 00:37:16 CEST 2009
Author: landauf
Date: 2009-04-01 00:37:16 +0200 (Wed, 01 Apr 2009)
New Revision: 2885
Modified:
trunk/src/orxonox/objects/controllers/PongAI.cc
trunk/src/orxonox/objects/controllers/PongAI.h
trunk/src/orxonox/objects/gametypes/Pong.cc
trunk/src/orxonox/objects/worldentities/PongBall.cc
trunk/src/orxonox/objects/worldentities/PongBall.h
Log:
Extended PongAI:
- Random prediction errors depend on the vertical ball-speed
- Fixed a bug: Position correction was also affected by the reaction delay. Now it works instantly.
- Added oscillation avoidance system (the already implemented hysteresis avoidance system failed at low framerates)
Additionally fixed auto-respawn in Pong Gametype.
Modified: trunk/src/orxonox/objects/controllers/PongAI.cc
===================================================================
--- trunk/src/orxonox/objects/controllers/PongAI.cc 2009-03-31 22:25:12 UTC (rev 2884)
+++ trunk/src/orxonox/objects/controllers/PongAI.cc 2009-03-31 22:37:16 UTC (rev 2885)
@@ -52,6 +52,8 @@
this->relHysteresisOffset_ = 0.02;
this->strength_ = 0.5;
this->movement_ = 0;
+ this->oldMove_ = 0;
+ this->bOscillationAvoidanceActive_ = false;
this->setConfigValues();
}
@@ -78,6 +80,7 @@
float hysteresisOffset = this->relHysteresisOffset_ * this->ball_->getFieldDimension().y;
char move = 0;
+ bool delay = false;
// Check in which direction the ball is flying
if ((mypos.x > 0 && ballvel.x < 0) || (mypos.x < 0 && ballvel.x > 0))
@@ -85,6 +88,7 @@
// The ball is flying away
this->ballDirection_.x = -1;
this->ballDirection_.y = 0;
+ this->bOscillationAvoidanceActive_ = false;
// Move to the middle
if (mypos.z > hysteresisOffset)
@@ -97,6 +101,7 @@
// The ball is standing still
this->ballDirection_.x = 0;
this->ballDirection_.y = 0;
+ this->bOscillationAvoidanceActive_ = false;
}
else
{
@@ -111,6 +116,8 @@
this->calculateRandomOffset();
this->calculateBallEndPosition();
+ delay = true;
+ this->bOscillationAvoidanceActive_ = false;
}
if (this->ballDirection_.y != sgn(ballvel.z))
@@ -119,18 +126,36 @@
this->ballDirection_.y = sgn(ballvel.z);
this->calculateBallEndPosition();
+ delay = true;
+ this->bOscillationAvoidanceActive_ = false;
}
// Move to the predicted end position with an additional offset (to hit the ball with the side of the bat)
- float desiredZValue = this->ballEndPosition_ + this->randomOffset_;
+ if (!this->bOscillationAvoidanceActive_)
+ {
+ float desiredZValue = this->ballEndPosition_ + this->randomOffset_;
- if (mypos.z > desiredZValue + hysteresisOffset * (this->randomOffset_ < 0))
- move = 1;
- else if (mypos.z < desiredZValue - hysteresisOffset * (this->randomOffset_ > 0))
- move = -1;
+ if (mypos.z > desiredZValue + hysteresisOffset * (this->randomOffset_ < 0))
+ move = 1;
+ else if (mypos.z < desiredZValue - hysteresisOffset * (this->randomOffset_ > 0))
+ move = -1;
+ }
+
+ if (move != 0 && this->oldMove_ != 0 && move != this->oldMove_ && !delay)
+ {
+ // We had to correct our position because we moved too far
+ // (and delay ist false, so we're not in the wrong place because of a new end-position prediction)
+ if (fabs(mypos.z - this->ballEndPosition_) < 0.5 * this->ball_->getBatLength() * this->ball_->getFieldDimension().y)
+ {
+ // We're not at the right position, but we still hit the ball, so just stay there to avoid oscillation
+ move = 0;
+ this->bOscillationAvoidanceActive_ = true;
+ }
+ }
}
- this->move(move);
+ this->oldMove_ = move;
+ this->move(move, delay);
this->getControllableEntity()->moveFrontBack(this->movement_);
}
@@ -167,18 +192,21 @@
// Calculate bounces
for (float limit = 0.35; limit < this->strength_ || this->strength_ > 0.99; limit += 0.4)
{
- // Bounce from the upper bound
+ // Calculate a random prediction error, based on the vertical speed of the ball and the strength of the AI
+ float randomError = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
+
+ // Bounce from the lower bound
if (this->ballEndPosition_ > dimension.y / 2)
{
// Mirror the predicted position at the upper bound and add some random error
- this->ballEndPosition_ = dimension.y - this->ballEndPosition_ + (rnd(-1, 1) * dimension.y * (1 - this->strength_));
+ this->ballEndPosition_ = dimension.y - this->ballEndPosition_ + randomError;
continue;
}
// Bounce from the upper bound
if (this->ballEndPosition_ < -dimension.y / 2)
{
// Mirror the predicted position at the lower bound and add some random error
- this->ballEndPosition_ = -dimension.y - this->ballEndPosition_ + (rnd(-1, 1) * dimension.y * (1 - this->strength_));
+ this->ballEndPosition_ = -dimension.y - this->ballEndPosition_ + randomError;
continue;
}
// No bounce - break
@@ -186,7 +214,7 @@
}
}
- void PongAI::move(char direction)
+ void PongAI::move(char direction, bool bUseDelay)
{
// The current direction is either what we're doing right now (movement_) or what is last in the queue
char currentDirection = this->movement_;
@@ -197,9 +225,9 @@
if (direction == currentDirection)
return;
- // Calculate delay, but only to change direction or start moving (stop works without delay)
- if (direction != 0)
+ if (bUseDelay)
{
+ // Calculate delay
float delay = MAX_REACTION_TIME * (1 - this->strength_);
// Add a new Timer
@@ -208,7 +236,7 @@
}
else
{
- this->movement_ = 0;
+ this->movement_ = direction;
}
}
Modified: trunk/src/orxonox/objects/controllers/PongAI.h
===================================================================
--- trunk/src/orxonox/objects/controllers/PongAI.h 2009-03-31 22:25:12 UTC (rev 2884)
+++ trunk/src/orxonox/objects/controllers/PongAI.h 2009-03-31 22:37:16 UTC (rev 2885)
@@ -55,7 +55,7 @@
protected:
void calculateRandomOffset();
void calculateBallEndPosition();
- void move(char direction);
+ void move(char direction, bool bUseDelay);
void delayedMove();
PongBall* ball_;
@@ -67,6 +67,8 @@
std::list<std::pair<Timer<PongAI>*, char> > reactionTimers_;
char movement_;
+ char oldMove_;
+ bool bOscillationAvoidanceActive_;
};
}
Modified: trunk/src/orxonox/objects/gametypes/Pong.cc
===================================================================
--- trunk/src/orxonox/objects/gametypes/Pong.cc 2009-03-31 22:25:12 UTC (rev 2884)
+++ trunk/src/orxonox/objects/gametypes/Pong.cc 2009-03-31 22:37:16 UTC (rev 2885)
@@ -53,8 +53,6 @@
this->bat_[0] = 0;
this->bat_[1] = 0;
- this->bForceSpawn_ = true;
-
this->starttimer_.setTimer(1.0, false, this, createExecutor(createFunctor(&Pong::startBall)));
this->starttimer_.stopTimer();
@@ -110,7 +108,13 @@
this->starttimer_.startTimer();
+
+ bool temp = this->bForceSpawn_;
+ this->bForceSpawn_ = true;
+
Deathmatch::start();
+
+ this->bForceSpawn_ = temp;
}
void Pong::end()
Modified: trunk/src/orxonox/objects/worldentities/PongBall.cc
===================================================================
--- trunk/src/orxonox/objects/worldentities/PongBall.cc 2009-03-31 22:25:12 UTC (rev 2884)
+++ trunk/src/orxonox/objects/worldentities/PongBall.cc 2009-03-31 22:37:16 UTC (rev 2885)
@@ -37,6 +37,8 @@
{
CreateFactory(PongBall);
+ const float PongBall::MAX_REL_Z_VELOCITY = 1.5;
+
PongBall::PongBall(BaseObject* creator) : MovableEntity(creator)
{
RegisterObject(PongBall);
@@ -78,7 +80,7 @@
{
position.x = this->fieldWidth_ / 2;
velocity.x = -velocity.x;
- velocity.z = distance * distance * sgn(distance) * 1.5 * this->speed_;
+ velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
}
else if (position.x > this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
{
@@ -96,7 +98,7 @@
{
position.x = -this->fieldWidth_ / 2;
velocity.x = -velocity.x;
- velocity.z = distance * distance * sgn(distance) * 1.5 * this->speed_;
+ velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
}
else if (position.x < -this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
{
Modified: trunk/src/orxonox/objects/worldentities/PongBall.h
===================================================================
--- trunk/src/orxonox/objects/worldentities/PongBall.h 2009-03-31 22:25:12 UTC (rev 2884)
+++ trunk/src/orxonox/objects/worldentities/PongBall.h 2009-03-31 22:37:16 UTC (rev 2885)
@@ -62,6 +62,8 @@
void setBats(PongBat** bats)
{ this->bat_ = bats; }
+ static const float MAX_REL_Z_VELOCITY;
+
private:
float fieldWidth_;
float fieldHeight_;
More information about the Orxonox-commit
mailing list