From 017d1d3e54a2723ebae72014b483cdf85aeb9cf9 Mon Sep 17 00:00:00 2001 From: kmetykog Date: Mon, 8 Nov 2010 23:42:00 +0000 Subject: [PATCH] Styled code consistently, based on Google C++ style guide. Re #183. git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@3115 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: 7cf19bbb7bfcc767975d5bceec053d0158de249b Former-commit-id: d4b766544d33e0bd5ace939461b6cfe7c0033d67 --- src/drivers/kilo2008/kdriver.cpp | 1533 ++++++++++++++--------------- src/drivers/kilo2008/kdriver.h | 216 ++-- src/drivers/kilo2008/opponent.cpp | 286 ++++-- src/drivers/kilo2008/opponent.h | 84 +- src/drivers/kilo2008/pit.cpp | 152 +-- src/drivers/kilo2008/pit.h | 69 +- src/drivers/kilo2008/raceline.cpp | 514 +++++----- src/drivers/kilo2008/raceline.h | 61 +- src/drivers/kilo2008/strategy.cpp | 122 +-- src/drivers/kilo2008/strategy.h | 34 +- 10 files changed, 1540 insertions(+), 1531 deletions(-) diff --git a/src/drivers/kilo2008/kdriver.cpp b/src/drivers/kilo2008/kdriver.cpp index 7313f8ad1..0ea1e542a 100644 --- a/src/drivers/kilo2008/kdriver.cpp +++ b/src/drivers/kilo2008/kdriver.cpp @@ -33,8 +33,8 @@ #include #include -// #define DEBUG -#ifdef DEBUG +// #define KDRIVER_DEBUG +#ifdef KDRIVER_DEBUG #include // NOLINT(readability/streams), used for logging only using ::std::cout; using ::std::endl; @@ -92,6 +92,9 @@ const double KDriver::LOOKAHEAD_FACTOR = 0.33; const double KDriver::WIDTHDIV = 2.0; // [m] const double KDriver::BORDER_OVERTAKE_MARGIN = 1.0; + +const double KDriver::SIDECOLL_MARGIN = 1.0; + // [m/s] Offset change speed. const double KDriver::OVERTAKE_OFFSET_SPEED = 5.0; // [m] Lookahead to stop in the pit. @@ -110,15 +113,12 @@ const double KDriver::DISTCUTOFF = 400.0; const double KDriver::MAX_INC_FACTOR = 8.0; // [-] select MIN(catchdist, dist*CATCH_FACTOR) to overtake. const double KDriver::CATCH_FACTOR = 10.0; -const double KDriver::TEAM_REAR_DIST = 50.0; // Reduce speed with this factor when being overlapped const double KDriver::LET_OVERTAKE_FACTOR = 0.6; -// When to change position in the team? -const int KDriver::TEAM_DAMAGE_CHANGE_LEAD = 800; // Static variables. -Cardata *KDriver::m_cardata = NULL; -double KDriver::m_currentSimTime; +Cardata *KDriver::cardata_ = NULL; +double KDriver::current_sim_time_; static char const *WheelSect[4] = { SECT_FRNTRGTWHEEL, SECT_FRNTLFTWHEEL, SECT_REARRGTWHEEL, SECT_REARLFTWHEEL }; @@ -130,20 +130,20 @@ static char const *WheelSect[4] = { SECT_FRNTRGTWHEEL, SECT_FRNTLFTWHEEL, KDriver::KDriver(int index) { INDEX = index; - m_rgtinc = m_lftinc = 0.0; - m_minoffset = m_maxoffset = 0.0; - m_rInverse = 0.0; + rgt_inc_ = lft_inc_ = 0.0; + min_offset_ = max_offset_ = 0.0; + r_inverse_ = 0.0; } KDriver::~KDriver() { - delete m_raceline; - delete m_opponents; - delete m_pit; - delete m_strategy; - if (m_cardata != NULL) { - delete m_cardata; - m_cardata = NULL; + delete raceline_; + delete opponents_; + delete pit_; + delete strategy_; + if (cardata_ != NULL) { + delete cardata_; + cardata_ = NULL; } } @@ -154,40 +154,41 @@ KDriver::~KDriver() { * @param[in] s Situation provided by the sim. */ void KDriver::drive(tSituation * s) { - memset(&m_car->ctrl, 0, sizeof(tCarCtrl)); - update(s); - // sprintf(m_m_car->_msgCmd[0], "%d", (int)(m_m_car->_distFromStartLine)); - // memcpy(m_m_car->_msgColorCmd, colour, sizeof(m_m_car->_msgColorCmd)); + memset(&car_->ctrl, 0, sizeof(tCarCtrl)); + Update(s); + // sprintf(car_->_msgCmd[0], "%d", (int)(car_->_distFromStartLine)); + // memcpy(car_->_msgColorCmd, colour, sizeof(car_->_msgColorCmd)); string sMsg; - if (isStuck()) { - m_car->_steerCmd = -m_mycardata->getCarAngle() / m_car->_steerLock; - m_car->_gearCmd = -1; // Reverse gear. - m_car->_accelCmd = 1.0; // 100% accelerator pedal. - m_car->_brakeCmd = 0.0; // No brakes. - m_car->_clutchCmd = 0.0; // Full clutch (gearbox connected with engine). + if (IsStuck()) { + car_->_steerCmd = - my_cardata_->getCarAngle() / car_->_steerLock; + car_->_gearCmd = -1; // Reverse gear. + car_->_accelCmd = 1.0; // 100% accelerator pedal. + car_->_brakeCmd = 0.0; // No brakes. + car_->_clutchCmd = 0.0; // Full clutch (gearbox connected with engine). sMsg = "Truagh :("; } else { - m_car->_steerCmd = getSteer(s); - m_car->_gearCmd = getGear(); - calcSpeed(); - m_car->_brakeCmd = - filterABS(filterBrakeSpeed(filterBColl(filterBPit(getBrake())))); - if (m_car->_brakeCmd == 0.0) { - m_car->_accelCmd = filterTCL(filterTrk(filterOverlap(getAccel()))); + car_->_steerCmd = GetSteer(s); + car_->_gearCmd = GetGear(); + CalcSpeed(); + car_->_brakeCmd = + FilterABS(FilterBrakeSpeed(FilterBColl(FilterBPit(GetBrake())))); + + if (car_->_brakeCmd == 0.0) { + car_->_accelCmd = FilterTCL(FilterTrk(FilterOverlap(GetAccel()))); sMsg = "Thig comhla ruinn!"; } else { - m_car->_accelCmd = 0.0; + car_->_accelCmd = 0.0; sMsg = "Sguir!"; } - m_car->_clutchCmd = getClutch(); - } // if isStuck + car_->_clutchCmd = GetClutch(); + } // if IsStuck - snprintf(m_car->_msgCmd[0], RM_MSG_LEN, "%s", sMsg.c_str()); - memcpy(m_car->_msgColorCmd, colour, sizeof(m_car->_msgColorCmd)); + snprintf(car_->_msgCmd[0], RM_MSG_LEN, "%s", sMsg.c_str()); + memcpy(car_->_msgColorCmd, colour, sizeof(car_->_msgColorCmd)); - m_laststeer = m_car->_steerCmd; - m_lastmode = m_mode; + last_steer_ = car_->_steerCmd; + last_mode_ = mode_; } // drive @@ -201,24 +202,24 @@ void KDriver::endRace(tSituation * s) { * * @return true if stuck */ -bool KDriver::isStuck() { +bool KDriver::IsStuck() { bool ret = false; - if (fabs(m_mycardata->getCarAngle()) > MAX_UNSTUCK_ANGLE - && m_car->_speed_x < MAX_UNSTUCK_SPEED - && fabs(m_car->_trkPos.toMiddle) > MIN_UNSTUCK_DIST) { - if (m_stuckCounter > MAX_UNSTUCK_COUNT - && m_car->_trkPos.toMiddle * m_mycardata->getCarAngle() < 0.0) { + if (fabs(my_cardata_->getCarAngle()) > MAX_UNSTUCK_ANGLE + && car_->_speed_x < MAX_UNSTUCK_SPEED + && fabs(car_->_trkPos.toMiddle) > MIN_UNSTUCK_DIST) { + if (stuck_counter_ > MAX_UNSTUCK_COUNT + && car_->_trkPos.toMiddle * my_cardata_->getCarAngle() < 0.0) { ret = true; } else { - m_stuckCounter++; + stuck_counter_++; } } else { - m_stuckCounter = 0; + stuck_counter_ = 0; } return ret; -} // isStuck +} // IsStuck /** @@ -228,189 +229,149 @@ bool KDriver::isStuck() { * @param[in] brake Original braking value * @return Modified braking value */ -double KDriver::filterBrakeSpeed(double brake) { - double weight = m_mass * G; +double KDriver::FilterBrakeSpeed(double brake) { + double weight = mass() * G; double maxForce = weight + CA * pow(MAX_SPEED, 2); - double force = weight + CA * m_currentSpeedSqr; + double force = weight + CA * current_speed_sqr(); return brake * force / maxForce; -} // filterBrakeSpeed +} // FilterBrakeSpeed -// Compute offset to normal target point -// for overtaking or let pass an opponent. -double KDriver::getOffset() { - m_mincatchdist = 500.0; +/** + * Compute offset to normal target point + * for overtaking or let pass an opponent. + * + * @return new offset. Equals member 'my_offset_' + */ +double KDriver::GetOffset() { + min_catch_dist_ = 500.0; Opponent *o = NULL; - m_myoffset = m_car->_trkPos.toMiddle; - m_avoidmode = 0; - m_avoidLftOffset = MAX(m_myoffset, m_car->_trkPos.seg->width / 2.0 - 1.5); - m_avoidRgtOffset = MIN(m_myoffset, -(m_car->_trkPos.seg->width / 2.0 - 1.5)); + my_offset_ = car_->_trkPos.toMiddle; + avoid_mode_ = 0; + avoid_lft_offset_ = MAX(my_offset_, car_->_trkPos.seg->width / 2.0 - 1.5); + avoid_rgt_offset_ = MIN(my_offset_, -(car_->_trkPos.seg->width / 2.0 - 1.5)); // Increment speed dependent. - m_rInverse = m_raceline->getRInverse(); - double incspeed = MIN(60.0, MAX(45.0, getSpeed())) - 18.0; + r_inverse_ = raceline_->rinverse(); + double incspeed = MIN(60.0, MAX(45.0, speed())) - 18.0; double incfactor = (MAX_INC_FACTOR - MIN(fabs(incspeed) / MAX_INC_FACTOR, (MAX_INC_FACTOR - 1.0))) * (12.0 + MAX(0.0, (CA-1.9) * 14)); - m_rgtinc = incfactor * MIN(1.3, MAX(0.4, - 1.0 + m_rInverse * (m_rInverse < 0.0 ? 20 : 80))); - m_lftinc = incfactor * MIN(1.3, MAX(0.4, - 1.0 - m_rInverse * (m_rInverse > 0.0 ? 20 : 80))); + rgt_inc_ = incfactor * MIN(1.3, MAX(0.4, + 1.0 + r_inverse_ * (r_inverse_ < 0.0 ? 20 : 80))); + lft_inc_ = incfactor * MIN(1.3, MAX(0.4, + 1.0 - r_inverse_ * (r_inverse_ > 0.0 ? 20 : 80))); - int offlft = m_myoffset > m_car->_trkPos.seg->width / 2 - 1.0; - int offrgt = m_myoffset < -(m_car->_trkPos.seg->width / 2 - 1.0); + int offlft = my_offset_ > car_->_trkPos.seg->width / 2 - 1.0; + int offrgt = my_offset_ < -(car_->_trkPos.seg->width / 2 - 1.0); if (offlft) { - m_myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc / 2; + my_offset_ -= OVERTAKE_OFFSET_INC * rgt_inc_ / 2; } else if (offrgt) { - m_myoffset += OVERTAKE_OFFSET_INC * m_lftinc / 2; + my_offset_ += OVERTAKE_OFFSET_INC * lft_inc_ / 2; } - m_avoidLftOffset = MAX(m_avoidLftOffset, - m_myoffset - OVERTAKE_OFFSET_INC * m_rgtinc + avoid_lft_offset_ = MAX(avoid_lft_offset_, + my_offset_ - OVERTAKE_OFFSET_INC * rgt_inc_ * (offlft ? 6 : 2)); - m_avoidRgtOffset = MIN(m_avoidRgtOffset, - m_myoffset + OVERTAKE_OFFSET_INC * m_lftinc + avoid_rgt_offset_ = MIN(avoid_rgt_offset_, + my_offset_ + OVERTAKE_OFFSET_INC * lft_inc_ * (offrgt ? 6 : 2)); // limit to the left - m_maxoffset = m_track->width / 2 - m_car->_dimension_y; + max_offset_ = track_->width / 2 - car_->_dimension_y; // limit to the right - // m_minoffset = -(m_track->width / 2 - m_car->_dimension_y); - m_minoffset = -m_maxoffset; + // min_offset_ = -(track_->width / 2 - car_->_dimension_y); + min_offset_ = -max_offset_; - if (m_myoffset < m_minoffset) { + if (my_offset_ < min_offset_) { // we're already outside right limit, bring us back towards track - m_minoffset = m_myoffset + OVERTAKE_OFFSET_INC * m_lftinc; - m_maxoffset = MIN(m_maxoffset, - m_myoffset + OVERTAKE_OFFSET_INC * m_lftinc * 2); - } else if (m_myoffset > m_maxoffset) { + min_offset_ = my_offset_ + OVERTAKE_OFFSET_INC * lft_inc_; + max_offset_ = MIN(max_offset_, + my_offset_ + OVERTAKE_OFFSET_INC * lft_inc_ * 2); + } else if (my_offset_ > max_offset_) { // outside left limit, bring us back - m_maxoffset = m_myoffset - OVERTAKE_OFFSET_INC * m_rgtinc; - m_minoffset = MAX(m_minoffset, - m_myoffset - OVERTAKE_OFFSET_INC * m_rgtinc * 2); + max_offset_ = my_offset_ - OVERTAKE_OFFSET_INC * rgt_inc_; + min_offset_ = MAX(min_offset_, + my_offset_ - OVERTAKE_OFFSET_INC * rgt_inc_ * 2); } else { // set tighter limits based on how far we're allowed to move - m_maxoffset = MIN(m_maxoffset, - m_myoffset + OVERTAKE_OFFSET_INC * m_lftinc * 2); - m_minoffset = MAX(m_minoffset, - m_myoffset - OVERTAKE_OFFSET_INC * m_rgtinc * 2); + max_offset_ = MIN(max_offset_, + my_offset_ + OVERTAKE_OFFSET_INC * lft_inc_ * 2); + min_offset_ = MAX(min_offset_, + my_offset_ - OVERTAKE_OFFSET_INC * rgt_inc_ * 2); } // Check for side collision - o = getSidecollOpp(); - if (o != NULL) - return filterSidecollOffset(o, incfactor); + o = opponents_->GetSidecollOpp(car_); + if (o != NULL) { + set_mode(AVOIDING); + return FilterSidecollOffset(o, incfactor); + } // If we have someone to take over, let's try it - o = getTakeoverOpp(); + o = GetTakeoverOpp(); if (o != NULL) - return filterTakeoverOffset(o); + return FilterTakeoverOffset(o); // If there is someone overlapping, move out of the way - o = getOverlappingOpp(); + o = opponents_->GetOverlappingOpp(car_); if (o != NULL) - return filterOverlappedOffset(o); + return FilterOverlappedOffset(o); // no-one to avoid, work back towards raceline - if (m_mode != NORMAL && fabs(m_myoffset - m_raceOffset) > 1.0) { - if (m_myoffset > m_raceOffset + OVERTAKE_OFFSET_INC * m_rgtinc / 4) { - m_myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc / 4; - } else if (m_myoffset < m_raceOffset + OVERTAKE_OFFSET_INC * m_lftinc / 4) { - m_myoffset += OVERTAKE_OFFSET_INC * m_lftinc / 4; + if (mode_ != NORMAL && fabs(my_offset_ - race_offset_) > 1.0) { + if (my_offset_ > race_offset_ + OVERTAKE_OFFSET_INC * rgt_inc_ / 4) { + my_offset_ -= OVERTAKE_OFFSET_INC * rgt_inc_ / 4; + } else if (my_offset_ < race_offset_ + OVERTAKE_OFFSET_INC * lft_inc_ / 4) { + my_offset_ += OVERTAKE_OFFSET_INC * lft_inc_ / 4; } - } // if m_mode + } // if mode_ - if (m_simTime > 2.0) { - if (m_myoffset > m_raceOffset) { - m_myoffset = MAX(m_raceOffset, - m_myoffset - OVERTAKE_OFFSET_INC * incfactor / 2); + if (sim_time_ > 2.0) { + if (my_offset_ > race_offset_) { + my_offset_ = MAX(race_offset_, + my_offset_ - OVERTAKE_OFFSET_INC * incfactor / 2); } else { - m_myoffset = MIN(m_raceOffset, - m_myoffset + OVERTAKE_OFFSET_INC * incfactor / 2); + my_offset_ = MIN(race_offset_, + my_offset_ + OVERTAKE_OFFSET_INC * incfactor / 2); } - } // if m_simTime + } // if sim_time_ - m_myoffset = MIN(m_maxoffset, MAX(m_minoffset, m_myoffset)); - return m_myoffset; -} // getOffset + my_offset_ = MIN(max_offset_, MAX(min_offset_, my_offset_)); + return my_offset_; +} // GetOffset /** - * Decide if there is a car behind overlapping us. - * - * A1) Teammate behind with more laps should overtake. - * A2) Slipstreaming: the less damaged teammate is also allowed to pass - * if on the same lap. - * The position change happens when the damage difference is greater - * than TEAM_DAMAGE_CHANGE_LEAD. - * B) Let other, overlapping opponents get by. - - * @return overlapping car pointer or NULL - */ -Opponent * KDriver::getOverlappingOpp() { - Opponent *ret = NULL; - double mindist = -1000.0; - - for (list::iterator it = m_opponents->begin(); - it != m_opponents->end(); - it++) { - tCarElt *ocar = it->getCarPtr(); - double oppDistance = it->getDistance(); - - if (( // If teammate has more laps under his belt, - (it->isTeammate() && ocar->race.laps > m_car->race.laps) - || // or teammate is less damaged, let him go - it->isQuickerTeammate(m_car)) - && (oppDistance > -TEAM_REAR_DIST) // if close enough - && (oppDistance < -m_car->_dimension_x)) { - // Behind, larger distances are smaller ("more negative"). - if (oppDistance > mindist) { - mindist = oppDistance; - ret = &(*it); - } - } else if (it->isState(OPP_LETPASS)) { - // Behind, larger distances are smaller ("more negative"). - if (oppDistance > mindist) { - mindist = oppDistance; - ret = &(*it); - } - } // else if - } // for i - - return ret; -} // getOverlappingOpp - - -/** - * Modifies the member 'm_myoffset' so that the car moves out of the way + * Modifies the member 'my_offset_' so that the car moves out of the way * of the overlapping opponent. * * @param [in] o: the opponent we should let go - * @return new offset. Equals member 'm_myoffset' + * @return new offset. Equals member 'my_offset_' * */ -double KDriver::filterOverlappedOffset(Opponent *o) { - double w = m_car->_trkPos.seg->width / WIDTHDIV - BORDER_OVERTAKE_MARGIN; +double KDriver::FilterOverlappedOffset(const Opponent *o) { + double w = car_->_trkPos.seg->width / WIDTHDIV - BORDER_OVERTAKE_MARGIN; - if (o->isOnRight(m_car->_trkPos.toMiddle)) { - if (m_myoffset < w) { - m_myoffset += OVERTAKE_OFFSET_INC * m_lftinc / 1; // 2; + if (o->IsOnRight(car_->_trkPos.toMiddle)) { + if (my_offset_ < w) { + my_offset_ += OVERTAKE_OFFSET_INC * lft_inc_ / 1; // 2; } } else { - if (m_myoffset > -w) { - m_myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc / 1; // 2; + if (my_offset_ > -w) { + my_offset_ -= OVERTAKE_OFFSET_INC * rgt_inc_ / 1; // 2; } } - setMode(BEING_OVERLAPPED); + set_mode(BEING_OVERLAPPED); - m_myoffset = MIN(m_avoidLftOffset, MAX(m_avoidRgtOffset, m_myoffset)); - return m_myoffset; -} // filterOverlappedOffset + my_offset_ = MIN(avoid_lft_offset_, MAX(avoid_rgt_offset_, my_offset_)); + return my_offset_; +} // FilterOverlappedOffset /** @@ -419,28 +380,11 @@ double KDriver::filterOverlappedOffset(Opponent *o) { * @param [in] accel: original acceleration value * @return possibly reduced acceleration value */ -double KDriver::filterOverlap(double accel) { - return (m_opponents->getOppByState(OPP_LETPASS) +double KDriver::FilterOverlap(double accel) { + return (opponents_->GetOppByState(OPP_LETPASS) ? MIN(accel, LET_OVERTAKE_FACTOR) : accel); -} // filterOverlap - - -/** - * If opponent is too much on either side of the track, - * (doesn't occupy center part of the segment) - * and we are 5+ metres far - * - * @param [in] ocar the opponent car - * @return true if the opp. is too far on either side -*/ -bool KDriver::oppTooFarOnSide(tCarElt *ocar) { - bool ret = false; - if (fabs(ocar->_trkPos.toMiddle) > m_car->_trkPos.seg->width / 2 + 3.0 - && fabs(m_car->_trkPos.toMiddle - ocar->_trkPos.toMiddle) >= 5.0) - ret = true; - return ret; -} // oppTooFarOnSide +} // FilterOverlap /** @@ -448,23 +392,23 @@ bool KDriver::oppTooFarOnSide(tCarElt *ocar) { * * @return Overlap car pointer or NULL */ -Opponent* KDriver::getTakeoverOpp() { +Opponent* KDriver::GetTakeoverOpp() { Opponent *ret = NULL; - m_mincatchdist = MAX(30.0, 1500.0 - fabs(m_rInverse) * 10000); + min_catch_dist_ = MAX(30.0, 1500.0 - fabs(r_inverse_) * 10000); int otrySuccess = 0; for (int otry = 0; otry <= 1; otry++) { - for (list::iterator it = m_opponents->begin(); - it != m_opponents->end(); - it++) { - tCarElt *ocar = it->getCarPtr(); + for (list::iterator it = opponents_->begin(); + it != opponents_->end(); + ++it) { + tCarElt *ocar = it->car_ptr(); // If opponent is clearly ahead of us, we don't care - if (it->isState(OPP_FRONT_FOLLOW)) + if (it->HasState(OPP_FRONT_FOLLOW)) continue; - if (oppTooFarOnSide(ocar)) + if (it->IsTooFarOnSide(car_)) continue; // If opponent is in pit, let him be ;) @@ -472,81 +416,81 @@ Opponent* KDriver::getTakeoverOpp() { continue; // If opponent is ahead, and is not a quicker teammate of ours - if ((it->isState(OPP_FRONT)) - && !it->isQuickerTeammate(m_car)) { + if ((it->HasState(OPP_FRONT)) + && !it->IsQuickerTeammate(car_)) { double otry_factor = otry - ? (0.2 + (1.0 - ((m_currentSimTime - m_avoidTime) / 7.0)) * 0.8) + ? (0.2 + (1.0 - ((current_sim_time_ - avoid_time_) / 7.0)) * 0.8) : 1.0; // How far ahead is he? - double distance = it->getDistance() * otry_factor; - double speed = MIN(m_avoidSpeed, - getSpeed() + MAX(0.0, 10.0 - distance)); - double ospeed = it->getSpeed(); // opponent's speed + double distance = it->distance() * otry_factor; + double my_speed = MIN(avoid_speed_, + speed() + MAX(0.0, 10.0 - distance)); + double ospeed = it->speed(); // opponent's speed // When will we reach up to the opponent? - double catchdist = MIN(speed * distance / (speed - ospeed), + double catchdist = MIN(my_speed * distance / (my_speed - ospeed), distance * CATCH_FACTOR) * otry_factor; // If we are close enough, // check again with avoidance speed taken into account - if (catchdist < m_mincatchdist - && distance < fabs(speed - ospeed) * 2) { - m_mincatchdist = catchdist; + if (catchdist < min_catch_dist_ + && distance < fabs(my_speed - ospeed) * 2) { + min_catch_dist_ = catchdist; ret = &(*it); // This is the guy we need to take over otrySuccess = otry; } } // if it state } // for it if (ret) break; - if (m_mode != AVOIDING) break; + if (mode_ != AVOIDING) break; } // for otry if (ret != NULL && otrySuccess == 0) - m_avoidTime = m_currentSimTime; + avoid_time_ = current_sim_time_; return ret; -} // getTakeoverOpp +} // GetTakeoverOpp /** - * Change offset value if we are to overtake a car. + * Change offset value if we are to overtake a car. * * @param [in] o the opponent - * @return new offset + * @return new offset. Equals member 'my_offset_' */ -double KDriver::filterTakeoverOffset(Opponent *o) { - setMode(AVOIDING); - tCarElt *ocar = o->getCarPtr(); +double KDriver::FilterTakeoverOffset(const Opponent *o) { + set_mode(AVOIDING); + tCarElt *ocar = o->car_ptr(); // Compute the opponent's distance to the middle. double otm = ocar->_trkPos.toMiddle; - double sidemargin = o->getWidth() + getWidth() + 1.0; - double sidedist = fabs(ocar->_trkPos.toLeft - m_car->_trkPos.toLeft); + double sidemargin = o->width() + width() + SIDECOLL_MARGIN; + double sidedist = fabs(ocar->_trkPos.toLeft - car_->_trkPos.toLeft); // Avoid more if on the outside of opponent on a bend. // Stops us from cutting in too much and colliding... - if ((otm < -(ocar->_trkPos.seg->width - 5.0) && m_rInverse < 0.0) - || (otm > (ocar->_trkPos.seg->width - 5.0) && m_rInverse > 0.0)) - sidemargin += fabs(m_rInverse) * 150; + if ((otm < -(ocar->_trkPos.seg->width - 5.0) && r_inverse_ < 0.0) + || (otm > (ocar->_trkPos.seg->width - 5.0) && r_inverse_ > 0.0)) + sidemargin += fabs(r_inverse_) * 150; if (otm > (ocar->_trkPos.seg->width - 5.0) - || (m_car->_trkPos.toLeft > ocar->_trkPos.toLeft - && (sidedist < sidemargin || o->isState(OPP_COLL)))) { - m_myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc; - setAvoidLeft(); + || (car_->_trkPos.toLeft > ocar->_trkPos.toLeft + && (sidedist < sidemargin || o->HasState(OPP_COLL)))) { + my_offset_ -= OVERTAKE_OFFSET_INC * rgt_inc_; + set_avoid_left(); } else if (otm < -(ocar->_trkPos.seg->width - 5.0) - || (m_car->_trkPos.toLeft < ocar->_trkPos.toLeft - && (sidedist < sidemargin || o->isState(OPP_COLL)))) { - m_myoffset += OVERTAKE_OFFSET_INC * m_lftinc; - setAvoidRight(); + || (car_->_trkPos.toLeft < ocar->_trkPos.toLeft + && (sidedist < sidemargin || o->HasState(OPP_COLL)))) { + my_offset_ += OVERTAKE_OFFSET_INC * lft_inc_; + set_avoid_right(); } else { // If the opponent is near the middle we try to move the offset toward // the inside of the expected turn. // Try to find out the characteristic of the track up to catchdist. - tTrackSeg *seg = m_car->_trkPos.seg; - double length = getDistToSegEnd(); + tTrackSeg *seg = car_->_trkPos.seg; + double length = GetDistToSegEnd(); double oldlen, seglen = length; double lenright = 0.0, lenleft = 0.0; - m_mincatchdist = MIN(m_mincatchdist, DISTCUTOFF); + min_catch_dist_ = MIN(min_catch_dist_, DISTCUTOFF); do { switch (seg->type) { @@ -564,7 +508,7 @@ double KDriver::filterTakeoverOffset(Opponent *o) { seglen = seg->length; oldlen = length; length += seglen; - } while (oldlen < m_mincatchdist); + } while (oldlen < min_catch_dist_); // If we are on a straight look for the next turn. if (lenleft == 0.0 && lenright == 0.0) { @@ -579,76 +523,55 @@ double KDriver::filterTakeoverOffset(Opponent *o) { } // if lenleft/lenright == 0 // Because we are inside we can go to the limit. - if ((lenleft > lenright && m_rInverse < 0.0) - || (lenleft <= lenright && m_rInverse > 0.0)) { + if ((lenleft > lenright && r_inverse_ < 0.0) + || (lenleft <= lenright && r_inverse_ > 0.0)) { // avoid more if on the outside of opponent on a bend. Stops us // from cutting in too much and colliding... - sidemargin += fabs(m_rInverse) * 150; + sidemargin += fabs(r_inverse_) * 150; } - if (sidedist < sidemargin || o->isState(OPP_COLL)) { + if (sidedist < sidemargin || o->HasState(OPP_COLL)) { if (lenleft > lenright) { - m_myoffset += OVERTAKE_OFFSET_INC * m_lftinc; // * 0.7; - setAvoidRight(); + my_offset_ += OVERTAKE_OFFSET_INC * lft_inc_; // * 0.7; + set_avoid_right(); } else { - m_myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc; // * 0.7; - setAvoidLeft(); + my_offset_ -= OVERTAKE_OFFSET_INC * rgt_inc_; // * 0.7; + set_avoid_left(); } // if lenleft > lenright } // if sidedist } // if opp near middle - m_myoffset = MIN(m_avoidLftOffset, MAX(m_avoidRgtOffset, m_myoffset)); - m_myoffset = MIN(m_maxoffset, MAX(m_minoffset, m_myoffset)); - return m_myoffset; -} // filterTakeoverOffset + my_offset_ = MIN(avoid_lft_offset_, MAX(avoid_rgt_offset_, my_offset_)); + my_offset_ = MIN(max_offset_, MAX(min_offset_, my_offset_)); + return my_offset_; +} // FilterTakeoverOffset /** - * Decide if there is a car on the side we are to collide with... - * - * @return Side collision car pointer or NULL + * Change offset value if we are at danger of side collision. + * + * @param [in] o the opponent + * @param [in] incfactor + * @return new offset. Equals member 'my_offset_' */ -Opponent *KDriver::getSidecollOpp() { - Opponent *ret = NULL; - for (list::iterator it = m_opponents->begin(); - it != m_opponents->end(); - it++) { - tCarElt *ocar = it->getCarPtr(); - - if (ocar->_state > RM_CAR_STATE_PIT) // Dont care for opponents in the pit - continue; - - if (oppTooFarOnSide(ocar)) - continue; - - if (it->isState(OPP_SIDE)) { // If opponent is on our side - setMode(AVOIDING); - ret = &(*it); - break; - } // if OPP_SIDE - } // for it - - return ret; -} // getSidecollOpp - - -double KDriver::filterSidecollOffset(Opponent *o, const double incfactor) { - double myToLeft = m_car->_trkPos.toLeft; - double oppToLeft = o->getCarPtr()->_trkPos.toLeft; +double KDriver::FilterSidecollOffset(const Opponent *o, + const double incfactor) { + double myToLeft = car_->_trkPos.toLeft; + double oppToLeft = o->car_ptr()->_trkPos.toLeft; double sidedist = fabs(oppToLeft - myToLeft); - double sidemargin = o->getWidth() + getWidth() + 2.0; - bool oppOnRight = o->isOnRight(m_car->_trkPos.toMiddle); + double sidemargin = o->width() + width() + SIDECOLL_MARGIN; + bool oppOnRight = o->IsOnRight(car_->_trkPos.toMiddle); // Avoid more if on the outside of opponent on a bend. // Stops us from cutting in too much and colliding... - if ((oppOnRight && m_rInverse < 0.0) - || (!oppOnRight && m_rInverse > 0.0)) - sidemargin += fabs(m_rInverse) * 150; + if ((oppOnRight && r_inverse_ < 0.0) + || (!oppOnRight && r_inverse_ > 0.0)) + sidemargin += fabs(r_inverse_) * 150; if (oppOnRight) { - sidemargin -= MIN(0.0, m_rInverse * 100); + sidemargin -= MIN(0.0, r_inverse_ * 100); } else { - sidemargin += MAX(0.0, m_rInverse * 100); + sidemargin += MAX(0.0, r_inverse_ * 100); } sidedist = MIN(sidedist, sidemargin); @@ -656,24 +579,24 @@ double KDriver::filterSidecollOffset(Opponent *o, const double incfactor) { double sdiff = 3.0 - (sidemargin - sidedist) / sidemargin; if (oppOnRight) { // He is on the right, we must move to the left - m_myoffset += OVERTAKE_OFFSET_INC * m_lftinc * MAX(0.2, MIN(1.0, sdiff)); + my_offset_ += OVERTAKE_OFFSET_INC * lft_inc_ * MAX(0.2, MIN(1.0, sdiff)); } else { // He is on the left, we must move to the right - m_myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc * MAX(0.2, MIN(1.0, sdiff)); + my_offset_ -= OVERTAKE_OFFSET_INC * rgt_inc_ * MAX(0.2, MIN(1.0, sdiff)); } } else if (sidedist > sidemargin + 3.0) { - if (m_raceOffset > m_myoffset + OVERTAKE_OFFSET_INC * incfactor) { - m_myoffset += OVERTAKE_OFFSET_INC * m_lftinc / 4; - } else if (m_raceOffset < m_myoffset - OVERTAKE_OFFSET_INC * incfactor) { - m_myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc / 4; + if (race_offset_ > my_offset_ + OVERTAKE_OFFSET_INC * incfactor) { + my_offset_ += OVERTAKE_OFFSET_INC * lft_inc_ / 4; + } else if (race_offset_ < my_offset_ - OVERTAKE_OFFSET_INC * incfactor) { + my_offset_ -= OVERTAKE_OFFSET_INC * rgt_inc_ / 4; } } - oppOnRight ? setAvoidRight() : setAvoidLeft(); - m_avoidmode |= AVOIDSIDE; + oppOnRight ? set_avoid_right() : set_avoid_left(); + avoid_mode_ |= AVOIDSIDE; - m_myoffset = MIN(m_maxoffset, MAX(m_minoffset, m_myoffset)); - return m_myoffset; -} // filterSidecollOffset + my_offset_ = MIN(max_offset_, MAX(min_offset_, my_offset_)); + return my_offset_; +} // FilterSidecollOffset /** @@ -700,21 +623,21 @@ double KDriver::filterSidecollOffset(Opponent *o, const double incfactor) { */ void KDriver::initTrack(tTrack * t, void *carHandle, void **carParmHandle, tSituation * s) { - initSkill(s); + InitSkill(s); //Read & calculate skilling info stringstream buf; // Load a custom setup if one is available. - m_track = t; + track_ = t; // Ptr to the track filename - char *trackname = strrchr(m_track->filename, '/') + 1; + char *trackname = strrchr(track_->filename, '/') + 1; stringstream botPath; // Try to load the default setup botPath << "drivers/" << bot << "/"; // << INDEX << "/"; buf << botPath.str() << "default.xml"; *carParmHandle = GfParmReadFile(buf.str().c_str(), GFPARM_RMODE_STD); -#ifdef DEBUG +#ifdef KDRIVER_DEBUG cout << "Default: " << buf.str() << endl; if (carParmHandle) cout << "default xml loaded, carParmHandle: " << *carParmHandle << endl; @@ -724,7 +647,7 @@ void KDriver::initTrack(tTrack * t, void *carHandle, buf.str(string()); buf << botPath.str() << "tracks/" << trackname; void *newhandle = GfParmReadFile(buf.str().c_str(), GFPARM_RMODE_STD); -#ifdef DEBUG +#ifdef KDRIVER_DEBUG cout << "track-based: " << buf.str() << endl; if (newhandle) cout << "track-based xml loaded, newhandle: " << newhandle << endl; @@ -732,28 +655,28 @@ void KDriver::initTrack(tTrack * t, void *carHandle, cout << "no track-based xml present" << endl; #endif - mergeCarSetups(carParmHandle, newhandle); -#ifdef DEBUG + MergeCarSetups(carParmHandle, newhandle); +#ifdef KDRIVER_DEBUG cout << "merge #1, carParmHandle: " << *carParmHandle << " newhandle: " << newhandle << endl; #endif // Discover somehow the name of the car used - if (m_carType.empty()) { + if (car_type_.empty()) { stringstream ssSection; ssSection << ROB_SECT_ROBOTS << "/" << ROB_LIST_INDEX << "/" << INDEX; - m_carType = GfParmGetStr(carHandle, ssSection.str().c_str(), + car_type_ = GfParmGetStr(carHandle, ssSection.str().c_str(), ROB_ATTR_CAR, DEFAULTCARTYPE); } // if carType empty -#ifdef DEBUG - cout << "Cartype: " << m_carType << endl; +#ifdef KDRIVER_DEBUG + cout << "Cartype: " << car_type_ << endl; #endif // Load setup tailored for car+track buf.str(string()); - buf << botPath.str() << m_carType << "/" << trackname; + buf << botPath.str() << car_type_ << "/" << trackname; newhandle = GfParmReadFile(buf.str().c_str(), GFPARM_RMODE_STD); -#ifdef DEBUG +#ifdef KDRIVER_DEBUG cout << "custom setup: " << buf.str() << endl; if (newhandle) cout << "car+track xml loaded, newhandle: " << newhandle << endl; @@ -764,8 +687,8 @@ void KDriver::initTrack(tTrack * t, void *carHandle, // If there is no tailored setup, let's load a default one // based on the track charateristics. if (!newhandle) - newhandle = loadDefaultSetup(); -#ifdef DEBUG + newhandle = LoadDefaultSetup(); +#ifdef KDRIVER_DEBUG if (newhandle) cout << "default setup xml loaded, newhandle: " << newhandle << endl; else @@ -773,28 +696,27 @@ void KDriver::initTrack(tTrack * t, void *carHandle, #endif // Merge the above two setups - mergeCarSetups(carParmHandle, newhandle); -#ifdef DEBUG + MergeCarSetups(carParmHandle, newhandle); +#ifdef KDRIVER_DEBUG cout << "merge #2" << endl; #endif // Load and set parameters. MU_FACTOR = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, KILO_ATT_MUFACTOR, NULL, 0.69f); - m_pitOffset = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, + pit_offset_ = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, KILO_ATT_PITOFFSET, NULL, 10.0); - m_brakeDelay = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, + brake_delay_ = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, KILO_ATT_BRDELAY, NULL, 10.0); - // Create a pit stop strategy object. - m_strategy = new KStrategy(); - // Init fuel. - m_strategy->SetFuelAtRaceStart(t, carParmHandle, s, INDEX); + // Create a pit stop strategy object & initialize fuel. + strategy_ = new KStrategy(); + strategy_->SetFuelAtRaceStart(t, carParmHandle, s, INDEX); - m_raceline = new LRaceLine; - // m_raceline->setSkill(m_skill); - m_raceline->InitTrack(m_track, carParmHandle, s, m_filterSideSkill); -} // initTrack + // Create a raceline object & initialize it for this track + raceline_ = new LRaceLine; + raceline_->InitTrack(track_, carParmHandle, s, side_skill_); +} // InitTrack /** @@ -802,32 +724,31 @@ void KDriver::initTrack(tTrack * t, void *carHandle, * * @param [in] s situation provided by the sim */ -void KDriver::update(tSituation * s) { +void KDriver::Update(tSituation * s) { // Update global car data (shared by all instances) just once per timestep. - if (m_currentSimTime != s->currentTime) { - m_currentSimTime = s->currentTime; - m_cardata->update(); + if (current_sim_time_ != s->currentTime) { + current_sim_time_ = s->currentTime; + cardata_->update(); } // Update the rest of local data - m_speedangle = -(m_mycardata->getTrackangle() - - atan2(m_car->_speed_Y, m_car->_speed_X)); - NORM_PI_PI(m_speedangle); - m_mass = CARMASS + m_car->_fuel; - m_currentSpeedSqr = pow(m_car->_speed_x, 2); + speed_angle_ = -(my_cardata_->getTrackangle() - + atan2(car_->_speed_Y, car_->_speed_X)); + NORM_PI_PI(speed_angle_); - m_opponents->update(s, this); - m_strategy->Update(); + opponents_->Update(s, this); + strategy_->Update(); - checkPitStatus(s); - m_pit->update(); - m_simTime = s->currentTime; + CheckPitStatus(s); + pit_->Update(); + sim_time_ = s->currentTime; + + double trackangle = RtTrackSideTgAngleL(&(car_->_trkPos)); + angle_ = trackangle - car_->_yaw; + NORM_PI_PI(angle_); + angle_ = -angle_; +} // Update - double trackangle = RtTrackSideTgAngleL(&(m_car->_trkPos)); - m_angle = trackangle - m_car->_yaw; - NORM_PI_PI(m_angle); - m_angle = -m_angle; -} // update /** * Checks if we need to plan a pitstop. @@ -836,48 +757,48 @@ void KDriver::update(tSituation * s) { * * @param [in] s Situation provided by the sim */ -void KDriver::checkPitStatus(tSituation *s) { - if (m_car->_state <= RM_CAR_STATE_PIT) { // If our car is still in the race - if (!m_pit->getPitstop()) { // if no pit is planned yet +void KDriver::CheckPitStatus(tSituation *s) { + if (car_->_state <= RM_CAR_STATE_PIT) { // If our car is still racing + if (!pit_->pit_planned()) { // if no pit is planned yet // and we are not in the pit range // or we are very low on fuel // then we can check if pitting is needed by strategy. - if ((m_car->_distFromStartLine < m_pit->getNPitEntry() - || m_car->_distFromStartLine > m_pit->getNPitEnd()) - || m_car->_fuel < 5.0) { - m_pit->setPitstop(m_strategy->NeedPitstop()); + if ((car_->_distFromStartLine < pit_->n_entry() + || car_->_distFromStartLine > pit_->n_end()) + || car_->_fuel < 5.0) { + pit_->set_pitstop(strategy_->NeedPitstop()); } } // if no pit planned - if (m_pit->getPitstop() && m_car->_pit) { // if pitting is planned - pitstatus[m_carIndex] = 1; // flag our car's pit as occupied + if (pit_->pit_planned() && car_->_pit) { // if pitting is planned + pitstatus[car_index_] = 1; // flag our car's pit as occupied - for (list::iterator it = m_opponents->begin(); - it != m_opponents->end(); - it++) { - tCarElt *ocar = it->getCarPtr(); + for (list::iterator it = opponents_->begin(); + it != opponents_->end(); + ++it) { + tCarElt *ocar = it->car_ptr(); // If the other car is our teammate, still in the race - if (it->isTeammate() && ocar->_state <= RM_CAR_STATE_PIT) { - int idx = it->getIndex(); + if (it->teammate() && ocar->_state <= RM_CAR_STATE_PIT) { + int idx = it->index(); if (pitstatus[idx] == 1 || ((pitstatus[idx] - || (ocar-> _fuel < m_car->_fuel - 1.0 - && m_car->_dammage < 5000)) - && fabs(m_car->_trkPos.toMiddle) - <= m_car->_trkPos.seg->width / 2)) { - m_pit->setPitstop(false); - pitstatus[m_carIndex] = 0; + || (ocar-> _fuel < car_->_fuel - 1.0 + && car_->_dammage < 5000)) + && fabs(car_->_trkPos.toMiddle) + <= car_->_trkPos.seg->width / 2)) { + pit_->set_pitstop(false); + pitstatus[car_index_] = 0; } break; } // if our teammate } // for it - } else if (!m_pit->getInPit()) { // If we are not in the pitlane - pitstatus[m_carIndex] = 0; // sign the pit as free + } else if (!pit_->in_pitlane()) { // If we are not in the pitlane + pitstatus[car_index_] = 0; // sign the pit as free } else { - pitstatus[m_carIndex] = 0; + pitstatus[car_index_] = 0; } } -} // checkPitStatus +} // CheckPitStatus /** @@ -887,115 +808,132 @@ void KDriver::checkPitStatus(tSituation *s) { * @param [in] brake Original brake value * @return Possibly modified brake value */ -double KDriver::filterBColl(const double brake) { +double KDriver::FilterBColl(const double brake) { double ret = brake; - if (m_simTime >= 1.5) { - double mu = m_car->_trkPos.seg->surface->kFriction; - for (list::iterator it = m_opponents->begin(); - it != m_opponents->end(); - it++) { - if (it->isState(OPP_COLL)) { // Endangered species - double ospeed = it->getSpeed(); - if (brakeDist(ospeed, mu) + MIN(1.0, - 0.5 + MAX(0.0, (getSpeed() - ospeed) / 4)) - > it->getDistance()) { // Damn, too close, brake hard!!! - m_accelCmd = 0.0; + if (sim_time_ >= 1.5) { + double mu = car_->_trkPos.seg->surface->kFriction; + for (list::iterator it = opponents_->begin(); + it != opponents_->end(); + ++it) { + if (it->HasState(OPP_COLL)) { // Endangered species + if (BrakeDist(it->speed(), mu) + + MIN(1.0, 0.5 + MAX(0.0, (speed() - it->speed()) / 4)) + > it->distance()) { // Damn, too close, brake hard!!! + accel_cmd_ = 0.0; ret = 1.0; break; - } // if brakeDist + } // if BrakeDist } // if state OPP_COLL } // for it - } // if m_simTime + } // if sim_time_ return ret; -} // filterBColl +} // FilterBColl -// Set pitstop commands. +/** + * Set pitstop commands. + * + * @param [in] s Situation provided by the sim + * @return Request pit immediately + */ int KDriver::pitCommand(tSituation * s) { - m_car->_pitRepair = m_strategy->PitRepair(); - m_car->_pitFuel = m_strategy->PitRefuel(); + car_->_pitRepair = strategy_->PitRepair(); + car_->_pitFuel = strategy_->PitRefuel(); // This should be the only place where the pit stop is set to false! - m_pit->setPitstop(false); + pit_->set_pitstop(false); return ROB_PIT_IM; // return immediately. } // pitCommand +/** + * Initialize a new race. + * + * @param [in] car Our own car + * @param [in] s Situation provided by the sim + */ void KDriver::newRace(tCarElt * car, tSituation * s) { - m_strategy->set_car(car); + strategy_->set_car(car); double deltaTime = static_cast(RCM_MAX_DT_ROBOTS); MAX_UNSTUCK_COUNT = static_cast(UNSTUCK_TIME_LIMIT / deltaTime); OVERTAKE_OFFSET_INC = OVERTAKE_OFFSET_SPEED * deltaTime; - m_stuckCounter = 0; - m_clutchTime = 0.0; - m_oldLookahead = m_laststeer = m_lastNSasteer = 0.0; - m_car = car; - CARMASS = GfParmGetNum(m_car->_carHandle, SECT_CAR, PRM_MASS, NULL, 1000.0); - m_myoffset = 0.0; - m_simTime = m_correctTimer = 0.0; - m_correctLimit = 1000.0; - initCa(); - initCw(); - initTireMu(); - initTCLFilter(); + stuck_counter_ = 0; + clutch_time_ = 0.0; + old_lookahead_ = last_steer_ = last_nsa_steer_ = 0.0; + car_ = car; + CARMASS = GfParmGetNum(car_->_carHandle, SECT_CAR, + PRM_MASS, NULL, 1000.0); + my_offset_ = 0.0; + sim_time_ = correct_timer_ = 0.0; + correct_limit_ = 1000.0; + InitCa(); + InitCw(); + InitTireMu(); + InitTCLFilter(); // Create just one instance of cardata shared by all drivers. - if (m_cardata == NULL) - m_cardata = new Cardata(s); - m_mycardata = m_cardata->findCar(m_car); - m_currentSimTime = s->currentTime; + if (cardata_ == NULL) + cardata_ = new Cardata(s); + my_cardata_ = cardata_->findCar(car_); + current_sim_time_ = s->currentTime; // initialize the list of opponents. - m_opponents = new Opponents(s, this, m_cardata); - m_opponents->setTeamMate(m_car); + opponents_ = new Opponents(s, this, cardata_); + opponents_->SetTeamMate(car_); // create the pit object. - m_pit = new Pit(s, this, m_pitOffset); + pit_ = new Pit(s, this, pit_offset_); // set initial mode // we set it to CORRECTING so the robot will steer towards the raceline - setMode(CORRECTING); - m_lastmode = CORRECTING; + set_mode(CORRECTING); + last_mode_ = CORRECTING; - for (m_carIndex = 0; m_carIndex < s->_ncars; m_carIndex++) { - if (s->cars[m_carIndex] == m_car) + // search for this car's index + for (car_index_ = 0; car_index_ < s->_ncars; ++car_index_) { + if (s->cars[car_index_] == car_) break; } - m_raceline->setCar(m_car); - m_raceline->NewRace(); + raceline_->set_car(car_); + raceline_->NewRace(); } // newRace -void KDriver::calcSpeed() { - m_accelCmd = m_brakeCmd = 0.0; +/** + * Calculates target speed dependent on the traffic situation. + * + */ +void KDriver::CalcSpeed() { + accel_cmd_ = brake_cmd_ = 0.0; double speed; - switch (m_mode) { + switch (mode_) { case AVOIDING: case BEING_OVERLAPPED: - speed = m_avoidSpeed; + speed = avoid_speed_; break; case CORRECTING: - speed = m_raceSpeed - - (m_raceSpeed - m_avoidSpeed) - * MAX(0.0, (m_correctTimer - m_simTime) / 7.0); + speed = race_speed_ - + (race_speed_ - avoid_speed_) + * MAX(0.0, (correct_timer_ - sim_time_) / 7.0); break; default: - speed = m_raceSpeed; - } // switch m_mode + speed = race_speed_; + } // switch mode_ - double x = (10 + m_car->_speed_x) * (speed - m_car->_speed_x) / 200; + double x = (10 + car_->_speed_x) * (speed - car_->_speed_x) / 200; + //Let's see if we must accelerate or brake a bit. if (x > 0.0) - m_accelCmd = x; + accel_cmd_ = x; else - m_brakeCmd = MIN(1.0, -(MAX(10.0, m_brakeDelay * 0.7)) * x); -} // calcSpeed + brake_cmd_ = MIN(1.0, -(MAX(10.0, brake_delay_ * 0.7)) * x); +} // CalcSpeed /** @@ -1004,14 +942,14 @@ void KDriver::calcSpeed() { * * @return Handler to the loaded default setup */ -void* KDriver::loadDefaultSetup() const { +void* KDriver::LoadDefaultSetup() const { void *ret = NULL; double dLength = 0.0; double dCurves = 0.0; // Count length and degrees of all turns - tTrackSeg *pSeg = m_track->seg; + tTrackSeg *pSeg = track_->seg; do { if (pSeg->type == TR_STR) { dLength += pSeg->length; @@ -1021,12 +959,12 @@ void* KDriver::loadDefaultSetup() const { } pSeg = pSeg->next; - } while (pSeg != m_track->seg); + } while (pSeg != track_->seg); double dRatio = dLength / dCurves; -#ifdef DEBUG - cout << "Track " << m_track->name +#ifdef KDRIVER_DEBUG + cout << "Track " << track_->name << " length: " << dLength << " curves: " << dCurves << " ratio: " << dRatio @@ -1034,7 +972,7 @@ void* KDriver::loadDefaultSetup() const { #endif stringstream buf; - buf << "drivers/" << bot << "/" << m_carType; + buf << "drivers/" << bot << "/" << car_type_; if (dRatio < SLOW_TRACK_LIMIT) { // Slow track @@ -1048,17 +986,23 @@ void* KDriver::loadDefaultSetup() const { } // if dRatio ret = GfParmReadFile(buf.str().c_str(), GFPARM_RMODE_STD); -#ifdef DEBUG +#ifdef KDRIVER_DEBUG cout << "Decision of setup: " << buf.str() << endl; if (ret) cout << "Def-XXX xml loaded" << endl; #endif return ret; -} // loadDefaultSetup +} // LoadDefaultSetup -void KDriver::mergeCarSetups(void **oldHandle, void *newHandle) { +/** + * Merges 2 car setup infos, possibly read from different setup files. + * + * @param [in,out] oldHandle setup #1, output as the merged setups. + * @param [in] newHandle setup #2 + */ +void KDriver::MergeCarSetups(void **oldHandle, void *newHandle) const { if (newHandle) { if (*oldHandle) *oldHandle = GfParmMergeHandles(*oldHandle, newHandle, @@ -1068,104 +1012,113 @@ void KDriver::mergeCarSetups(void **oldHandle, void *newHandle) { else *oldHandle = newHandle; } // if newHandle -} // mergeCarSetups +} // MergeCarSetups -// Compute aerodynamic downforce coefficient CA. -void KDriver::initCa() { +/** + * Computes CA (aerodynamic downforce coefficient). + * + */ +void KDriver::InitCa() { double rearWingArea = - GfParmGetNum(m_car->_carHandle, SECT_REARWING, PRM_WINGAREA, NULL, 0.0); + GfParmGetNum(car_->_carHandle, SECT_REARWING, PRM_WINGAREA, NULL, 0.0); double rearWingAngle = - GfParmGetNum(m_car->_carHandle, SECT_REARWING, PRM_WINGANGLE, NULL, 0.0); + GfParmGetNum(car_->_carHandle, SECT_REARWING, PRM_WINGANGLE, NULL, 0.0); double wingCa = 1.23 * rearWingArea * sin(rearWingAngle); double cl = - GfParmGetNum(m_car->_carHandle, SECT_AERODYNAMICS, PRM_FCL, NULL, 0.0) + - GfParmGetNum(m_car->_carHandle, SECT_AERODYNAMICS, PRM_RCL, NULL, 0.0); + GfParmGetNum(car_->_carHandle, SECT_AERODYNAMICS, PRM_FCL, NULL, 0.0) + + GfParmGetNum(car_->_carHandle, SECT_AERODYNAMICS, PRM_RCL, NULL, 0.0); double h = 0.0; for (int i = 0; i < 4; i++) - h += GfParmGetNum(m_car->_carHandle, WheelSect[i], - PRM_RIDEHEIGHT, NULL, 0.2); + h += GfParmGetNum(car_->_carHandle, WheelSect[i], + PRM_RIDEHEIGHT, NULL, 0.2); h *= 1.5; h = pow(h, 4); h = 2.0 * exp(-3.0 * h); CA = h * cl + 4.0 * wingCa; -} // initCa +} // InitCa -// Compute aerodynamic drag coefficient CW. -void KDriver::initCw() { - double cx = - GfParmGetNum(m_car->_carHandle, SECT_AERODYNAMICS, PRM_CX, NULL, 0.0); - double frontArea = - GfParmGetNum(m_car->_carHandle, SECT_AERODYNAMICS, PRM_FRNTAREA, NULL, 0.0); +/** + * Computes CW (aerodynamic drag coefficient). + * + */ +void KDriver::InitCw() { + double cx = GfParmGetNum(car_->_carHandle, SECT_AERODYNAMICS, + PRM_CX, NULL, 0.0); + double frontArea = GfParmGetNum(car_->_carHandle, SECT_AERODYNAMICS, + PRM_FRNTAREA, NULL, 0.0); CW = 0.645 * cx * frontArea; -} // initCw +} // InitCw -// Init the friction coefficient of the the tires. -void KDriver::initTireMu() { +/** + * Init the friction coefficient of the tires. + * + */ +void KDriver::InitTireMu() { double tm = DBL_MAX; for (int i = 0; i < 4; i++) - tm = MIN(tm, - GfParmGetNum(m_car->_carHandle, WheelSect[i], PRM_MU, NULL, 1.0)); + tm = MIN(tm, GfParmGetNum(car_->_carHandle, WheelSect[i], + PRM_MU, NULL, 1.0)); TIREMU = tm; -} // initTireMu +} // InitTireMu // Traction Control (TCL) setup. -void KDriver::initTCLFilter() { - const string traintype = GfParmGetStr(m_car->_carHandle, +void KDriver::InitTCLFilter() { + const string traintype = GfParmGetStr(car_->_carHandle, SECT_DRIVETRAIN, PRM_TYPE, VAL_TRANS_RWD); if (traintype == VAL_TRANS_RWD) - GET_DRIVEN_WHEEL_SPEED = &KDriver::filterTCL_RWD; + GET_DRIVEN_WHEEL_SPEED = &KDriver::FilterTCL_RWD; else if (traintype == VAL_TRANS_FWD) - GET_DRIVEN_WHEEL_SPEED = &KDriver::filterTCL_FWD; + GET_DRIVEN_WHEEL_SPEED = &KDriver::FilterTCL_FWD; else if (traintype == VAL_TRANS_4WD) - GET_DRIVEN_WHEEL_SPEED = &KDriver::filterTCL_4WD; -} // initTCLFilter + GET_DRIVEN_WHEEL_SPEED = &KDriver::FilterTCL_4WD; +} // InitTCLFilter // TCL filter plugin for rear wheel driven cars. -double KDriver::filterTCL_RWD() { - return (m_car->_wheelSpinVel(REAR_RGT) + m_car->_wheelSpinVel(REAR_LFT)) * - m_car->_wheelRadius(REAR_LFT) / 2.0; +double KDriver::FilterTCL_RWD() { + return (car_->_wheelSpinVel(REAR_RGT) + car_->_wheelSpinVel(REAR_LFT)) * + car_->_wheelRadius(REAR_LFT) / 2.0; } // TCL filter plugin for front wheel driven cars. -double KDriver::filterTCL_FWD() { - return (m_car->_wheelSpinVel(FRNT_RGT) + m_car->_wheelSpinVel(FRNT_LFT)) * - m_car->_wheelRadius(FRNT_LFT) / 2.0; +double KDriver::FilterTCL_FWD() { + return (car_->_wheelSpinVel(FRNT_RGT) + car_->_wheelSpinVel(FRNT_LFT)) * + car_->_wheelRadius(FRNT_LFT) / 2.0; } // TCL filter plugin for all wheel driven cars. -double KDriver::filterTCL_4WD() { - return ((m_car->_wheelSpinVel(FRNT_RGT) + m_car->_wheelSpinVel(FRNT_LFT)) * - m_car->_wheelRadius(FRNT_LFT) + - (m_car->_wheelSpinVel(REAR_RGT) + m_car->_wheelSpinVel(REAR_LFT)) * - m_car->_wheelRadius(REAR_LFT)) / 4.0; +double KDriver::FilterTCL_4WD() { + return ((car_->_wheelSpinVel(FRNT_RGT) + car_->_wheelSpinVel(FRNT_LFT)) * + car_->_wheelRadius(FRNT_LFT) + + (car_->_wheelSpinVel(REAR_RGT) + car_->_wheelSpinVel(REAR_LFT)) * + car_->_wheelRadius(REAR_LFT)) / 4.0; } // TCL filter for accelerator pedal. -double KDriver::filterTCL(const double accel) { +double KDriver::FilterTCL(const double accel) { double ret = accel; - if (m_simTime >= 3.0) { + if (sim_time_ >= 3.0) { ret = MIN(1.0, accel); double accel1 = ret, accel2 = ret, accel3 = ret; - if (m_car->_speed_x > 10.0) { - tTrackSeg *seg = m_car->_trkPos.seg; - tTrackSeg *wseg0 = m_car->_wheelSeg(0); - tTrackSeg *wseg1 = m_car->_wheelSeg(1); + if (car_->_speed_x > 10.0) { + tTrackSeg *seg = car_->_trkPos.seg; + tTrackSeg *wseg0 = car_->_wheelSeg(0); + tTrackSeg *wseg1 = car_->_wheelSeg(1); int count = 0; if ( @@ -1181,95 +1134,96 @@ double KDriver::filterTCL(const double accel) { count++; if (count) { - if (m_mode != NORMAL + if (mode_ != NORMAL && ((seg->type == TR_RGT && seg->radius <= 200.0 - && m_car->_trkPos.toLeft < 3.0) + && car_->_trkPos.toLeft < 3.0) || (seg->type == TR_LFT && seg->radius <= 200.0 - && m_car->_trkPos.toRight < 3.0))) + && car_->_trkPos.toRight < 3.0))) count++; accel1 = MAX(0.0, MIN(accel1, (1.0 - (0.25 * count)) - - MAX(0.0, (getSpeed() - m_car->_speed_x) / 10.0))); + MAX(0.0, (speed() - car_->_speed_x) / 10.0))); } // if count - if (fabs(m_angle) > 1.0) - accel1 = MIN(accel1, 1.0 - (fabs(m_angle) - 1.0) * 1.3); - } // if m_car->_speed_x + if (fabs(angle_) > 1.0) + accel1 = MIN(accel1, 1.0 - (fabs(angle_) - 1.0) * 1.3); + } // if car_->_speed_x - if (fabs(m_car->_steerCmd) > 0.02) { - double decel = ((fabs(m_car->_steerCmd) - 0.02) * - (1.0 + fabs(m_car->_steerCmd)) * 0.7); + if (fabs(car_->_steerCmd) > 0.02) { + double decel = ((fabs(car_->_steerCmd) - 0.02) * + (1.0 + fabs(car_->_steerCmd)) * 0.7); accel2 = MIN(accel2, MAX(0.45, 1.0 - decel)); - } // if m_car->_steerCmd + } // if car_->_steerCmd - double slip = (this->*GET_DRIVEN_WHEEL_SPEED) () - m_car->_speed_x; + double slip = (this->*GET_DRIVEN_WHEEL_SPEED) () - car_->_speed_x; if (slip > TCL_SLIP) accel3 = accel3 - MIN(accel3, (slip - TCL_SLIP) / TCL_RANGE); ret = MIN(accel1, MIN(accel2, accel3)); - } // if m_simTime + } // if sim_time_ return ret; -} // filterTCL +} // FilterTCL // Hold car on the track. -double KDriver::filterTrk(const double accel) { +double KDriver::FilterTrk(double accel) { double ret = accel; - tTrackSeg *seg = m_car->_trkPos.seg; + tTrackSeg *seg = car_->_trkPos.seg; - if (m_car->_speed_x >= MAX_UNSTUCK_SPEED // Not too slow - && !m_pit->getInPit() // Not on pit stop - && m_car->_trkPos.toMiddle * -m_speedangle <= 0.0) { + if (car_->_speed_x >= MAX_UNSTUCK_SPEED // Not too slow + && !pit_->in_pitlane() // Not on pit stop + && car_->_trkPos.toMiddle * -speed_angle_ <= 0.0) { // Speedvector points to the outside of the turn if (seg->type == TR_STR) { - double tm = fabs(m_car->_trkPos.toMiddle); - double w = (seg->width - m_car->_dimension_y) / 2.0; + double tm = fabs(car_->_trkPos.toMiddle); + double w = (seg->width - car_->_dimension_y) / 2.0; ret = (tm > w) ? 0.0 : accel; } else { double sign = (seg->type == TR_RGT) ? -1.0 : 1.0; - if (m_car->_trkPos.toMiddle * sign > 0.0) { + if (car_->_trkPos.toMiddle * sign > 0.0) { ret = accel; } else { - double tm = fabs(m_car->_trkPos.toMiddle); + double tm = fabs(car_->_trkPos.toMiddle); double w = seg->width / WIDTHDIV; ret = (tm > w) ? 0.0 : accel; } } // if seg->type } // if not too slow return ret; -} // filterTrk +} // FilterTrk // Compute the needed distance to brake. -double KDriver::brakeDist(double allowedspeed, double mu) { +double KDriver::BrakeDist(double allowedspeed, double mu) const { double c = mu * G; - double d = (CA * mu + CW) / m_mass; - double v1sqr = m_currentSpeedSqr; + double d = (CA * mu + CW) / mass(); + double v1sqr = current_speed_sqr(); double v2sqr = pow(allowedspeed, 2); double ret = -log((c + v2sqr * d) / (c + v1sqr * d)) / (2.0 * d); - ret /= m_filterBrakeSkill; + ret /= brake_skill_; // skilling return ret; -} // brakeDist +} // BrakeDist // Antilocking filter for brakes. -double KDriver::filterABS(double brake) { +double KDriver::FilterABS(double brake) { double ret = brake; - if (m_car->_speed_x >= ABS_MINSPEED) { + if (car_->_speed_x >= ABS_MINSPEED) { double origbrake = brake; - double rearskid = MAX(0.0, MAX(m_car->_skid[2], m_car->_skid[3]) - - MAX(m_car->_skid[0], m_car->_skid[1])); + double rearskid = MAX(0.0, MAX(car_->_skid[2], car_->_skid[3]) - + MAX(car_->_skid[0], car_->_skid[1])); double slip = 0.0; for (int i = 0; i < 4; i++) - slip += m_car->_wheelSpinVel(i) * m_car->_wheelRadius(i); + slip += car_->_wheelSpinVel(i) * car_->_wheelRadius(i); slip *= - 1.0 + MAX(rearskid, MAX(fabs(m_car->_yaw_rate) / 5, fabs(m_angle) / 6)); - slip = m_car->_speed_x - slip / 4.0; + 1.0 + MAX(rearskid, MAX(fabs(car_->_yaw_rate) / 5, + fabs(angle_) / 6)); + slip = car_->_speed_x - slip / 4.0; if (slip > ABS_SLIP) ret = brake - MIN(brake, (slip - ABS_SLIP) / ABS_RANGE); @@ -1278,101 +1232,101 @@ double KDriver::filterABS(double brake) { } return ret; -} // filterABS +} // FilterABS // Brake filter for pit stop. -double KDriver::filterBPit(double brake) { - double mu = m_car->_trkPos.seg->surface->kFriction * TIREMU * PIT_MU; +double KDriver::FilterBPit(double brake) { + double mu = car_->_trkPos.seg->surface->kFriction * TIREMU * PIT_MU; - if (m_pit->getPitstop() && !m_pit->getInPit()) { + if (pit_->pit_planned() && !pit_->in_pitlane()) { tdble dl, dw; - RtDistToPit(m_car, m_track, &dl, &dw); + RtDistToPit(car_, track_, &dl, &dw); if (dl < PIT_BRAKE_AHEAD) { - if (brakeDist(0.0, mu) > dl) + if (BrakeDist(0.0, mu) > dl) return 1.0; } } - if (m_pit->getInPit()) { - double s = m_pit->toSplineCoord(m_car->_distFromStartLine); + if (pit_->in_pitlane()) { + double s = pit_->ToSplineCoord(car_->_distFromStartLine); // Pit entry. - if (m_pit->getPitstop()) { - if (s < m_pit->getNPitStart()) { + if (pit_->pit_planned()) { + if (s < pit_->n_start()) { // Brake to pit speed limit. - double dist = m_pit->getNPitStart() - s; - if (brakeDist(m_pit->getSpeedlimit(), mu) > dist) + double dist = pit_->n_start() - s; + if (BrakeDist(pit_->speed_limit(), mu) > dist) return 1.0; } else { // Hold speed limit. - if (m_currentSpeedSqr > m_pit->getSpeedlimitSqr()) - return m_pit->getSpeedLimitBrake(m_currentSpeedSqr); + if (current_speed_sqr() > pit_->speed_limit_sqr()) + return pit_->speed_limit_brake(current_speed_sqr()); } // if s // Brake into pit (speed limit 0.0 to stop) - double dist = m_pit->getNPitLoc() - s; - if (m_pit->isTimeout(dist)) { - m_pit->setPitstop(false); + double dist = pit_->n_loc() - s; + if (pit_->is_timeout(dist)) { + pit_->set_pitstop(false); return 0.0; } else { - if (brakeDist(0.0, mu) > dist) + if (BrakeDist(0.0, mu) > dist) return 1.0; - else if (s > m_pit->getNPitLoc()) + else if (s > pit_->n_loc()) return 1.0; // Stop in the pit. } // if pit timeout } else { // Pit exit. - if (s < m_pit->getNPitEnd()) { + if (s < pit_->n_end()) { // Pit speed limit. - if (m_currentSpeedSqr > m_pit->getSpeedlimitSqr()) - return m_pit->getSpeedLimitBrake(m_currentSpeedSqr); + if (current_speed_sqr() > pit_->speed_limit_sqr()) + return pit_->speed_limit_brake(current_speed_sqr()); } } } return brake; -} // filterBPit +} // FilterBPit -double KDriver::calcSteer(double targetAngle, int rl) { +double KDriver::CalcSteer(double targetAngle, int rl) { double rearskid = MAX(0.0, - MAX(m_car->_skid[2], m_car->_skid[3]) - - MAX(m_car->_skid[0], m_car->_skid[1])) - + MAX(m_car->_skid[2], m_car->_skid[3]) - * fabs(m_angle) * 0.9; + MAX(car_->_skid[2], car_->_skid[3]) + - MAX(car_->_skid[0], car_->_skid[1])) + + MAX(car_->_skid[2], car_->_skid[3]) + * fabs(angle_) * 0.9; double angle_correction = 0.0; - double factor = (rl ? 1.4f : (m_mode == CORRECTING ? 1.1f : 1.2f)); - if (m_angle < 0.0) - angle_correction = MAX(m_angle, - MIN(0.0, m_angle / 2.0) - / MAX(15.0, 70.0 - m_car->_speed_x) * factor); + double factor = (rl ? 1.4f : (mode_ == CORRECTING ? 1.1f : 1.2f)); + if (angle_ < 0.0) + angle_correction = MAX(angle_, + MIN(0.0, angle_ / 2.0) + / MAX(15.0, 70.0 - car_->_speed_x) * factor); else - angle_correction = MIN(m_angle, - MAX(0.0, m_angle / 2.0) - / MAX(15.0, 70.0 - m_car->_speed_x) * factor); + angle_correction = MIN(angle_, + MAX(0.0, angle_ / 2.0) + / MAX(15.0, 70.0 - car_->_speed_x) * factor); - double steer_direction = targetAngle - m_car->_yaw + angle_correction; + double steer_direction = targetAngle - car_->_yaw + angle_correction; NORM_PI_PI(steer_direction); - if (m_car->_speed_x > 10.0) { - double speedsteer = (80.0 - MIN(70.0, MAX(40.0, getSpeed()))) / - ((185.0 * MIN(1.0, m_car->_steerLock / 0.785)) + + if (car_->_speed_x > 10.0) { + double speedsteer = (80.0 - MIN(70.0, MAX(40.0, speed()))) / + ((185.0 * MIN(1.0, car_->_steerLock / 0.785)) + (185.0 * (MIN(1.3, MAX(1.0, 1.0 + rearskid))) - 185.0)); if (fabs(steer_direction) > speedsteer) steer_direction = MAX(-speedsteer, MIN(speedsteer, steer_direction)); } - double steer = steer_direction / m_car->_steerLock; + double steer = steer_direction / car_->_steerLock; // smooth steering. check for separate function for this! - if (m_mode != PITTING) { + if (mode_ != PITTING) { double minspeedfactor = (((105.0 - - MAX(40.0, MIN(70.0, getSpeed() + MAX(0.0, m_car->_accel_x * 5.0)))) + MAX(40.0, MIN(70.0, speed() + MAX(0.0, car_->_accel_x * 5.0)))) / 300.0) * (5.0 + MAX(0.0, (CA-1.9) * 20.0))); double maxspeedfactor = minspeedfactor; - double rInverse = m_raceline->getRInverse(); + double rInverse = raceline_->rinverse(); if (rInverse > 0.0) { minspeedfactor = MAX(minspeedfactor / 3, minspeedfactor - rInverse * 80); @@ -1382,71 +1336,72 @@ double KDriver::calcSteer(double targetAngle, int rl) { minspeedfactor = MAX(minspeedfactor / 3, minspeedfactor + rInverse * 20); } // if rInverse - steer = MAX(m_lastNSasteer - minspeedfactor, - MIN(m_lastNSasteer + maxspeedfactor, steer)); + steer = MAX(last_nsa_steer_ - minspeedfactor, + MIN(last_nsa_steer_ + maxspeedfactor, steer)); } // if mode != PITTING - m_lastNSasteer = steer; + last_nsa_steer_ = steer; - if (fabs(m_angle) > fabs(m_speedangle)) { + if (fabs(angle_) > fabs(speed_angle_)) { // steer into the skid - double sa = MAX(-0.3, MIN(0.3, m_speedangle / 3)); - double anglediff = (sa - m_angle) - * (0.7 - MAX(0.0, MIN(0.3, m_car->_accel_x / 100))); - // anglediff += m_raceline->getRInverse() * 10; + double sa = MAX(-0.3, MIN(0.3, speed_angle_ / 3)); + double anglediff = (sa - angle_) + * (0.7 - MAX(0.0, MIN(0.3, car_->_accel_x / 100))); + // anglediff += raceline_->rinverse() * 10; steer += anglediff * 0.7; } - if (fabs(m_angle) > 1.2) { + if (fabs(angle_) > 1.2) { steer = sign(steer); - } else if (fabs(m_car->_trkPos.toMiddle) - - m_car->_trkPos.seg->width / 2 > 2.0) { + } else if (fabs(car_->_trkPos.toMiddle) + - car_->_trkPos.seg->width / 2 > 2.0) { steer = MIN(1.0, MAX(-1.0, - steer * (1.0 + (fabs(m_car->_trkPos.toMiddle) - - m_car->_trkPos.seg->width / 2) / 14 + fabs(m_angle) / 2))); + steer * (1.0 + (fabs(car_->_trkPos.toMiddle) + - car_->_trkPos.seg->width / 2) / 14 + + fabs(angle_) / 2))); } - if (m_mode != PITTING) { + if (mode_ != PITTING) { // limit how far we can steer against raceline - double limit = (90.0 - MAX(40.0, - MIN(60.0, - m_car->_speed_x))) / - (50 + fabs(m_angle) * fabs(m_angle) * 3); - steer = MAX(m_raceSteer - limit, MIN(m_raceSteer + limit, steer)); + double limit = (90.0 - MAX(40.0, MIN(60.0, car_->_speed_x))) / + (50 + fabs(angle_) * fabs(angle_) * 3); + steer = MAX(race_steer_ - limit, MIN(race_steer_ + limit, steer)); } return steer; -} // calcSteer +} // CalcSteer -double KDriver::correctSteering(double avoidsteer, double racesteer) { +double KDriver::CorrectSteering(double avoidsteer, double racesteer) { double steer = avoidsteer; - // double accel = MIN(0.0, m_car->_accel_x); - double speed = MAX(50.0, getSpeed()); - // double changelimit = MIN(1.0, m_raceline->correctLimit()); - double changelimit = MIN(m_raceline->correctLimit(), - (((120.0 - getSpeed()) / 6000) + // double accel = MIN(0.0, car_->_accel_x); + double act_speed = MAX(50.0, speed()); + // double changelimit = MIN(1.0, raceline_->correctLimit()); + double changelimit = MIN(raceline_->CorrectLimit(), + (((120.0 - speed()) / 6000) * (0.5 + MIN(fabs(avoidsteer), fabs(racesteer)) / 10))); - if (m_mode == CORRECTING && m_simTime > 2.0) { + if (mode_ == CORRECTING && sim_time_ > 2.0) { // move steering towards racesteer... - if (m_correctLimit < 900.0) { + if (correct_limit_ < 900.0) { if (steer < racesteer) { - steer = (m_correctLimit >= 0.0) + steer = (correct_limit_ >= 0.0) ? racesteer - : MIN(racesteer, MAX(steer, racesteer + m_correctLimit)); + : MIN(racesteer, MAX(steer, racesteer + correct_limit_)); } else { - steer = (m_correctLimit <= 0.0) + steer = (correct_limit_ <= 0.0) ? racesteer - : MAX(racesteer, MIN(steer, racesteer + m_correctLimit)); + : MAX(racesteer, MIN(steer, racesteer + correct_limit_)); } } - speed -= m_car->_accel_x / 10; - speed = MAX(55.0, MIN(150.0, speed + (speed * speed / 55.0))); - double rInverse = m_raceline->getRInverse() * - (m_car->_accel_x < 0.0 ? 1.0 + fabs(m_car->_accel_x) / 10.0 : 1.0); + act_speed -= car_->_accel_x / 10; + act_speed = MAX(55.0, MIN(150.0, act_speed + (pow(act_speed , 2) / 55.0))); + double rInverse = raceline_->rinverse() * + (car_->_accel_x < 0.0 + ? 1.0 + fabs(car_->_accel_x) / 10.0 + : 1.0); double correctspeed = 0.5; if ((rInverse > 0.0 && racesteer > steer) || (rInverse < 0.0 && racesteer < steer)) @@ -1460,101 +1415,104 @@ double KDriver::correctSteering(double avoidsteer, double racesteer) { * steer = MAX(racesteer, * steer - (((155.0-speed)/10000) * correctspeed)); */ - m_correctLimit = (steer - racesteer); // * 1.08; + correct_limit_ = (steer - racesteer); // * 1.08; } // if mode=correcting return steer; -} // correctSteering +} // CorrectSteering // try to limit sudden changes in steering // to avoid loss of control through oversteer. -double KDriver::smoothSteering(double steercmd) { +double KDriver::SmoothSteering(double steercmd) { double speedfactor = (((60.0 - - (MAX(40.0, MIN(70.0, getSpeed() + MAX(0.0, m_car->_accel_x * 5))) + (MAX(40.0, MIN(70.0, speed() + MAX(0.0, car_->_accel_x * 5))) - 25)) / 300) * 2.5) / 0.585; // double rearskid = MAX(0.0, - // MAX(m_car->_skid[2], m_car->_skid[3]) - // - MAX(m_car->_skid[0], m_car->_skid[1])); + // MAX(car_->_skid[2], car_->_skid[3]) + // - MAX(car_->_skid[0], car_->_skid[1])); - if (fabs(steercmd) < fabs(m_laststeer) - && fabs(steercmd) <= fabs(m_laststeer - steercmd)) + if (fabs(steercmd) < fabs(last_steer_) + && fabs(steercmd) <= fabs(last_steer_ - steercmd)) speedfactor *= 2; - double lftspeedfactor = speedfactor - MIN(0.0f, m_car->_yaw_rate / 10.0); - double rgtspeedfactor = speedfactor + MAX(0.0f, m_car->_yaw_rate / 10.0); + double lftspeedfactor = speedfactor - MIN(0.0f, car_->_yaw_rate / 10.0); + double rgtspeedfactor = speedfactor + MAX(0.0f, car_->_yaw_rate / 10.0); - steercmd = MAX(m_laststeer - rgtspeedfactor, - MIN(m_laststeer + lftspeedfactor, steercmd)); + steercmd = MAX(last_steer_ - rgtspeedfactor, + MIN(last_steer_ + lftspeedfactor, steercmd)); return steercmd; -} // smoothSteering +} // SmoothSteering /** - * getSteer + * GetSteer * Computes steer value. - * @param s global situation - * @return steer value range -1...1 + * + * @param[in] s global situation + * @return steer value range -1...1 */ -double KDriver::getSteer(tSituation *s) { +double KDriver::GetSteer(tSituation *s) { double steer = 0.0; + v2d race_target; // the 2d point the raceline is driving at. + double look_ahead; // how far ahead on the track we look for steering - m_raceline->GetRaceLineData(s, &m_raceTarget, - &m_raceSpeed, &m_avoidSpeed, - &m_raceOffset, &m_rLookahead, - &m_raceSteer); - vec2f target = getTargetPoint(); + raceline_->GetRaceLineData(s, &race_target, + &race_speed_, &avoid_speed_, + &race_offset_, &look_ahead, + &race_steer_); + vec2f target = TargetPoint(); double targetAngle = - atan2(target.y - m_car->_pos_Y, target.x - m_car->_pos_X); - double avoidsteer = calcSteer(targetAngle, 0); + atan2(target.y - car_->_pos_Y, target.x - car_->_pos_X); + double avoidsteer = CalcSteer(targetAngle, 0); - if (m_mode == PITTING) + if (mode_ == PITTING) return avoidsteer; targetAngle = - atan2(m_raceTarget.y - m_car->_pos_Y, m_raceTarget.x - m_car->_pos_X); + atan2(race_target.y - car_->_pos_Y, race_target.x - car_->_pos_X); // uncomment the following if we want to use BT steering rather than K1999 - // m_raceSteer = calcSteer( targetAngle, 1 ); + // race_steer_ = CalcSteer( targetAngle, 1 ); - if (m_mode == AVOIDING && - (!m_avoidmode - || (m_avoidmode == AVOIDRIGHT - && m_raceOffset >= m_myoffset - && m_raceOffset < m_avoidLftOffset) - || (m_avoidmode == AVOIDLEFT - && m_raceOffset <= m_myoffset - && m_raceOffset > m_avoidRgtOffset))) { + if (mode_ == AVOIDING && + (!avoid_mode_ + || (avoid_mode_ == AVOIDRIGHT + && race_offset_ >= my_offset_ + && race_offset_ < avoid_lft_offset_) + || (avoid_mode_ == AVOIDLEFT + && race_offset_ <= my_offset_ + && race_offset_ > avoid_rgt_offset_))) { // we're avoiding, but trying to steer somewhere the raceline takes us. // hence we'll just correct towards the raceline instead. - setMode(CORRECTING); + set_mode(CORRECTING); } - if (m_mode == CORRECTING - && (m_lastmode == NORMAL - || (fabs(m_angle) < 0.2f && fabs(m_raceSteer) < 0.4f - && fabs(m_laststeer - m_raceSteer) < 0.05 - && ((fabs(m_car->_trkPos.toMiddle) - < m_car->_trkPos.seg->width / 2 - 1.0) - || m_car->_speed_x < 10.0) && m_raceline->isOnLine()))) { + if (mode_ == CORRECTING + && (last_mode_ == NORMAL + || (fabs(angle_) < 0.2f && fabs(race_steer_) < 0.4f + && fabs(last_steer_ - race_steer_) < 0.05 + && ((fabs(car_->_trkPos.toMiddle) + < car_->_trkPos.seg->width / 2 - 1.0) + || car_->_speed_x < 10.0) && raceline_->isOnLine()))) { // we're CORRECTING & are now close enough to the raceline to // switch back to 'normal' mode... - setMode(NORMAL); + set_mode(NORMAL); } - if (m_mode == NORMAL) { - steer = m_raceSteer; - m_lastNSasteer = m_raceSteer * 0.8; + if (mode_ == NORMAL) { + steer = race_steer_; + last_nsa_steer_ = race_steer_ * 0.8; } else { - if (m_mode != CORRECTING) { - m_correctLimit = 1000.0; - m_correctTimer = m_simTime + 7.0; - steer = smoothSteering(avoidsteer); + if (mode_ != CORRECTING) { + correct_limit_ = 1000.0; + correct_timer_ = sim_time_ + 7.0; + steer = SmoothSteering(avoidsteer); } else { - steer = smoothSteering(correctSteering(avoidsteer, m_raceSteer)); + steer = SmoothSteering(CorrectSteering(avoidsteer, race_steer_)); } // mode != CORRECTING - if (fabs(m_angle) >= 1.6) { + if (fabs(angle_) >= 1.6) { steer = (steer > 0.0) ? 1.0 : -1.0; } } // mode != NORMAL @@ -1562,56 +1520,58 @@ double KDriver::getSteer(tSituation *s) { #if 0 fprintf(stderr, "%s %d: %c%c %.3f (a%.3f k%.3f) cl=%.3f ct=%.1f myof=%.3f->%.3f\n", - m_car->_name, m_car->_dammage, - (m_mode == - NORMAL ? 'n' : (m_mode == - AVOIDING ? 'a' : (m_mode == + car_->_name, car_->_dammage, + (mode_ == + NORMAL ? 'n' : (mode_ == + AVOIDING ? 'a' : (mode_ == CORRECTING ? 'c' : 'p'))), - (m_avoidmode == - AVOIDLEFT ? 'l' : (m_avoidmode == - AVOIDRIGHT ? 'r' : (m_avoidmode == + (avoid_mode_ == + AVOIDLEFT ? 'l' : (avoid_mode_ == + AVOIDRIGHT ? 'r' : (avoid_mode_ == (AVOIDLEFT + AVOIDRIGHT) ? 'b' : ' '))), steer, - avoidsteer, m_raceSteer, m_correctLimit, (m_correctTimer - m_simTime), - m_car->_trkPos.toMiddle, m_myoffset); + avoidsteer, race_steer_, correct_limit_, (correct_timer_ - sim_time_), + car_->_trkPos.toMiddle, my_offset_); fflush(stderr); #endif return steer; -} // getSteer +} // GetSteer /** - * getTargetPoint + * TargetPoint * Computes target point for steering. + * * @return 2D coords of the target */ -vec2f KDriver::getTargetPoint() { +vec2f KDriver::TargetPoint() { double lookahead; - if (m_pit->getInPit()) { + if (pit_->in_pitlane()) { // To stop in the pit we need special lookahead values. lookahead = PIT_LOOKAHEAD; - if (m_currentSpeedSqr > m_pit->getSpeedlimitSqr()) - lookahead += m_car->_speed_x * LOOKAHEAD_FACTOR; + if (current_speed_sqr() > pit_->speed_limit_sqr()) + lookahead += car_->_speed_x * LOOKAHEAD_FACTOR; } else { // Usual lookahead. - double speed = MAX(20.0, getSpeed()); // + MAX(0.0, m_car->_accel_x)); - lookahead = LOOKAHEAD_CONST * 1.2 + speed * 0.60; - lookahead = MIN(lookahead, LOOKAHEAD_CONST + (pow(speed, 2) / 7 * 0.15)); + double my_speed = MAX(20.0, speed()); // + MAX(0.0, car_->_accel_x)); + lookahead = LOOKAHEAD_CONST * 1.2 + my_speed * 0.60; + lookahead = MIN(lookahead, LOOKAHEAD_CONST + (pow(my_speed, 2) / 7 * 0.15)); // Prevent "snap back" of lookahead on harsh braking. - double cmplookahead = m_oldLookahead - m_car->_speed_x * RCM_MAX_DT_ROBOTS; + double cmplookahead = old_lookahead_ + - car_->_speed_x * RCM_MAX_DT_ROBOTS; lookahead = MAX(cmplookahead, lookahead); - } // if getInPit + } // if in_pitlane - lookahead *= m_filterLookaheadSkill; + lookahead *= lookahead_skill_; - m_oldLookahead = lookahead; + old_lookahead_ = lookahead; // Search for the segment containing the target point. - tTrackSeg *seg = m_car->_trkPos.seg; - double length = getDistToSegEnd(); + tTrackSeg *seg = car_->_trkPos.seg; + double length = GetDistToSegEnd(); while (length < lookahead) { seg = seg->next; length += seg->length; @@ -1621,18 +1581,18 @@ vec2f KDriver::getTargetPoint() { double fromstart = seg->lgfromstart + length; // Compute the target point. - double offset = getOffset(); - double pitoffset = m_pit->getPitOffset(-100.0, fromstart); - if ((m_pit->getPitstop() || m_pit->getInPit()) && pitoffset != -100.0) { - setMode(PITTING); - offset = m_myoffset = pitoffset; - } else if (m_mode == PITTING) { - setMode(CORRECTING); + double offset = GetOffset(); + double pitoffset = pit_->CalcPitOffset(-100.0, fromstart); + if ((pit_->pit_planned() || pit_->in_pitlane()) && pitoffset != -100.0) { + set_mode(PITTING); + offset = my_offset_ = pitoffset; + } else if (mode_ == PITTING) { + set_mode(CORRECTING); } vec2f s; - if (m_mode != PITTING) { - m_raceline->GetPoint(offset, lookahead, &s); + if (mode_ != PITTING) { + raceline_->GetPoint(offset, lookahead, &s); return s; } @@ -1658,16 +1618,16 @@ vec2f KDriver::getTargetPoint() { n.normalize(); t = s + static_cast(arcsign) * static_cast(offset) * n; - if (m_mode != PITTING) { + if (mode_ != PITTING) { // bugfix - calculates target point a different way, thus // bypassing an error in the BT code that sometimes made // the target closer to the car than lookahead... - m_raceline->GetPoint(offset, lookahead, &rt); - double dx = t.x - m_car->_pos_X; - double dy = t.y - m_car->_pos_Y; + raceline_->GetPoint(offset, lookahead, &rt); + double dx = t.x - car_->_pos_X; + double dy = t.y - car_->_pos_Y; double dist1 = Mag(dx, dy); - dx = rt.x - m_car->_pos_X; - dy = rt.y - m_car->_pos_Y; + dx = rt.x - car_->_pos_X; + dy = rt.y - car_->_pos_Y; double dist2 = Mag(dx, dy); if (dist2 > dist1) t = rt; @@ -1675,165 +1635,168 @@ vec2f KDriver::getTargetPoint() { return t; } // if seg->type -} // getTargetPoint +} // TargetPoint /** - * getDistToSegEnd - * Computes the length to the end of the segment. + * GetDistToSegEnd + * Computes the distance to the end of the segment. * - * @return distance to segment end, in meter. + * @return distance in meter. */ -double KDriver::getDistToSegEnd() { - const tTrackSeg *seg = m_car->_trkPos.seg; +inline double KDriver::GetDistToSegEnd() const { + const tTrackSeg *seg = car_->_trkPos.seg; double ret = (seg->type == TR_STR) - ? seg->length - m_car->_trkPos.toStart // simple when straight - : (seg->arc - m_car->_trkPos.toStart) * seg->radius; // uhm, arc + ? seg->length - car_->_trkPos.toStart // simple when straight + : (seg->arc - car_->_trkPos.toStart) * seg->radius; // uhm, arc return ret; -} // getDistToSegEnd +} // GetDistToSegEnd -void KDriver::setMode(int newmode) { - if (m_mode != newmode) { - if (m_mode == NORMAL || m_mode == PITTING) { - m_correctTimer = m_simTime + 7.0; - m_correctLimit = 1000.0; +void KDriver::set_mode(int newmode) { + if (mode_ != newmode) { + if (mode_ == NORMAL || mode_ == PITTING) { + correct_timer_ = sim_time_ + 7.0; + correct_limit_ = 1000.0; } - m_mode = newmode; - } // m_mode != newmode -} // setMode + mode_ = newmode; + } // mode_ != newmode +} // set_mode /** - * getAccel + * GetAccel * Computes fitting acceleration. * * @return Acceleration scaled 0-1. */ -double KDriver::getAccel() { +double KDriver::GetAccel() { double ret = 1.0; - if (m_car->_gear > 0) { - m_accelCmd = MIN(1.0, m_accelCmd); - if (fabs(m_angle) > 0.8 && getSpeed() > 10.0) { - m_accelCmd = MAX(0.0, MIN(m_accelCmd, - 1.0 - getSpeed() / 100.0 * fabs(m_angle))); + if (car_->_gear > 0) { + accel_cmd_ = MIN(1.0, accel_cmd_); + if (fabs(angle_) > 0.8 && speed() > 10.0) { + accel_cmd_ = MAX(0.0, MIN(accel_cmd_, + 1.0 - speed() / 100.0 * fabs(angle_))); } - ret = m_accelCmd; - ret *= (m_car->_gear > 1) ? m_filterAccelSkill : 1.0; - } // if m_car->_gear + // Even the most unskilled driver can push the throttle 100% at first gear + accel_cmd_ *= (car_->_gear > 1) ? accel_skill_ : 1.0; + ret = accel_cmd_; + } // if car_->_gear return ret; -} // getAccel +} // GetAccel /** - * getBrake + * GetBrake * Computes initial brake value. * * @return brake scaled 0-1 */ -double KDriver::getBrake() { +double KDriver::GetBrake() { double ret; - if (m_car->_speed_x < -MAX_UNSTUCK_SPEED) { + if (car_->_speed_x < -MAX_UNSTUCK_SPEED) { ret = 1.0; // Car drives backward, brake } else { - ret = m_brakeCmd; // Car drives forward, normal braking. - // ret *= m_filterBrakeSkill; //Brake earlier if less skilled + brake_cmd_ *= brake_skill_; // Brake earlier if less skilled. + ret = brake_cmd_; // Car drives forward, normal braking. } return ret; -} // getBrake +} // GetBrake // Compute gear. -int KDriver::getGear() { - int ret = m_car->_gear <= 0 ? 1 : m_car->_gear; +int KDriver::GetGear() { + int ret = car_->_gear <= 0 ? 1 : car_->_gear; - if (m_car->_gear > 0) { - double gr_up = m_car->_gearRatio[m_car->_gear + m_car->_gearOffset]; - double omega = m_car->_enginerpmRedLine / gr_up; - double wr = m_car->_wheelRadius(2); + if (car_->_gear > 0) { + double gr_up = + car_->_gearRatio[car_->_gear + car_->_gearOffset]; + double omega = car_->_enginerpmRedLine / gr_up; + double wr = car_->_wheelRadius(2); - if (omega * wr * SHIFT < m_car->_speed_x) { - ret = m_car->_gear + 1; + if (omega * wr * SHIFT < car_->_speed_x) { + ret = car_->_gear + 1; } else { - double gr_down = m_car->_gearRatio[m_car->_gear + m_car->_gearOffset - 1]; - omega = m_car->_enginerpmRedLine / gr_down; - if (m_car->_gear > 1 - && omega * wr * SHIFT > m_car->_speed_x + SHIFT_MARGIN) - ret = m_car->_gear - 1; + double gr_down = + car_->_gearRatio[car_->_gear + car_->_gearOffset - 1]; + omega = car_->_enginerpmRedLine / gr_down; + if (car_->_gear > 1 + && omega * wr * SHIFT > car_->_speed_x + SHIFT_MARGIN) + ret = car_->_gear - 1; } } // if gear > 0 return ret; -} // getGear +} // GetGear // Compute the clutch value. -double KDriver::getClutch() { +double KDriver::GetClutch() { // ??? - if (1 || m_car->_gearCmd > 1) { - double maxtime = MAX(0.06, 0.32 - (m_car->_gearCmd / 65.0)); - if (m_car->_gear != m_car->_gearCmd) - m_clutchTime = maxtime; - if (m_clutchTime > 0.0) - m_clutchTime -= (RCM_MAX_DT_ROBOTS * - (0.02 + (m_car->_gearCmd / 8.0))); - return 2.0 * m_clutchTime; + if (1 || car_->_gearCmd > 1) { + double maxtime = MAX(0.06, 0.32 - (car_->_gearCmd / 65.0)); + if (car_->_gear != car_->_gearCmd) + clutch_time_ = maxtime; + if (clutch_time_ > 0.0) + clutch_time_ -= (RCM_MAX_DT_ROBOTS * + (0.02 + (car_->_gearCmd / 8.0))); + return 2.0 * clutch_time_; } else { // unreachable code??? - double drpm = m_car->_enginerpm - m_car->_enginerpmRedLine / 2.0; + double drpm = car_->_enginerpm - car_->_enginerpmRedLine / 2.0; double ctlimit = 0.9; - if (m_car->_gearCmd > 1) - ctlimit -= 0.15 + m_car->_gearCmd / 13.0; - m_clutchTime = MIN(ctlimit, m_clutchTime); - if (m_car->_gear != m_car->_gearCmd) - m_clutchTime = 0.0; - double clutcht = (ctlimit - m_clutchTime) / ctlimit; - if (m_car->_gear == 1 && m_car->_accelCmd > 0.0) - m_clutchTime += RCM_MAX_DT_ROBOTS; + if (car_->_gearCmd > 1) + ctlimit -= 0.15 + car_->_gearCmd / 13.0; + clutch_time_ = MIN(ctlimit, clutch_time_); + if (car_->_gear != car_->_gearCmd) + clutch_time_ = 0.0; + double clutcht = (ctlimit - clutch_time_) / ctlimit; + if (car_->_gear == 1 && car_->_accelCmd > 0.0) + clutch_time_ += RCM_MAX_DT_ROBOTS; - if (m_car->_gearCmd == 1 || drpm > 0) { + if (car_->_gearCmd == 1 || drpm > 0) { double speedr; - if (m_car->_gearCmd == 1) { + if (car_->_gearCmd == 1) { // Compute corresponding speed to engine rpm. double omega = - m_car->_enginerpmRedLine / m_car->_gearRatio[m_car->_gear + - m_car->_gearOffset]; - double wr = m_car->_wheelRadius(2); + car_->_enginerpmRedLine / car_->_gearRatio[car_->_gear + + car_->_gearOffset]; + double wr = car_->_wheelRadius(2); speedr = (CLUTCH_SPEED + - MAX(0.0, m_car->_speed_x)) / fabs(wr * omega); + MAX(0.0, car_->_speed_x)) / fabs(wr * omega); double clutchr = MAX(0.0, (1.0 - speedr * 2.0 * drpm / - m_car->_enginerpmRedLine)) * - (m_car->_gearCmd == - 1 ? 0.95 : (0.7 - (m_car->_gearCmd) / 30.0)); + car_->_enginerpmRedLine)) * + (car_->_gearCmd == + 1 ? 0.95 : (0.7 - (car_->_gearCmd) / 30.0)); return MIN(clutcht, clutchr); } else { // For the reverse gear. - m_clutchTime = 0.0; + clutch_time_ = 0.0; return 0.0; } } else { return clutcht; } } -} // getClutch +} // GetClutch /** - * initSkill + * InitSkill * Reads the global and the driver-specific skill values. * * @return The accumulated skill value */ -double KDriver::initSkill(tSituation * s) { - double globalSkill = m_skill = 0.0; - m_filterBrakeSkill = 1.0; - m_filterAccelSkill = 1.0; - m_filterLookaheadSkill = 1.0; - m_filterSideSkill = 1.0; +double KDriver::InitSkill(tSituation * s) { + double globalSkill = skill_ = 0.0; + brake_skill_ = 1.0; + accel_skill_ = 1.0; + lookahead_skill_ = 1.0; + side_skill_ = 1.0; if (s->_raceType != RM_TYPE_PRACTICE) { stringstream buf; @@ -1866,23 +1829,23 @@ double KDriver::initSkill(tSituation * s) { } // limits: 0.0 - 24.0 - m_skill = (globalSkill + driverSkill * 2.0) * (1.0 + driverSkill); + skill_ = (globalSkill + driverSkill * 2.0) * (1.0 + driverSkill); // Set up different handicap values - m_filterBrakeSkill = MAX(0.85, 1.0 - m_skill / 24.0 * 0.15); - m_filterAccelSkill = MAX(0.80, 1.0 - m_skill / 24.0 * 0.20); - m_filterLookaheadSkill = 1.0 / (1.0 + m_skill / 24.0); - m_filterSideSkill = 1.0 + m_skill / 24.0; + brake_skill_ = MAX(0.85, 1.0 - skill_ / 24.0 * 0.15); + accel_skill_ = MAX(0.80, 1.0 - skill_ / 24.0 * 0.20); + lookahead_skill_ = 1.0 / (1.0 + skill_ / 24.0); + side_skill_ = 1.0 + skill_ / 24.0; } // if not practice -#ifdef DEBUG - cout << "Skill: " << m_skill - << ", brake: " << m_filterBrakeSkill - << ", accel: " << m_filterAccelSkill - << ", lookA: " << m_filterLookaheadSkill - << ", sides: " << m_filterSideSkill +#ifdef KDRIVER_DEBUG + cout << "Skill: " << skill_ + << ", brake: " << brake_skill_ + << ", accel: " << accel_skill_ + << ", lookA: " << lookahead_skill_ + << ", sides: " << side_skill_ << endl; #endif - return m_skill; -} // initSkill + return skill_; +} // InitSkill diff --git a/src/drivers/kilo2008/kdriver.h b/src/drivers/kilo2008/kdriver.h index 43658804b..e39f4bd42 100644 --- a/src/drivers/kilo2008/kdriver.h +++ b/src/drivers/kilo2008/kdriver.h @@ -81,65 +81,68 @@ class KDriver { void endRace(tSituation * s); std::string bot; // to make it possible to differentiate between Kilo & Dots - // Used by Opponents - tCarElt *getCarPtr() { return m_car;} - tTrack *getTrackPtr() { return m_track;} - double getSpeed() { return m_mycardata->getSpeedInTrackDirection(); } + // Used by Opponents & Pit + tCarElt *car_ptr() const { return car_;} + tTrack *track_ptr() const { return track_;} + double speed() const { return my_cardata_->getSpeedInTrackDirection(); } protected: // Initialize - void initCa(); - void initCw(); - void initTireMu(); - void initTCLFilter(); - double initSkill(tSituation * s); + void InitCa(); + void InitCw(); + void InitTireMu(); + void InitTCLFilter(); + double InitSkill(tSituation * s); // Driving aids - double filterTCL_RWD(); - double filterTCL_FWD(); - double filterTCL_4WD(); - double filterTCL(const double accel); - double filterTrk(double accel); - double brakeDist(double allowedspeed, double mu); - double filterABS(double brake); - double filterBPit(double brake); + double FilterTCL_RWD(); + double FilterTCL_FWD(); + double FilterTCL_4WD(); + double FilterTCL(double accel); + double FilterTrk(double accel); + double FilterABS(double brake); + double FilterBPit(double brake); // Steering - double getSteer(tSituation * s); - double calcSteer(double targetAngle, int rl); - double correctSteering(double avoidsteer, double racesteer); - double smoothSteering(double steercmd); - vec2f getTargetPoint(); + double GetSteer(tSituation * s); + double CalcSteer(double targetAngle, int rl); + double CorrectSteering(double avoidsteer, double racesteer); + double SmoothSteering(double steercmd); + double GetOffset(); + vec2f TargetPoint(); + + // Throttle/brake handling + void CalcSpeed(); + double GetAccel(); + double GetBrake(); + double BrakeDist(double allowedspeed, double mu) const; + double FilterBrakeSpeed(double brake); + double FilterBColl(double brake); + double FilterOverlap(double accel); + + // Gear/clutch + int GetGear(); + double GetClutch(); // 'own' utilities - void update(tSituation * s); - double filterBrakeSpeed(double brake); - double filterBColl(double brake); - double filterOverlap(double accel); - void calcSpeed(); - void setAvoidRight() {m_avoidmode |= AVOIDRIGHT;} - void setAvoidLeft() {m_avoidmode |= AVOIDLEFT;} - void setMode(int newmode); - bool oppTooFarOnSide(tCarElt *ocar); - bool isStuck(); - double getDistToSegEnd(); - double getOffset(); - double getAccel(); - double getBrake(); - int getGear(); - double getClutch(); - double getWidth() { return m_mycardata->getWidthOnTrack();} - void checkPitStatus(tSituation *s); - void * loadDefaultSetup() const; - void mergeCarSetups(void **oldHandle, void *newHandle); + void Update(tSituation * s); + bool IsStuck(); + inline double GetDistToSegEnd() const; + void CheckPitStatus(tSituation *s); + void * LoadDefaultSetup() const; + void MergeCarSetups(void **oldHandle, void *newHandle) const; + void set_avoid_right() { avoid_mode_ |= AVOIDRIGHT; } + void set_avoid_left() { avoid_mode_ |= AVOIDLEFT; } + double width() const { return my_cardata_->getWidthOnTrack(); } + double mass() const { return CARMASS + car_->_fuel; } + double current_speed_sqr() const { return car_->_speed_x * car_->_speed_x; } + void set_mode(int newmode); // Opponent handling - Opponent * getOverlappingOpp(); - Opponent * getTakeoverOpp(); - Opponent * getSidecollOpp(); - double filterOverlappedOffset(Opponent *o); - double filterTakeoverOffset(Opponent *o); - double filterSidecollOffset(Opponent *o, const double); + Opponent * GetTakeoverOpp(); + double FilterOverlappedOffset(const Opponent *o); + double FilterTakeoverOffset(const Opponent *o); + double FilterSidecollOffset(const Opponent *o, const double incfactor); // Constants. @@ -147,65 +150,74 @@ class KDriver { enum { TEAM_FRIEND = 1, TEAM_FOE }; enum { AVOIDLEFT = 1, AVOIDRIGHT = 2, AVOIDSIDE = 4 }; - tCarElt *m_car; // Pointer to tCarElt struct. - LRaceLine *m_raceline; - Opponents *m_opponents; // The container for opponents. - Pit *m_pit; // Pointer to the pit instance. - KStrategy *m_strategy; // Pit stop strategy. - tTrack *m_track; // Track variables. + // Pointers to other classes + tCarElt *car_; // Pointer to tCarElt struct. + LRaceLine *raceline_; // The racing line + Opponents *opponents_; // The container for opponents. + Pit *pit_; // Pointer to the pit instance. + KStrategy *strategy_; // Pit stop strategy. + tTrack *track_; // Track variables. - static Cardata *m_cardata; // Data about all cars shared by all instances. - SingleCardata *m_mycardata; // Pointer to "global" data about my car. + static Cardata *cardata_; // Data about all cars shared by all instances. + SingleCardata *my_cardata_; // Pointer to "global" data about my car. - static double m_currentSimTime; // Store time to avoid useless updates. + static double current_sim_time_; // Store time to avoid useless updates. // Per robot global data - int m_mode; - int m_avoidmode; - int m_lastmode; - int m_stuckCounter; - double m_speedangle; // the angle of the speed vector - // relative to trackangle, > 0.0 points to right. - double m_angle; - double m_mass; // Mass of car + fuel. - double m_myoffset; // Offset to the track middle. - double m_laststeer; - double m_lastNSasteer; - double m_simTime; // how long since the race started - double m_avoidTime; // how long since we began avoiding - double m_correctTimer; // how long we've been correcting - double m_correctLimit; // level of divergence with raceline steering - double m_brakeDelay; - double m_currentSpeedSqr; // Square of the current speed_x. - double m_clutchTime; // Clutch timer. - double m_oldLookahead; // Lookahead for steering in the previous step. - double m_raceSteer; // steer command to get to raceline - double m_rLookahead; // how far ahead on the track we look for steering - double m_raceOffset; // offset from middle of track towards which + int car_index_; + std::string car_type_; + + // Driving modes + int mode_; + int avoid_mode_; + int last_mode_; + + // Timers + double sim_time_; // how long since the race started + double avoid_time_; // how long since we began avoiding + double correct_timer_; // how long we've been correcting + double correct_limit_; // level of divergence with raceline steering + double clutch_time_; // clutch timer + int stuck_counter_; // to determine if we are stuck + + // Car state + double angle_; + double speed_angle_; // the angle of the speed vector + // relative to trackangle, > 0.0 points to right. + double my_offset_; // Offset to the track middle. + + // Raceline data + double old_lookahead_; // Lookahead for steering in the previous step. + double race_offset_; // offset from middle of track towards which // raceline is steering - double m_avoidLftOffset; // closest opponent on the left - double m_avoidRgtOffset; // closest opponent on the right - double m_raceSpeed; // how fast raceline code says we should be going - double m_avoidSpeed; // how fast we should go if avoiding - double m_accelCmd; - double m_brakeCmd; - double m_pitOffset; - v2d m_raceTarget; // the 2d point the raceline is driving at. - double m_mincatchdist; - double m_rgtinc; - double m_lftinc; - double m_maxoffset; - double m_minoffset; - double m_rInverse; - std::string m_carType; - int m_carIndex; + double race_speed_; // how fast raceline code says we should be going + double avoid_speed_; // how fast we should go if avoiding + double brake_delay_; // configurable, brake a wee bit late + double pit_offset_; // configurable, pit lane can start late/early + + // Commands + double accel_cmd_; // throttle pedal command [0..1] + double brake_cmd_; // brake pedal command [0..1] + double race_steer_; // steer command to get to raceline + double last_steer_; // previous steer command + double last_nsa_steer_; + + // Handling traffic + double min_catch_dist_; // used in considering takeover + double avoid_lft_offset_; // closest opponent on the left + double avoid_rgt_offset_; // closest opponent on the right + double rgt_inc_; + double lft_inc_; + double max_offset_; + double min_offset_; + double r_inverse_; // Skilling - double m_skill; - double m_filterBrakeSkill; - double m_filterAccelSkill; - double m_filterLookaheadSkill; - double m_filterSideSkill; + double skill_; + double brake_skill_; + double accel_skill_; + double lookahead_skill_; + double side_skill_; // Data that should stay constant after first initialization. int MAX_UNSTUCK_COUNT; @@ -234,6 +246,7 @@ class KDriver { static const double LOOKAHEAD_FACTOR; static const double WIDTHDIV; static const double BORDER_OVERTAKE_MARGIN; + static const double SIDECOLL_MARGIN; static const double OVERTAKE_OFFSET_SPEED; static const double PIT_LOOKAHEAD; static const double PIT_BRAKE_AHEAD; @@ -246,9 +259,6 @@ class KDriver { static const double CATCH_FACTOR; static const double TEAM_REAR_DIST; static const double LET_OVERTAKE_FACTOR; - - public: - static const int TEAM_DAMAGE_CHANGE_LEAD; // Used in opponent.cpp too }; #endif // SRC_DRIVERS_KILO2008_KDRIVER_H_ diff --git a/src/drivers/kilo2008/opponent.cpp b/src/drivers/kilo2008/opponent.cpp index 58c6b636a..c00d43260 100644 --- a/src/drivers/kilo2008/opponent.cpp +++ b/src/drivers/kilo2008/opponent.cpp @@ -35,8 +35,6 @@ using std::string; using std::list; -// class variables and constants. -tTrack * Opponent::m_track; // [m] distance on the track ahead to check other cars. const double Opponent::FRONTCOLLDIST = 200.0; // [m] distance on the track behind to check other cars. @@ -53,58 +51,62 @@ const double Opponent::LAP_BACK_TIME_PENALTY = -30.0; const double Opponent::OVERLAP_WAIT_TIME = 5.0; // [m/s] avoid overlapping opponents to stuck behind me. const double Opponent::SPEED_PASS_MARGIN = 5.0; +// When to change position in the team? +const int Opponent::TEAM_DAMAGE_CHANGE_LEAD = 800; + +const double Opponents::TEAM_REAR_DIST = 50.0; // Constructor Opponent::Opponent(tCarElt *car, SingleCardata * cardata, int index) { - m_car = car; - m_cardata = cardata; - m_index = index; - m_teammate = false; + car_ = car; + cardata_ = cardata; + index_ = index; + teammate_ = false; } -void Opponent::update(tSituation *s, KDriver *driver) { +void Opponent::Update(tSituation *s, KDriver *driver) { // Init state of opponent to ignore. - m_state = OPP_IGNORE; + state_ = OPP_IGNORE; // If this car is out of the simulation or is in pits, ignore it. - if ((m_car->_state & RM_CAR_STATE_NO_SIMU) - || (m_car->_state & RM_CAR_STATE_PIT)) + if ((car_->_state & RM_CAR_STATE_NO_SIMU) + || (car_->_state & RM_CAR_STATE_PIT)) return; // Updating distance along the middle. - tCarElt *mycar = driver->getCarPtr(); - double oppToStart = m_car->_trkPos.seg->lgfromstart + getDistToSegStart(); - m_distance = oppToStart - mycar->_distFromStartLine; - if (m_distance > m_track->length / 2.0) { - m_distance -= m_track->length; - } else if (m_distance < -m_track->length / 2.0) { - m_distance += m_track->length; + tCarElt *mycar = driver->car_ptr(); + tTrack *track = driver->track_ptr(); + double oppToStart = car_->_trkPos.seg->lgfromstart + DistToSegStart(); + distance_ = oppToStart - mycar->_distFromStartLine; + if (distance_ > track->length / 2.0) { + distance_ -= track->length; + } else if (distance_ < -track->length / 2.0) { + distance_ += track->length; } - const double SIDECOLLDIST = MAX(m_car->_dimension_x, mycar->_dimension_x); + const double SIDECOLLDIST = MAX(car_->_dimension_x, mycar->_dimension_x); // Is opponent in relevant range BACKCOLLDIST..FRONTCOLLDIST? - if (BetweenStrict(m_distance, BACKCOLLDIST, FRONTCOLLDIST)) { + if (BetweenStrict(distance_, BACKCOLLDIST, FRONTCOLLDIST)) { // Is opponent aside? - if (BetweenStrict(m_distance, -SIDECOLLDIST, SIDECOLLDIST)) { - m_sidedist = m_car->_trkPos.toMiddle - mycar->_trkPos.toMiddle; - m_state |= OPP_SIDE; + if (BetweenStrict(distance_, -SIDECOLLDIST, SIDECOLLDIST)) { + state_ |= OPP_SIDE; } // Is opponent in front and slower? - if (m_distance > SIDECOLLDIST && getSpeed() <= driver->getSpeed()) { - m_state |= OPP_FRONT; + if (distance_ > SIDECOLLDIST && speed() <= driver->speed()) { + state_ |= OPP_FRONT; - if (isQuickerTeammate(mycar)) - m_state |= OPP_FRONT_FOLLOW; + if (IsQuickerTeammate(mycar)) + state_ |= OPP_FRONT_FOLLOW; - m_distance -= SIDECOLLDIST; - m_distance -= LENGTH_MARGIN; + distance_ -= SIDECOLLDIST; + distance_ -= LENGTH_MARGIN; // If the distance is small we compute it more accurate. - if (m_distance < EXACT_DIST) { + if (distance_ < EXACT_DIST) { straight2f carFrontLine( mycar->_corner_x(FRNT_LFT), mycar->_corner_y(FRNT_LFT), @@ -114,96 +116,75 @@ void Opponent::update(tSituation *s, KDriver *driver) { mycar->_corner_y(FRNT_LFT)); double mindist = FLT_MAX; - for (int i = 0; i < 4; i++) { - vec2f corner(m_car->_corner_x(i), m_car->_corner_y(i)); + for (int i = 0; i < 4; ++i) { + vec2f corner(car_->_corner_x(i), car_->_corner_y(i)); double dist = carFrontLine.dist(corner); mindist = MIN(dist, mindist); } - m_distance = MIN(m_distance, mindist); + distance_ = MIN(distance_, mindist); } // if small distance - m_catchdist = driver->getSpeed() * m_distance - / (driver->getSpeed() - getSpeed()); - - m_sidedist = m_car->_trkPos.toMiddle - mycar->_trkPos.toMiddle; - double cardist = fabs(m_sidedist) - fabs(getWidth() / 2.0) - + double side_dist = car_->_trkPos.toMiddle - mycar->_trkPos.toMiddle; + double cardist = fabs(side_dist) - fabs(width() / 2.0) - mycar->_dimension_y / 2.0; if (cardist < SIDE_MARGIN) - m_state |= OPP_COLL; - } else if (m_distance < -SIDECOLLDIST - && getSpeed() > driver->getSpeed() - SPEED_PASS_MARGIN) { + state_ |= OPP_COLL; + } else if (distance_ < -SIDECOLLDIST + && speed() > driver->speed() - SPEED_PASS_MARGIN) { // Is opponent behind and faster. - m_catchdist = driver->getSpeed() * m_distance - / (getSpeed() - driver->getSpeed()); - m_state |= OPP_BACK; - m_distance -= SIDECOLLDIST; - m_distance -= LENGTH_MARGIN; - } else if (m_distance > SIDECOLLDIST && getSpeed() > driver->getSpeed()) { + state_ |= OPP_BACK; + distance_ -= SIDECOLLDIST; + distance_ -= LENGTH_MARGIN; + } else if (distance_ > SIDECOLLDIST && speed() > driver->speed()) { // Opponent is in front and faster. - m_state |= OPP_FRONT_FAST; - if (isQuickerTeammate(mycar)) - m_state |= OPP_FRONT_FOLLOW; - m_distance -= SIDECOLLDIST; - if (m_distance < 20.0 - (getSpeed() - driver->getSpeed()) * 4) - m_state |= OPP_FRONT; + state_ |= OPP_FRONT_FAST; + if (IsQuickerTeammate(mycar)) + state_ |= OPP_FRONT_FOLLOW; + distance_ -= SIDECOLLDIST; + if (distance_ < 20.0 - (speed() - driver->speed()) * 4) + state_ |= OPP_FRONT; } } // Check if we should let overtake the opponent. - updateOverlapTimer(s, mycar); - if (m_overlaptimer > OVERLAP_WAIT_TIME) - m_state |= OPP_LETPASS; - - m_brakedistance = m_distance - m_car->_dimension_x; -} // update + UpdateOverlapTimer(s, mycar); +} // Update // Compute the length to the start of the segment. -double Opponent::getDistToSegStart() const { - double ret = (m_car->_trkPos.seg->type == TR_STR) - ? m_car->_trkPos.toStart - : m_car->_trkPos.toStart * m_car->_trkPos.seg->radius; +inline double Opponent::DistToSegStart() const { + double ret = (car_->_trkPos.seg->type == TR_STR) + ? car_->_trkPos.toStart + : car_->_trkPos.toStart * car_->_trkPos.seg->radius; return ret; } // getDistToSegStart // Update overlaptimers of opponents. -void Opponent::updateOverlapTimer(tSituation * const s, tCarElt * const mycar) { - if ((m_car->race.laps > mycar->race.laps) || isQuickerTeammate(mycar)) { - if (isState(OPP_BACK | OPP_SIDE)) { - m_overlaptimer += s->deltaTime; - } else if (isState(OPP_FRONT)) { - m_overlaptimer = LAP_BACK_TIME_PENALTY; +void Opponent::UpdateOverlapTimer(tSituation * const s, tCarElt * const mycar) { + if ((car_->race.laps > mycar->race.laps) || IsQuickerTeammate(mycar)) { + if (HasState(OPP_BACK | OPP_SIDE)) { + overlap_timer_ += s->deltaTime; + } else if (HasState(OPP_FRONT)) { + overlap_timer_ = LAP_BACK_TIME_PENALTY; } else { - if (m_overlaptimer > 0.0) { - if (isState(OPP_FRONT_FAST)) { - m_overlaptimer = MIN(0.0, m_overlaptimer); + if (overlap_timer_ > 0.0) { + if (HasState(OPP_FRONT_FAST)) { + overlap_timer_ = MIN(0.0, overlap_timer_); } else { - m_overlaptimer -= s->deltaTime; + overlap_timer_ -= s->deltaTime; } } else { - m_overlaptimer += s->deltaTime; + overlap_timer_ += s->deltaTime; } } } else { - m_overlaptimer = 0.0; + overlap_timer_ = 0.0; } -} // updateOverlapTimer - -/** - * Returns true, if the other car is our teammate - * and has significantly less damage - * (defined in KDriver::TEAM_DAMAGE_CHANGE_LEAD) - * - * @param mycar pointer to the other car - * @return true, if the opponent is our teammate - */ -bool -Opponent::isQuickerTeammate(tCarElt * const mycar) { - return (isTeammate() - && (mycar->_dammage - m_car->_dammage > KDriver::TEAM_DAMAGE_CHANGE_LEAD)); -} // isQuickerTeammate + if (overlap_timer_ > OVERLAP_WAIT_TIME) + state_ |= OPP_LETPASS; +} // UpdateOverlapTimer /** @@ -216,11 +197,11 @@ Opponent::isQuickerTeammate(tCarElt * const mycar) { * @param c Opponent car data */ Opponents::Opponents(tSituation *s, KDriver *driver, Cardata *c) { - m_opps = new list; - const tCarElt *ownCar = driver->getCarPtr(); + opps_ = new list; + const tCarElt *ownCar = driver->car_ptr(); // Step through all the cars - for (int i = 0; i < s->_ncars; i++) { + for (int i = 0; i < s->_ncars; ++i) { // If it is not our own car if (s->cars[i] != ownCar) { // Create and set up new opponent @@ -228,46 +209,44 @@ Opponents::Opponents(tSituation *s, KDriver *driver, Cardata *c) { s->cars[i], // car ptr c->findCar(s->cars[i]), // car data ptr i); // index - m_opps->push_back(opp); // Store it in list + opps_->push_back(opp); // Store it in list } // if s->cars[i] } // for i - - Opponent::setTrackPtr(driver->getTrackPtr()); } // Opponents::Opponents /** - * update + * Update * Makes every opponent update its own data. * * @param s Situation provided by TORCS * @param driver Our own robot */ -void Opponents::update(tSituation *s, KDriver *driver) { +void Opponents::Update(tSituation *s, KDriver *driver) { // for_each(begin(), end(), update); - for (list::iterator it = begin(); it != end(); it++) - it->update(s, driver); -} // update + for (list::iterator it = begin(); it != end(); ++it) + it->Update(s, driver); +} // Update // for find() inline bool operator==(const Opponent& o, const std::string s) - { return !s.compare(o.getCarPtr()->_name); } + { return !s.compare(o.car_ptr()->_name); } /** - * setTeamMate + * SetTeamMate * Search the opponent list for our own teammate, * based on the teammate name given in the config as "teammate". * * @param car Our own car, to read its config */ -void Opponents::setTeamMate(const tCarElt *car) { +void Opponents::SetTeamMate(const tCarElt *car) { string teammate( GfParmGetStr(car->_paramsHandle, KILO_SECT_PRIV, KILO_ATT_TEAMMATE, "")); list::iterator found = find(begin(), end(), teammate); if (found != end()) - found->markAsTeamMate(); -} // setTeamMate + found->set_teammate(); +} // SetTeamMate /** @@ -276,13 +255,102 @@ void Opponents::setTeamMate(const tCarElt *car) { * @param [in] state: we only care for an opponent in this state * @return pointer to the opponent we've found, or NULL */ -Opponent * Opponents::getOppByState(const int state) { +Opponent * Opponents::GetOppByState(const int state) { Opponent *ret = NULL; - for (list::iterator it = begin(); it != end(); it++) { - if (it->isState(state)) { + for (list::iterator it = begin(); it != end(); ++it) { + if (it->HasState(state)) { ret = &(*it); break; } } // for it return ret; -} // getOppByState +} // GetOppByState + + +/** + * Decide if there is a car on the side we are to collide with... + * + * @param[in] car Our own car + * @return Side collision car pointer or NULL + */ +Opponent * Opponents::GetSidecollOpp(const tCarElt *car) { + Opponent *ret = NULL; + for (list::iterator it = begin(); it != end(); ++it) { + tCarElt *ocar = it->car_ptr(); + + if (ocar->_state > RM_CAR_STATE_PIT) // Dont care for opponents in the pit + continue; + + // if opp is too far on side + if (it->IsTooFarOnSide(car)) + continue; + + if (it->HasState(OPP_SIDE)) { // If opponent is on our side + ret = &(*it); + break; + } // if OPP_SIDE + } // for it + + return ret; +} // GetSidecollOpp + + +/** + * Decide if there is a car behind overlapping us. + * + * A1) Teammate behind with more laps should overtake. + * A2) Slipstreaming: the less damaged teammate is also allowed to pass + * if on the same lap. + * The position change happens when the damage difference is greater + * than TEAM_DAMAGE_CHANGE_LEAD. + * B) Let other, overlapping opponents get by. + + * @return overlapping car pointer or NULL + */ +Opponent * Opponents::GetOverlappingOpp(const tCarElt *car) { + Opponent *ret = NULL; + double mindist = -1000.0; + + for (list::iterator it = begin(); it != end(); ++it) { + tCarElt *ocar = it->car_ptr(); + double oppDistance = it->distance(); + + if (( // If teammate has more laps under his belt, + (it->teammate() && ocar->race.laps > car->race.laps) + || // or teammate is less damaged, let him go + it->IsQuickerTeammate(car)) + && (oppDistance > -TEAM_REAR_DIST) // if close enough + && (oppDistance < -car->_dimension_x)) { + // Behind, larger distances are smaller ("more negative"). + if (oppDistance > mindist) { + mindist = oppDistance; + ret = &(*it); + } + } else if (it->HasState(OPP_LETPASS)) { + // Behind, larger distances are smaller ("more negative"). + if (oppDistance > mindist) { + mindist = oppDistance; + ret = &(*it); + } + } // else if + } // for i + + return ret; +} // GetOverlappingOpp + + +/** + * Checks if opponent is too much on either side of the track, + * (doesn't occupy center part of the segment) + * and whether we are 5+ metres far. + * + * @param [in] ocar the opponent car + * @return true if the opp. is too far on either side +*/ +bool Opponent::IsTooFarOnSide(const tCarElt *mycar) const { + bool ret = false; + if (fabs(car_->_trkPos.toMiddle) > mycar->_trkPos.seg->width / 2 + 3.0 + && fabs(mycar->_trkPos.toMiddle - car_->_trkPos.toMiddle) >= 5.0) + ret = true; + return ret; +} // IsTooFarOnSide diff --git a/src/drivers/kilo2008/opponent.h b/src/drivers/kilo2008/opponent.h index d4da1a82e..a0a61aae5 100644 --- a/src/drivers/kilo2008/opponent.h +++ b/src/drivers/kilo2008/opponent.h @@ -50,49 +50,45 @@ class Opponent { public: Opponent(tCarElt *car, SingleCardata *cardata, int index); - static void setTrackPtr(tTrack * const track) {Opponent::m_track = track;} - tCarElt *getCarPtr() const {return m_car;} - double getDistance() const {return m_distance;} - double getWidth() const {return m_cardata->getWidthOnTrack();} - double getSpeed() const {return m_cardata->getSpeedInTrackDirection();} - int getIndex() const {return m_index;} + // Accessors + inline tCarElt *car_ptr() const { return car_; } + inline double distance() const { return distance_; } + inline double width() const { return cardata_->getWidthOnTrack(); } + inline double speed() const { return cardata_->getSpeedInTrackDirection(); } + inline int index() const { return index_; } + inline bool teammate() const { return teammate_; } - inline bool isState(const int state) const - { return static_cast(m_state & state); } - inline bool isTeammate() const {return m_teammate;} - bool isQuickerTeammate(tCarElt * const mycar); - inline bool isOnRight(const double dMiddle) - { return (dMiddle > m_car->_trkPos.toMiddle) ? true : false; } + // State queries + inline bool HasState(const int state) const + { return static_cast(state_ & state); } + inline bool IsQuickerTeammate(const tCarElt *mycar) const + { return (teammate_ + && (mycar->_dammage - car_->_dammage > TEAM_DAMAGE_CHANGE_LEAD));} + inline bool IsOnRight(const double dMiddle) const + { return (dMiddle > car_->_trkPos.toMiddle) ? true : false; } + bool IsTooFarOnSide(const tCarElt *mycar) const; + + // Mutators + inline void set_teammate() {teammate_ = true;} + void Update(tSituation *s, KDriver *driver); - inline void markAsTeamMate() {m_teammate = true;} - void update(tSituation *s, KDriver *driver); private: - double getDistToSegStart() const; - void updateOverlapTimer(tSituation * const s, tCarElt * const mycar); + // distance minus opponent car length + inline double brake_distance() const {return distance_ - car_->_dimension_x;} + inline double DistToSegStart() const; + void UpdateOverlapTimer(tSituation * const s, tCarElt * const mycar); // approximation of the real distance, negative if the opponent is behind. - double m_distance; - // distance minus opponent car length - double m_brakedistance; - // distance needed to catch the opponent (linear estimate). - double m_catchdist; - // approx distance of center of gravity of the cars. - double m_sidedist; - // State variable to characterize the relation to the opponent, - // e. g. opponent is behind. - int m_state; - int m_index; - double m_overlaptimer; + double distance_; - tCarElt *m_car; - SingleCardata *m_cardata; // Pointer to global data about this opponent. - bool m_teammate; // Is this opponent a team mate of me - // TODO(kilo): configure it in setup XML? - - // class variables. - static tTrack *m_track; + int state_; // State describes the relation to the opp, eg. opp is behind + int index_; + double overlap_timer_; + tCarElt *car_; + SingleCardata *cardata_; // Pointer to global data about this opponent. + bool teammate_; // Is this opponent a team mate of me // constants. static const double FRONTCOLLDIST; @@ -103,6 +99,7 @@ class Opponent { static const double LAP_BACK_TIME_PENALTY; static const double OVERLAP_WAIT_TIME; static const double SPEED_PASS_MARGIN; + static const int TEAM_DAMAGE_CHANGE_LEAD; }; @@ -111,17 +108,20 @@ class Opponent { class Opponents { public: Opponents(tSituation *s, KDriver *driver, Cardata *cardata); - ~Opponents() {delete m_opps;} + ~Opponents() { if (opps_ != NULL) delete opps_;} - void update(tSituation *s, KDriver *driver); - void setTeamMate(const tCarElt *car); - Opponent *getOppByState(const int state); + void Update(tSituation *s, KDriver *driver); + void SetTeamMate(const tCarElt *car); + Opponent *GetOppByState(const int state); + Opponent *GetSidecollOpp(const tCarElt *car); + Opponent *GetOverlappingOpp(const tCarElt *car); - inline std::list::iterator begin() {return m_opps->begin();} - inline std::list::iterator end() {return m_opps->end();} + inline std::list::iterator begin() {return opps_->begin();} + inline std::list::iterator end() {return opps_->end();} private: - std::list *m_opps; + std::list *opps_; + static const double TEAM_REAR_DIST; }; diff --git a/src/drivers/kilo2008/pit.cpp b/src/drivers/kilo2008/pit.cpp index 3351da772..7e7c31020 100644 --- a/src/drivers/kilo2008/pit.cpp +++ b/src/drivers/kilo2008/pit.cpp @@ -32,160 +32,160 @@ const double Pit::SPEED_LIMIT_MARGIN = 0.5; Pit::Pit(const tSituation * s, KDriver * driver, const double pitoffset) { - m_track = driver->getTrackPtr(); - m_car = driver->getCarPtr(); - m_mypit = driver->getCarPtr()->_pit; - m_pitinfo = &m_track->pits; - m_pitstop = m_inpitlane = false; - m_pittimer = 0.0; + track_ = driver->track_ptr(); + car_ = driver->car_ptr(); + mypit_ = driver->car_ptr()->_pit; + pitinfo_ = &track_->pits; + pit_planned_ = in_pitlane_ = false; + pit_timer_ = 0.0; - if (m_mypit != NULL) { - m_speedlimit = m_pitinfo->speedLimit - SPEED_LIMIT_MARGIN; - m_speedlimitsqr = pow(m_speedlimit, 2); - m_pitspeedlimitsqr = pow(m_pitinfo->speedLimit, 2); + if (mypit_ != NULL) { + speed_limit_ = pitinfo_->speedLimit - SPEED_LIMIT_MARGIN; + pit_speed_limit_sqr_ = pow(pitinfo_->speedLimit, 2); // Compute pit spline points along the track. - m_p[3].x = m_mypit->pos.seg->lgfromstart + m_mypit->pos.toStart; - m_p[2].x = m_p[3].x - m_pitinfo->len; - m_p[4].x = m_p[3].x + m_pitinfo->len; - m_p[0].x = m_pitinfo->pitEntry->lgfromstart + pitoffset; - m_p[1].x = m_pitinfo->pitStart->lgfromstart; + points_[3].x = mypit_->pos.seg->lgfromstart + mypit_->pos.toStart; + points_[2].x = points_[3].x - pitinfo_->len; + points_[4].x = points_[3].x + pitinfo_->len; + points_[0].x = pitinfo_->pitEntry->lgfromstart + pitoffset; + points_[1].x = pitinfo_->pitStart->lgfromstart; // Use nPitSeg to respect the pit speed limit on Migrants e.a. - m_p[5].x = m_pitinfo->pitStart->lgfromstart - + m_pitinfo->nPitSeg * m_pitinfo->len; - m_p[6].x = m_pitinfo->pitExit->lgfromstart; + points_[5].x = pitinfo_->pitStart->lgfromstart + + pitinfo_->nPitSeg * pitinfo_->len; + points_[6].x = pitinfo_->pitExit->lgfromstart; - m_pitentry = m_p[0].x; - m_pitexit = m_p[6].x; + pit_entry_ = points_[0].x; + pit_exit_ = points_[6].x; // Normalizing spline segments to >= 0.0. for (int i = 0; i < NPOINTS; i++) { - m_p[i].s = 0.0; - m_p[i].x = toSplineCoord(m_p[i].x); + points_[i].s = 0.0; + points_[i].x = ToSplineCoord(points_[i].x); } // for i // Fix broken pit exit. - if (m_p[6].x < m_p[5].x) - m_p[6].x = m_p[5].x + 50.0; + if (points_[6].x < points_[5].x) + points_[6].x = points_[5].x + 50.0; // Fix point for first pit if necessary. - if (m_p[1].x > m_p[2].x) - m_p[1].x = m_p[2].x; + if (points_[1].x > points_[2].x) + points_[1].x = points_[2].x; // Fix point for last pit if necessary. - if (m_p[4].x > m_p[5].x) - m_p[5].x = m_p[4].x; + if (points_[4].x > points_[5].x) + points_[5].x = points_[4].x; - double sign = (m_pitinfo->side == TR_LFT) ? 1.0 : -1.0; - m_p[0].y = 0.0; - m_p[6].y = 0.0; + double sign = (pitinfo_->side == TR_LFT) ? 1.0 : -1.0; + points_[0].y = 0.0; + points_[6].y = 0.0; for (int i = 1; i < NPOINTS - 1; i++) { - m_p[i].y = fabs(m_pitinfo->driversPits->pos.toMiddle) - m_pitinfo->width; - m_p[i].y *= sign; + points_[i].y = fabs(pitinfo_->driversPits->pos.toMiddle) + - pitinfo_->width; + points_[i].y *= sign; } // for i - m_p[3].y = fabs(m_pitinfo->driversPits->pos.toMiddle + 1.0) * sign; - m_spline = new Spline(NPOINTS, m_p); + points_[3].y = fabs(pitinfo_->driversPits->pos.toMiddle + 1.0) * sign; + spline_ = new Spline(NPOINTS, points_); } // if pit not null } // Pit::Pit Pit::~Pit() { - if (m_mypit != NULL) - delete m_spline; + if (mypit_ != NULL) + delete spline_; } // Pit::~Pit // Transforms track coordinates to spline parameter coordinates. -double Pit::toSplineCoord(const double x) const { - double ret = x - m_pitentry; +double Pit::ToSplineCoord(const double x) const { + double ret = x - pit_entry_; while (ret < 0.0) - ret += m_track->length; + ret += track_->length; return ret; -} // toSplineCoord +} // ToSplineCoord // Computes offset to track middle for trajectory. -double Pit::getPitOffset(const double offset, double fromstart) { - if (m_mypit != NULL) { - if (getInPit() || (getPitstop() && isBetween(fromstart))) { - fromstart = toSplineCoord(fromstart); - return m_spline->evaluate(fromstart); +double Pit::CalcPitOffset(const double offset, double fromstart) { + if (mypit_ != NULL) { + if (in_pitlane() || (pit_planned() && is_between(fromstart))) { + fromstart = ToSplineCoord(fromstart); + return spline_->evaluate(fromstart); } } return offset; -} // getPitOffset +} // CalcPitOffset // Sets the pitstop flag if we are not in the pit range. -void Pit::setPitstop(bool pitstop) { - if (m_mypit != NULL) { - double fromstart = m_car->_distFromStartLine; +void Pit::set_pitstop(bool pitstop) { + if (mypit_ != NULL) { + double fromstart = car_->_distFromStartLine; - if (!isBetween(fromstart)) { - m_pitstop = pitstop; + if (!is_between(fromstart)) { + pit_planned_ = pitstop; } else { if (!pitstop) { - m_pitstop = pitstop; - m_pittimer = 0.0; + pit_planned_ = pitstop; + pit_timer_ = 0.0; } } } -} // setPitstop +} // set_pitstop // Check if the argument fromstart is in the range of the pit. -bool Pit::isBetween(const double fromstart) const { +bool Pit::is_between(const double fromstart) const { bool ret = false; - if (m_pitentry <= m_pitexit) { - if (fromstart >= m_pitentry && fromstart <= m_pitexit) { + if (pit_entry_ <= pit_exit_) { + if (fromstart >= pit_entry_ && fromstart <= pit_exit_) { ret = true; } } else { // Warning: TORCS reports sometimes negative values for "fromstart"! - if (fromstart <= m_pitexit || fromstart >= m_pitentry) { + if (fromstart <= pit_exit_ || fromstart >= pit_entry_) { ret = true; } } // if pitentry <= pitexit return ret; -} // isBetween +} // is_between // Checks if we stay too long without getting captured by the pit. // Distance is the distance to the pit along the track, when the pit is // ahead it is > 0, if we overshoot the pit it is < 0. -bool Pit::isTimeout(const double distance) { +bool Pit::is_timeout(const double distance) { bool ret = false; - if (m_car->_speed_x > 1.0 || distance > 3.0 || !getPitstop()) { - m_pittimer = 0.0; + if (car_->_speed_x > 1.0 || distance > 3.0 || !pit_planned()) { + pit_timer_ = 0.0; } else { - m_pittimer += RCM_MAX_DT_ROBOTS; - if (m_pittimer > 3.0) { - m_pittimer = 0.0; + pit_timer_ += RCM_MAX_DT_ROBOTS; + if (pit_timer_ > 3.0) { + pit_timer_ = 0.0; ret = true; } } return ret; -} // isTimeout +} // is_timeout // Update pit data and strategy. -void Pit::update() { - if (m_mypit != NULL) { - if (isBetween(m_car->_distFromStartLine)) { - if (getPitstop()) { - setInPit(true); +void Pit::Update() { + if (mypit_ != NULL) { + if (is_between(car_->_distFromStartLine)) { + if (pit_planned()) { + in_pitlane_ = true; } } else { - setInPit(false); + in_pitlane_ = false; } - if (getPitstop()) - m_car->_raceCmd = RM_CMD_PIT_ASKED; + if (pit_planned()) + car_->_raceCmd = RM_CMD_PIT_ASKED; } -} // update +} // Update diff --git a/src/drivers/kilo2008/pit.h b/src/drivers/kilo2008/pit.h index 6590c2c4e..ba4e5e842 100644 --- a/src/drivers/kilo2008/pit.h +++ b/src/drivers/kilo2008/pit.h @@ -36,52 +36,47 @@ class Pit { Pit(const tSituation * s, KDriver * driver, const double PitOffset); ~Pit(); - void setPitstop(const bool pitstop); - inline bool getPitstop() const {return m_pitstop;} - inline void setInPit(const bool inpitlane) {m_inpitlane = inpitlane;} - inline bool getInPit() const {return m_inpitlane;} + inline bool pit_planned() const { return pit_planned_; } + inline bool in_pitlane() const { return in_pitlane_; } + inline double speed_limit() const { return speed_limit_; } + inline double speed_limit_sqr() const { return pow(speed_limit_, 2); } - double getPitOffset(const double offset, double fromstart); + inline double n_start() const { return points_[1].x; } + inline double n_loc() const { return points_[3].x; } + inline double n_end() const { return points_[5].x; } + inline double n_entry() const { return points_[0].x; } - bool isBetween(const double fromstart) const; - bool isTimeout(const double distance); + inline double speed_limit_brake(const double speedsqr) const + { return (speedsqr - speed_limit_sqr()) + / (pit_speed_limit_sqr_ - speed_limit_sqr()); } - inline double getNPitStart() const {return m_p[1].x;} - inline double getNPitLoc() const {return m_p[3].x;} - inline double getNPitEnd() const {return m_p[5].x;} - inline double getNPitEntry() const {return m_p[0].x;} - - double toSplineCoord(double x) const; - - inline double getSpeedlimitSqr() const {return m_speedlimitsqr;} - inline double getSpeedlimit() const {return m_speedlimit;} - inline double getSpeedLimitBrake(const double speedsqr) const - {return (speedsqr - m_speedlimitsqr) - / (m_pitspeedlimitsqr - m_speedlimitsqr);} - - void update(); + void set_pitstop(const bool pitstop); + bool is_timeout(const double distance); + double CalcPitOffset(const double offset, double fromstart); + double ToSplineCoord(double x) const; + void Update(); private: - tTrack *m_track; - tCarElt *m_car; - tTrackOwnPit *m_mypit; // Pointer to my pit. - tTrackPitInfo *m_pitinfo; // General pit info. + bool is_between(const double fromstart) const; - enum - { NPOINTS = 7 }; - SplinePoint m_p[NPOINTS]; // Spline points. - Spline *m_spline; // Spline. + tTrack *track_; + tCarElt *car_; + tTrackOwnPit *mypit_; // Pointer to my pit. + tTrackPitInfo *pitinfo_; // General pit info. - bool m_pitstop; // Pitstop planned. - bool m_inpitlane; // We are still in the pit lane. - double m_pitentry; // Distance to start line of the pit entry. - double m_pitexit; // Distance to the start line of the pit exit. + enum { NPOINTS = 7 }; + SplinePoint points_[NPOINTS]; // Spline points. + Spline *spline_; // Spline. - double m_speedlimitsqr; // Pit speed limit squared. - double m_speedlimit; // Pit speed limit. - double m_pitspeedlimitsqr; // The original speedlimit squared. + bool pit_planned_; // Pitstop planned. + bool in_pitlane_; // We are still in the pit lane. + double pit_entry_; // Distance to start line of the pit entry. + double pit_exit_; // Distance to the start line of the pit exit. - double m_pittimer; // Timer for pit timeouts. + double speed_limit_; // Pit speed limit. + double pit_speed_limit_sqr_; // The original speedlimit squared. + + double pit_timer_; // Timer for pit timeouts. static const double SPEED_LIMIT_MARGIN; }; diff --git a/src/drivers/kilo2008/raceline.cpp b/src/drivers/kilo2008/raceline.cpp index 99b9a7842..9e8cf2246 100644 --- a/src/drivers/kilo2008/raceline.cpp +++ b/src/drivers/kilo2008/raceline.cpp @@ -77,7 +77,7 @@ void LRaceLine::SetSegmentInfo(const tTrackSeg * pseg, const int i, const double l) { if (pseg) { std::pair info(i, l); - m_SegInfo.push_back(info); + seg_info_.push_back(info); } } @@ -89,7 +89,7 @@ void LRaceLine::SetSegmentInfo(const tTrackSeg * pseg, void LRaceLine::SplitTrack(const tTrack * const ptrack, const int rl, const tSituation *s) { - m_lDivLength = 3; // Length of path elements in meters + div_length_ = 3; // Length of path elements in meters const tTrackSeg *psegCurrent = ptrack->seg; double dAngle = psegCurrent->angle[TR_ZS]; @@ -115,10 +115,10 @@ void LRaceLine::SplitTrack(const tTrack * const ptrack, } // if pits.type - m_SegInfo.reserve(ptrack->nseg); + seg_info_.reserve(ptrack->nseg); unsigned int i = 0; do { - int Divisions = static_cast(psegCurrent->length / m_lDivLength) + 1; + int Divisions = static_cast(psegCurrent->length / div_length_) + 1; double Step = psegCurrent->length / Divisions; SetSegmentInfo(psegCurrent, i, Step); @@ -220,30 +220,30 @@ void LRaceLine::SplitTrack(const tTrack * const ptrack, double dx = -psegCurrent->width * sin(dAngle) / 2; double dy = psegCurrent->width * cos(dAngle) / 2; - if (m_Seg.size() <= i) { // if it is the first run + if (seg_.size() <= i) { // if it is the first run // Create & store new segment rlSegment *newSeg = new rlSegment; - m_Seg.push_back(*newSeg); + seg_.push_back(*newSeg); delete newSeg; } - // We can be quite sure m_Seg[i] exists as we created it just above - m_Seg[i].txLeft = dXPos + dx; - m_Seg[i].tyLeft = dYPos + dy; - m_Seg[i].txRight = dXPos - dx; - m_Seg[i].tyRight = dYPos - dy; - m_Seg[i].tLane = 0.5; - m_Seg[i].tLaneLMargin = lft_margin; - m_Seg[i].tLaneRMargin = rgt_margin; - m_Seg[i].tFriction = psegCurrent->surface->kFriction; - SetSegCamber(psegCurrent, i); + // We can be quite sure seg_[i] exists as we created it just above + seg_[i].txLeft = dXPos + dx; + seg_[i].tyLeft = dYPos + dy; + seg_[i].txRight = dXPos - dx; + seg_[i].tyRight = dYPos - dy; + seg_[i].tLane = 0.5; + seg_[i].tLaneLMargin = lft_margin; + seg_[i].tLaneRMargin = rgt_margin; + seg_[i].tFriction = psegCurrent->surface->kFriction; + SetSegmentCamber(psegCurrent, i); // cerr << i << " " << psegCurrent->name << endl; // ??? ugly trick for dirt - // if (m_Seg[i].tFriction < 1) - // m_Seg[i].tFriction *= 0.90; + // if (seg_[i].tFriction < 1) + // seg_[i].tFriction *= 0.90; - m_Seg[i].UpdateTxTy(rl); + seg_[i].UpdateTxTy(rl); i++; } // for j @@ -251,26 +251,26 @@ void LRaceLine::SplitTrack(const tTrack * const ptrack, psegCurrent = psegCurrent->next; } while (psegCurrent != ptrack->seg); - m_cDivs = i - 1; // m_Seg.size-1! - m_dWidth = psegCurrent->width; + divs_ = i - 1; // seg_.size-1! + width_ = psegCurrent->width; } // SplitTrack ///////////////////////////////////////////////////////////////////////////// // Compute the inverse of the radius ///////////////////////////////////////////////////////////////////////////// -double LRaceLine::getRInverse(const int prev, +double LRaceLine::rinverse(const int prev, const double x, const double y, const int next, const int rl) const { - // vector::iterator itNext = m_Seg[next]; - double x1 = m_Seg[next].tx[rl] - x; - double y1 = m_Seg[next].ty[rl] - y; - double x2 = m_Seg[prev].tx[rl] - x; - double y2 = m_Seg[prev].ty[rl] - y; - double x3 = m_Seg[next].tx[rl] - m_Seg[prev].tx[rl]; - double y3 = m_Seg[next].ty[rl] - m_Seg[prev].ty[rl]; + // vector::iterator itNext = seg_[next]; + double x1 = seg_[next].tx[rl] - x; + double y1 = seg_[next].ty[rl] - y; + double x2 = seg_[prev].tx[rl] - x; + double y2 = seg_[prev].ty[rl] - y; + double x3 = seg_[next].tx[rl] - seg_[prev].tx[rl]; + double y3 = seg_[next].ty[rl] - seg_[prev].ty[rl]; double det = x1 * y2 - x2 * y1; double n1 = x1 * x1 + y1 * y1; @@ -279,7 +279,7 @@ double LRaceLine::getRInverse(const int prev, double nnn = sqrt(n1 * n2 * n3); return 2 * det / nnn; -} // getRInverse +} // rinverse ///////////////////////////////////////////////////////////////////////////// @@ -288,53 +288,53 @@ double LRaceLine::getRInverse(const int prev, void LRaceLine::AdjustRadius(int prev, int i, int next, double TargetRInverse, int rl, double Security) { - double OldLane = m_Seg[i].tLane; + double OldLane = seg_[i].tLane; // Start by aligning points for a reasonable initial lane - m_Seg[i].tLane = (-(m_Seg[next].ty[rl] - m_Seg[prev].ty[rl]) - * (m_Seg[i].txLeft - m_Seg[prev].tx[rl]) - + (m_Seg[next].tx[rl] - m_Seg[prev].tx[rl]) - * (m_Seg[i].tyLeft - m_Seg[prev].ty[rl])) / - ((m_Seg[next].ty[rl] - m_Seg[prev].ty[rl]) - * (m_Seg[i].txRight - m_Seg[i].txLeft) - - (m_Seg[next].tx[rl] - m_Seg[prev].tx[rl]) - * (m_Seg[i].tyRight - m_Seg[i].tyLeft)); + seg_[i].tLane = (-(seg_[next].ty[rl] - seg_[prev].ty[rl]) + * (seg_[i].txLeft - seg_[prev].tx[rl]) + + (seg_[next].tx[rl] - seg_[prev].tx[rl]) + * (seg_[i].tyLeft - seg_[prev].ty[rl])) / + ((seg_[next].ty[rl] - seg_[prev].ty[rl]) + * (seg_[i].txRight - seg_[i].txLeft) + - (seg_[next].tx[rl] - seg_[prev].tx[rl]) + * (seg_[i].tyRight - seg_[i].tyLeft)); if (rl == LINE_RL) { - m_Seg[i].tLane = MAX(m_Seg[i].tLane, -1.2 - m_Seg[i].tLaneLMargin); - m_Seg[i].tLane = MIN(m_Seg[i].tLane, 1.2 + m_Seg[i].tLaneRMargin); + seg_[i].tLane = MAX(seg_[i].tLane, -1.2 - seg_[i].tLaneLMargin); + seg_[i].tLane = MIN(seg_[i].tLane, 1.2 + seg_[i].tLaneRMargin); } // if rl - m_Seg[i].UpdateTxTy(rl); + seg_[i].UpdateTxTy(rl); // // Newton-like resolution method // const double dLane = 0.0001; - double dx = dLane * (m_Seg[i].txRight - m_Seg[i].txLeft); - double dy = dLane * (m_Seg[i].tyRight - m_Seg[i].tyLeft); + double dx = dLane * (seg_[i].txRight - seg_[i].txLeft); + double dy = dLane * (seg_[i].tyRight - seg_[i].tyLeft); double dRInverse = - getRInverse(prev, m_Seg[i].tx[rl] + dx, m_Seg[i].ty[rl] + dy, next, rl); + rinverse(prev, seg_[i].tx[rl] + dx, seg_[i].ty[rl] + dy, next, rl); if (dRInverse > 0.000000001) { - m_Seg[i].tLane += (dLane / dRInverse) * TargetRInverse; + seg_[i].tLane += (dLane / dRInverse) * TargetRInverse; - double ExtLane = MIN((m_dExtMargin + Security) / m_dWidth, 0.5); - double IntLane = MIN((m_dIntMargin + Security) / m_dWidth, 0.5); + double ExtLane = MIN((ext_margin_ + Security) / width_, 0.5); + double IntLane = MIN((int_margin_ + Security) / width_, 0.5); // ~ //kilo HACK E-track-1 // ~ if(BetweenLoose(i, 1077, 1112)) //bus-stop // ~ { - // ~ //ExtLane = MIN((m_dExtMargin + 20.0) / m_dWidth, 0.5); - // ~ //IntLane = MIN((m_dIntMargin + 0.0) / m_dWidth, 0.5); + // ~ //ExtLane = MIN((ext_margin_ + 20.0) / width_, 0.5); + // ~ //IntLane = MIN((int_margin_ + 0.0) / width_, 0.5); // ~ IntLane = 0.27; // ~ } // ~ //end kilo HACK // ~ //kilo HACK Alpine-2 // ~ if(BetweenLoose(i, 1470, 1490)) //left-right bump after tunnel // ~ { - // ExtLane = MIN((m_dExtMargin + 20.0) / m_dWidth, 0.5); - // IntLane = MIN((m_dIntMargin + 0.0) / m_dWidth, 0.5); + // ExtLane = MIN((ext_margin_ + 20.0) / width_, 0.5); + // IntLane = MIN((int_margin_ + 0.0) / width_, 0.5); // ExtLane = 4.0; // IntLane = 0.3; // ~ } @@ -342,64 +342,64 @@ void LRaceLine::AdjustRadius(int prev, int i, int next, if (rl == LINE_RL) { if (TargetRInverse >= 0.0) { - IntLane -= m_Seg[i].tLaneLMargin; - ExtLane -= m_Seg[i].tLaneRMargin; + IntLane -= seg_[i].tLaneLMargin; + ExtLane -= seg_[i].tLaneRMargin; } else { - ExtLane -= m_Seg[i].tLaneLMargin; - IntLane -= m_Seg[i].tLaneRMargin; + ExtLane -= seg_[i].tLaneLMargin; + IntLane -= seg_[i].tLaneRMargin; } } // if rl if (TargetRInverse >= 0.0) { - if (m_Seg[i].tLane < IntLane) - m_Seg[i].tLane = IntLane; + if (seg_[i].tLane < IntLane) + seg_[i].tLane = IntLane; - if (1 - m_Seg[i].tLane < ExtLane) { + if (1 - seg_[i].tLane < ExtLane) { if (1 - OldLane < ExtLane) { - m_Seg[i].tLane = MIN(OldLane, m_Seg[i].tLane); + seg_[i].tLane = MIN(OldLane, seg_[i].tLane); } else { - m_Seg[i].tLane = 1 - ExtLane; + seg_[i].tLane = 1 - ExtLane; } } } else { - if (m_Seg[i].tLane < ExtLane) { + if (seg_[i].tLane < ExtLane) { if (OldLane < ExtLane) { - m_Seg[i].tLane = MAX(OldLane, m_Seg[i].tLane); + seg_[i].tLane = MAX(OldLane, seg_[i].tLane); } else { - m_Seg[i].tLane = ExtLane; + seg_[i].tLane = ExtLane; } } - if (1 - m_Seg[i].tLane < IntLane) - m_Seg[i].tLane = 1 - IntLane; + if (1 - seg_[i].tLane < IntLane) + seg_[i].tLane = 1 - IntLane; } } - m_Seg[i].UpdateTxTy(rl); + seg_[i].UpdateTxTy(rl); } ///////////////////////////////////////////////////////////////////////////// // Smooth path ///////////////////////////////////////////////////////////////////////////// void LRaceLine::Smooth(const int Step, const int rl) { - int prev = ((m_cDivs - Step) / Step) * Step; + int prev = ((divs_ - Step) / Step) * Step; int prevprev = prev - Step; int next = Step; int nextnext = next + Step; - for (int i = 0; i <= m_cDivs - Step; i += Step) { - double ri0 = getRInverse(prevprev, m_Seg[prev].tx[rl], - m_Seg[prev].ty[rl], i, rl); - double ri1 = getRInverse(i, m_Seg[next].tx[rl], - m_Seg[next].ty[rl], nextnext, rl); - double lPrev = Mag(m_Seg[i].tx[rl] - m_Seg[prev].tx[rl], - m_Seg[i].ty[rl] - m_Seg[prev].ty[rl]); - double lNext = Mag(m_Seg[i].tx[rl] - m_Seg[next].tx[rl], - m_Seg[i].ty[rl] - m_Seg[next].ty[rl]); + for (int i = 0; i <= divs_ - Step; i += Step) { + double ri0 = rinverse(prevprev, seg_[prev].tx[rl], + seg_[prev].ty[rl], i, rl); + double ri1 = rinverse(i, seg_[next].tx[rl], + seg_[next].ty[rl], nextnext, rl); + double lPrev = Mag(seg_[i].tx[rl] - seg_[prev].tx[rl], + seg_[i].ty[rl] - seg_[prev].ty[rl]); + double lNext = Mag(seg_[i].tx[rl] - seg_[next].tx[rl], + seg_[i].ty[rl] - seg_[next].ty[rl]); double TargetRInverse = (lNext * ri0 + lPrev * ri1) / (lNext + lPrev); - double Security = lPrev * lNext / (8 * m_dSecurityRadius); + double Security = lPrev * lNext / (8 * security_radius_); if (rl == LINE_RL) { if (ri0 * ri1 > 0) { @@ -422,7 +422,7 @@ void LRaceLine::Smooth(const int Step, const int rl) { prev = i; next = nextnext; nextnext = next + Step; - if (nextnext > m_cDivs - Step) + if (nextnext > divs_ - Step) nextnext = 0; } } // Smooth @@ -432,22 +432,22 @@ void LRaceLine::Smooth(const int Step, const int rl) { // Interpolate between two control points ///////////////////////////////////////////////////////////////////////////// void LRaceLine::StepInterpolate(int iMin, int iMax, int Step, int rl) { - int next = (iMax + Step) % m_cDivs; - if (next > m_cDivs - Step) + int next = (iMax + Step) % divs_; + if (next > divs_ - Step) next = 0; - int prev = (((m_cDivs + iMin - Step) % m_cDivs) / Step) * Step; - if (prev > m_cDivs - Step) + int prev = (((divs_ + iMin - Step) % divs_) / Step) * Step; + if (prev > divs_ - Step) prev -= Step; - double ir0 = getRInverse(prev, m_Seg[iMin].tx[rl], - m_Seg[iMin].ty[rl], iMax % m_cDivs, rl); - double ir1 = getRInverse(iMin, m_Seg[iMax % m_cDivs].tx[rl], - m_Seg[iMax % m_cDivs].ty[rl], next, rl); + double ir0 = rinverse(prev, seg_[iMin].tx[rl], + seg_[iMin].ty[rl], iMax % divs_, rl); + double ir1 = rinverse(iMin, seg_[iMax % divs_].tx[rl], + seg_[iMax % divs_].ty[rl], next, rl); for (int k = iMax; --k > iMin;) { double x = static_cast(k - iMin) / static_cast(iMax - iMin); double TargetRInverse = x * ir1 + (1 - x) * ir0; - AdjustRadius(iMin, k, iMax % m_cDivs, TargetRInverse, rl); + AdjustRadius(iMin, k, iMax % divs_, TargetRInverse, rl); } } @@ -458,41 +458,41 @@ void LRaceLine::StepInterpolate(int iMin, int iMax, int Step, int rl) { void LRaceLine::Interpolate(int Step, int rl) { if (Step > 1) { int i; - for (i = Step; i <= m_cDivs - Step; i += Step) + for (i = Step; i <= divs_ - Step; i += Step) StepInterpolate(i - Step, i, Step, rl); - StepInterpolate(i - Step, m_cDivs, Step, rl); + StepInterpolate(i - Step, divs_, Step, rl); } } void LRaceLine::InitTrack(const tTrack * const track, void **parm_handle, const tSituation *s, const double filterSideSkill) { - m_dMinCornerInverse = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, + min_corner_inverse_ = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, KILO_ATT_MINCORNER, NULL, 0.002); - m_dCornerSpeed = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, + corner_speed_ = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, KILO_ATT_CORNERSP, NULL, 15.0); - m_dAvoidSpeedAdjust = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, + avoid_speed_adjust_ = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, KILO_ATT_AVOIDSP, NULL, 2.0); - m_dCornerAccel = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, + corner_accel_ = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, KILO_ATT_CORNERACC, NULL, 1.0); - m_dIntMargin = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, + int_margin_ = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, KILO_ATT_INTMARG, NULL, 1.0); - m_dExtMargin = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, + ext_margin_ = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, KILO_ATT_EXTMARG, NULL, 2.0); - m_dBrakeDelay = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, + brake_delay_ = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, KILO_ATT_BRDELAY, NULL, 10.0); - m_dSecurityRadius = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, + security_radius_ = GfParmGetNum(*parm_handle, KILO_SECT_PRIV, KILO_ATT_SECRAD, NULL, 100.0); if (s->_raceType != RM_TYPE_PRACTICE) { - m_dExtMargin *= filterSideSkill; - m_dIntMargin *= filterSideSkill; + ext_margin_ *= filterSideSkill; + int_margin_ *= filterSideSkill; } // if not practice // split track for (int rl = LINE_MID; rl <= LINE_RL; rl++) { g_rl = rl; - std::for_each(m_Seg.begin(), m_Seg.end(), Nullify); + std::for_each(seg_.begin(), seg_.end(), Nullify); SplitTrack(track, rl, s); @@ -507,28 +507,28 @@ void LRaceLine::InitTrack(const tTrack * const track, void **parm_handle, } // Compute curvature and speed along the path - for (int i = m_cDivs; --i >= 0;) { - double TireAccel = m_dCornerSpeed * m_Seg[i].tFriction; + for (int i = divs_; --i >= 0;) { + double TireAccel = corner_speed_ * seg_[i].tFriction; if (rl == LINE_MID) - TireAccel += m_dAvoidSpeedAdjust; - int next = (i + 1) % m_cDivs; - int prev = (i - 1 + m_cDivs) % m_cDivs; + TireAccel += avoid_speed_adjust_; + int next = (i + 1) % divs_; + int prev = (i - 1 + divs_) % divs_; - double rInverse = getRInverse(prev, - m_Seg[i].tx[rl], - m_Seg[i].ty[rl], + double rInverse = rinverse(prev, + seg_[i].tx[rl], + seg_[i].ty[rl], next, rl); - m_Seg[i].tRInverse = rInverse; + seg_[i].tRInverse = rInverse; double MaxSpeed = 10000.0; double dAbsInverse = fabs(rInverse); - if (dAbsInverse > m_dMinCornerInverse * 1.01) - MaxSpeed = sqrt(TireAccel / (dAbsInverse - m_dMinCornerInverse)); + if (dAbsInverse > min_corner_inverse_ * 1.01) + MaxSpeed = sqrt(TireAccel / (dAbsInverse - min_corner_inverse_)); // Increase or decrease speed depending on track camber if (dAbsInverse > 0.002) { - double camber = m_Seg[i].dCamber; + double camber = seg_[i].dCamber; if (camber < -0.02) { // bad camber. slow us down. MaxSpeed -= MIN(MaxSpeed/4, fabs(camber) * 20); @@ -541,34 +541,34 @@ void LRaceLine::InitTrack(const tTrack * const track, void **parm_handle, // TODO(kilo): increase or decrease speed depending on approaching bumps - m_Seg[i].tSpeed[rl] = m_Seg[i].tMaxSpeed = MaxSpeed; + seg_[i].tSpeed[rl] = seg_[i].tMaxSpeed = MaxSpeed; } // for i // Anticipate braking for (int j = 32; --j >= 0;) { - for (int i = m_cDivs; --i >= 0;) { - double TireAccel = m_dCornerSpeed * m_Seg[i].tFriction; - int prev = (i - 1 + m_cDivs) % m_cDivs; + for (int i = divs_; --i >= 0;) { + double TireAccel = corner_speed_ * seg_[i].tFriction; + int prev = (i - 1 + divs_) % divs_; - double dx = m_Seg[i].tx[rl] - m_Seg[prev].tx[rl]; - double dy = m_Seg[i].ty[rl] - m_Seg[prev].ty[rl]; + double dx = seg_[i].tx[rl] - seg_[prev].tx[rl]; + double dy = seg_[i].ty[rl] - seg_[prev].ty[rl]; double dist = Mag(dx, dy); - double Speed = (m_Seg[i].tSpeed[rl] + m_Seg[prev].tSpeed[rl]) / 2; + double Speed = (seg_[i].tSpeed[rl] + seg_[prev].tSpeed[rl]) / 2; - double LatA = m_Seg[i].tSpeed[rl] * m_Seg[i].tSpeed[rl] * - (fabs(m_Seg[prev].tRInverse) + fabs(m_Seg[i].tRInverse)) / 2; + double LatA = seg_[i].tSpeed[rl] * seg_[i].tSpeed[rl] * + (fabs(seg_[prev].tRInverse) + fabs(seg_[i].tRInverse)) / 2; double TanA = TireAccel * TireAccel + - m_dMinCornerInverse * Speed * Speed - LatA * LatA; + min_corner_inverse_ * Speed * Speed - LatA * LatA; double brakedelay = - m_dBrakeDelay + (rl == LINE_MID ? m_dAvoidSpeedAdjust : 0.0); + brake_delay_ + (rl == LINE_MID ? avoid_speed_adjust_ : 0.0); TanA = MAX(TanA, 0.0); - TanA = MIN(TanA, brakedelay * m_Seg[i].tFriction); + TanA = MIN(TanA, brakedelay * seg_[i].tFriction); double Time = dist / Speed; - double MaxSpeed = m_Seg[i].tSpeed[rl] + TanA * Time; - m_Seg[prev].tSpeed[rl] = MIN(MaxSpeed, m_Seg[prev].tMaxSpeed); + double MaxSpeed = seg_[i].tSpeed[rl] + TanA * Time; + seg_[prev].tSpeed[rl] = MIN(MaxSpeed, seg_[prev].tMaxSpeed); } // for i } // for j } // for rl @@ -579,13 +579,13 @@ void LRaceLine::InitTrack(const tTrack * const track, void **parm_handle, // New race //////////////////////////////////////////////////////////////////////////// void LRaceLine::NewRace() { - const tPrivCar * const cp = &m_pCar->priv; - m_dWheelBase = (cp->wheel[FRNT_RGT].relPos.x + + const tPrivCar * const cp = &car_->priv; + wheel_base_ = (cp->wheel[FRNT_RGT].relPos.x + cp->wheel[FRNT_LFT].relPos.x - cp->wheel[REAR_RGT].relPos.x - cp->wheel[REAR_LFT].relPos.x) / 2; - m_dWheelTrack = (cp->wheel[FRNT_LFT].relPos.y + + wheel_track_ = (cp->wheel[FRNT_LFT].relPos.y + cp->wheel[REAR_LFT].relPos.y - cp->wheel[FRNT_RGT].relPos.y - cp->wheel[REAR_RGT].relPos.y) / 2; @@ -604,110 +604,110 @@ LRaceLine::GetRaceLineData(const tSituation * const s, double *lookahead, double *racesteer) { // Find index in data arrays - tTrackSeg *pSeg = m_pCar->_trkPos.seg; - double dist = MAX(m_pCar->_trkPos.toStart, 0.0); + tTrackSeg *pSeg = car_->_trkPos.seg; + double dist = MAX(car_->_trkPos.toStart, 0.0); if (pSeg->type != TR_STR) dist *= pSeg->radius; - int Index = m_SegInfo[pSeg->id].first - + static_cast(dist / m_SegInfo[pSeg->id].second); - This = Index; + int Index = seg_info_[pSeg->id].first + + static_cast(dist / seg_info_[pSeg->id].second); + this_ = Index; - Index = (Index + m_cDivs - 5) % m_cDivs; - static const double Time = s->deltaTime * 9 + m_dCornerAccel / 80.0; - // ??? 0.50 + m_dCornerAccel/80; - double X = m_pCar->_pos_X + m_pCar->_speed_X * Time / 2; - double Y = m_pCar->_pos_Y + m_pCar->_speed_Y * Time / 2; + Index = (Index + divs_ - 5) % divs_; + static const double Time = s->deltaTime * 9 + corner_accel_ / 80.0; + // ??? 0.50 + corner_accel_/80; + double X = car_->_pos_X + car_->_speed_X * Time / 2; + double Y = car_->_pos_Y + car_->_speed_Y * Time / 2; // *lookahead = 0.0; while (1) { - Next = (Index + 1) % m_cDivs; - double dx = m_Seg[Next].tx[LINE_RL] - m_pCar->_pos_X; - double dy = m_Seg[Next].ty[LINE_RL] - m_pCar->_pos_Y; + next_ = (Index + 1) % divs_; + double dx = seg_[next_].tx[LINE_RL] - car_->_pos_X; + double dy = seg_[next_].ty[LINE_RL] - car_->_pos_Y; *lookahead = Mag(dx, dy); if (*lookahead > 10.0 && - (m_Seg[Next].tx[LINE_RL] - m_Seg[Index].tx[LINE_RL]) - * (X - m_Seg[Next].tx[LINE_RL]) + - (m_Seg[Next].ty[LINE_RL] - m_Seg[Index].ty[LINE_RL]) - * (Y - m_Seg[Next].ty[LINE_RL]) < 0.1) + (seg_[next_].tx[LINE_RL] - seg_[Index].tx[LINE_RL]) + * (X - seg_[next_].tx[LINE_RL]) + + (seg_[next_].ty[LINE_RL] - seg_[Index].ty[LINE_RL]) + * (Y - seg_[next_].ty[LINE_RL]) < 0.1) break; - Index = Next; + Index = next_; } - double toMiddle = m_pCar->_trkPos.toMiddle; - if ((m_Seg[Next].tRInverse > 0.0 && toMiddle < 0.0) - || (m_Seg[Next].tRInverse < 0.0 && toMiddle > 0.0)) { + double toMiddle = car_->_trkPos.toMiddle; + if ((seg_[next_].tRInverse > 0.0 && toMiddle < 0.0) + || (seg_[next_].tRInverse < 0.0 && toMiddle > 0.0)) { *lookahead *= MIN(4.0, 1.5 + fabs(toMiddle * 0.3)); } else { *lookahead *= MAX(0.7, 1.5 - fabs(toMiddle * 0.2)); } - if ((m_Seg[Next].tRInverse < 0.0 && toMiddle > 0.0) - || (m_Seg[Next].tRInverse > 0.0 && toMiddle < 0.0)) { + if ((seg_[next_].tRInverse < 0.0 && toMiddle > 0.0) + || (seg_[next_].tRInverse > 0.0 && toMiddle < 0.0)) { *lookahead *= MAX(1.0, MIN(3.6, 1.0 + (MIN(2.6, fabs(toMiddle) / (pSeg->width / 2)) / 2) - * (1.0 + fabs(m_Seg[Next].tRInverse) * 65.0 + - m_pCar->_speed_x / 120.0))); - } else if ((m_Seg[Next].tRInverse < 0.0 && m_pCar->_trkPos.toRight < 5.0) - || (m_Seg[Next].tRInverse > 0.0 && m_pCar->_trkPos.toLeft < 5.0)) { + * (1.0 + fabs(seg_[next_].tRInverse) * 65.0 + + car_->_speed_x / 120.0))); + } else if ((seg_[next_].tRInverse < 0.0 && car_->_trkPos.toRight < 5.0) + || (seg_[next_].tRInverse > 0.0 && car_->_trkPos.toLeft < 5.0)) { *lookahead *= MAX(0.8, MIN(1.0, 1.0 - - fabs(m_Seg[Next].tRInverse) * 200.0 * - ((5.0 - MIN(m_pCar->_trkPos.toRight, m_pCar->_trkPos.toLeft)) / 5.0))); + fabs(seg_[next_].tRInverse) * 200.0 * + ((5.0 - MIN(car_->_trkPos.toRight, car_->_trkPos.toLeft)) / 5.0))); } - target->x = m_Seg[Next].tx[LINE_RL]; - target->y = m_Seg[Next].ty[LINE_RL]; + target->x = seg_[next_].tx[LINE_RL]; + target->y = seg_[next_].ty[LINE_RL]; // // Find target speed // double c0 = - (m_Seg[Next].tx[LINE_RL] - m_Seg[Index].tx[LINE_RL]) - * (m_Seg[Next].tx[LINE_RL] - X) + - (m_Seg[Next].ty[LINE_RL] - m_Seg[Index].ty[LINE_RL]) - * (m_Seg[Next].ty[LINE_RL] - Y); + (seg_[next_].tx[LINE_RL] - seg_[Index].tx[LINE_RL]) + * (seg_[next_].tx[LINE_RL] - X) + + (seg_[next_].ty[LINE_RL] - seg_[Index].ty[LINE_RL]) + * (seg_[next_].ty[LINE_RL] - Y); double c1 = - (m_Seg[Next].tx[LINE_RL] - m_Seg[Index].tx[LINE_RL]) - * (X - m_Seg[Index].tx[LINE_RL]) + - (m_Seg[Next].ty[LINE_RL] - m_Seg[Index].ty[LINE_RL]) - * (Y - m_Seg[Index].ty[LINE_RL]); + (seg_[next_].tx[LINE_RL] - seg_[Index].tx[LINE_RL]) + * (X - seg_[Index].tx[LINE_RL]) + + (seg_[next_].ty[LINE_RL] - seg_[Index].ty[LINE_RL]) + * (Y - seg_[Index].ty[LINE_RL]); double sum = c0 + c1; c0 /= sum; c1 /= sum; - m_dTargetSpeed = - (1 - c0) * m_Seg[Next].tSpeed[LINE_RL] + c0 * m_Seg[Index].tSpeed[LINE_RL]; - *avspeed = MAX(10.0, m_Seg[Next].tSpeed[LINE_MID]); - *speed = MAX(*avspeed, m_dTargetSpeed); + target_speed_ = + (1 - c0) * seg_[next_].tSpeed[LINE_RL] + c0 * seg_[Index].tSpeed[LINE_RL]; + *avspeed = MAX(10.0, seg_[next_].tSpeed[LINE_MID]); + *speed = MAX(*avspeed, target_speed_); - if ((m_Seg[Next].tRInverse > 0.0 && m_Seg[Next].tLane > m_Seg[Index].tLane - && m_pCar->_trkPos.toLeft <= m_Seg[Next].tLane * m_dWidth + 1.0) - || (m_Seg[Next].tRInverse < 0.0 && m_Seg[Next].tLane < m_Seg[Index].tLane - && m_pCar->_trkPos.toLeft >= m_Seg[Next].tLane * m_dWidth - 1.0)) { + if ((seg_[next_].tRInverse > 0.0 && seg_[next_].tLane > seg_[Index].tLane + && car_->_trkPos.toLeft <= seg_[next_].tLane * width_ + 1.0) + || (seg_[next_].tRInverse < 0.0 && seg_[next_].tLane < seg_[Index].tLane + && car_->_trkPos.toLeft >= seg_[next_].tLane * width_ - 1.0)) { *avspeed = MAX(*speed, *avspeed); - } else if ((m_Seg[Next].tRInverse > 0.001 - && m_Seg[Next].tLane < m_Seg[Index].tLane - && m_pCar->_trkPos.toLeft < m_Seg[Next].tLane * m_dWidth - 1.0) - || (m_Seg[Next].tRInverse < -0.001 - && m_Seg[Next].tLane > m_Seg[Index].tLane - && m_pCar->_trkPos.toLeft > m_Seg[Next].tLane * m_dWidth + 1.0)) { - *avspeed *= MAX(0.7, 1.0 - fabs(m_Seg[Next].tRInverse) * 100); + } else if ((seg_[next_].tRInverse > 0.001 + && seg_[next_].tLane < seg_[Index].tLane + && car_->_trkPos.toLeft < seg_[next_].tLane * width_ - 1.0) + || (seg_[next_].tRInverse < -0.001 + && seg_[next_].tLane > seg_[Index].tLane + && car_->_trkPos.toLeft > seg_[next_].tLane * width_ + 1.0)) { + *avspeed *= MAX(0.7, 1.0 - fabs(seg_[next_].tRInverse) * 100); } - double laneoffset = m_dWidth / 2 - (m_Seg[Next].tLane * m_dWidth); + double laneoffset = width_ / 2 - (seg_[next_].tLane * width_); *raceoffset = laneoffset; // // Find target curveture (for the inside wheel) // - double TargetCurvature = (1 - c0) * m_Seg[Next].tRInverse - + c0 * m_Seg[Index].tRInverse; + double TargetCurvature = (1 - c0) * seg_[next_].tRInverse + + c0 * seg_[Index].tRInverse; if (fabs(TargetCurvature) > 0.01) { double r = 1 / TargetCurvature; if (r > 0) { - r -= m_dWheelTrack / 2; + r -= wheel_track_ / 2; } else { - r += m_dWheelTrack / 2; + r += wheel_track_ / 2; } TargetCurvature = 1 / r; } @@ -717,30 +717,30 @@ LRaceLine::GetRaceLineData(const tSituation * const s, // double Error = 0; double VnError = 0; - double carspeed = Mag(m_pCar->_speed_X, m_pCar->_speed_Y); + double carspeed = Mag(car_->_speed_X, car_->_speed_Y); // // Ideal value // - double steer = atan(m_dWheelBase * TargetCurvature) / m_pCar->_steerLock; + double steer = atan(wheel_base_ * TargetCurvature) / car_->_steerLock; // // Servo system to stay on the pre-computed path // { - double dx = m_Seg[Next].tx[LINE_RL] - m_Seg[Index].tx[LINE_RL]; - double dy = m_Seg[Next].ty[LINE_RL] - m_Seg[Index].ty[LINE_RL]; + double dx = seg_[next_].tx[LINE_RL] - seg_[Index].tx[LINE_RL]; + double dy = seg_[next_].ty[LINE_RL] - seg_[Index].ty[LINE_RL]; Error = - (dx * (Y - m_Seg[Index].ty[LINE_RL]) - - dy * (X - m_Seg[Index].tx[LINE_RL])) / Mag(dx, dy); + (dx * (Y - seg_[Index].ty[LINE_RL]) - + dy * (X - seg_[Index].tx[LINE_RL])) / Mag(dx, dy); } - int Prev = (Index + m_cDivs - 1) % m_cDivs; - int NextNext = (Next + 1) % m_cDivs; - double Prevdx = m_Seg[Next].tx[LINE_RL] - m_Seg[Prev].tx[LINE_RL]; - double Prevdy = m_Seg[Next].ty[LINE_RL] - m_Seg[Prev].ty[LINE_RL]; - double Nextdx = m_Seg[NextNext].tx[LINE_RL] - m_Seg[Index].tx[LINE_RL]; - double Nextdy = m_Seg[NextNext].ty[LINE_RL] - m_Seg[Index].ty[LINE_RL]; + int Prev = (Index + divs_ - 1) % divs_; + int NextNext = (next_ + 1) % divs_; + double Prevdx = seg_[next_].tx[LINE_RL] - seg_[Prev].tx[LINE_RL]; + double Prevdy = seg_[next_].ty[LINE_RL] - seg_[Prev].ty[LINE_RL]; + double Nextdx = seg_[NextNext].tx[LINE_RL] - seg_[Index].tx[LINE_RL]; + double Nextdy = seg_[NextNext].ty[LINE_RL] - seg_[Index].ty[LINE_RL]; double dx = c0 * Prevdx + (1 - c0) * Nextdx; double dy = c0 * Prevdy + (1 - c0) * Nextdy; double n = Mag(dx, dy); @@ -748,34 +748,34 @@ LRaceLine::GetRaceLineData(const tSituation * const s, dy /= n; double sError = - (dx * m_pCar->_speed_Y - dy * m_pCar->_speed_X) / (carspeed + 0.01); + (dx * car_->_speed_Y - dy * car_->_speed_X) / (carspeed + 0.01); double cError = - (dx * m_pCar->_speed_X + dy * m_pCar->_speed_Y) / (carspeed + 0.01); + (dx * car_->_speed_X + dy * car_->_speed_Y) / (carspeed + 0.01); VnError = asin(sError); if (cError < 0) VnError = PI - VnError; steer -= (atan(Error * (300 / (carspeed + 300)) / 15) + VnError) - / m_pCar->_steerLock; + / car_->_steerLock; // // Steer into the skid // - double vx = m_pCar->_speed_X; - double vy = m_pCar->_speed_Y; - double dirx = cos(m_pCar->_yaw); - double diry = sin(m_pCar->_yaw); + double vx = car_->_speed_X; + double vy = car_->_speed_Y; + double dirx = cos(car_->_yaw); + double diry = sin(car_->_yaw); double Skid = (dirx * vy - vx * diry) / (carspeed + 0.1); if (Skid > 0.9) Skid = 0.9; if (Skid < -0.9) Skid = -0.9; - steer += (asin(Skid) / m_pCar->_steerLock) * 0.9; + steer += (asin(Skid) / car_->_steerLock) * 0.9; double yr = carspeed * TargetCurvature; - double diff = m_pCar->_yaw_rate - yr; - steer -= (0.06 * (100 / (carspeed + 100)) * diff) / m_pCar->_steerLock; + double diff = car_->_yaw_rate - yr; + steer -= (0.06 * (100 / (carspeed + 100)) * diff) / car_->_steerLock; - double trackangle = RtTrackSideTgAngleL(&(m_pCar->_trkPos)); - double angle = trackangle - m_pCar->_yaw; + double trackangle = RtTrackSideTgAngleL(&(car_->_trkPos)); + double angle = trackangle - car_->_yaw; NORM_PI_PI(angle); angle = -angle; @@ -796,9 +796,9 @@ LRaceLine::GetRaceLineData(const tSituation * const s, bool LRaceLine::isOnLine() const { bool ret = false; - double lane2left = m_Seg[Next].tLane * m_dWidth; - if (fabs(m_pCar->_trkPos.toLeft - lane2left) < - MAX(0.1, 1.0 - (m_pCar->_speed_x * (m_pCar->_speed_x / 10)) / 600)) + double lane2left = seg_[next_].tLane * width_; + if (fabs(car_->_trkPos.toLeft - lane2left) < + MAX(0.1, 1.0 - (car_->_speed_x * (car_->_speed_x / 10)) / 600)) ret = true; return ret; @@ -807,23 +807,23 @@ bool LRaceLine::isOnLine() const { void LRaceLine::GetPoint(const double offset, const double lookahead, vec2f * const rt) const { - double dLane = (m_dWidth / 2.0 - offset) / m_dWidth; + double dLane = (width_ / 2.0 - offset) / width_; vec2f last; - last.x = dLane * m_Seg[This].txRight + (1.0 - dLane) * m_Seg[This].txLeft; - last.y = dLane * m_Seg[This].tyRight + (1.0 - dLane) * m_Seg[This].tyLeft; + last.x = dLane * seg_[this_].txRight + (1.0 - dLane) * seg_[this_].txLeft; + last.y = dLane * seg_[this_].tyRight + (1.0 - dLane) * seg_[this_].tyLeft; - int ndiv = Next; + int ndiv = next_; double dLength = 0.0; double la = static_cast(lookahead) - * MIN(1.0, MAX(0.8, m_pCar->_speed_x / m_dTargetSpeed)); - int iLookaheadLimit = static_cast(la / m_lDivLength); + * MIN(1.0, MAX(0.8, car_->_speed_x / target_speed_)); + int iLookaheadLimit = static_cast(la / div_length_); for (int count = 0; count < iLookaheadLimit && dLength < la; count++) { - rt->x = dLane * m_Seg[ndiv].txRight + (1 - dLane) * m_Seg[ndiv].txLeft; - rt->y = dLane * m_Seg[ndiv].tyRight + (1 - dLane) * m_Seg[ndiv].tyLeft; + rt->x = dLane * seg_[ndiv].txRight + (1 - dLane) * seg_[ndiv].txLeft; + rt->y = dLane * seg_[ndiv].tyRight + (1 - dLane) * seg_[ndiv].tyLeft; vec2f d = (*rt) - last; dLength += Mag(d.x, d.y); - ndiv = (ndiv + 1) % m_cDivs; + ndiv = (ndiv + 1) % divs_; last = (*rt); } // for } // GetPoint @@ -832,61 +832,37 @@ void LRaceLine::GetPoint(const double offset, const double lookahead, // this returns true if we're approaching a corner & are significantly // inside the ideal racing line. The idea is to prevent a sudden outwards // movement at a time when we should be looking to turn in. -double LRaceLine::correctLimit(void) const { - double toLeft = m_pCar->_trkPos.toLeft; - double nlane2left = m_Seg[Next].tLane * m_dWidth; +double LRaceLine::CorrectLimit(void) const { + double toLeft = car_->_trkPos.toLeft; + double nlane2left = seg_[next_].tLane * width_; - if ((m_Seg[Next].tRInverse > 0.001 && toLeft < nlane2left - 2.0) - || (m_Seg[Next].tRInverse < -0.001 && toLeft > nlane2left + 2.0)) - return MAX(0.2, MIN(1.0, 1.0 - fabs(m_Seg[Next].tRInverse) * 100.0)); + if ((seg_[next_].tRInverse > 0.001 && toLeft < nlane2left - 2.0) + || (seg_[next_].tRInverse < -0.001 && toLeft > nlane2left + 2.0)) + return MAX(0.2, MIN(1.0, 1.0 - fabs(seg_[next_].tRInverse) * 100.0)); - int nnext = (Next + static_cast(m_pCar->_speed_x / 3)) % m_cDivs; - double nnlane2left = m_Seg[nnext].tLane * m_dWidth; - if ((m_Seg[nnext].tRInverse > 0.001 && toLeft < nnlane2left - 2.0) - || (m_Seg[nnext].tRInverse < -0.001 && toLeft > nnlane2left + 2.0)) - return MAX(0.3, MIN(1.0, 1.0 - fabs(m_Seg[nnext].tRInverse) * 40.0)); + int nnext = (next_ + static_cast(car_->_speed_x / 3)) % divs_; + double nnlane2left = seg_[nnext].tLane * width_; + if ((seg_[nnext].tRInverse > 0.001 && toLeft < nnlane2left - 2.0) + || (seg_[nnext].tRInverse < -0.001 && toLeft > nnlane2left + 2.0)) + return MAX(0.3, MIN(1.0, 1.0 - fabs(seg_[nnext].tRInverse) * 40.0)); // ok, we're not inside the racing line. Check and see // if we're outside it and turning into a corner, // in which case we want to correct more to try // and get closer to the apex. - if ((m_Seg[Next].tRInverse > 0.001 - && m_Seg[Next].tLane <= m_Seg[This].tLane + if ((seg_[next_].tRInverse > 0.001 + && seg_[next_].tLane <= seg_[this_].tLane && toLeft > nlane2left + 2.0) - || (m_Seg[Next].tRInverse < -0.001 - && m_Seg[Next].tLane >= m_Seg[This].tLane + || (seg_[next_].tRInverse < -0.001 + && seg_[next_].tLane >= seg_[this_].tLane && toLeft < nlane2left - 2.0)) - return MAX(1.0, MIN(1.5, 1.0 + fabs(m_Seg[Next].tRInverse))); + return MAX(1.0, MIN(1.5, 1.0 + fabs(seg_[next_].tRInverse))); return 1.0; } -double LRaceLine::getAvoidSpeed(const double distance1, - const double distance2) const { - double speed1 = 1000.0; - double speed2 = 1000.0; - - int i = Next; - int dist_limit = static_cast(distance1 / m_lDivLength); - for (int count = 0; count < dist_limit; count++, i++) { - i = i % m_cDivs; - speed1 = MIN(speed1, m_Seg[i].tSpeed[LINE_MID]); - } - - dist_limit = static_cast(MIN(distance2, distance1 * 3) - distance1) - / m_lDivLength; - for (int count = 0; count < dist_limit; count++, i++) { - i = i % m_cDivs; - speed2 = MIN(speed2, m_Seg[i].tSpeed[LINE_MID] - + static_cast(count) * 0.25); - } - - return MIN(speed1, speed2); -} - - -void LRaceLine::SetSegCamber(const tTrackSeg *seg, const int div) { +void LRaceLine::SetSegmentCamber(const tTrackSeg *seg, const int div) { double dDistRatio = 0.7; double dCamberStart = seg->vertex[TR_SR].z - seg->vertex[TR_SL].z; double dCamberEnd = seg->vertex[TR_ER].z - seg->vertex[TR_EL].z; @@ -896,7 +872,7 @@ void LRaceLine::SetSegCamber(const tTrackSeg *seg, const int div) { dCamberEnd /= seg->width; dCamber /= seg->width; - if (m_Seg[div].tRInverse < 0.0) { + if (seg_[div].tRInverse < 0.0) { dCamber *= -1.0; dCamberStart *= -1.0; dCamberEnd *= -1.0; @@ -908,6 +884,6 @@ void LRaceLine::SetSegCamber(const tTrackSeg *seg, const int div) { dCamber += (dCamberEnd - dCamberStart) * 0.4; } - m_Seg[div].dCamber = dCamber; -} // SetSegCamber + seg_[div].dCamber = dCamber; +} // SetSegmentCamber diff --git a/src/drivers/kilo2008/raceline.h b/src/drivers/kilo2008/raceline.h index 39bcd0ac4..7e6c03621 100644 --- a/src/drivers/kilo2008/raceline.h +++ b/src/drivers/kilo2008/raceline.h @@ -86,7 +86,11 @@ class LRaceLine { LRaceLine() {} virtual ~LRaceLine() {} - inline void setCar(tCarElt * const car) {m_pCar = car;} + inline double rinverse(void) const { return seg_[next_].tRInverse; } + inline double rinverse(const double distance) const { + int d = ((next_ + static_cast(distance / div_length_)) % divs_); + return seg_[d].tRInverse; } + inline void set_car(tCarElt * const car) {car_ = car;} void InitTrack(const tTrack * const track, void **carParmHandle, const tSituation *s, const double filterSideSkill); @@ -97,53 +101,46 @@ class LRaceLine { void GetPoint(const double offset, const double lookahead, vec2f * const rt) const; bool isOnLine(void) const; - double correctLimit(void) const; - inline double getRInverse(void) const {return m_Seg[Next].tRInverse;} - inline double getRInverse(const double distance) const { - int d = ((Next + static_cast(distance / m_lDivLength)) % m_cDivs); - return m_Seg[d].tRInverse; - } + double CorrectLimit(void) const; private: + double rinverse(const int prev, const double x, const double y, + const int next, const int rl) const; void SetSegmentInfo(const tTrackSeg * pseg, const int i, const double l); + void SetSegmentCamber(const tTrackSeg *seg, const int div); void SplitTrack(const tTrack * const ptrack, const int rl, const tSituation *s); - double getRInverse(const int prev, const double x, const double y, - const int next, const int rl) const; void AdjustRadius(int prev, int i, int next, double TargetRInverse, int rl, - double Security = 0); + double Security = 0); void Smooth(const int Step, const int rl); void StepInterpolate(int iMin, int iMax, int Step, int rl); void Interpolate(int Step, int rl); - double getAvoidSpeed(const double distance1, const double distance2) const; - void SetSegCamber(const tTrackSeg *seg, const int div); private: - double m_dMinCornerInverse; - double m_dCornerSpeed; - double m_dCornerAccel; - double m_dBrakeDelay; - double m_dIntMargin; - double m_dExtMargin; - double m_dAvoidSpeedAdjust; - double m_dSecurityRadius; - tCarElt * m_pCar; + tCarElt *car_; + double min_corner_inverse_; + double corner_speed_; + double corner_accel_; + double brake_delay_; + double int_margin_; + double ext_margin_; + double avoid_speed_adjust_; + double security_radius_; + double wheel_base_; + double wheel_track_; - double m_dWheelBase; - double m_dWheelTrack; - - int m_cDivs; - int m_lDivLength; - double m_dTargetSpeed; - double m_dWidth; + int divs_; + int div_length_; + double target_speed_; + double width_; // first: segment index, second: elem length - std::vector< std::pair > m_SegInfo; + std::vector< std::pair > seg_info_; - std::vector m_Seg; + std::vector seg_; - int Next; - int This; + int next_; + int this_; }; #endif // SRC_DRIVERS_KILO2008_RACELINE_H_ diff --git a/src/drivers/kilo2008/strategy.cpp b/src/drivers/kilo2008/strategy.cpp index a64ce19e3..026c2d10d 100644 --- a/src/drivers/kilo2008/strategy.cpp +++ b/src/drivers/kilo2008/strategy.cpp @@ -43,13 +43,13 @@ const int KStrategy::LAST_LAPS = 10; KStrategy::KStrategy() { - m_last_damages = new std::deque; + last_damages_ = new std::deque; - m_laps = 0; - m_fuel_checked = false; - m_fuel_per_lap = 0.0; - m_last_pit_fuel = 0.0; - m_fuel_sum = 0.0; + laps_ = 0; + fuel_checked_ = false; + fuel_per_lap_ = 0.0; + last_pit_fuel_ = 0.0; + fuel_sum_ = 0.0; } // KStrategy @@ -69,13 +69,13 @@ void KStrategy::SetFuelAtRaceStart(const tTrack * const t, const double fuel = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, KILO_ATT_FUELPERLAP, NULL, t->length * MAX_FUEL_PER_METER); - m_expected_fuel_per_lap = fuel; + expected_fuel_per_lap_ = fuel; // Pittime is pittime without refuel. - m_pittime = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, + pittime_ = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, KILO_ATT_PITTIME, NULL, 25.0); - m_best_lap = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, + best_lap_ = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, KILO_ATT_BESTLAP, NULL, 87.0); - m_worst_lap = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, + worst_lap_ = GfParmGetNum(*carParmHandle, KILO_SECT_PRIV, KILO_ATT_WORSTLAP, NULL, 87.0); // Fuel tank capacity const double maxfuel = GfParmGetNum(*carParmHandle, SECT_CAR, @@ -88,7 +88,7 @@ void KStrategy::SetFuelAtRaceStart(const tTrack * const t, // Compute race times for min to min + 9 pit stops. ComputeBestNumberOfPits(maxfuel, fuelForRace, s->_totLaps, true); - m_last_fuel = m_fuel_per_stint; + last_fuel_ = fuel_per_stint_; // If the setup defines initial fuel amount, use that value in races. // Otherwise use computed amount. @@ -100,7 +100,7 @@ void KStrategy::SetFuelAtRaceStart(const tTrack * const t, } else { // Add fuel dependent on index to avoid fuel stop in the same lap. GfParmSetNum(*carParmHandle, SECT_CAR, PRM_FUEL, NULL, - m_last_fuel + index * m_expected_fuel_per_lap); + last_fuel_ + index * expected_fuel_per_lap_); } } else { // Use fuel for whole 'race', ie qualy or practice N laps. @@ -121,14 +121,14 @@ void KStrategy::SetFuelAtRaceStart(const tTrack * const t, void KStrategy::UpdateFuelStrategy() { // Required additional fuel for the rest of the race. // +1 because the computation happens right after crossing the start line. - double fuelperlap = MAX(m_fuel_per_lap, 2.5); // average - double required_fuel = ((LapsToGo() + 1) - ceil(m_car->_fuel / fuelperlap)) + double fuelperlap = MAX(fuel_per_lap_, 2.5); // average + double required_fuel = ((LapsToGo() + 1) - ceil(car_->_fuel / fuelperlap)) * fuelperlap; // We don't have enough fuel to end the race, need at least one stop. if (required_fuel >= 0.0) { // Compute race times for different pit strategies. - ComputeBestNumberOfPits(m_car->_tank, required_fuel, LapsToGo(), FALSE); + ComputeBestNumberOfPits(car_->_tank, required_fuel, LapsToGo(), FALSE); } } // UpdateFuelStrategy @@ -141,19 +141,19 @@ double KStrategy::PitRefuel() { UpdateFuelStrategy(); double fuel; - if (m_remaining_stops > 1) { - fuel = MIN(MAX(m_fuel_per_stint, MAXFUEL_FOR_THIS_RACE), - m_car->_tank - m_car->_fuel); // !!! - --m_remaining_stops; + if (remaining_stops_ > 1) { + fuel = MIN(MAX(fuel_per_stint_, MAXFUEL_FOR_THIS_RACE), + car_->_tank - car_->_fuel); // !!! + --remaining_stops_; } else { - double cmpfuel = (m_fuel_per_lap == 0.0) - ? m_expected_fuel_per_lap - : m_fuel_per_lap; - fuel = MAX(MIN((LapsToGo() + 1.0) * cmpfuel - m_car->_fuel, - m_car->_tank - m_car->_fuel), 0.0); + double cmpfuel = (fuel_per_lap_ == 0.0) + ? expected_fuel_per_lap_ + : fuel_per_lap_; + fuel = MAX(MIN((LapsToGo() + 1.0) * cmpfuel - car_->_fuel, + car_->_tank - car_->_fuel), 0.0); } - m_last_pit_fuel = fuel; + last_pit_fuel_ = fuel; return fuel; } // pitRefuel @@ -174,16 +174,16 @@ void KStrategy::ComputeBestNumberOfPits(const double tankCapacity, for (int i = 0; i < (preRace ? 5 : 4); ++i) { double stintFuel = requiredFuel / (pitstopMin + i); // + 1); double fillratio = stintFuel / tankCapacity; - double avglapest = m_best_lap + (m_worst_lap - m_best_lap) * fillratio; - double racetime = (pitstopMin + i) * (m_pittime + stintFuel / 8.0) + + double avglapest = best_lap_ + (worst_lap_ - best_lap_) * fillratio; + double racetime = (pitstopMin + i) * (pittime_ + stintFuel / 8.0) + remainingLaps * avglapest; if (mintime > racetime) { mintime = racetime; beststops = pitstopMin + i - (preRace ? 1 : 0); - m_fuel_per_stint = stintFuel; + fuel_per_stint_ = stintFuel; } } - m_remaining_stops = beststops; + remaining_stops_ = beststops; } // ComputeBestNumberOfPits @@ -198,45 +198,45 @@ void KStrategy::ComputeBestNumberOfPits(const double tankCapacity, * @return: - */ void KStrategy::Update() { - if (m_car->_laps > m_laps) { // If a new lap has been finished - m_laps = m_car->_laps; - m_last_damages->push_front(m_car->_dammage); // store last lap's damage - if (static_cast(m_last_damages->size()) > LAST_LAPS) - m_last_damages->pop_back(); // and keep deque size at limit + if (car_->_laps > laps_) { // If a new lap has been finished + laps_ = car_->_laps; + last_damages_->push_front(car_->_dammage); // store last lap's damage + if (static_cast(last_damages_->size()) > LAST_LAPS) + last_damages_->pop_back(); // and keep deque size at limit #ifdef STRAT_DEBUG // print damage values in reverse order cerr << car->_name << ": damages"; - for (deque::reverse_iterator rit = m_last_damages->rbegin(); - rit < m_last_damages->rend(); - rit++) + for (deque::reverse_iterator rit = last_damages_->rbegin(); + rit < last_damages_->rend(); + ++rit) cerr << " " << *rit; cerr << endl; #endif } // Update best & worst lap times - m_best_lap = MIN((m_best_lap == 0.0 ? m_car->_lastLapTime : m_best_lap), - m_car->_lastLapTime); - m_worst_lap = MAX(m_worst_lap, m_car->_lastLapTime); + best_lap_ = MIN((best_lap_ == 0.0 ? car_->_lastLapTime : best_lap_), + car_->_lastLapTime); + worst_lap_ = MAX(worst_lap_, car_->_lastLapTime); // Fuel statistics update. - int id = m_car->_trkPos.seg->id; + int id = car_->_trkPos.seg->id; // Range must include enough segments to be executed once guaranteed. - if (id >= 0 && id < 5 && !m_fuel_checked) { - if (m_car->race.laps > 1) { - m_fuel_sum += (m_last_fuel + m_last_pit_fuel - m_car->priv.fuel); - m_fuel_per_lap = (m_fuel_sum / (m_car->race.laps - 1)); + if (id >= 0 && id < 5 && !fuel_checked_) { + if (car_->race.laps > 1) { + fuel_sum_ += (last_fuel_ + last_pit_fuel_ - car_->priv.fuel); + fuel_per_lap_ = (fuel_sum_ / (car_->race.laps - 1)); // This is here for adding strategy decisions, otherwise // it could be moved to pitRefuel for efficiency. UpdateFuelStrategy(); } - m_last_fuel = m_car->priv.fuel; - m_last_pit_fuel = 0.0; - m_fuel_checked = true; + last_fuel_ = car_->priv.fuel; + last_pit_fuel_ = 0.0; + fuel_checked_ = true; } else if (id > 5) { - m_fuel_checked = false; + fuel_checked_ = false; } } // update @@ -255,14 +255,14 @@ bool KStrategy::NeedPitstop() const { bool ret = false; // Question makes sense only if there is a pit. - if (m_car->_pit != NULL) { + if (car_->_pit != NULL) { // Ideally we shouldn't pit on the last lap for any reason, // just get to the finish line somehow. if (LapsToGo() > 0) { // Do we need to refuel? - double cmpfuel = (m_fuel_per_lap == 0.0) - ? m_expected_fuel_per_lap - : m_fuel_per_lap; + double cmpfuel = (fuel_per_lap_ == 0.0) + ? expected_fuel_per_lap_ + : fuel_per_lap_; #ifdef STRAT_DEBUG if (strcmp(car->_name, "Kilo 1") == 0 && car->_fuel < 5.0) @@ -278,20 +278,20 @@ bool KStrategy::NeedPitstop() const { << endl; #endif cmpfuel *= MIN(SAFE_LAPS, LapsToGo()); - if (m_car->_fuel < cmpfuel) { + if (car_->_fuel < cmpfuel) { #ifdef STRAT_DEBUG cerr << car->_name << " REFUEL" << endl; #endif ret = true; } else { // Do we need to repair and is the pit free? - if (m_car->_dammage > PIT_DAMAGE) { + if (car_->_dammage > PIT_DAMAGE) { // Let's see if we can make it somehow onto the finish line // BEWARE doesnt check for limits, works for races > 5 laps!!! if (LapsToGo() <= LAST_LAPS) { // If prediction shows we would top the damage limit, // let's visit the pit - if (m_car->_dammage + GetAvgDamage() * LapsToGo() >= 10000) { + if (car_->_dammage + GetAvgDamage() * LapsToGo() >= 10000) { ret = IsPitFree(); } } else { @@ -314,8 +314,8 @@ bool KStrategy::NeedPitstop() const { * @return average damage increment */ int KStrategy::GetAvgDamage(void) const { - return (m_last_damages->front() - m_last_damages->back()) - / MAX(m_last_damages->size(), 1); + return (last_damages_->front() - last_damages_->back()) + / MAX(last_damages_->size(), 1); } // GetAvgDamage @@ -331,7 +331,7 @@ int KStrategy::GetAvgDamage(void) const { int KStrategy::PitRepair() const { int ret = (LapsToGo() <= LAST_LAPS) // In the last N laps ? GetAvgDamage() * LapsToGo() // repair only as much as really needed. - : m_car->_dammage; // Otherwise repair everything. + : car_->_dammage; // Otherwise repair everything. #ifdef STRAT_DEBUG cerr << car->_name @@ -340,14 +340,14 @@ int KStrategy::PitRepair() const { #endif // Clear buffer - m_last_damages->clear(); + last_damages_->clear(); return ret; } // pitRepair bool KStrategy::IsPitFree() const { - if (m_car->_pit != NULL && m_car->_pit->pitCarIndex == TR_PIT_STATE_FREE) + if (car_->_pit != NULL && car_->_pit->pitCarIndex == TR_PIT_STATE_FREE) return true; else return false; diff --git a/src/drivers/kilo2008/strategy.h b/src/drivers/kilo2008/strategy.h index 7f53f1bfd..89bc6ed24 100644 --- a/src/drivers/kilo2008/strategy.h +++ b/src/drivers/kilo2008/strategy.h @@ -39,7 +39,7 @@ class KStrategy { public: KStrategy(); - ~KStrategy() {delete m_last_damages;} + ~KStrategy() {delete last_damages_;} // Interface void Update(); @@ -50,33 +50,33 @@ class KStrategy { void ** const carParmHandle, const tSituation * const s, const int index); - void set_car(const tCarElt * const car) {this->m_car = car;} + void set_car(const tCarElt * const car) {this->car_ = car;} protected: bool IsPitFree() const; int GetAvgDamage() const; inline int LapsToGo() const - {return m_car->_remainingLaps - m_car->_lapsBehindLeader;} + {return car_->_remainingLaps - car_->_lapsBehindLeader;} void UpdateFuelStrategy(); void ComputeBestNumberOfPits(const double tankCapacity, const double requiredFuel, const int remainingLaps, const bool preRace); - const tCarElt * m_car; - int m_laps; - std::deque *m_last_damages; - int m_remaining_stops; - double m_fuel_per_stint; - double m_pittime; // Expected additional time for pit stop. - double m_best_lap; // Best possible lap, empty tank and alone. - double m_worst_lap; // Worst possible lap, full tank and alone. - bool m_fuel_checked; // Fuel statistics updated. - double m_fuel_per_lap; // Maximum amount of fuel we needed for a lap. - double m_last_pit_fuel; // Amount refueled, special case when we refuel. - double m_last_fuel; // Fuel available when we cross the start lane. - double m_expected_fuel_per_lap; // Expected fuel per lap (may be inaccurate). - double m_fuel_sum; // All the fuel used. + const tCarElt * car_; + int laps_; + std::deque *last_damages_; + int remaining_stops_; + double fuel_per_stint_; + double pittime_; // Expected additional time for pit stop. + double best_lap_; // Best possible lap, empty tank and alone. + double worst_lap_; // Worst possible lap, full tank and alone. + bool fuel_checked_; // Fuel statistics updated. + double fuel_per_lap_; // Maximum amount of fuel we needed for a lap. + double last_pit_fuel_; // Amount refueled, special case when we refuel. + double last_fuel_; // Fuel available when we cross the start lane. + double expected_fuel_per_lap_; // Expected fuel per lap (may be inaccurate). + double fuel_sum_; // All the fuel used. static const double MAX_FUEL_PER_METER; // [kg/m] fuel consumtion. static const int PIT_DAMAGE; // If damage > we request a pit stop.