Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 2885


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.

Location:
code/trunk/src/orxonox/objects
Files:
5 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    }
  • code/trunk/src/orxonox/objects/controllers/PongAI.h

    r2872 r2885  
    5656            void calculateRandomOffset();
    5757            void calculateBallEndPosition();
    58             void move(char direction);
     58            void move(char direction, bool bUseDelay);
    5959            void delayedMove();
    6060
     
    6868            std::list<std::pair<Timer<PongAI>*, char> > reactionTimers_;
    6969            char movement_;
     70            char oldMove_;
     71            bool bOscillationAvoidanceActive_;
    7072    };
    7173}
  • code/trunk/src/orxonox/objects/gametypes/Pong.cc

    r2872 r2885  
    5353        this->bat_[0] = 0;
    5454        this->bat_[1] = 0;
    55 
    56         this->bForceSpawn_ = true;
    5755
    5856        this->starttimer_.setTimer(1.0, false, this, createExecutor(createFunctor(&Pong::startBall)));
     
    111109        this->starttimer_.startTimer();
    112110
     111
     112        bool temp = this->bForceSpawn_;
     113        this->bForceSpawn_ = true;
     114
    113115        Deathmatch::start();
     116
     117        this->bForceSpawn_ = temp;
    114118    }
    115119
  • code/trunk/src/orxonox/objects/worldentities/PongBall.cc

    r2839 r2885  
    3737{
    3838    CreateFactory(PongBall);
     39
     40    const float PongBall::MAX_REL_Z_VELOCITY = 1.5;
    3941
    4042    PongBall::PongBall(BaseObject* creator) : MovableEntity(creator)
     
    7981                            position.x = this->fieldWidth_ / 2;
    8082                            velocity.x = -velocity.x;
    81                             velocity.z = distance * distance * sgn(distance) * 1.5 * this->speed_;
     83                            velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
    8284                        }
    8385                        else if (position.x > this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
     
    9799                            position.x = -this->fieldWidth_ / 2;
    98100                            velocity.x = -velocity.x;
    99                             velocity.z = distance * distance * sgn(distance) * 1.5 * this->speed_;
     101                            velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
    100102                        }
    101103                        else if (position.x < -this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
  • code/trunk/src/orxonox/objects/worldentities/PongBall.h

    r2839 r2885  
    6363                { this->bat_ = bats; }
    6464
     65            static const float MAX_REL_Z_VELOCITY;
     66
    6567        private:
    6668            float fieldWidth_;
Note: See TracChangeset for help on using the changeset viewer.