- Update Shadow's driver
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@6807 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: b87e36785eae588746234881369ecd4c266efb91 Former-commit-id: f352314d14eb3eb79e9c3fb69ebfcd5b33e7da16
This commit is contained in:
parent
0ebd6b6a12
commit
5b3c1bc9c7
10 changed files with 2103 additions and 27 deletions
|
@ -11,6 +11,8 @@ SET(ROBOT_SOURCES src/Array.h
|
|||
src/AveragedData.h
|
||||
src/Avoidance.cpp
|
||||
src/Avoidance.h
|
||||
src/CarBounds2d.cpp
|
||||
src/CarBounds2d.h
|
||||
src/CarModel.cpp
|
||||
src/CarModel.h
|
||||
src/ClothoidPath.cpp
|
||||
|
@ -58,6 +60,8 @@ SET(ROBOT_SOURCES src/Array.h
|
|||
src/Span.h
|
||||
src/Strategy.cpp
|
||||
src/Strategy.h
|
||||
src/Stuck.cpp
|
||||
src/Stuck.h
|
||||
src/TeamInfo.cpp
|
||||
src/TeamInfo.h
|
||||
src/Utils.cpp
|
||||
|
|
242
src/drivers/shadow/src/CarBounds2d.cpp
Normal file
242
src/drivers/shadow/src/CarBounds2d.cpp
Normal file
|
@ -0,0 +1,242 @@
|
|||
|
||||
#include "CarBounds2d.h"
|
||||
#include "Utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const int s_next_corner[] = {FRNT_LFT, REAR_LFT, REAR_RGT, FRNT_RGT};
|
||||
|
||||
CarBounds2d::CarBounds2d( const tCarElt* car )
|
||||
{
|
||||
/*
|
||||
xAxis = Vec2d(car->pub.DynGC.pos.az);
|
||||
yAxis = xAxis.GetNormal();
|
||||
|
||||
Vec2d middle(car->pub.DynGC.pos.x, car->pub.DynGC.pos.y);
|
||||
|
||||
pts[FRNT_LFT] = middle + xAxis * car->pub.corner[FRNT_LFT].x + yAxis * car->pub.corner[FRNT_LFT].y;
|
||||
pts[FRNT_RGT] = middle + xAxis * car->pub.corner[FRNT_RGT].x + yAxis * car->pub.corner[FRNT_RGT].y;
|
||||
pts[REAR_LFT] = middle + xAxis * car->pub.corner[REAR_LFT].x + yAxis * car->pub.corner[REAR_LFT].y;
|
||||
pts[REAR_RGT] = middle + xAxis * car->pub.corner[REAR_RGT].x + yAxis * car->pub.corner[REAR_RGT].y;
|
||||
*/
|
||||
pts[FRNT_LFT] = Vec2d(car->pub.corner[FRNT_LFT].ax, car->pub.corner[FRNT_LFT].ay);
|
||||
pts[FRNT_RGT] = Vec2d(car->pub.corner[FRNT_RGT].ax, car->pub.corner[FRNT_RGT].ay);
|
||||
pts[REAR_LFT] = Vec2d(car->pub.corner[REAR_LFT].ax, car->pub.corner[REAR_LFT].ay);
|
||||
pts[REAR_RGT] = Vec2d(car->pub.corner[REAR_RGT].ax, car->pub.corner[REAR_RGT].ay);
|
||||
|
||||
xAxis = Vec2d(pts[FRNT_LFT] - pts[REAR_LFT]).GetUnit();
|
||||
yAxis = Vec2d(pts[FRNT_LFT] - pts[FRNT_RGT]).GetUnit();
|
||||
}
|
||||
|
||||
double CarBounds2d::distToSide( int side, double maxDist, const CarBounds2d& other ) const
|
||||
{
|
||||
vector<Vec2d> pts;
|
||||
pts.push_back( other.pts[FRNT_RGT] );
|
||||
pts.push_back( other.pts[FRNT_LFT] );
|
||||
pts.push_back( other.pts[REAR_LFT] );
|
||||
pts.push_back( other.pts[REAR_RGT] );
|
||||
pts.push_back( other.pts[FRNT_RGT] );
|
||||
|
||||
return distToSide(side, maxDist, pts);
|
||||
}
|
||||
|
||||
double CarBounds2d::distToSide( int side, double maxDist, const vector<Vec2d>& pts ) const
|
||||
{
|
||||
CarBounds2d temp(*this);
|
||||
|
||||
Vec2d midPt;
|
||||
double midLen = 0;
|
||||
switch( side )
|
||||
{
|
||||
case SIDE_FRONT:
|
||||
temp.pts[REAR_LFT] = temp.pts[FRNT_LFT];
|
||||
temp.pts[REAR_RGT] = temp.pts[FRNT_RGT];
|
||||
midPt = (temp.pts[FRNT_LFT] + temp.pts[FRNT_RGT]) * 0.5;
|
||||
midLen = temp.pts[FRNT_LFT].dist(temp.pts[FRNT_RGT]);
|
||||
break;
|
||||
|
||||
case SIDE_REAR:
|
||||
temp.pts[FRNT_LFT] = temp.pts[REAR_LFT];
|
||||
temp.pts[FRNT_RGT] = temp.pts[REAR_RGT];
|
||||
midPt = (temp.pts[REAR_LFT] + temp.pts[REAR_RGT]) * 0.5;
|
||||
midLen = temp.pts[REAR_LFT].dist(temp.pts[REAR_RGT]);
|
||||
break;
|
||||
|
||||
case SIDE_LEFT:
|
||||
temp.pts[FRNT_RGT] = temp.pts[FRNT_LFT];
|
||||
temp.pts[REAR_RGT] = temp.pts[REAR_LFT];
|
||||
midPt = (temp.pts[FRNT_LFT] + temp.pts[REAR_LFT]) * 0.5;
|
||||
midLen = temp.pts[FRNT_LFT].dist(temp.pts[REAR_LFT]);
|
||||
break;
|
||||
|
||||
case SIDE_RIGHT:
|
||||
temp.pts[FRNT_LFT] = temp.pts[FRNT_RGT];
|
||||
temp.pts[REAR_LFT] = temp.pts[REAR_RGT];
|
||||
midPt = (temp.pts[FRNT_RGT] + temp.pts[REAR_RGT]) * 0.5;
|
||||
midLen = temp.pts[FRNT_RGT].dist(temp.pts[REAR_RGT]);
|
||||
break;
|
||||
}
|
||||
|
||||
double filterDistSq = (midLen + maxDist) * (midLen + maxDist);
|
||||
|
||||
if( temp.collidesWith(pts, midPt, filterDistSq) )
|
||||
return 0;
|
||||
|
||||
temp.inflateSide( side, maxDist );
|
||||
if( !temp.collidesWith(pts, midPt, filterDistSq) )
|
||||
return maxDist;
|
||||
|
||||
double incr = maxDist * 0.5;
|
||||
double dist = maxDist - incr;
|
||||
temp.inflateSide( side, -incr );
|
||||
|
||||
while( incr > 0.01 )
|
||||
{
|
||||
if( temp.collidesWith(pts, midPt, filterDistSq) )
|
||||
{
|
||||
incr *= 0.5;
|
||||
dist -= incr;
|
||||
temp.inflateSide( side, -incr );
|
||||
}
|
||||
else
|
||||
{
|
||||
incr *= 0.5;
|
||||
dist += incr;
|
||||
temp.inflateSide( side, incr );
|
||||
}
|
||||
}
|
||||
|
||||
if( !temp.collidesWith(pts, midPt, filterDistSq) )
|
||||
dist -= incr;
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
void CarBounds2d::inflateSide( int side, double delta )
|
||||
{
|
||||
switch( side )
|
||||
{
|
||||
case SIDE_FRONT:
|
||||
pts[FRNT_LFT] += xAxis * delta;
|
||||
pts[FRNT_RGT] += xAxis * delta;
|
||||
break;
|
||||
|
||||
case SIDE_REAR:
|
||||
pts[REAR_LFT] -= xAxis * delta;
|
||||
pts[REAR_RGT] -= xAxis * delta;
|
||||
break;
|
||||
|
||||
case SIDE_LEFT:
|
||||
pts[FRNT_LFT] += yAxis * delta;
|
||||
pts[REAR_LFT] += yAxis * delta;
|
||||
break;
|
||||
|
||||
case SIDE_RIGHT:
|
||||
pts[FRNT_RGT] -= yAxis * delta;
|
||||
pts[REAR_RGT] -= yAxis * delta;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CarBounds2d::inflate( double deltaX, double deltaY )
|
||||
{
|
||||
inflate( deltaX, deltaX, deltaY, deltaY );
|
||||
}
|
||||
|
||||
void CarBounds2d::inflate( double deltaFront, double deltaRear, double deltaLeft, double deltaRight )
|
||||
{
|
||||
pts[FRNT_LFT] += xAxis * deltaFront + yAxis * deltaLeft;
|
||||
pts[REAR_LFT] += -xAxis * deltaRear + yAxis * deltaLeft;
|
||||
pts[REAR_RGT] += -xAxis * deltaRear - yAxis * deltaRight;
|
||||
pts[FRNT_RGT] += xAxis * deltaFront - yAxis * deltaRight;
|
||||
}
|
||||
|
||||
bool CarBounds2d::contains( const Vec2d& pt ) const
|
||||
{
|
||||
for( int i = 0; i < 4; i++ )
|
||||
{
|
||||
if( Vec2d(pts[s_next_corner[i]] - pts[i]).GetNormal() * (pt - pts[i]) > 0 )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CarBounds2d::collidesWith( const CarBounds2d& other ) const
|
||||
{
|
||||
// test for points contained.
|
||||
for( int i = 0; i < 4; i++ )
|
||||
{
|
||||
if( contains(other.pts[i]) || other.contains(pts[i]) )
|
||||
return true;
|
||||
}
|
||||
|
||||
// test the edges crossing too.
|
||||
double t1, t2;
|
||||
for( int i = 0; i < 4; i++ )
|
||||
{
|
||||
Vec2d v = pts[s_next_corner[i]] - pts[i];
|
||||
for( int j = 0; j < 4; j++ )
|
||||
{
|
||||
Vec2d ov = other.pts[s_next_corner[j]] - other.pts[j];
|
||||
if( Utils::LineCrossesLine(pts[i], v, other.pts[j], ov, t1, t2) )
|
||||
{
|
||||
if( t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CarBounds2d::collidesWith( const Vec2d& pt1, const Vec2d& pt2 ) const
|
||||
{
|
||||
double t1, t2;
|
||||
Vec2d lv = pt2 - pt1;
|
||||
|
||||
for( int i = 0; i < 4; i++ )
|
||||
{
|
||||
Vec2d v = pts[s_next_corner[i]] - pts[i];
|
||||
if( Utils::LineCrossesLine(pts[i], v, pt1, lv, t1, t2) )
|
||||
{
|
||||
if( t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CarBounds2d::collidesWith( const std::vector<Vec2d>& otherPts, const Vec2d& filterPt, double filterDistSqLimit ) const
|
||||
{
|
||||
if( otherPts.empty() )
|
||||
return false;
|
||||
|
||||
bool lastIsOk = filterDistSqLimit < 0 || otherPts[0].DistSq(filterPt) <= filterDistSqLimit;
|
||||
|
||||
double t1, t2;
|
||||
for( int i = 1; i < (int)otherPts.size(); i++ )
|
||||
{
|
||||
bool currIsOk = filterDistSqLimit < 0 || otherPts[i].DistSq(filterPt) <= filterDistSqLimit;
|
||||
|
||||
if( lastIsOk && currIsOk )
|
||||
{
|
||||
Vec2d otherV = otherPts[i] - otherPts[i - 1];
|
||||
|
||||
for( int j = 0; j < 4; j++ )
|
||||
{
|
||||
Vec2d v = pts[s_next_corner[j]] - pts[j];
|
||||
if( Utils::LineCrossesLine(otherPts[i - 1], otherV, pts[j], v, t1, t2) )
|
||||
{
|
||||
if( t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastIsOk = currIsOk;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
45
src/drivers/shadow/src/CarBounds2d.h
Normal file
45
src/drivers/shadow/src/CarBounds2d.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef MOUSE_CAR_BOUNDARY_2D_
|
||||
#define MOUSE_CAR_BOUNDARY_2D_
|
||||
|
||||
#include "car.h"
|
||||
#include "Vec2d.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// The "SHADOW" logger instance.
|
||||
extern GfLogger* PLogSHADOW;
|
||||
#define LogSHADOW (*PLogSHADOW)
|
||||
|
||||
class CarBounds2d
|
||||
{
|
||||
Vec2d pts[4];
|
||||
Vec2d xAxis; // direction that is forwards.
|
||||
Vec2d yAxis; // direction this is to the right.
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
SIDE_FRONT,
|
||||
SIDE_REAR,
|
||||
SIDE_LEFT,
|
||||
SIDE_RIGHT,
|
||||
};
|
||||
|
||||
public:
|
||||
CarBounds2d( const tCarElt* car );
|
||||
|
||||
const Vec2d& operator[]( int index ) const { return pts[index]; }
|
||||
|
||||
double distToSide( int side, double maxDist, const CarBounds2d& other ) const;
|
||||
double distToSide( int side, double maxDist, const std::vector<Vec2d>& pts ) const;
|
||||
|
||||
void inflateSide( int sideX, double delta );
|
||||
void inflate( double deltaX, double deltaY );
|
||||
void inflate( double deltaX1, double deltaX2, double deltaY1, double deltaY2 );
|
||||
bool contains( const Vec2d& pt ) const;
|
||||
bool collidesWith( const CarBounds2d& other ) const;
|
||||
bool collidesWith( const Vec2d& pt1, const Vec2d& pt2 ) const;
|
||||
bool collidesWith( const std::vector<Vec2d>& pts, const Vec2d& filterPt, double filterDistSqLimit = -1 ) const;
|
||||
};
|
||||
|
||||
#endif // MOUSE_CAR_BOUNDARY_2D_
|
|
@ -770,10 +770,23 @@ void TDriver::NewRace( tCarElt* pCar, tSituation* pS )
|
|||
LogSHADOW.debug("End Shadow NewRace\n");
|
||||
}
|
||||
|
||||
bool TDriver::Pitting(int path, double pos) const
|
||||
{
|
||||
return m_Strategy->needPitstop(car, m_Situation) &&
|
||||
m_pitPath[path].ContainsPos(pos);
|
||||
}
|
||||
|
||||
bool TDriver::Pitting(tCarElt* car) const
|
||||
{
|
||||
double pos = m_track.CalcPos(car);
|
||||
|
||||
return Pitting(PATH_NORMAL, pos);
|
||||
}
|
||||
|
||||
void TDriver::GetPtInfo( int path, double pos, PtInfo& pi ) const
|
||||
{
|
||||
|
||||
if( m_Strategy->needPitstop(car, m_Situation) && m_pitPath[path].ContainsPos(pos) )
|
||||
if(m_Strategy->needPitstop(car, m_Situation) && m_pitPath[path].ContainsPos(pos) )
|
||||
m_pitPath[path].GetPtInfo( pos, pi );
|
||||
else
|
||||
m_path[path].GetPtInfo( pos, pi );
|
||||
|
@ -1858,6 +1871,19 @@ void TDriver::Drive( tSituation* s )
|
|||
m_LastAccel = acc;
|
||||
m_LastAbsDriftAngle = m_AbsDriftAngle;
|
||||
|
||||
const Opponent::Sit& mySit = m_opp[car->index].GetInfo().sit;
|
||||
m_stuck = NOT_STUCK;
|
||||
|
||||
bool doStuckThing = true;
|
||||
|
||||
if (Pitting(car))
|
||||
{
|
||||
doStuckThing = false;
|
||||
}
|
||||
|
||||
if (doStuckThing)
|
||||
m_stuckThing.execute(m_track, s, car, mySit);
|
||||
|
||||
m_Strategy->update(car, s);
|
||||
//m_Strategy->needPitstop(car, m_Situation);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "LinePath.h"
|
||||
#include "PtInfo.h"
|
||||
#include "Strategy.h"
|
||||
#include "Stuck.h"
|
||||
#include "teammanager.h"
|
||||
|
||||
#define SECT_PRIV "private"
|
||||
|
@ -189,6 +190,13 @@ public:
|
|||
|
||||
void InitTrack(tTrack* track, void* carHandle, void** carParmHandle, tSituation* s);
|
||||
void NewRace(tCarElt* car, tSituation* s );
|
||||
void Drive(tSituation* s);
|
||||
int PitCmd(tSituation* s);
|
||||
void EndRace(tSituation* s);
|
||||
void Shutdown();
|
||||
|
||||
bool Pitting(int path, double pos) const;
|
||||
bool Pitting(tCarElt* car) const;
|
||||
|
||||
void GetPtInfo( int path, double pos, PtInfo& pi ) const;
|
||||
void GetPosInfo( double pos, PtInfo& pi, double u, double v ) const;
|
||||
|
@ -232,11 +240,6 @@ public:
|
|||
void SpeedControl6(double targetSpd, double spd0, CarElt* car, double& acc, double& brk );
|
||||
void SpeedControl( int which, double targetSpd, double spd0, CarElt* car, double& acc, double& brk );
|
||||
|
||||
void Drive(tSituation* s );
|
||||
int PitCmd(tSituation* s );
|
||||
void EndRace(tSituation* s );
|
||||
void Shutdown();
|
||||
|
||||
double CurrSimTime; // Current simulation time
|
||||
double Frc; // Friction coefficient
|
||||
//bool UseBrakeLimit; // Enable/disable brakelimit
|
||||
|
@ -358,6 +361,11 @@ private:
|
|||
MAX_OPP = 100
|
||||
};
|
||||
|
||||
enum StuckAction
|
||||
{
|
||||
NOT_STUCK, STUCK_GO_BACKWARDS, STUCK_GO_FORWARDS,
|
||||
};
|
||||
|
||||
private:
|
||||
MyTrack m_track;
|
||||
OptimisedPath m_path[N_PATHS];
|
||||
|
@ -481,19 +489,21 @@ private:
|
|||
double m_JumpOffset; // Offset for calculation of jumps
|
||||
bool m_FirstJump;
|
||||
int m_Flying; // Flag prepare landing
|
||||
int m_nCars;
|
||||
int m_myOppIdx;
|
||||
Opponent *m_opp; // info about other cars.
|
||||
double m_avgAY;
|
||||
bool m_raceStart;
|
||||
double m_avoidS; // where we are LR->T (0..1).
|
||||
double m_avoidSVel;
|
||||
double m_avoidT; // where we are L->R (-1..1).
|
||||
double m_avoidTVel;
|
||||
double m_avoidU;
|
||||
double m_avoidV;
|
||||
double m_attractor; // where we want to be.
|
||||
int m_followPath; // path we want to follow;
|
||||
int m_nCars;
|
||||
int m_myOppIdx;
|
||||
Opponent *m_opp; // info about other cars.
|
||||
double m_avgAY;
|
||||
bool m_raceStart;
|
||||
double m_avoidS; // where we are LR->T (0..1).
|
||||
double m_avoidSVel;
|
||||
double m_avoidT; // where we are L->R (-1..1).
|
||||
double m_avoidTVel;
|
||||
double m_avoidU;
|
||||
double m_avoidV;
|
||||
double m_attractor; // where we want to be.
|
||||
int m_followPath; // path we want to follow;
|
||||
Stuck m_stuckThing;
|
||||
StuckAction m_stuck;
|
||||
|
||||
LinearRegression m_accBrkCoeff; //
|
||||
double m_brkCoeff[50];
|
||||
|
|
|
@ -32,6 +32,8 @@ public:
|
|||
double oang; // global angle.
|
||||
double toL; // distance to edge of track on left.
|
||||
double toR; // distance to edge of track on right.
|
||||
double extL;
|
||||
double extR;
|
||||
double k; // curvature at point.
|
||||
double kz; // curvature in z at point
|
||||
double spd; // speed.
|
||||
|
|
|
@ -47,9 +47,11 @@ SimpleStrategy::SimpleStrategy()
|
|||
fuelPerLap = 0.0f; // [Kg] The maximum amount of fuel we needed for a lap.
|
||||
lastPitFuel = 0.0f; // [Kg] Amount refueled, special case when we refuel.
|
||||
fuelSum = 0.0f; // [Kg] All the fuel used.
|
||||
fuelSumPerMeter = 0.0;
|
||||
counterFuelLaps = 0; // [-] Counter of the total laps.
|
||||
countPitStop = 0; // [-] Counter of the total pitStop.
|
||||
avgFuelPerLap = 0.0; // [Kg] Average fuel per lap.
|
||||
avgFuelPerMeter = 0.0;
|
||||
m_maxDamage = 0; // [-] max damage before we request a pit stop.
|
||||
m_Fuel = 0; // [Kg] Security fuel at the strat race.
|
||||
m_expectedfuelperlap = 0; // [Kg] Expected fuel per lap
|
||||
|
@ -78,7 +80,7 @@ void SimpleStrategy::setFuelAtRaceStart(tTrack* t, void **carParmHandle, tSituat
|
|||
maxFuel = (tdble)(GfParmGetNum(*carParmHandle, SECT_CAR, PRM_TANK, (char*)NULL, (tdble) MAX_FUEL_TANK));
|
||||
LogSHADOW.info("Strategy max fuel = %.2f\n", maxFuel);
|
||||
FuelperMeters = GfParmGetNum(*carParmHandle, SECT_PRIV, PRV_FUELPERMETERS, (char*)NULL, (tdble) MAX_FUEL_PER_METER);
|
||||
LogSHADOW.info("Strategy fuel per meters = %.5f\n", FuelperMeters);
|
||||
LogSHADOW.info("Strategy fuel per meters = %.7f\n", FuelperMeters);
|
||||
fuelPerLap = (tdble) (TrackLength * FuelperMeters);
|
||||
LogSHADOW.info("Strategy fuel per lap = %.2f\n", fuelPerLap);
|
||||
fullfuel = GfParmGetNum(*carParmHandle, SECT_PRIV, PRV_FULL_FUEL, (char*)NULL, 0.0);
|
||||
|
@ -161,14 +163,14 @@ void SimpleStrategy::setFuelAtRaceStart(tTrack* t, void **carParmHandle, tSituat
|
|||
m_fuel = 0;
|
||||
//m_FuelStart = ((raceLaps / 2) * fuelPerLap) + 0.3;
|
||||
m_FuelStart = (tdble)(1.92 * fuelPerLap);
|
||||
fprintf(stderr,"...Check PitStop Enabled!\n");
|
||||
LogSHADOW.info("...Check PitStop Enabled!\n");
|
||||
//maybe we need to check Best Lap Time for qualifying
|
||||
} else if (test_qualifTime && s->_raceType == RM_TYPE_PRACTICE)
|
||||
{
|
||||
qualifRace = true;
|
||||
m_fuel = 0;
|
||||
m_FuelStart = s->_totLaps * fuelPerLap;
|
||||
fprintf(stderr,"...Check QualifTime Enabled!\n");
|
||||
LogSHADOW.info("...Check QualifTime Enabled!\n");
|
||||
}
|
||||
|
||||
if (m_FuelStart > maxFuel)
|
||||
|
@ -185,7 +187,7 @@ void SimpleStrategy::setFuelAtRaceStart(tTrack* t, void **carParmHandle, tSituat
|
|||
|
||||
m_FuelStart = (tdble)(MIN(m_FuelStart, maxFuel));
|
||||
|
||||
fprintf(stderr,"# SHADOW Index %d : Laps = %d, Fuel per Lap = %.2f, securityFuel = + %.2f, Fuel at Start Race = %.2f\n",
|
||||
LogSHADOW.debug("# SHADOW Index %d : Laps = %d, Fuel per Lap = %.2f, securityFuel = + %.2f, Fuel at Start Race = %.2f\n",
|
||||
index, s->_totLaps, fuelPerLap, m_fuel, m_FuelStart);
|
||||
|
||||
GfParmSetNum(*carParmHandle, SECT_CAR, PRM_FUEL, (char*)NULL, m_FuelStart);
|
||||
|
@ -203,9 +205,14 @@ void SimpleStrategy::update(tCarElt* car, tSituation *s)
|
|||
{
|
||||
//fuelPerLap = MAX(fuelPerLap, (lastFuel + lastPitFuel - car->priv.fuel));
|
||||
fuelSum += (lastFuel + lastPitFuel - car->priv.fuel);
|
||||
fuelSumPerMeter += (lastFuel - car->_fuel);
|
||||
fuelPerLap = (fuelSum/(car->race.laps - 1));
|
||||
counterFuelLaps++;
|
||||
avgFuelPerLap = fuelSum / counterFuelLaps;
|
||||
avgFuelPerMeter = fuelSumPerMeter / car->_distRaced;
|
||||
|
||||
LogSHADOW.info(" # Fuel per meter = %.7f\n", avgFuelPerMeter);
|
||||
|
||||
|
||||
if (strategy_verbose)
|
||||
{
|
||||
|
@ -290,7 +297,7 @@ bool SimpleStrategy::needPitstop(tCarElt* car, tSituation *s)
|
|||
{
|
||||
if (!m_checkFuel)
|
||||
{
|
||||
LogSHADOW.debug("%s Go to Pit the next lap to refuel: reqFuel= %.2f, carFuel= %.2f, remLap= %d\n",
|
||||
LogSHADOW.info("%s Go to Pit the next lap to refuel: reqFuel= %.2f, carFuel= %.2f, remLap= %d\n",
|
||||
car->_name, reqfuel, car->_fuel, car->_remainingLaps);
|
||||
m_checkFuel = true;
|
||||
}
|
||||
|
@ -407,7 +414,8 @@ float SimpleStrategy::pitRefuel(tCarElt* car, tSituation *s)
|
|||
{
|
||||
LogSHADOW.debug(">> [PitStrat 2] ");
|
||||
}
|
||||
LogSHADOW.debug(" %s in Pit to refuel < PitStop %d >\n", car->_name, countPitStop);
|
||||
|
||||
LogSHADOW.info(" %s in Pit to refuel < PitStop %d >\n", car->_name, countPitStop);
|
||||
|
||||
m_fuelperstint = (tdble)((fuelToEnd / num_remStops) + addFuel);
|
||||
|
||||
|
@ -434,13 +442,14 @@ float SimpleStrategy::pitRefuel(tCarElt* car, tSituation *s)
|
|||
if (m_remainingstops >= 1)
|
||||
{
|
||||
m_fuelperstint = (tdble)((fuelToEnd / num_remStops) + addFuel);
|
||||
} else if (m_remainingstops <= 0)
|
||||
}
|
||||
else if (m_remainingstops <= 0)
|
||||
{
|
||||
m_fuelperstint = (tdble)((lapsToEnd * fuelPerLap) + addMinFuel);
|
||||
}
|
||||
|
||||
fuel = MIN(m_fuelperstint - car->_fuel, car->_tank - car->_fuel);
|
||||
LogSHADOW.debug(" %s in Pit to refuel %.2fl < PitStop %d >\n", car->_name, fuel, countPitStop);
|
||||
LogSHADOW.info(" %s in Pit to refuel %.2fl < PitStop %d >\n", car->_name, fuel, countPitStop);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -134,9 +134,11 @@ protected:
|
|||
float lastPitFuel; // Amount refueled, special case when we refuel.
|
||||
float lastFuel; // The fuel available when we cross the start lane.
|
||||
float fuelSum; // All the fuel used needed for the race.
|
||||
double fuelSumPerMeter;
|
||||
int counterFuelLaps; // Counter of the total laps.
|
||||
int countPitStop; // Counter of the total pits stop.
|
||||
double avgFuelPerLap; // The average amount of fuel we needed for a lap.
|
||||
double avgFuelPerMeter;
|
||||
int m_maxDamage; // The Max damage set in the XML file.
|
||||
float m_Fuel; // The new average fuel per lap
|
||||
float m_expectedfuelperlap; // Expected fuel per lap (may be very inaccurate).
|
||||
|
|
1417
src/drivers/shadow/src/Stuck.cpp
Normal file
1417
src/drivers/shadow/src/Stuck.cpp
Normal file
File diff suppressed because it is too large
Load diff
319
src/drivers/shadow/src/Stuck.h
Normal file
319
src/drivers/shadow/src/Stuck.h
Normal file
|
@ -0,0 +1,319 @@
|
|||
#ifndef _STUCK_H
|
||||
#define _STUCK_H
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
#include <car.h>
|
||||
#include <robot.h>
|
||||
|
||||
#include "Utils.h"
|
||||
#include "MyTrack.h"
|
||||
#include "Opponent.h"
|
||||
|
||||
// The "SHADOW" logger instance.
|
||||
extern GfLogger* PLogSHADOW;
|
||||
#define LogSHADOW (*PLogSHADOW)
|
||||
|
||||
class Stuck
|
||||
{
|
||||
public:
|
||||
Stuck();
|
||||
~Stuck();
|
||||
|
||||
bool execute( const MyTrack& track, const tSituation* s, tCarElt* me, const Opponent::Sit& mySit );
|
||||
|
||||
private:
|
||||
void executeRacing( const MyTrack& track, const tSituation* s, const tCarElt* me, const Opponent::Sit& mySit );
|
||||
void executeReorient(const MyTrack& track, const tSituation* s, tCarElt* me, const Opponent::Sit& mySit );
|
||||
void executeInit( const MyTrack& track, const tSituation* s, tCarElt* me );
|
||||
void executeSolving( const MyTrack& track, const tSituation* s, tCarElt* me );
|
||||
void executePlan( const MyTrack& track, const tSituation* s, tCarElt* me );
|
||||
|
||||
private:
|
||||
enum { N_ANGLES = 64 };
|
||||
enum { HALF_ANGLE = N_ANGLES / 2 };
|
||||
enum { ANGLE_MASK = N_ANGLES - 1 };
|
||||
enum { OCTANT = N_ANGLES / 8 };
|
||||
enum { HALF_OCTANT = OCTANT / 2 };
|
||||
|
||||
enum { GRID_RAD = 50 };
|
||||
enum { GRID_SIZE = 2 * GRID_RAD + 1 };
|
||||
enum { CAR_RAD = 4 };
|
||||
|
||||
enum { SPD = 4 }; // speed of car while getting unstuck.
|
||||
|
||||
enum State { RACING, REORIENT_FORWARDS, REORIENT_BACKWARDS, REINIT, SOLVING, EXEC_PLAN };
|
||||
|
||||
static inline int fwang( int iang, bool fw ) { return (iang << 1) | int(fw); }
|
||||
|
||||
struct GridPoint
|
||||
{
|
||||
unsigned int pt; // current position.
|
||||
float est_time; // estimated time to finish.
|
||||
float time; // current time.
|
||||
|
||||
GridPoint()
|
||||
: pt(0), est_time(0), time(0)
|
||||
{
|
||||
}
|
||||
|
||||
GridPoint( int p )
|
||||
: pt(p), est_time(0), time(0)
|
||||
{
|
||||
}
|
||||
|
||||
GridPoint( int x, int y, int iang, bool fw, float time, float est )
|
||||
{
|
||||
set(x, y, iang, fw, time, est);
|
||||
}
|
||||
|
||||
GridPoint( int x, int y, float ang, bool fw, float time, float est )
|
||||
{
|
||||
set(x, y, ang, fw, time, est);
|
||||
}
|
||||
|
||||
GridPoint( const Stuck& stuck, const tCarElt* car, bool fw, float est )
|
||||
{
|
||||
float dx = car->pub.DynGCg.pos.x - stuck._gridOrigin.x;
|
||||
float dy = car->pub.DynGCg.pos.y - stuck._gridOrigin.y;
|
||||
int x = (int)floor(dx + 0.5);
|
||||
int y = (int)floor(dy + 0.5);
|
||||
set(x, y, (float)car->pub.DynGCg.pos.az, fw, 0.0f, est);
|
||||
}
|
||||
|
||||
bool operator<( const GridPoint& other ) const
|
||||
{
|
||||
return est_time > other.est_time;
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void set( int x, int y, int iang, bool fw, float tm, float est )
|
||||
{
|
||||
x = x & 0xFF;
|
||||
y = y & 0xFF;
|
||||
iang = iang & ANGLE_MASK;
|
||||
pt = (fw << 24) | (x << 16) | (y << 8) | (iang);
|
||||
time = tm;
|
||||
est_time = est;
|
||||
}
|
||||
|
||||
void set( int x, int y, float ang, bool fw, float time, float est )
|
||||
{
|
||||
int iang = to_iang(ang);
|
||||
set(x, y, iang, fw, time, est);
|
||||
}
|
||||
|
||||
void set_fw( bool fw )
|
||||
{
|
||||
pt = (fw << 24) | (0x00FFFFFF & pt);
|
||||
}
|
||||
|
||||
double dist( const GridPoint& other ) const
|
||||
{
|
||||
int dx = x() - other.x();
|
||||
int dy = y() - other.y();
|
||||
int da = iang() - other.iang();
|
||||
if( da > 32 )
|
||||
da -= 64;
|
||||
else if( da < -32 )
|
||||
da += 64;
|
||||
|
||||
return dx*dx + dy*dy + da*da*0.001;
|
||||
}
|
||||
|
||||
bool fw() const { return (pt >> 24) != 0; }
|
||||
bool bw() const { return (pt >> 24) == 0; }
|
||||
int x() const { return (pt >> 16) & 0xFF; }
|
||||
int y() const { return ((pt >> 8) & 0xFF); }
|
||||
int iang() const { return pt & 0xFF; }
|
||||
int fwang() const { return (iang() << 1) | int(fw()); }
|
||||
};
|
||||
|
||||
struct Cell
|
||||
{
|
||||
enum { EDGE_MASK = 0x80000000 };
|
||||
unsigned int occupied_mask;
|
||||
float est_time_to_car;
|
||||
float est_time_to_dest;
|
||||
int dist_from_walls;
|
||||
float times[N_ANGLES * 2]; // indexed by fwang
|
||||
int from[N_ANGLES * 2]; // indexed by fwang
|
||||
char solution[N_ANGLES * 2]; // indexed by fwang
|
||||
|
||||
|
||||
Cell() { clear(); }
|
||||
|
||||
void clear()
|
||||
{
|
||||
occupied_mask = EDGE_MASK; // track edges...
|
||||
//occupied_mask = 0;
|
||||
est_time_to_car = -1;
|
||||
est_time_to_dest = -1;
|
||||
dist_from_walls = 0;
|
||||
for( int i = 0; i < N_ANGLES * 2; i++ )
|
||||
{
|
||||
times[i] = 9e9f;
|
||||
from[i] = -1;
|
||||
solution[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void addCarMask( int carIdx ) { occupied_mask |= (1u << carIdx); };
|
||||
void removeCarMask( int carIdx ) { occupied_mask &= ~(1u << carIdx); };
|
||||
void clearAllCarMasks() { occupied_mask &= EDGE_MASK; };
|
||||
|
||||
void addEdgeMask() { occupied_mask |= EDGE_MASK; };
|
||||
void removeEdgeMask() { occupied_mask &= ~EDGE_MASK; };
|
||||
|
||||
bool isAvailable() const { return occupied_mask == 0; }
|
||||
bool isAvailable( int fwang ) const { return occupied_mask == 0 && times[fwang] >= 0; }
|
||||
|
||||
void setSolution( int fwang ) { solution[fwang] = 1; times[fwang] = 9e9f; }
|
||||
bool isSolution( int fwang ) const { return solution[fwang] == 1; }
|
||||
};
|
||||
|
||||
struct Edge
|
||||
{
|
||||
int sy; // starting y value
|
||||
int ey; // ending y value
|
||||
float sx; // starting x value
|
||||
float dX; // for a step of size 1 in y
|
||||
int x; // current x value
|
||||
|
||||
Edge( float x1, float y1, float x2, float y2 )
|
||||
{
|
||||
if( y1 > y2 )
|
||||
{
|
||||
std::swap( x1, x2 );
|
||||
std::swap( y1, y2 );
|
||||
}
|
||||
|
||||
sy = (int)ceil(y1);
|
||||
ey = (int)floor(y2);
|
||||
dX = y1 < y2 ? (x2 - x1) / (y2 - y1) : 0;
|
||||
sx = x1 + (sy - y1) * dX;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
bool operator<( const Edge& other ) const
|
||||
{
|
||||
return x < other.x;
|
||||
}
|
||||
|
||||
int calcX(int y) { return (int)floor(sx + (y - sy) * dX); }
|
||||
};
|
||||
|
||||
struct OppInfo
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
int ix;
|
||||
int iy;
|
||||
const tCarElt* car;
|
||||
|
||||
OppInfo() : x(0), y(0), ix(0), iy(0), car(0) {}
|
||||
OppInfo( double X, double Y, const tCarElt* CAR )
|
||||
: x(X), y(Y), car(CAR)
|
||||
{
|
||||
ix = (int)floor(x + 0.5);
|
||||
iy = (int)floor(x + 0.5);
|
||||
}
|
||||
|
||||
bool operator==( const OppInfo& other ) const
|
||||
{
|
||||
return ix == other.ix && iy == other.iy && car == other.car;
|
||||
}
|
||||
|
||||
bool operator!=( const OppInfo& other ) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
static const int delta8_x[8];
|
||||
static const int delta8_y[8];
|
||||
static const float delta8_t[8];
|
||||
static const float delta64_t[64];
|
||||
|
||||
private:
|
||||
void updateStuckTime( const tCarElt* me, const tSituation* s );
|
||||
void makeOpponentsList( const tSituation* s, const tCarElt* me,
|
||||
std::vector<OppInfo>* opponents );
|
||||
bool clearAhead( const MyTrack& track, const tSituation* s, const tCarElt* me ) const;
|
||||
bool opponentsChanged( const tSituation* s, const tCarElt* me );
|
||||
|
||||
bool isInitialised() const { return _me != 0; }
|
||||
void reorient( const tCarElt* me, double dirAng );
|
||||
void init( const MyTrack& track, const tSituation* s, const tCarElt* me );
|
||||
void fillCarCells( int carI, double carX, double carY, double carAng, double dx, double dy, double rad, bool addMask );
|
||||
void fillTrackCells( const MyTrack& track );
|
||||
bool solve( const tCarElt* me );
|
||||
bool solveR( const tCarElt* me );
|
||||
void dumpGrid() const;
|
||||
void getUnstuck( const MyTrack& track, tCarElt* me, const tSituation* s );
|
||||
|
||||
private:
|
||||
const Cell& at( int x, int y ) const { return _grid[x][y]; }
|
||||
Cell& at( int x, int y ) { return _grid[x][y]; }
|
||||
|
||||
const Cell& at( const GridPoint& pt ) const { return _grid[pt.x()][pt.y()]; }
|
||||
Cell& at( const GridPoint& pt ) { return _grid[pt.x()][pt.y()]; }
|
||||
|
||||
bool isValid( int x, int y ) const { return x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE; }
|
||||
|
||||
const Cell& operator[]( const GridPoint& pt ) const { return at(pt); }
|
||||
|
||||
double calcCarDist( bool fw, double maxDist, const tCarElt* me, const tSituation* s ) const;
|
||||
|
||||
void generateSuccessorsN( const GridPoint& from, std::vector<GridPoint>& succs ) const;
|
||||
void generateSuccessorsR( const GridPoint& from, std::vector<GridPoint>& succs ) const;
|
||||
|
||||
static int to_iang( double ang )
|
||||
{
|
||||
const float ang_step = float(N_ANGLES / (2 * 3.14159265));
|
||||
int iang = (int)floor(ang * ang_step + 0.5);
|
||||
return iang & ANGLE_MASK;
|
||||
}
|
||||
|
||||
static int reverse( int iang ) { return (iang + N_ANGLES / 2) & ANGLE_MASK; }
|
||||
|
||||
static void sort( std::vector<Edge>& row, int y );
|
||||
|
||||
private:
|
||||
const tCarElt* _me;
|
||||
Vec2d _gridOrigin;
|
||||
std::vector<std::vector<Cell>> _grid;
|
||||
State _stuckState;
|
||||
double _stuckTime;
|
||||
int _stuckCount;
|
||||
|
||||
// track points for collision detection.
|
||||
std::vector<Vec2d> _leftPoints;
|
||||
std::vector<Vec2d> _rightPoints;
|
||||
|
||||
// intialisation variables
|
||||
std::vector<OppInfo> _opponents;
|
||||
GridPoint _origCarPt;
|
||||
|
||||
// for debugging
|
||||
std::vector<GridPoint> _destinations;
|
||||
|
||||
// solver variables
|
||||
int _expansionsN;
|
||||
std::priority_queue<GridPoint> _pqN;
|
||||
int _expansionsR;
|
||||
std::priority_queue<GridPoint> _pqR;
|
||||
float _bestTime;
|
||||
GridPoint _bestPt;
|
||||
|
||||
// plan variables
|
||||
std::vector<GridPoint> _plan;
|
||||
int _planIndex;
|
||||
};
|
||||
|
||||
#endif // _STUCK_H
|
Loading…
Reference in a new issue