Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Apr 1, 2009, 12:37:16 AM (15 years ago)
Author:
landauf
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/orxonox/objects/controllers/PongAI.cc

    r2872 r2885  
    5353        this->strength_ = 0.5;
    5454        this->movement_ = 0;
     55        this->oldMove_ = 0;
     56        this->bOscillationAvoidanceActive_ = false;
    5557
    5658        this->setConfigValues();
     
    7981
    8082        char move = 0;
     83        bool delay = false;
    8184
    8285        // Check in which direction the ball is flying
     
    8689            this->ballDirection_.x = -1;
    8790            this->ballDirection_.y = 0;
     91            this->bOscillationAvoidanceActive_ = false;
    8892
    8993            // Move to the middle
     
    98102            this->ballDirection_.x = 0;
    99103            this->ballDirection_.y = 0;
     104            this->bOscillationAvoidanceActive_ = false;
    100105        }
    101106        else
     
    112117                this->calculateRandomOffset();
    113118                this->calculateBallEndPosition();
     119                delay = true;
     120                this->bOscillationAvoidanceActive_ = false;
    114121            }
    115122
     
    120127
    121128                this->calculateBallEndPosition();
     129                delay = true;
     130                this->bOscillationAvoidanceActive_ = false;
    122131            }
    123132
    124133            // Move to the predicted end position with an additional offset (to hit the ball with the side of the bat)
    125             float desiredZValue = this->ballEndPosition_ + this->randomOffset_;
    126 
    127             if (mypos.z > desiredZValue + hysteresisOffset * (this->randomOffset_ < 0))
    128                 move = 1;
    129             else if (mypos.z < desiredZValue - hysteresisOffset * (this->randomOffset_ > 0))
    130                 move = -1;
    131         }
    132 
    133         this->move(move);
     134            if (!this->bOscillationAvoidanceActive_)
     135            {
     136                float desiredZValue = this->ballEndPosition_ + this->randomOffset_;
     137
     138                if (mypos.z > desiredZValue + hysteresisOffset * (this->randomOffset_ < 0))
     139                    move = 1;
     140                else if (mypos.z < desiredZValue - hysteresisOffset * (this->randomOffset_ > 0))
     141                    move = -1;
     142            }
     143
     144            if (move != 0 && this->oldMove_ != 0 && move != this->oldMove_ && !delay)
     145            {
     146                // We had to correct our position because we moved too far
     147                // (and delay ist false, so we're not in the wrong place because of a new end-position prediction)
     148                if (fabs(mypos.z - this->ballEndPosition_) < 0.5 * this->ball_->getBatLength() * this->ball_->getFieldDimension().y)
     149                {
     150                    // We're not at the right position, but we still hit the ball, so just stay there to avoid oscillation
     151                    move = 0;
     152                    this->bOscillationAvoidanceActive_ = true;
     153                }
     154            }
     155        }
     156
     157        this->oldMove_ = move;
     158        this->move(move, delay);
    134159        this->getControllableEntity()->moveFrontBack(this->movement_);
    135160    }
     
    168193        for (float limit = 0.35; limit < this->strength_ || this->strength_ > 0.99; limit += 0.4)
    169194        {
    170             // Bounce from the upper bound
     195            // Calculate a random prediction error, based on the vertical speed of the ball and the strength of the AI
     196            float randomError = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
     197
     198            // Bounce from the lower bound
    171199            if (this->ballEndPosition_ > dimension.y / 2)
    172200            {
    173201                // Mirror the predicted position at the upper bound and add some random error
    174                 this->ballEndPosition_ = dimension.y - this->ballEndPosition_ + (rnd(-1, 1) * dimension.y * (1 - this->strength_));
     202                this->ballEndPosition_ = dimension.y - this->ballEndPosition_ + randomError;
    175203                continue;
    176204            }
     
    179207            {
    180208                // Mirror the predicted position at the lower bound and add some random error
    181                 this->ballEndPosition_ = -dimension.y - this->ballEndPosition_ + (rnd(-1, 1) * dimension.y * (1 - this->strength_));
     209                this->ballEndPosition_ = -dimension.y - this->ballEndPosition_ + randomError;
    182210                continue;
    183211            }
     
    187215    }
    188216
    189     void PongAI::move(char direction)
     217    void PongAI::move(char direction, bool bUseDelay)
    190218    {
    191219        // The current direction is either what we're doing right now (movement_) or what is last in the queue
     
    198226            return;
    199227
    200         // Calculate delay, but only to change direction or start moving (stop works without delay)
    201         if (direction != 0)
    202         {
     228        if (bUseDelay)
     229        {
     230            // Calculate delay
    203231            float delay = MAX_REACTION_TIME * (1 - this->strength_);
    204232
     
    209237        else
    210238        {
    211             this->movement_ = 0;
     239            this->movement_ = direction;
    212240        }
    213241    }
Note: See TracChangeset for help on using the changeset viewer.