1) Added support for limiting the amount of steering per

frame for the AI (to reduce shaking, but for now this
   is not used, since the steering parameters are not fixed)
2) Bugfix in AI: in some cases out-of-road was detected incorrectly
   (caused by using kart width instead of length)


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2660 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2008-12-13 14:00:18 +00:00
parent 22d027ed5f
commit f7fef13442
5 changed files with 54 additions and 15 deletions

View File

@@ -46,6 +46,13 @@
(wheel-base 1.2 )
(heightCOG 0.2 )
(time-full-steer 0.15 )
;; Time for the AI to go from neutral steering to extreme
;; left (or right). This can be used to reduce 'shaking' of
;; AI karts caused by changing steering direction too often.
;; A value of 1/maxFPS / 2 will guarantee that the wheel can
;; go from -1 to +1 steering in one frame, basically
;; disabling this mechanism.
(time-full-steer-ai 0.004) ;; Disabled for now.
(corn-f 4 )
(corn-r 4 )

View File

@@ -59,7 +59,7 @@ KartProperties::KartProperties() : m_icon_material(0)
m_max_speed_turn = m_angle_at_max = m_brake_factor =
m_engine_power[0] = m_engine_power[1] = m_engine_power[2] =
m_max_speed[0] = m_max_speed[1] = m_max_speed[2] =
m_time_full_steer = m_nitro_power_boost =
m_time_full_steer = m_time_full_steer_ai = m_nitro_power_boost =
m_suspension_stiffness = m_wheel_damping_relaxation = m_wheel_base =
m_wheel_damping_compression = m_friction_slip = m_roll_influence =
m_wheel_radius = m_chassis_linear_damping =
@@ -186,6 +186,7 @@ void KartProperties::getAllData(const lisp::Lisp* lisp)
lisp->get("engine-power", m_engine_power);
lisp->get("time-full-steer", m_time_full_steer);
lisp->get("time-full-steer-ai", m_time_full_steer_ai);
lisp->get("brake-factor", m_brake_factor);
lisp->get("mass", m_mass);
@@ -306,6 +307,7 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_max_radius, "max-speed-angle" );
CHECK_NEG(m_brake_factor, "brake-factor" );
CHECK_NEG(m_time_full_steer, "time-full-steer" );
CHECK_NEG(m_time_full_steer_ai, "time-full-steer-ai" );
//bullet physics data
CHECK_NEG(m_suspension_stiffness, "suspension-stiffness" );

View File

