diff --git a/src/drivers/kilo2008/driver.cpp b/src/drivers/kilo2008/driver.cpp index b89a5ef8..6787fd6f 100644 --- a/src/drivers/kilo2008/driver.cpp +++ b/src/drivers/kilo2008/driver.cpp @@ -762,10 +762,10 @@ Driver::getTargetPoint() raceline->GetPoint(offset, lookahead, &rt); double dx = t.x - car->_pos_X; double dy = t.y - car->_pos_Y; - double dist1 = sqrt(dx * dx + dy * dy); + double dist1 = Mag(dx, dy); dx = rt.x - car->_pos_X; dy = rt.y - car->_pos_Y; - double dist2 = sqrt(dx * dx + dy * dy); + double dist2 = Mag(dx, dy); if(dist2 > dist1) t = rt; } @@ -1116,6 +1116,6 @@ Driver::brakedist(double allowedspeed, double mu) double c = mu * G; double d = (CA * mu + CW) / mass; double v1sqr = currentspeedsqr; - double v2sqr = allowedspeed * allowedspeed; + double v2sqr = pow(allowedspeed, 2); return -log((c + v2sqr * d) / (c + v1sqr * d)) / (2.0 * d); } diff --git a/src/drivers/kilo2008/driver.h b/src/drivers/kilo2008/driver.h index 7fee055d..49c185e1 100644 --- a/src/drivers/kilo2008/driver.h +++ b/src/drivers/kilo2008/driver.h @@ -40,7 +40,6 @@ #define BT_ATT_BESTLAP "bestlap" #define BT_ATT_WORSTLAP "worstlap" #define BT_ATT_TEAMMATE "teammate" -#define BT_ATT_SECRADIUS "securityradius" class Opponents; diff --git a/src/drivers/kilo2008/kdriver.cpp b/src/drivers/kilo2008/kdriver.cpp index ae5c1508..af52c659 100644 --- a/src/drivers/kilo2008/kdriver.cpp +++ b/src/drivers/kilo2008/kdriver.cpp @@ -55,7 +55,12 @@ KDriver::KDriver(int index):Driver(index) m_rInverse = 0.0; } -// Drive during race. + +/** + * Drive during the race. + * + * @param[in] s Situation provided by the sim. + */ void KDriver::drive(tSituation * s) { @@ -91,7 +96,11 @@ KDriver::drive(tSituation * s) }//drive -// Check if I'm stuck. +/** + * Checks if I'm stuck. + * + * @return true if stuck + */ bool KDriver::isStuck() { @@ -113,7 +122,13 @@ KDriver::isStuck() }//isStuck -// Reduces the brake value such that it fits the speed (more downforce -> more braking). +/** + * Reduces the brake value such that it fits the speed + * (more downforce -> more braking). + * + * @param[in] brake Original braking value + * @return Modified braking value + */ double KDriver::filterBrakeSpeed(double brake) { @@ -121,7 +136,7 @@ KDriver::filterBrakeSpeed(double brake) double maxForce = weight + CA * MAX_SPEED * MAX_SPEED; double force = weight + CA * currentspeedsqr; return brake * force / maxForce; -} +}//filterBrakeSpeed // Compute offset to normal target point for overtaking or let pass an opponent. @@ -176,21 +191,21 @@ KDriver::getOffset() } //Check for side collision - o = get_sidecoll_opp(); + o = getSidecollOpp(); if(o != NULL) - return filter_sidecoll_offset(o, incfactor); + return filterSidecollOffset(o, incfactor); // If we have someone to take over, let's try it - o = get_takeover_opp(); + o = getTakeoverOpp(); if(o != NULL) - return filter_takeover_offset(o); + return filterTakeoverOffset(o); // If there is someone overlapping, move out of the way - o = get_overlapping_opp(); + o = getOverlappingOpp(); if(o != NULL) - return filter_overlapped_offset(o); + return filterOverlappedOffset(o); // no-one to avoid, work back towards raceline @@ -213,10 +228,7 @@ KDriver::getOffset() }//getOffset -/* - * - * name: get_overlapping_opp - * +/** * Decide if there is a car behind overlapping us. * * A1) Teammate behind with more laps should overtake. @@ -226,121 +238,93 @@ KDriver::getOffset() * than TEAM_DAMAGE_CHANGE_LEAD. * B) Let other, overlapping opponents get by. - * @param: - - * @return: Opponent *, overlapping car pointer or NULL + * @return overlapping car pointer or NULL */ Opponent * -KDriver::get_overlapping_opp() +KDriver::getOverlappingOpp() { Opponent *ret = NULL; double mindist = -1000.0; for(list::iterator it = opponents->begin(); it != opponents->end(); - it++) - { - tCarElt *ocar = it->getCarPtr(); - double opp_distance = it->getDistance(); + it++) { + tCarElt *ocar = it->getCarPtr(); + double oppDistance = it->getDistance(); - if( - (//if teammate has more laps under his belt, - (it->is_teammate() && ocar->race.laps > car->race.laps) - || //or teammate is less damaged, let him go - it->is_quicker_teammate(car) - ) - && //if close enough - (opp_distance > -TEAM_REAR_DIST) - && - (opp_distance < -car->_dimension_x) - ) - { - // Behind, larger distances are smaller ("more negative"). - if(opp_distance > mindist) { - mindist = opp_distance; - ret = &(*it); - } - } // if teammate - else if(it->is_state(OPP_LETPASS)) - { - // Behind, larger distances are smaller ("more negative"). - if(opp_distance > mindist) { - mindist = opp_distance; - ret = &(*it); - } - } // else if - } // for i + if((//if teammate has more laps under his belt, + (it->isTeammate() && 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->isState(OPP_LETPASS)) { + // Behind, larger distances are smaller ("more negative"). + if(oppDistance > mindist) { + mindist = oppDistance; + ret = &(*it); + } + } // else if + } // for i + return ret; -}//get_overlapping_opp +}//getOverlappingOpp -/* - * - * name: filter_overlapped_offset - * +/** * Modifies the member 'myoffset' so that the car moves out of the way * of the overlapping opponent. * - * @param Opponent *o: the opponent we should let go - * @return: double, new offset. Equals member 'myoffset' + * @param [in] o: the opponent we should let go + * @return new offset. Equals member 'myoffset' * */ double -KDriver::filter_overlapped_offset(Opponent *o) +KDriver::filterOverlappedOffset(Opponent *o) { double w = car->_trkPos.seg->width / WIDTHDIV - BORDER_OVERTAKE_MARGIN; - if(opp_is_on_right(o)) - { - if(myoffset < w) - myoffset += OVERTAKE_OFFSET_INC * m_lftinc / 1;//2; - } - else - { - if(myoffset > -w) - myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc / 1;//2; - } + if(o->isOnRight(car->_trkPos.toMiddle)) { + if(myoffset < w) + myoffset += OVERTAKE_OFFSET_INC * m_lftinc / 1;//2; + } else { + if(myoffset > -w) + myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc / 1;//2; + } setMode(BEING_OVERLAPPED); myoffset = MIN(avoidlftoffset, MAX(avoidrgtoffset, myoffset)); return myoffset; -} +}//filterOverlappedOffset -/* - * - * name: filterOverlap - * + +/** * If there is an opponent overlapping us, reduce accelerator. * - * @param double accel: original acceleration value - * @return: double, possibly reduced acceleration value + * @param [in] accel: original acceleration value + * @return possibly reduced acceleration value */ double KDriver::filterOverlap(double accel) { - return (get_opp_by_state(OPP_LETPASS) ? MIN(accel, LET_OVERTAKE_FACTOR) : accel); -} + return (opponents->getOppByState(OPP_LETPASS) + ? MIN(accel, LET_OVERTAKE_FACTOR) + : accel); +}//filterOverlap -Opponent * -KDriver::get_opp_by_state(const int state) -{ - Opponent *ret = NULL; - for(list::iterator it = opponents->begin(); - it != opponents->end(); - it++) - { - if(it->is_state(state)) - { - ret = &(*it); - break; - } - } - return ret; -} -/* +/** * 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) @@ -350,76 +334,76 @@ KDriver::oppTooFarOnSide(tCarElt *ocar) && fabs(car->_trkPos.toMiddle - ocar->_trkPos.toMiddle) >= 5.0) ret = true; return ret; -} +}//oppTooFarOnSide -/* - * - * name: get_takeover_opp - * + +/** * Decide if there is a car ahead we can take over. * - * @param: - - * @return: Opponent *, overlapping car pointer or NULL + * @return Overlap car pointer or NULL */ Opponent* -KDriver::get_takeover_opp() +KDriver::getTakeoverOpp() { Opponent *ret = NULL; m_mincatchdist = MAX(30.0, 1500.0 - fabs(m_rInverse) * 10000); - int otry_success = 0; + int otrySuccess = 0; - for(int otry = 0; otry <= 1; otry++) - { - for(list::iterator it = opponents->begin(); - it != opponents->end(); - it++) - { - tCarElt *ocar = it->getCarPtr(); + for(int otry = 0; otry <= 1; otry++) { + for(list::iterator it = opponents->begin(); + it != opponents->end(); + it++) { + tCarElt *ocar = it->getCarPtr(); - // If opponent is clearly ahead of us, we don't care - if(it->is_state(OPP_FRONT_FOLLOW)) - continue; + // If opponent is clearly ahead of us, we don't care + if(it->isState(OPP_FRONT_FOLLOW)) + continue; - if(oppTooFarOnSide(ocar)) - continue; + if(oppTooFarOnSide(ocar)) + continue; - // If opponent is in pit, let him be ;) - if(ocar->_state > RM_CAR_STATE_PIT) - continue; + // If opponent is in pit, let him be ;) + if(ocar->_state > RM_CAR_STATE_PIT) + continue; - // If opponent is ahead, and is not a quicker teammate of ours - if((it->is_state(OPP_FRONT)) - && !it->is_quicker_teammate(car)) - { - double otry_factor = (otry ? (0.2 + (1.0 - ((currentsimtime - avoidtime) / 7.0)) * 0.8) : 1.0); - double distance = it->getDistance() * otry_factor; //how far ahead is he - double speed = MIN(avoidspeed, getSpeed() + MAX(0.0, 10.0 - distance)); - double ospeed = it->getSpeed(); //opponent's speed - double catchdist = MIN(speed * distance / (speed - ospeed), - distance * CATCH_FACTOR) * otry_factor; //when will we reach the opponent + // If opponent is ahead, and is not a quicker teammate of ours + if((it->isState(OPP_FRONT)) + && !it->isQuickerTeammate(car)) { + double otry_factor = (otry ? (0.2 + (1.0 - ((currentsimtime - avoidtime) / 7.0)) * 0.8) : 1.0); + double distance = it->getDistance() * otry_factor; //how far ahead is he + double speed = MIN(avoidspeed, getSpeed() + MAX(0.0, 10.0 - distance)); + double ospeed = it->getSpeed(); //opponent's speed + double catchdist = MIN(speed * distance / (speed - ospeed), + distance * CATCH_FACTOR) * otry_factor; //when will we reach the opponent - //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; - ret = &(*it); //This is the guy we need to take over - otry_success = otry; - } - } - } //for it - if (ret) break; - if (mode != AVOIDING) break; - } //for otry + //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; + ret = &(*it); //This is the guy we need to take over + otrySuccess = otry; + } + }//if it state + } //for it + if (ret) break; + if (mode != AVOIDING) break; + } //for otry - if(ret != NULL && otry_success == 0) + if(ret != NULL && otrySuccess == 0) avoidtime = currentsimtime; return ret; -} +}//getTakeoverOpp + +/** + * Change offset value if we are to overtake a car. + * + * @param [in] o the opponent + * @return new offset + */ double -KDriver::filter_takeover_offset(Opponent *o) +KDriver::filterTakeoverOffset(Opponent *o) { setMode(AVOIDING); tCarElt *ocar = o->getCarPtr(); @@ -435,166 +419,154 @@ KDriver::filter_takeover_offset(Opponent *o) (otm > (ocar->_trkPos.seg->width - 5.0) && m_rInverse > 0.0)) sidemargin += fabs(m_rInverse) * 150; - if (otm > (ocar->_trkPos.seg->width - 5.0) || - (car->_trkPos.toLeft > ocar->_trkPos.toLeft && - (sidedist < sidemargin || o->is_state(OPP_COLL)))) - { - myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc; - setAvoidLeft(); + if (otm > (ocar->_trkPos.seg->width - 5.0) + || (car->_trkPos.toLeft > ocar->_trkPos.toLeft + && (sidedist < sidemargin || o->isState(OPP_COLL)))) { + myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc; + setAvoidLeft(); + } else if (otm < -(ocar->_trkPos.seg->width - 5.0) + || (car->_trkPos.toLeft < ocar->_trkPos.toLeft + && (sidedist < sidemargin || o->isState(OPP_COLL)))) { + myoffset += OVERTAKE_OFFSET_INC * m_lftinc; + setAvoidRight(); + } 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 = car->_trkPos.seg; + double length = getDistToSegEnd(); + double oldlen, seglen = length; + double lenright = 0.0, lenleft = 0.0; + m_mincatchdist = MIN(m_mincatchdist, DISTCUTOFF); + + do { + switch(seg->type) { + case TR_LFT: + lenleft += seglen; + break; + case TR_RGT: + lenright += seglen; + break; + default: + // Do nothing. + break; + }//switch seg->type + seg = seg->next; + seglen = seg->length; + oldlen = length; + length += seglen; + } while(oldlen < m_mincatchdist); + + // If we are on a straight look for the next turn. + if(lenleft == 0.0 && lenright == 0.0) { + while(seg->type == TR_STR) + seg = seg->next; + + // Assume: left or right if not straight. + if(seg->type == TR_LFT) + lenleft = 1.0; + else + lenright = 1.0; + }//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)) { + // 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; } - else if (otm < -(ocar->_trkPos.seg->width - 5.0) || - (car->_trkPos.toLeft < ocar->_trkPos.toLeft && - (sidedist < sidemargin || o->is_state(OPP_COLL)))) - { - myoffset += OVERTAKE_OFFSET_INC * m_lftinc; - setAvoidRight(); - } - 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 = car->_trkPos.seg; - double length = getDistToSegEnd(); - double oldlen, seglen = length; - double lenright = 0.0, lenleft = 0.0; - m_mincatchdist = MIN(m_mincatchdist, DISTCUTOFF); - - do - { - switch(seg->type) - { - case TR_LFT: - lenleft += seglen; - break; - case TR_RGT: - lenright += seglen; - break; - default: - // Do nothing. - break; - } - seg = seg->next; - seglen = seg->length; - oldlen = length; - length += seglen; - } - while(oldlen < m_mincatchdist); - - // If we are on a straight look for the next turn. - if(lenleft == 0.0 && lenright == 0.0) - { - while(seg->type == TR_STR) - { - seg = seg->next; - } - // Assume: left or right if not straight. - if(seg->type == TR_LFT) - lenleft = 1.0; - else - lenright = 1.0; - } - - // Because we are inside we can go to the border. - if ((lenleft > lenright && m_rInverse < 0.0) || - (lenleft <= lenright && m_rInverse > 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; - } - if(sidedist < sidemargin || o->is_state(OPP_COLL)) - { - if(lenleft > lenright) - { - myoffset += OVERTAKE_OFFSET_INC * m_lftinc;// * 0.7; - setAvoidRight(); - } - else - { - myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc;// * 0.7; - setAvoidLeft(); - }//if lenleft - }//if sidedist - }//if opp near middle + if(sidedist < sidemargin || o->isState(OPP_COLL)) { + if(lenleft > lenright) { + myoffset += OVERTAKE_OFFSET_INC * m_lftinc;// * 0.7; + setAvoidRight(); + } else { + myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc;// * 0.7; + setAvoidLeft(); + }//if lenleft > lenright + }//if sidedist + }//if opp near middle myoffset = MIN(avoidlftoffset, MAX(avoidrgtoffset, myoffset)); myoffset = MIN(m_maxoffset, MAX(m_minoffset, myoffset)); return myoffset; -}//filter_takeover_offset +}//filterTakeoverOffset +/** + * Decide if there is a car on the side we are to collide with... + * + * @return Side collision car pointer or NULL + */ Opponent * -KDriver::get_sidecoll_opp() +KDriver::getSidecollOpp() { Opponent *ret = NULL; for(list::iterator it = opponents->begin(); it != opponents->end(); - it++) - { - tCarElt *ocar = it->getCarPtr(); + it++) { + tCarElt *ocar = it->getCarPtr(); - if(ocar->_state > RM_CAR_STATE_PIT) //Dont care for opponents in the pit - continue; + if(ocar->_state > RM_CAR_STATE_PIT) //Dont care for opponents in the pit + continue; - if(oppTooFarOnSide(ocar)) - continue; + if(oppTooFarOnSide(ocar)) + continue; - if(it->is_state(OPP_SIDE)) //If opponent is on our side - { - setMode(AVOIDING); - ret = &(*it); - break; - } //if OPP_SIDE - } //for it + 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::filter_sidecoll_offset(Opponent *o, - const double incfactor) +KDriver::filterSidecollOffset(Opponent *o, const double incfactor) { double myToLeft = car->_trkPos.toLeft; double oppToLeft = o->getCarPtr()->_trkPos.toLeft; double sidedist = fabs(oppToLeft - myToLeft); double sidemargin = o->getWidth() + getWidth() + 2.0; + + 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((opp_is_on_right(o) && m_rInverse < 0.0) - || (!opp_is_on_right(o) && m_rInverse > 0.0)) + if((oppOnRight && m_rInverse < 0.0) + || (!oppOnRight && m_rInverse > 0.0)) sidemargin += fabs(m_rInverse) * 150; - if(opp_is_on_right(o)) + if(oppOnRight) sidemargin -= MIN(0.0, m_rInverse * 100); else sidemargin += MAX(0.0, m_rInverse * 100); sidedist = MIN(sidedist, sidemargin); - if(sidedist < sidemargin) - { - double sdiff = 3.0 - (sidemargin - sidedist) / sidemargin; - - if(opp_is_on_right(o)) //He is on the right, we must move to the left - myoffset += OVERTAKE_OFFSET_INC * m_lftinc * MAX(0.2, MIN(1.0, sdiff)); - else //He is on the left, we must move to the right - myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc * MAX(0.2, MIN(1.0, sdiff)); - } - else if(sidedist > sidemargin + 3.0) - { - if(raceoffset > myoffset + OVERTAKE_OFFSET_INC * incfactor) - myoffset += OVERTAKE_OFFSET_INC * m_lftinc / 4; - else if (raceoffset < myoffset - OVERTAKE_OFFSET_INC * incfactor) - myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc / 4; - } + if(sidedist < sidemargin) { + double sdiff = 3.0 - (sidemargin - sidedist) / sidemargin; + + if(oppOnRight) //He is on the right, we must move to the left + myoffset += OVERTAKE_OFFSET_INC * m_lftinc * MAX(0.2, MIN(1.0, sdiff)); + else //He is on the left, we must move to the right + myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc * MAX(0.2, MIN(1.0, sdiff)); + } else if(sidedist > sidemargin + 3.0) { + if(raceoffset > myoffset + OVERTAKE_OFFSET_INC * incfactor) + myoffset += OVERTAKE_OFFSET_INC * m_lftinc / 4; + else if (raceoffset < myoffset - OVERTAKE_OFFSET_INC * incfactor) + myoffset -= OVERTAKE_OFFSET_INC * m_rgtinc / 4; + } - opp_is_on_right(o) ? setAvoidRight() : setAvoidLeft(); + oppOnRight ? setAvoidRight() : setAvoidLeft(); avoidmode |= AVOIDSIDE; myoffset = MIN(m_maxoffset, MAX(m_minoffset, myoffset)); return myoffset; -} +}//filterSidecollOffset + void KDriver::initTrack(tTrack * t, void *carHandle, void **carParmHandle, @@ -650,6 +622,7 @@ KDriver::initTrack(tTrack * t, void *carHandle, void **carParmHandle, *carParmHandle = newhandle; } + // Create a pit stop strategy object. strategy = new KStrategy(); // Init fuel. @@ -661,53 +634,35 @@ KDriver::initTrack(tTrack * t, void *carHandle, void **carParmHandle, MU_FACTOR = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, BT_ATT_MUFACTOR, (char *) NULL, 0.69f); - double MinCornerInverse = - GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "MinCornerInverse", - (char *) NULL, 0.002); - double CornerSpeed = - GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "CornerSpeed", - (char *) NULL, 15.0); - double AvoidSpeed = - GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "AvoidSpeedAdjust", - (char *) NULL, 2.0); - double CornerAccel = - GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "CornerAccel", - (char *) NULL, 1.0); - double IntMargin = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "IntMargin", - (char *) NULL, 1.0); - double ExtMargin = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "ExtMargin", - (char *) NULL, 2.0); - brakedelay = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "BrakeDelay", - (char *) NULL, 10.0); PitOffset = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "PitOffset", (char *) NULL, 10.0); - brakedelay = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "BrakeDelay", - (char *) NULL, 10.0); - raceline->InitTrack(track, carParmHandle, s); } -// Update my private data every timestep. +/** + * Update own private data on every timestep. + * + * @param [in] s situation provided by the sim + */ void KDriver::update(tSituation * s) { // Update global car data (shared by all instances) just once per timestep. - if(currentsimtime != s->currentTime) - { - currentsimtime = s->currentTime; - cardata->update(); - } - // Update the local data rest. + if(currentsimtime != s->currentTime) { + currentsimtime = s->currentTime; + cardata->update(); + } + // Update the rest of local data speedangle = -(mycardata->getTrackangle() - atan2(car->_speed_Y, car->_speed_X)); NORM_PI_PI(speedangle); mass = CARMASS + car->_fuel; - currentspeedsqr = car->_speed_x * car->_speed_x; + currentspeedsqr = pow(car->_speed_x, 2); opponents->update(s, this); strategy->update(); - check_pit_status(s); + checkPitStatus(s); pit->update(); simtime = s->currentTime; @@ -715,21 +670,17 @@ KDriver::update(tSituation * s) angle = trackangle - car->_yaw; NORM_PI_PI(angle); angle = -angle; -} +}//update -/* - * - * name: check_pit_status - * +/** * Checks if we need to plan a pitstop. * If yes, checks availability of the pit, * is it free or occupied by teammate. * - * @param - * @return + * @param [in] s Situation provided by the sim */ void -KDriver::check_pit_status(tSituation *s) +KDriver::checkPitStatus(tSituation *s) { //If our car is still in the race if(car->_state <= RM_CAR_STATE_PIT) @@ -753,7 +704,7 @@ KDriver::check_pit_status(tSituation *s) { tCarElt *ocar = it->getCarPtr(); //If the other car is our teammate, still in the race - if(it->is_teammate() && ocar->_state <= RM_CAR_STATE_PIT) + if(it->isTeammate() && ocar->_state <= RM_CAR_STATE_PIT) { int idx = it->getIndex(); if(pitstatus[idx] == 1 @@ -773,35 +724,40 @@ KDriver::check_pit_status(tSituation *s) } else pitstatus[carindex] = 0; -} +}//checkPitStatus -// Brake filter for collision avoidance. +/** + * Brake filter for collision avoidance. + * If there is an opponent we are to collide, brake brake brake! + * + * @param [in] brake Original brake value + * @return Possibly modified brake value + */ double -KDriver::filterBColl(double brake) +KDriver::filterBColl(const double brake) { - if(simtime < 1.5) - return brake; + double ret = brake; + + if(simtime >= 1.5) { + double mu = car->_trkPos.seg->surface->kFriction; + for(list::iterator it = opponents->begin(); + it != 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!!! + accelcmd = 0.0; + ret = 1.0; + break; + }//if brakedist + }//if state OPP_COLL + }//for it + + return ret; +}//filterBColl - double mu = car->_trkPos.seg->surface->kFriction; - for(list::iterator it = opponents->begin(); - it != opponents->end(); - it++) - { - if(it->is_state(OPP_COLL)) - { - double ospeed = it->getSpeed(); - if(brakedist(ospeed, mu) - + MIN(1.0, 0.5 + MAX(0.0,(getSpeed() - ospeed) / 4)) - > it->getDistance()) - { - accelcmd = 0.0; - return 1.0; - } - } - } - return brake; -} // Set pitstop commands. int @@ -812,14 +768,16 @@ KDriver::pitCommand(tSituation * s) // This should be the only place where the pit stop is set to false! pit->setPitstop(false); return ROB_PIT_IM; // return immediately. -} +}//pitCommand + void KDriver::newRace(tCarElt * car, tSituation * s) { strategy->setCar(car); Driver::newRace(car, s); -} +}//newRace + void KDriver::calcSpeed() @@ -851,9 +809,3 @@ KDriver::calcSpeed() brakecmd = MIN(1.0, -(MAX(10.0, brakedelay * 0.7)) * x); }//calcSpeed -inline bool -KDriver::opp_is_on_right(Opponent *o) { - return (car->_trkPos.toMiddle > o->getCarPtr()->_trkPos.toMiddle) - ? true - : false; - } diff --git a/src/drivers/kilo2008/kdriver.h b/src/drivers/kilo2008/kdriver.h index cc5e105e..bd3ebcc2 100644 --- a/src/drivers/kilo2008/kdriver.h +++ b/src/drivers/kilo2008/kdriver.h @@ -57,15 +57,13 @@ protected: bool oppTooFarOnSide(tCarElt *ocar); //'own' utilities - Opponent * get_overlapping_opp(); - Opponent * get_takeover_opp(); - Opponent * get_sidecoll_opp(); - double filter_overlapped_offset(Opponent *o); - double filter_takeover_offset(Opponent *o); - double filter_sidecoll_offset(Opponent *o, const double); - Opponent * get_opp_by_state(const int state); - inline bool opp_is_on_right(Opponent *o); - void check_pit_status(tSituation *s); + Opponent * getOverlappingOpp(); + Opponent * getTakeoverOpp(); + Opponent * getSidecollOpp(); + double filterOverlappedOffset(Opponent *o); + double filterTakeoverOffset(Opponent *o); + double filterSidecollOffset(Opponent *o, const double); + void checkPitStatus(tSituation *s); //'own' variables double m_mincatchdist; diff --git a/src/drivers/kilo2008/opponent.cpp b/src/drivers/kilo2008/opponent.cpp index 8c81506d..4ef1233a 100644 --- a/src/drivers/kilo2008/opponent.cpp +++ b/src/drivers/kilo2008/opponent.cpp @@ -97,7 +97,7 @@ Opponent::update(tSituation *s, Driver *driver) { m_state |= OPP_FRONT; - if(is_quicker_teammate(mycar)) + if(isQuickerTeammate(mycar)) m_state |= OPP_FRONT_FOLLOW; m_distance -= SIDECOLLDIST; @@ -145,7 +145,7 @@ Opponent::update(tSituation *s, Driver *driver) else if(m_distance > SIDECOLLDIST && getSpeed() > driver->getSpeed()) { m_state |= OPP_FRONT_FAST; - if(is_quicker_teammate(mycar)) + if(isQuickerTeammate(mycar)) m_state |= OPP_FRONT_FOLLOW; m_distance -= SIDECOLLDIST; if (m_distance < 20.0 - (getSpeed() - driver->getSpeed()) * 4) @@ -177,17 +177,17 @@ Opponent::getDistToSegStart() const void Opponent::updateOverlapTimer(tSituation * const s, tCarElt * const mycar) { - if((m_car->race.laps > mycar->race.laps) || is_quicker_teammate(mycar)) + if((m_car->race.laps > mycar->race.laps) || isQuickerTeammate(mycar)) { - if(is_state(OPP_BACK | OPP_SIDE)) + if(isState(OPP_BACK | OPP_SIDE)) m_overlaptimer += s->deltaTime; - else if(is_state(OPP_FRONT)) + else if(isState(OPP_FRONT)) m_overlaptimer = LAP_BACK_TIME_PENALTY; else { if(m_overlaptimer > 0.0) { - if(is_state(OPP_FRONT_FAST)) + if(isState(OPP_FRONT_FAST)) m_overlaptimer = MIN(0.0, m_overlaptimer); else m_overlaptimer -= s->deltaTime; @@ -202,8 +202,6 @@ Opponent::updateOverlapTimer(tSituation * const s, tCarElt * const mycar) /** - * is_quicker_teammate - * * Returns true, if the other car is our teammate * and has significantly less damage * (defined in Driver::TEAM_DAMAGE_CHANGE_LEAD) @@ -212,11 +210,11 @@ Opponent::updateOverlapTimer(tSituation * const s, tCarElt * const mycar) * @return true, if the opponent is our teammate */ bool -Opponent::is_quicker_teammate(tCarElt * const mycar) +Opponent::isQuickerTeammate(tCarElt * const mycar) { - return (is_teammate() + return (isTeammate() && (mycar->_dammage - m_car->_dammage > Driver::TEAM_DAMAGE_CHANGE_LEAD)); -}//is_quicker_teammate +}//isQuickerTeammate /** @@ -291,45 +289,21 @@ Opponents::setTeamMate(const tCarElt *car) }//setTeamMate -#if 0 -void -TeamTacticsMatrix(tCarElt *car_A, tCarElt *car_B, int *order_A, int *order_B) +/** + * Searches the first opponent with the given state. + * + * @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) { - tCarElt *car_front; - tCarElt *car_behind; - - //Decide which car is ahead - if(car_A->_distRaced >= car_B->_distRaced) - { - car_front = car_A; - car_behind = car_B; - } - else - { - car_front = car_B; - car_behind = car_A; - } - - //For easier handling, f_: front, b_: behind - int f_laps = car_front->_laps; - int b_laps = car_behind->_laps; - int f_damage = car_front->_dammage; - int b_damage = car_behind->_dammage; - - - if(b_laps > f_laps) //Case 1,2,3 - { - - } - else - { - if(b_laps == f_laps) //Case 4,5,6 - { - } - else //Case 7,8,9 - { - - } - } -} -#endif + Opponent *ret = NULL; + for(list::iterator it = begin(); it != end(); it++) { + if(it->isState(state)) { + ret = &(*it); + break; + } + }//for it + return ret; +}//getOppByState diff --git a/src/drivers/kilo2008/opponent.h b/src/drivers/kilo2008/opponent.h index d47319a4..96aa0eaa 100644 --- a/src/drivers/kilo2008/opponent.h +++ b/src/drivers/kilo2008/opponent.h @@ -59,9 +59,11 @@ public: double getSpeed() const {return m_cardata->getSpeedInTrackDirection();} int getIndex() const {return m_index;} - inline bool is_state(const int state) const {return bool(m_state & state);} - inline bool is_teammate() const {return m_teammate;} - bool is_quicker_teammate(tCarElt * const mycar); + inline bool isState(const int state) const {return bool(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;} inline void markAsTeamMate() {m_teammate = true;} void update(tSituation *s, Driver *driver); @@ -107,6 +109,8 @@ public: void update(tSituation *s, Driver *driver); void setTeamMate(const tCarElt *car); + Opponent *getOppByState(const int state); + inline list::iterator begin() {return m_opps->begin();} inline list::iterator end() {return m_opps->end();} diff --git a/src/drivers/kilo2008/pit.cpp b/src/drivers/kilo2008/pit.cpp index 6ebbe17a..9e387b8d 100644 --- a/src/drivers/kilo2008/pit.cpp +++ b/src/drivers/kilo2008/pit.cpp @@ -33,91 +33,78 @@ const double Pit::Pit(const tSituation * s, Driver * driver, const double pitoffset) { - track = driver->getTrackPtr(); - car = driver->getCarPtr(); - mypit = driver->getCarPtr()->_pit; - pitinfo = &track->pits; - pitstop = inpitlane = false; - pittimer = 0.0; + 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; - if(mypit != NULL) - { - speedlimit = pitinfo->speedLimit - SPEED_LIMIT_MARGIN; - speedlimitsqr = speedlimit * speedlimit; - pitspeedlimitsqr = pitinfo->speedLimit * pitinfo->speedLimit; + 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); - // Compute pit spline points along the track. - p[3].x = mypit->pos.seg->lgfromstart + mypit->pos.toStart; - p[2].x = p[3].x - pitinfo->len; - p[4].x = p[3].x + pitinfo->len; - p[0].x = pitinfo->pitEntry->lgfromstart + pitoffset; - p[1].x = pitinfo->pitStart->lgfromstart; - p[5].x = pitinfo->pitStart->lgfromstart + pitinfo->nMaxPits * pitinfo->len; - p[6].x = pitinfo->pitExit->lgfromstart; + // 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; + m_p[5].x = m_pitinfo->pitStart->lgfromstart + m_pitinfo->nMaxPits * m_pitinfo->len; + m_p[6].x = m_pitinfo->pitExit->lgfromstart; - pitentry = p[0].x; - pitexit = p[6].x; + m_pitentry = m_p[0].x; + m_pitexit = m_p[6].x; - // Normalizing spline segments to >= 0.0. - for(int i = 0; i < NPOINTS; i++) - { - p[i].s = 0.0; - p[i].x = toSplineCoord(p[i].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); + }//for i - // Fix broken pit exit. - if(p[6].x < p[5].x) - { - //printf("bt: Pitexit broken on track %s.\n", track->name); - p[6].x = p[5].x + 50.0; - } + // Fix broken pit exit. + if(m_p[6].x < m_p[5].x) + m_p[6].x = m_p[5].x + 50.0; - // Fix point for first pit if necessary. - if(p[1].x > p[2].x) - { - p[1].x = p[2].x; - } + // Fix point for first pit if necessary. + if(m_p[1].x > m_p[2].x) + m_p[1].x = m_p[2].x; - // Fix point for last pit if necessary. - if(p[4].x > p[5].x) - { - p[5].x = p[4].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; - double sign = (pitinfo->side == TR_LFT) ? 1.0 : -1.0; - p[0].y = 0.0; - p[6].y = 0.0; - for(int i = 1; i < NPOINTS - 1; i++) - { - p[i].y = fabs(pitinfo->driversPits->pos.toMiddle) - pitinfo->width; - p[i].y *= sign; - } + double sign = (m_pitinfo->side == TR_LFT) ? 1.0 : -1.0; + m_p[0].y = 0.0; + m_p[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; + }//for i - p[3].y = fabs(pitinfo->driversPits->pos.toMiddle + 1.0) * sign; - spline = new Spline(NPOINTS, p); - } -} + m_p[3].y = fabs(m_pitinfo->driversPits->pos.toMiddle + 1.0) * sign; + m_spline = new Spline(NPOINTS, m_p); + }//if pit not null +}//Pit::Pit Pit::~Pit() { - if(mypit != NULL) - { - delete spline; - } -} + if(m_mypit != NULL) + delete m_spline; +}//Pit::~Pit // Transforms track coordinates to spline parameter coordinates. double -Pit::toSplineCoord(double x) const +Pit::toSplineCoord(const double x) const { - x -= pitentry; - while(x < 0.0) - { - x += track->length; - } - return x; + double ret = x - m_pitentry; + while(ret < 0.0) + ret += m_track->length; + + return ret; }//toSplineCoord @@ -125,69 +112,51 @@ Pit::toSplineCoord(double x) const double Pit::getPitOffset(const double offset, double fromstart) { - if(mypit != NULL) - { - if(getInPit() || (getPitstop() && isBetween(fromstart))) - { - fromstart = toSplineCoord(fromstart); - return spline->evaluate(fromstart); - } + if(m_mypit != NULL) { + if(getInPit() || (getPitstop() && isBetween(fromstart))) { + fromstart = toSplineCoord(fromstart); + return m_spline->evaluate(fromstart); } + } return offset; -} +}//getPitOffset // Sets the pitstop flag if we are not in the pit range. void Pit::setPitstop(bool pitstop) { - if(mypit != NULL) - { - double fromstart = car->_distFromStartLine; + if(m_mypit != NULL) { + double fromstart = m_car->_distFromStartLine; - if(!isBetween(fromstart)) - { - this->pitstop = pitstop; - } - else - { - if(!pitstop) - { - this->pitstop = pitstop; - pittimer = 0.0; - } - } + if(!isBetween(fromstart)) { + m_pitstop = pitstop; + } else { + if(!pitstop) { + m_pitstop = pitstop; + m_pittimer = 0.0; + } } -} + } +}//setPitstop // Check if the argument fromstart is in the range of the pit. bool Pit::isBetween(const double fromstart) const { - if(pitentry <= pitexit) - { - if(fromstart >= pitentry && fromstart <= pitexit) - { - return true; - } - else - { - return false; - } - } - else - { - // Warning: TORCS reports sometimes negative values for "fromstart"! - if(fromstart <= pitexit || fromstart >= pitentry) - { - return true; - } - else - { - return false; - } - } + bool ret = false; + + if(m_pitentry <= m_pitexit) { + if(fromstart >= m_pitentry && fromstart <= m_pitexit) + ret = true; + } else { + // Warning: TORCS reports sometimes negative values for "fromstart"! + if(fromstart <= m_pitexit || fromstart >= m_pitentry) + ret = true; + }//if pitentry <= pitexit + + return ret; }//isBetween @@ -197,24 +166,19 @@ Pit::isBetween(const double fromstart) const bool Pit::isTimeout(const double distance) { - if(car->_speed_x > 1.0 || distance > 3.0 || !getPitstop()) - { - pittimer = 0.0; - return false; - } - else - { - pittimer += RCM_MAX_DT_ROBOTS; - if(pittimer > 3.0) - { - pittimer = 0.0; - return true; - } - else - { - return false; - } + bool ret = false; + + if(m_car->_speed_x > 1.0 || distance > 3.0 || !getPitstop()) { + m_pittimer = 0.0; + } else { + m_pittimer += RCM_MAX_DT_ROBOTS; + if(m_pittimer > 3.0) { + m_pittimer = 0.0; + ret = true; } + } + + return ret; }//isTimeout @@ -222,23 +186,15 @@ Pit::isTimeout(const double distance) void Pit::update() { - if(mypit != NULL) - { - if(isBetween(car->_distFromStartLine)) - { - if(getPitstop()) - { - setInPit(true); - } - } - else - { - setInPit(false); - } - + if(m_mypit != NULL) { + if(isBetween(m_car->_distFromStartLine)) { if(getPitstop()) - { - car->_raceCmd = RM_CMD_PIT_ASKED; - } + setInPit(true); + } else { + setInPit(false); } + + if(getPitstop()) + m_car->_raceCmd = RM_CMD_PIT_ASKED; + } }//update diff --git a/src/drivers/kilo2008/pit.h b/src/drivers/kilo2008/pit.h index d0d4cae7..e81fedfa 100644 --- a/src/drivers/kilo2008/pit.h +++ b/src/drivers/kilo2008/pit.h @@ -39,50 +39,51 @@ public: ~Pit(); void setPitstop(const bool pitstop); - inline bool getPitstop() const {return pitstop;} - inline void setInPit(const bool inpitlane) {this->inpitlane = inpitlane;} - inline bool getInPit() const {return inpitlane;} + inline bool getPitstop() const {return m_pitstop;} + inline void setInPit(const bool inpitlane) {m_inpitlane = inpitlane;} + inline bool getInPit() const {return m_inpitlane;} double getPitOffset(const double offset, double fromstart); bool isBetween(const double fromstart) const; bool isTimeout(const double distance); - inline double getNPitStart() const {return p[1].x;} - inline double getNPitLoc() const {return p[3].x;} - inline double getNPitEnd() const {return p[5].x;} - inline double getNPitEntry() const {return p[0].x;} + 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 speedlimitsqr;} - inline double getSpeedlimit() const {return speedlimit;} + inline double getSpeedlimitSqr() const {return m_speedlimitsqr;} + inline double getSpeedlimit() const {return m_speedlimit;} inline double getSpeedLimitBrake(const double speedsqr) const - {return (speedsqr - speedlimitsqr) / (pitspeedlimitsqr - speedlimitsqr);} + {return (speedsqr - m_speedlimitsqr) + / (m_pitspeedlimitsqr - m_speedlimitsqr);} void update(); private: - tTrack * track; - tCarElt *car; - tTrackOwnPit *mypit; // Pointer to my pit. - tTrackPitInfo *pitinfo; // General pit info. + tTrack *m_track; + tCarElt *m_car; + tTrackOwnPit *m_mypit; // Pointer to my pit. + tTrackPitInfo *m_pitinfo; // General pit info. enum { NPOINTS = 7 }; - SplinePoint p[NPOINTS]; // Spline points. - Spline *spline; // Spline. + SplinePoint m_p[NPOINTS]; // Spline points. + Spline *m_spline; // Spline. - bool pitstop; // Pitstop planned. - bool inpitlane; // We are still in the pit lane. - double pitentry; // Distance to start line of the pit entry. - double pitexit; // Distance to the start line of the pit exit. + 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. - double speedlimitsqr; // Pit speed limit squared. - double speedlimit; // Pit speed limit. - double pitspeedlimitsqr; // The original speedlimit squared. + double m_speedlimitsqr; // Pit speed limit squared. + double m_speedlimit; // Pit speed limit. + double m_pitspeedlimitsqr; // The original speedlimit squared. - double pittimer; // Timer for pit timeouts. + double m_pittimer; // 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 29b66f38..4537f7b4 100644 --- a/src/drivers/kilo2008/raceline.cpp +++ b/src/drivers/kilo2008/raceline.cpp @@ -498,7 +498,7 @@ LRaceLine::InitTrack(const tTrack * const track, void **carParmHandle, const tSi (char *) NULL, 2.0); m_dBrakeDelay = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "BrakeDelay", (char *) NULL, 10.0); - m_dSecurityRadius = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, BT_ATT_SECRADIUS, + m_dSecurityRadius = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, "securityradius", (char *) NULL, 100.0); // split track