More code cleanup.

Re #183.

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@2805 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: f676c3d1119a9774e6520f7b064f3585a58f5c2e
Former-commit-id: 9f562ec22146aec23c6f3b7e56b0fce94696b4a5
This commit is contained in:
kmetykog 2010-09-26 22:47:53 +00:00
parent 75221cb6db
commit c901c15f59
9 changed files with 458 additions and 574 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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<Opponent>::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<Opponent>::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<Opponent>::iterator it = opponents->begin();
it != opponents->end();
it++)
{
tCarElt *ocar = it->getCarPtr();
for(int otry = 0; otry <= 1; otry++) {
for(list<Opponent>::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<Opponent>::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<Opponent>::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<Opponent>::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;
}

View file

@ -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;

View file

@ -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<Opponent>::iterator it = begin(); it != end(); it++) {
if(it->isState(state)) {
ret = &(*it);
break;
}
}//for it
return ret;
}//getOppByState

View file

@ -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<Opponent>::iterator begin() {return m_opps->begin();}
inline list<Opponent>::iterator end() {return m_opps->end();}

View file

@ -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

View file

@ -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;
};

View file

@ -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