@@ -75,6 +75,9 @@ protected:
* braking force. */
float m_time_full_steer; /**< Time for player karts to reach full
* steer angle. */
float m_time_full_steer_ai; /**< Time for AI karts to reach full
* steer angle (used to reduce shaking
* of karts). */
float m_min_speed_turn, /**< Speed for smallest turn radius. */
m_angle_at_min, /**< Steering angle for minimal turn
radius. Computed from radius and
@@ -162,6 +165,7 @@ public:
float getMass () const {return m_mass; }
float getMaxPower () const {return m_engine_power[race_manager->getDifficulty()];}
float getTimeFullSteer () const {return m_time_full_steer; }
float getTimeFullSteerAI () const {return m_time_full_steer_ai; }
float getBrakeFactor () const {return m_brake_factor; }
float getMaxSpeedReverseRatio () const {return m_max_speed_reverse_ratio; }
SFXManager::SFXType getEngineSfxType()

View File

@@ -61,6 +61,7 @@ DefaultRobot::DefaultRobot(const std::string& kart_name,
}
reset();
m_kart_length = m_kart_properties->getKartModel()->getLength();
m_kart_width = m_kart_properties->getKartModel()->getWidth();
m_track = RaceManager::getTrack();
m_world = dynamic_cast<LinearWorld*>(RaceManager::getWorld());
assert(m_world != NULL);
@@ -80,6 +81,9 @@ DefaultRobot::DefaultRobot(const std::string& kart_name,
case RaceManager::RD_MEDIUM:
m_wait_for_players = true;
m_max_handicap_accel = 0.95f;
// FT_PARALLEL had problems on some tracks when suddenly a smaller
// section occurred (e.g. bridge in stone track): the AI would drive
// over and over into the river
m_fallback_tactic = FT_FAREST_POINT;
m_item_tactic = IT_CALCULATE;
m_max_start_delay = 0.4f;
@@ -332,10 +336,10 @@ void DefaultRobot::handleSteering(float dt)
}
// avoid steer vibrations
if (fabsf(steer_angle) < 2.0f*3.1415/180.0f)
steer_angle = 0.f;
//if (fabsf(steer_angle) < 1.0f*3.1415/180.0f)
// steer_angle = 0.f;
setSteering(steer_angle);
setSteering(steer_angle, dt);
} // handleSteering
//-----------------------------------------------------------------------------
@@ -570,7 +574,7 @@ void DefaultRobot::handleNitro()
} // handleNitro
//-----------------------------------------------------------------------------
float DefaultRobot::steerToAngle (const size_t SECTOR, const float ANGLE)
float DefaultRobot::steerToAngle(const size_t SECTOR, const float ANGLE)
{
float angle = m_track->m_angle[SECTOR];
@@ -798,7 +802,7 @@ void DefaultRobot::findNonCrashingPoint( sgVec2 result )
: -step_track_coord[0];
//If we are outside, the previous sector is what we are looking for
if ( distance + m_kart_length * 0.5f > m_track->getWidth()[sector] )
if ( distance + m_kart_width * 0.5f > m_track->getWidth()[sector] )
{
sgCopyVec2( result, m_track->m_driveline[sector] );
@@ -896,16 +900,36 @@ int DefaultRobot::calcSteps()
//-----------------------------------------------------------------------------
/** Converts the steering angle to a lr steering in the range of -1 to 1.
* If the steering angle is too great, it will also trigger skidding.
* If the steering angle is too great, it will also trigger skidding. This
* function uses a 'time till full steer' value specifying the time it takes
* for the wheel to reach full left/right steering similar to player karts
* when using a digital input device. This is done to remove shaking of
* AI karts (which happens when the kart frequently changes the direction
* of a turn). The parameter is defined in the kart properties.
* \param angle Steering angle.
* \param dt Time step.
*/
void DefaultRobot::setSteering( float angle )
void DefaultRobot::setSteering(float angle, float dt)
{
angle = angle / getMaxSteerAngle();
m_controls.jump = fabsf(angle)>=m_skidding_threshold;
float steer_fraction = angle / getMaxSteerAngle();
m_controls.jump = fabsf(steer_fraction)>=m_skidding_threshold;
float old_lr = m_controls.lr;
if (angle > 1.0f) m_controls.lr = 1.0f;
else if(angle < -1.0f) m_controls.lr = -1.0f;
else m_controls.lr = angle;
if (steer_fraction > 1.0f) steer_fraction = 1.0f;
else if(steer_fraction < -1.0f) steer_fraction = -1.0f;
// The AI has its own 'time full steer' value (which is the time
float max_steer_change = dt/m_kart_properties->getTimeFullSteerAI();
if(old_lr < steer_fraction)
{
m_controls.lr = (old_lr+max_steer_change > steer_fraction)
? steer_fraction : old_lr+max_steer_change;
}
else
{
m_controls.lr = (old_lr-max_steer_change < steer_fraction)
? steer_fraction : old_lr-max_steer_change;
}
} // setSteering
//-----------------------------------------------------------------------------

View File

@@ -108,7 +108,7 @@ private:
/** Cache kart_info.m_track_sector. */
int m_track_sector;
float m_time_since_stuck;
int m_start_kart_crash_direction; //-1 = left, 1 = right, 0 = no crash.
@@ -116,6 +116,8 @@ private:
/** Length of the kart, storing it here saves many function calls. */
float m_kart_length;
/** Cache width of kart. */
float m_kart_width;
/** All AIs share the track info object, so that its information needs
* only to be computed once. */
static const TrackInfo *m_track_info;
@@ -154,7 +156,7 @@ private:
float normalizeAngle(float angle);
int calcSteps();
void setSteering(float angle);
void setSteering(float angle, float dt);
float getApproxRadius(const int START, const int END) const;
void findCurve();