forked from speed-dreams/speed-dreams-code
- replace default logging by LogDANDROID on this driver
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@7085 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: b033e8639ded0686d7093a4336a4498e98335873 Former-commit-id: 45578095341d79afef6f3162753401aded819e44
This commit is contained in:
parent
2ce184fb36
commit
35d96145e8
4 changed files with 2059 additions and 1895 deletions
|
@ -19,12 +19,17 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <tgf.h>
|
||||
#include <robot.h> // ROB_IDENT
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "driver.h"
|
||||
|
||||
// The "DANDROID" logger instance
|
||||
GfLogger* PLogDANDROID = 0;
|
||||
|
||||
using ::std::string;
|
||||
using ::std::vector;
|
||||
using ::std::pair;
|
||||
|
@ -70,22 +75,19 @@ static int indexOffset = 0;
|
|||
// in the robot's xml-file between others, not only at the end of the list
|
||||
const char *sUndefined = "undefined";
|
||||
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Utility
|
||||
////////////////////////////////
|
||||
#ifdef DANDROID_SPEEDDREAMS
|
||||
|
||||
// Set robots's name and xml file pathname
|
||||
static void setRobotName(const string &name) {
|
||||
static void setRobotName(const string &name)
|
||||
{
|
||||
char buffer[BUFSIZE];
|
||||
snprintf(buffer, BUFSIZE, "drivers/%s/%s.xml", name.c_str(), name.c_str());
|
||||
nameBuffer = name;
|
||||
pathBuffer = buffer;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// SD Interface (new, fixed name scheme, from Andrew's USR code)
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
@ -94,14 +96,18 @@ static void setRobotName(const string &name) {
|
|||
// Extended for use with schismatic robots
|
||||
|
||||
extern "C" int moduleWelcome(const tModWelcomeIn* welcomeIn,
|
||||
tModWelcomeOut* welcomeOut) {
|
||||
tModWelcomeOut* welcomeOut)
|
||||
{
|
||||
// Save module name and loadDir, and determine module XML file pathname.
|
||||
setRobotName(welcomeIn->name);
|
||||
|
||||
// Filehandle for robot's xml-file
|
||||
void *pRobotSettings = GfParmReadFile(pathBuffer.c_str(), GFPARM_RMODE_STD);
|
||||
|
||||
if (pRobotSettings) { // robot settings XML could be read
|
||||
PLogDANDROID = GfLogger::instance("DANDROID");
|
||||
|
||||
if (pRobotSettings) // robot settings XML could be read
|
||||
{
|
||||
NBBOTS = 0;
|
||||
|
||||
char SectionBuffer[BUFSIZE];
|
||||
|
@ -151,11 +157,10 @@ extern "C" int moduleWelcome(const tModWelcomeIn* welcomeIn,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Module entry point (new fixed name scheme).
|
||||
extern "C" int moduleInitialize(tModInfo *modInfo) {
|
||||
extern "C" int moduleInitialize(tModInfo *modInfo)
|
||||
{
|
||||
// Clear all structures.
|
||||
memset(modInfo, 0, NBBOTS * sizeof(tModInfo));
|
||||
for (int i = 0; i < NBBOTS; i++) {
|
||||
|
|
|
@ -23,12 +23,14 @@
|
|||
|
||||
//#define DANPATH_VERBOSE
|
||||
|
||||
// The "DANDROID" logger instance.
|
||||
extern GfLogger* PLogDANDROID;
|
||||
#define LogDANDROID (*PLogDANDROID)
|
||||
|
||||
DanLine::DanLine()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DanLine::init(PTrack t)
|
||||
{
|
||||
MAX_RADIUS = 1000.0;
|
||||
|
@ -36,45 +38,58 @@ void DanLine::init(PTrack t)
|
|||
myseg = mTrack->seg;
|
||||
}
|
||||
|
||||
|
||||
void DanLine::addDanPoint(const DanPoint &danpoint)
|
||||
{
|
||||
mLine.push_back(danpoint);
|
||||
}
|
||||
|
||||
|
||||
bool DanLine::calcParam()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)mLine.size(); i++) {
|
||||
if (fromStart(mLine[i].pos, mLine[i].fromstart)) {
|
||||
if (!toMiddle(mLine[i].pos, mLine[i].tomiddle)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < (int)mLine.size(); i++)
|
||||
{
|
||||
if (fromStart(mLine[i].pos, mLine[i].fromstart))
|
||||
{
|
||||
if (!toMiddle(mLine[i].pos, mLine[i].tomiddle))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (int)mLine.size(); i++) {
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)mLine.size(); i++)
|
||||
{
|
||||
mLine[i].yaw = calcYaw(mLine[i]);
|
||||
double trackyaw;
|
||||
if (!calcTrackYaw(mLine[i], trackyaw)) {
|
||||
|
||||
if (!calcTrackYaw(mLine[i], trackyaw))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mLine[i].angletotrack = mLine[i].yaw - trackyaw;
|
||||
NORM_PI_PI(mLine[i].angletotrack);
|
||||
}
|
||||
for (i = 0; i < (int)mLine.size(); i++) {
|
||||
if (fabs(mLine[i].radius) < MAX_RADIUS) {
|
||||
|
||||
for (i = 0; i < (int)mLine.size(); i++)
|
||||
{
|
||||
if (fabs(mLine[i].radius) < MAX_RADIUS)
|
||||
{
|
||||
mLine[i].type = (SIGN(mLine[i].radius) > 0) ? TR_LFT : TR_RGT;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mLine[i].type = TR_STR;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DanLine::createSectors(std::vector <DanSector>& sect)
|
||||
{
|
||||
int sector = 0;
|
||||
|
@ -91,68 +106,90 @@ void DanLine::createSectors(std::vector <DanSector>& sect)
|
|||
double lastfromstart = dansect.fromstart;
|
||||
bool newsector = false;
|
||||
bool largeradius = true;
|
||||
for (int i = 1 ; i < (int)mLine.size(); i++) {
|
||||
|
||||
for (int i = 1 ; i < (int)mLine.size(); i++)
|
||||
{
|
||||
// Find sector
|
||||
if (fabs(mLine[i].radius) < 150.0) {
|
||||
if (fabs(mLine[i].radius) < 150.0)
|
||||
{
|
||||
largeradius = false;
|
||||
}
|
||||
if (fabs(mLine[i].radius) > 200.0) {
|
||||
if (!largeradius) {
|
||||
|
||||
if (fabs(mLine[i].radius) > 200.0)
|
||||
{
|
||||
if (!largeradius)
|
||||
{
|
||||
newsector = true;
|
||||
}
|
||||
|
||||
largeradius = true;
|
||||
}
|
||||
// Store sector
|
||||
if (newsector) {
|
||||
if (mLine[mLine.size()-1].fromstart - mLine[i].fromstart > 400.0) {
|
||||
if (mLine[i].fromstart < 200.0) {
|
||||
if (newsector)
|
||||
{
|
||||
if (mLine[mLine.size()-1].fromstart - mLine[i].fromstart > 400.0)
|
||||
{
|
||||
if (mLine[i].fromstart < 200.0)
|
||||
{
|
||||
// Do nothing
|
||||
} else if (mLine[i].fromstart - lastfromstart > 200.0) {
|
||||
}
|
||||
else if (mLine[i].fromstart - lastfromstart > 200.0)
|
||||
{
|
||||
sector++;
|
||||
dansect.sector = sector;
|
||||
dansect.fromstart = mLine[i].fromstart;
|
||||
lastfromstart = dansect.fromstart;
|
||||
sect.push_back(dansect);
|
||||
//GfOut("fs:%g radius:%g\n", mLine[i].fromstart, fabs(mLine[i].radius));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
sect[sector].fromstart = mLine[i].fromstart;
|
||||
lastfromstart = mLine[i].fromstart;
|
||||
//GfOut("overwrite fs:%g radius:%g\n", mLine[i].fromstart, fabs(mLine[i].radius));
|
||||
}
|
||||
}
|
||||
|
||||
newsector = false;
|
||||
}
|
||||
}
|
||||
|
||||
printData();
|
||||
}
|
||||
|
||||
|
||||
void DanLine::printData()
|
||||
{
|
||||
#ifdef DANPATH_VERBOSE
|
||||
if (mLine[0].line == 0) {
|
||||
for (int i = 0; i < (int)mLine.size(); i++) {
|
||||
GfOut("ind:%d fs:%g r:%g curv_z:%g\n", i, mLine[i].fromstart, mLine[i].radius, mLine[i].curv_z);
|
||||
if (mLine[0].line == 0)
|
||||
{
|
||||
for (int i = 0; i < (int)mLine.size(); i++)
|
||||
{
|
||||
LogDANDROID.debug("ind:%d fs:%g r:%g curv_z:%g\n", i, mLine[i].fromstart, mLine[i].radius, mLine[i].curv_z);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool DanLine::getDanPos(double fromstart, DanPoint& danpoint)
|
||||
{
|
||||
if (!mLine.size()) {
|
||||
if (!mLine.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = getIndex(fromstart);
|
||||
danpoint = mLine[index];
|
||||
|
||||
// Calculate radius
|
||||
double radius = mLine[index].radius;
|
||||
double nextradius = nextPos(mLine[index]).radius;
|
||||
if (SIGN(radius) != SIGN(nextradius)) {
|
||||
|
||||
if (SIGN(radius) != SIGN(nextradius))
|
||||
{
|
||||
danpoint.radius = 100000.0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate radius linear
|
||||
double seglength = getDistDiff(mLine[index].fromstart, nextPos(mLine[index]).fromstart);
|
||||
double poslength = getDistDiff(mLine[index].fromstart, fromstart);
|
||||
|
@ -164,136 +201,150 @@ bool DanLine::getDanPos(double fromstart, DanPoint& danpoint)
|
|||
danpoint.pos = getNearestPoint(danpoint.index, fromstart); // position (straight interpolation)
|
||||
danpoint.fromstart = fromstart;
|
||||
//danpoint.yaw = calcYaw(danpoint); // useless without interpolation
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
DanPoint DanLine::nextPos(DanPoint danpoint)
|
||||
{
|
||||
danpoint.index++;
|
||||
|
||||
return getPos(danpoint.index);
|
||||
}
|
||||
|
||||
|
||||
DanPoint DanLine::prevPos(DanPoint danpoint)
|
||||
{
|
||||
danpoint.index--;
|
||||
|
||||
return getPos(danpoint.index);
|
||||
}
|
||||
|
||||
|
||||
DanPoint DanLine::getPos(int index)
|
||||
{
|
||||
if (index < 0) {
|
||||
if (index < 0)
|
||||
{
|
||||
return mLine[mLine.size() - 1];
|
||||
} else if (index >= (int)mLine.size()) {
|
||||
}
|
||||
else if (index >= (int)mLine.size())
|
||||
{
|
||||
return mLine[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return mLine[index];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double DanLine::calcYaw(DanPoint danpoint)
|
||||
{
|
||||
Vec2d prev = danpoint.pos - prevPos(danpoint).pos;
|
||||
Vec2d next = nextPos(danpoint).pos - danpoint.pos;
|
||||
|
||||
return Utils::VecAngle(prev + next);
|
||||
}
|
||||
|
||||
|
||||
double DanLine::calcTrackYaw(DanPoint danpoint, double& trackyaw)
|
||||
{
|
||||
tTrkLocPos locpos;
|
||||
RtTrackGlobal2Local(myseg, (tdble) danpoint.pos.x, (tdble) danpoint.pos.y, &locpos, TR_LPOS_MAIN);
|
||||
myseg = locpos.seg;
|
||||
trackyaw = RtTrackSideTgAngleL(&locpos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DanLine::fromStart(Vec2d pos, double& fromstart)
|
||||
{
|
||||
tTrkLocPos locpos;
|
||||
RtTrackGlobal2Local(myseg, (tdble) pos.x, (tdble) pos.y, &locpos, TR_LPOS_MAIN);
|
||||
myseg = locpos.seg;
|
||||
fromstart = RtGetDistFromStart2(&locpos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DanLine::toMiddle(Vec2d pos, double& tomiddle)
|
||||
{
|
||||
tTrkLocPos locpos;
|
||||
RtTrackGlobal2Local(myseg, (tdble) pos.x, (tdble) pos.y, &locpos, TR_LPOS_MAIN);
|
||||
myseg = locpos.seg;
|
||||
tomiddle = locpos.toMiddle;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Find nearest section on mLine
|
||||
int DanLine::getIndex(double fromstart)
|
||||
{
|
||||
if (fromstart >= 0.0 && fromstart <= mTrack->length) {
|
||||
if (fromstart >= 0.0 && fromstart <= mTrack->length)
|
||||
{
|
||||
double estpos = fromstart / mTrack->length;
|
||||
int i = (int)floor(estpos * mLine.size());
|
||||
while (true) {
|
||||
if (i < 0) {
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (i < 0)
|
||||
{
|
||||
i = mLine.size() - 1;
|
||||
} else if (i >= (int)mLine.size()) {
|
||||
}
|
||||
else if (i >= (int)mLine.size())
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
double sectlen = getDistDiff(getPos(i).fromstart, getPos(i + 1).fromstart);
|
||||
// double poslen = getDistDiff(getPos(i).fromstart, fromstart);
|
||||
double poslen = getDistDiff(getPos(i).fromstart, fromstart+0.001);
|
||||
if (poslen >= 0.0 && poslen <= sectlen) {
|
||||
|
||||
if (poslen >= 0.0 && poslen <= sectlen)
|
||||
{
|
||||
//GfOut("poslen:%g sectlen:%g", poslen, sectlen);
|
||||
break;
|
||||
}
|
||||
|
||||
i += (int)SIGN(poslen);
|
||||
}
|
||||
|
||||
return i;
|
||||
} else {
|
||||
GfOut("!!!!!!!!!!!!!There is a bug in DanLine::getIndex, 'fromstart'=%g is out of range !!!!!!!!!!!!!!!", fromstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDANDROID.info("!!!!!!!!!!!!!There is a bug in DanLine::getIndex, 'fromstart'=%g is out of range !!!!!!!!!!!!!!!\n", fromstart);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vec2d DanLine::getNearestPoint(int index, double fromstart)
|
||||
{
|
||||
Vec2d straight = getPos(index+1).pos - mLine[index].pos;
|
||||
double straightlen = getDistDiff(mLine[index].fromstart, getPos(index+1).fromstart);
|
||||
double poslen = getDistDiff(mLine[index].fromstart, fromstart);
|
||||
Vec2d pointonStraight = mLine[index].pos + straight * (poslen / straightlen);
|
||||
|
||||
return pointonStraight;
|
||||
}
|
||||
|
||||
|
||||
double DanLine::getToMiddle(double fromstart)
|
||||
{
|
||||
int index = getIndex(fromstart);
|
||||
TCubic ccurve(mLine[index].fromstart, mLine[index].tomiddle, mLine[index].angletotrack, nextPos(mLine[index]).fromstart, nextPos(mLine[index]).tomiddle, nextPos(mLine[index]).angletotrack);
|
||||
|
||||
return ccurve.CalcOffset(fromstart);
|
||||
}
|
||||
|
||||
|
||||
double DanLine::getDistDiff(double fromstart1, double fromstart2)
|
||||
{
|
||||
double diff = fromstart2 - fromstart1;
|
||||
diff = (diff >= 0.0) ? diff : diff + mTrack->length;
|
||||
|
||||
return (diff <= mTrack->length / 2.0) ? diff : diff - mTrack->length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DanPath::DanPath()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DanPath::init(PTrack t, double max_left, double max_right, double marginIn, double marginOut, double factor, double seglen)
|
||||
{
|
||||
mTrack = t;
|
||||
|
@ -304,56 +355,68 @@ void DanPath::init(PTrack t, double max_left, double max_right, double marginIn,
|
|||
mClothFactor = factor;
|
||||
mSegLen = seglen;
|
||||
|
||||
for (int i=0; i < NUM_LINES; i++) {
|
||||
for (int i=0; i < NUM_LINES; i++)
|
||||
{
|
||||
mDanLine[i].init(t);
|
||||
}
|
||||
|
||||
getClothPath();
|
||||
|
||||
for (int i=0; i < NUM_LINES; i++) {
|
||||
if (!mDanLine[i].calcParam()) {
|
||||
GfOut("Error danpath: calcParam() failed\n");
|
||||
for (int i=0; i < NUM_LINES; i++)
|
||||
{
|
||||
if (!mDanLine[i].calcParam())
|
||||
{
|
||||
LogDANDROID.info("Error danpath: calcParam() failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
mDanLine[IDEAL_LINE].createSectors(mSector);
|
||||
for (int i = 0; i < (int)mSector.size(); i++) {
|
||||
GfOut("sector:%d fs:%g speedfactor:%g\n", mSector[i].sector, mSector[i].fromstart, mSector[i].speedfactor);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)mSector.size(); i++)
|
||||
{
|
||||
LogDANDROID.info("sector:%d fs:%g speedfactor:%g\n", mSector[i].sector, mSector[i].fromstart, mSector[i].speedfactor);
|
||||
}
|
||||
}
|
||||
|
||||
bool DanPath::getDanPos(int line, double fromstart, DanPoint& danpoint)
|
||||
{
|
||||
return mDanLine[line].getDanPos(fromstart, danpoint);
|
||||
}
|
||||
|
||||
|
||||
DanPoint DanPath::nextPos(DanPoint danpoint)
|
||||
{
|
||||
return mDanLine[danpoint.line].nextPos(danpoint);
|
||||
}
|
||||
|
||||
|
||||
void DanPath::getClothPath()
|
||||
{
|
||||
Vec2d point(0, 0);
|
||||
|
||||
MyTrack track;
|
||||
track.NewTrack(mTrack, mSegLen);
|
||||
for (int l = 0; l < NUM_LINES; l++) {
|
||||
|
||||
for (int l = 0; l < NUM_LINES; l++)
|
||||
{
|
||||
ClothoidPath clpath;
|
||||
if (l == IDEAL_LINE ) {
|
||||
if (l == IDEAL_LINE )
|
||||
{
|
||||
clpath.MakeSmoothPath(&track, ClothoidPath::Options(mMaxL, mMaxR, mMarginIns, mMarginOuts, mClothFactor));
|
||||
}
|
||||
if (l == LEFT_LINE ) {
|
||||
|
||||
if (l == LEFT_LINE )
|
||||
{
|
||||
clpath.MakeSmoothPath(&track, ClothoidPath::Options(mMaxL, -0.5, 1.0, 1.5, mClothFactor));
|
||||
}
|
||||
if (l == RIGHT_LINE) {
|
||||
|
||||
if (l == RIGHT_LINE)
|
||||
{
|
||||
clpath.MakeSmoothPath(&track, ClothoidPath::Options(-0.5, mMaxR, 1.0, 1.5, mClothFactor));
|
||||
}
|
||||
|
||||
LinePath::PathPt pathpoint;
|
||||
for (int j = 0; j < track.GetSize(); j++) {
|
||||
|
||||
for (int j = 0; j < track.GetSize(); j++)
|
||||
{
|
||||
pathpoint = clpath.GetAt(j);
|
||||
point.x = pathpoint.pt.x;
|
||||
point.y = pathpoint.pt.y;
|
||||
|
|
|
@ -103,6 +103,7 @@ TDriver::~TDriver()
|
|||
|
||||
void TDriver::InitTrack(PTrack Track, PCarHandle CarHandle, PCarSettings *CarParmHandle, PSituation Situation)
|
||||
{
|
||||
LogDANDROID.info("# Dandroid Driver initrack ...\n");
|
||||
mTrack = Track;
|
||||
|
||||
// Get file handles
|
||||
|
@ -144,8 +145,17 @@ void TDriver::InitTrack(PTrack Track, PCarHandle CarHandle, PCarSettings *CarPar
|
|||
mSTARTCLUTCHRATE = GfParmGetNum(handle, "private", "startclutchrate", (char*)NULL, 0.01);
|
||||
}
|
||||
|
||||
LogDANDROID.info("# mLearning = %i\n", mLearning);
|
||||
LogDANDROID.info("# mTestPitStop = %i\n", mTestpitstop);
|
||||
LogDANDROID.info("# mTestLine = %i\n", mTestLine);
|
||||
LogDANDROID.info("# mDriverMsgLevel = %i\n", mDriverMsgLevel);
|
||||
LogDANDROID.info("# mDriverMsgCarIndex = %i\n", mDriverMsgCarIndex);
|
||||
LogDANDROID.info("# mFRONTCOLL_MARGIN = %.2f\n", mFRONTCOLL_MARGIN);
|
||||
LogDANDROID.info("# mSTARTCLUTCHRATE = %.2f\n", mSTARTCLUTCHRATE);
|
||||
|
||||
// Parameters that are track specific
|
||||
*CarParmHandle = NULL;
|
||||
|
||||
switch (Situation->_raceType)
|
||||
{
|
||||
case RM_TYPE_QUALIF:
|
||||
|
@ -174,10 +184,13 @@ void TDriver::InitTrack(PTrack Track, PCarHandle CarHandle, PCarSettings *CarPar
|
|||
// Set initial fuel
|
||||
double distance = Situation->_totLaps * mTrack->length;
|
||||
mFuelStart = getFuel(distance);
|
||||
if (mLearning) {
|
||||
|
||||
if (mLearning)
|
||||
{
|
||||
mFuelStart = 5.0;
|
||||
GfParmSetNum(*CarParmHandle, SECT_ENGINE, PRM_FUELCONS, (char*)NULL, 0.0);
|
||||
}
|
||||
|
||||
GfParmSetNum(*CarParmHandle, SECT_CAR, PRM_FUEL, (char*)NULL, (tdble) mFuelStart);
|
||||
|
||||
// Get skill level
|
||||
|
@ -185,19 +198,25 @@ void TDriver::InitTrack(PTrack Track, PCarHandle CarHandle, PCarSettings *CarPar
|
|||
sprintf(buffer, "%sconfig/raceman/extra/skill.xml", GetLocalDir());
|
||||
handle = GfParmReadFile(buffer, GFPARM_RMODE_REREAD);
|
||||
double globalskill = 0.0;
|
||||
if (handle != NULL) {
|
||||
|
||||
if (handle != NULL)
|
||||
{
|
||||
// Skill levels: 0 pro, 3 semi-pro, 7 amateur, 10 rookie
|
||||
globalskill = GfParmGetNum(handle, "skill", "level", (char*)NULL, 0.0);
|
||||
}
|
||||
|
||||
mSkillGlobal = MAX(0.7, 1.0 - 0.5 * globalskill / 10.0);
|
||||
//load the driver skill level, range 0 - 1
|
||||
handle = NULL;
|
||||
sprintf(buffer, "drivers/%s/%d/skill.xml", MyBotName, mCarIndex);
|
||||
handle = GfParmReadFile(buffer, GFPARM_RMODE_STD);
|
||||
double driverskill = 0.0;
|
||||
if (handle != NULL) {
|
||||
|
||||
if (handle != NULL)
|
||||
{
|
||||
driverskill = GfParmGetNum(handle,"skill","level", (char*)NULL, 0.0);
|
||||
}
|
||||
|
||||
mSkillDriver = MAX(0.95, 1.0 - 0.05 * driverskill);
|
||||
}
|
||||
|
||||
|
@ -217,16 +236,24 @@ void TDriver::NewRace(PtCarElt Car, PSituation Situation)
|
|||
|
||||
// File with speed factors
|
||||
mNewFile = false;
|
||||
if (!readSectorSpeeds()) {
|
||||
|
||||
if (!readSectorSpeeds())
|
||||
{
|
||||
mSect = mDanPath.mSector;
|
||||
if (!mLearning) {
|
||||
for (int i = 0; i < (int)mSect.size(); i++) {
|
||||
|
||||
if (!mLearning)
|
||||
{
|
||||
for (int i = 0; i < (int)mSect.size(); i++)
|
||||
{
|
||||
mSect[i].brakedistfactor = 1.9;
|
||||
mSect[i].speedfactor = 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
writeSectorSpeeds();
|
||||
if (mLearning) {
|
||||
|
||||
if (mLearning)
|
||||
{
|
||||
mNewFile = true;
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +261,6 @@ void TDriver::NewRace(PtCarElt Car, PSituation Situation)
|
|||
mPrevRacePos= Car->_pos;
|
||||
}
|
||||
|
||||
|
||||
void TDriver::Drive()
|
||||
{
|
||||
#ifdef TIME_ANALYSIS
|
||||
|
@ -514,7 +540,7 @@ void TDriver::printChangedVars()
|
|||
if (prev_mSector != mSector) {
|
||||
driverMsgValue(2, "mSector: ", mSector);
|
||||
if (mSector == 0) {
|
||||
GfOut("time: %g\n", oCar->_lastLapTime);
|
||||
LogDANDROID.info("time: %g\n", oCar->_lastLapTime);
|
||||
}
|
||||
}
|
||||
if (prev_mControlAttackAngle != mControlAttackAngle) {
|
||||
|
@ -1335,7 +1361,6 @@ bool TDriver::onCollision()
|
|||
return mColl;
|
||||
}
|
||||
|
||||
|
||||
bool TDriver::oppInCollisionZone(Opponent* opp)
|
||||
{
|
||||
double diffspeedmargin = diffSpeedMargin(opp);
|
||||
|
@ -1345,42 +1370,52 @@ bool TDriver::oppInCollisionZone(Opponent* opp)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool TDriver::oppOnMyLine(Opponent* opp, double margin)
|
||||
{
|
||||
if (mDrvState != STATE_RACE) {
|
||||
if (mDrvState != STATE_RACE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double oppfs = fromStart(opp->fromStart);
|
||||
DanPoint oppdp;
|
||||
mDanPath.getDanPos(mDrvPath, oppfs, oppdp);
|
||||
if (fabs(oppdp.tomiddle - opp->toMiddle) < margin) {
|
||||
|
||||
if (fabs(oppdp.tomiddle - opp->toMiddle) < margin)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
double TDriver::diffSpeedMargin(Opponent* opp)
|
||||
{
|
||||
double speeddiff = MAX(0.0, mSpeed - opp->speed);
|
||||
double oppangle = opp->mAngle;
|
||||
double angle = 0.0;
|
||||
if ((oppangle < 0.0 && mOppLeftOfMe) || (oppangle > 0.0 && !mOppLeftOfMe)) {
|
||||
|
||||
if ((oppangle < 0.0 && mOppLeftOfMe) || (oppangle > 0.0 && !mOppLeftOfMe))
|
||||
{
|
||||
angle = MIN(0.3, fabs(oppangle));
|
||||
}
|
||||
|
||||
double factor = MAX(0.05, 0.5 * angle);
|
||||
double diffspeedmargin = MIN(15.0, 2.0 + sin(fabs(oppangle)) + factor * speeddiff);
|
||||
if (mSpeed < 5.0 || oppNoDanger(opp)) {
|
||||
|
||||
if (mSpeed < 5.0 || oppNoDanger(opp))
|
||||
{
|
||||
diffspeedmargin = 2.0 + sin(fabs(oppangle));
|
||||
}
|
||||
if (mDrivingFast) {
|
||||
|
||||
if (mDrivingFast)
|
||||
{
|
||||
diffspeedmargin += 1.0 + 0.2 * speeddiff;
|
||||
}
|
||||
|
||||
return diffspeedmargin;
|
||||
}
|
||||
|
||||
|
||||
bool TDriver::oppNoDanger(Opponent* opp)
|
||||
{
|
||||
if ((opp->borderdist < -3.0 && fabs(opp->speed) < 0.5 && mBorderdist > 0.0 && fabs(opp->mDist) > 1.0)) {
|
||||
|
@ -1389,7 +1424,6 @@ bool TDriver::oppNoDanger(Opponent* opp)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
void TDriver::initCa(PCarSettings CarParmHandle)
|
||||
{
|
||||
char* WheelSect[4] = {(char*)SECT_FRNTRGTWHEEL, (char*)SECT_FRNTLFTWHEEL, (char*)SECT_REARRGTWHEEL, (char*)SECT_REARLFTWHEEL};
|
||||
|
@ -1408,7 +1442,6 @@ void TDriver::initCa(PCarSettings CarParmHandle)
|
|||
mCA = h * cl + 4.0 * (frntwingca + rearwingca);
|
||||
}
|
||||
|
||||
|
||||
void TDriver::initCw(PCarSettings CarParmHandle)
|
||||
{
|
||||
double cx = GfParmGetNum(CarParmHandle, SECT_AERODYNAMICS, PRM_CX, (char*)NULL, 0.0);
|
||||
|
@ -1416,7 +1449,6 @@ void TDriver::initCw(PCarSettings CarParmHandle)
|
|||
mCW = 0.645 * cx * frontarea;
|
||||
}
|
||||
|
||||
|
||||
void TDriver::initBrakes()
|
||||
{
|
||||
double maxf = 2.0 * mBRAKEREPARTITION * mBRAKEPRESS * oCar->_brakeDiskRadius(0) * mBRAKEPISTONAREA_FRONT * mBRAKEDISKMU_FRONT / oCar->_wheelRadius(0);
|
||||
|
@ -1424,7 +1456,6 @@ void TDriver::initBrakes()
|
|||
mBRAKEFORCE_MAX = maxf + maxr;
|
||||
}
|
||||
|
||||
|
||||
void TDriver::readConstSpecs(PCarHandle CarHandle)
|
||||
{
|
||||
mCARMASS = GfParmGetNum(CarHandle, SECT_CAR, PRM_MASS, NULL, 1000.0);
|
||||
|
@ -1438,7 +1469,6 @@ void TDriver::readConstSpecs(PCarHandle CarHandle)
|
|||
mBRAKEDISKMU_REAR = GfParmGetNum(CarHandle, SECT_REARRGTBRAKE, PRM_MU, (char*)NULL, 0.30f);
|
||||
}
|
||||
|
||||
|
||||
void TDriver::readVarSpecs(PCarSettings CarParmHandle)
|
||||
{
|
||||
mBRAKEPRESS = GfParmGetNum(CarParmHandle, SECT_BRKSYST, PRM_BRKPRESS, (char*)NULL, 20000.0);
|
||||
|
@ -1447,7 +1477,6 @@ void TDriver::readVarSpecs(PCarSettings CarParmHandle)
|
|||
mREARWINGANGLE = GfParmGetNum(CarParmHandle, SECT_REARWING, PRM_WINGANGLE, (char*)NULL, 0.0);
|
||||
}
|
||||
|
||||
|
||||
void TDriver::readPrivateSection(PCarSettings *CarParmHandle)
|
||||
{
|
||||
mBRAKEFORCEFACTOR = GfParmGetNum(*CarParmHandle, "private", "brakeforcefactor", (char*)NULL, 1.0);
|
||||
|
@ -1470,57 +1499,55 @@ void TDriver::readPrivateSection(PCarSettings *CarParmHandle)
|
|||
mSEGLEN = GfParmGetNum(*CarParmHandle, "private", "seglen", (char*)NULL, 3.0);
|
||||
}
|
||||
|
||||
|
||||
void TDriver::printSetup()
|
||||
{
|
||||
//if (mDriverMsgLevel && mCarIndex == mDriverMsgCarIndex)
|
||||
{
|
||||
GfOut("%s: Learning=%d\n", oCar->_name, mLearning);
|
||||
GfOut("%s: Testpitstop=%d\n", oCar->_name, mTestpitstop);
|
||||
GfOut("%s: TestLine=%d\n", oCar->_name, mTestLine);
|
||||
GfOut("%s: DriverMsgLevel=%d\n", oCar->_name, mDriverMsgLevel);
|
||||
GfOut("%s: DriverMsgCarIndex=%d\n", oCar->_name, mDriverMsgCarIndex);
|
||||
GfOut("%s: FRONTCOLL_MARGIN=%g\n", oCar->_name, mFRONTCOLL_MARGIN);
|
||||
LogDANDROID.info("%s: Learning = %d\n", oCar->_name, mLearning);
|
||||
LogDANDROID.info("%s: Testpitstop = %d\n", oCar->_name, mTestpitstop);
|
||||
LogDANDROID.info("%s: TestLine = %d\n", oCar->_name, mTestLine);
|
||||
LogDANDROID.info("%s: DriverMsgLevel = %d\n", oCar->_name, mDriverMsgLevel);
|
||||
LogDANDROID.info("%s: DriverMsgCarIndex = %d\n", oCar->_name, mDriverMsgCarIndex);
|
||||
LogDANDROID.info("%s: FRONTCOLL_MARGIN = %g\n", oCar->_name, mFRONTCOLL_MARGIN);
|
||||
|
||||
GfOut("%s: BRAKEPRESS=%g\n", oCar->_name, mBRAKEPRESS);
|
||||
GfOut("%s: BRAKE_REPARTITION=%g\n", oCar->_name, mBRAKEREPARTITION);
|
||||
GfOut("%s: FRONTWINGANGLE=%g\n", oCar->_name, mFRONTWINGANGLE * 360 / (2 * PI));
|
||||
GfOut("%s: REARWINGANGLE=%g\n", oCar->_name, mREARWINGANGLE * 360 / (2 * PI));
|
||||
GfOut("%s: CA=%g\n", oCar->_name, mCA);
|
||||
GfOut("%s: CW=%g\n", oCar->_name, mCW);
|
||||
GfOut("%s: WHEELBASE=%g\n", oCar->_name, mWHEELBASE);
|
||||
GfOut("%s: CARMASS=%g\n", oCar->_name, mCARMASS);
|
||||
GfOut("%s: BRAKEPISTON_AREA_FRONT=%g\n", oCar->_name, mBRAKEPISTONAREA_FRONT);
|
||||
GfOut("%s: BRAKEPISTON_AREA_REAR=%g\n", oCar->_name, mBRAKEPISTONAREA_REAR);
|
||||
GfOut("%s: BRAKEDISK_MU_FRONT=%g\n", oCar->_name, mBRAKEDISKMU_FRONT);
|
||||
GfOut("%s: BRAKEDISK_MU_REAR=%g\n", oCar->_name, mBRAKEDISKMU_REAR);
|
||||
LogDANDROID.info("%s: BRAKEPRESS = %g\n", oCar->_name, mBRAKEPRESS);
|
||||
LogDANDROID.info("%s: BRAKE_REPARTITION = %g\n", oCar->_name, mBRAKEREPARTITION);
|
||||
LogDANDROID.info("%s: FRONTWINGANGLE = %g\n", oCar->_name, mFRONTWINGANGLE * 360 / (2 * PI));
|
||||
LogDANDROID.info("%s: REARWINGANGLE = %g\n", oCar->_name, mREARWINGANGLE * 360 / (2 * PI));
|
||||
LogDANDROID.info("%s: CA = %g\n", oCar->_name, mCA);
|
||||
LogDANDROID.info("%s: CW = %g\n", oCar->_name, mCW);
|
||||
LogDANDROID.info("%s: WHEELBASE = %g\n", oCar->_name, mWHEELBASE);
|
||||
LogDANDROID.info("%s: CARMASS = %g\n", oCar->_name, mCARMASS);
|
||||
LogDANDROID.info("%s: BRAKEPISTON_AREA_FRONT = %g\n", oCar->_name, mBRAKEPISTONAREA_FRONT);
|
||||
LogDANDROID.info("%s: BRAKEPISTON_AREA_REAR = %g\n", oCar->_name, mBRAKEPISTONAREA_REAR);
|
||||
LogDANDROID.info("%s: BRAKEDISK_MU_FRONT = %g\n", oCar->_name, mBRAKEDISKMU_FRONT);
|
||||
LogDANDROID.info("%s: BRAKEDISK_MU_REAR = %g\n", oCar->_name, mBRAKEDISKMU_REAR);
|
||||
|
||||
GfOut("%s: brakeforcefactor=%g\n", oCar->_name, mBRAKEFORCEFACTOR);
|
||||
GfOut("%s: brakeforcemin=%g\n", oCar->_name, mBRAKEFORCEMIN);
|
||||
GfOut("%s: bumpspeedfactor=%g\n", oCar->_name, mBUMPSPEEDFACTOR);
|
||||
GfOut("%s: fuelpermeter=%g\n", oCar->_name, mFUELPERMETER);
|
||||
GfOut("%s: fuelweightfactor=%g\n", oCar->_name, mFUELWEIGHTFACTOR);
|
||||
GfOut("%s: pitdamage=%d\n", oCar->_name, mPITDAMAGE);
|
||||
GfOut("%s: pitentrymargin=%g\n", oCar->_name, mPITENTRYMARGIN);
|
||||
GfOut("%s: pitentryspeed=%g\n", oCar->_name, mPITENTRYSPEED);
|
||||
GfOut("%s: pitexitspeed=%g\n", oCar->_name, mPITEXITSPEED);
|
||||
GfOut("%s: targetfactor=%g\n", oCar->_name, mTARGETFACTOR);
|
||||
GfOut("%s: targetwalldist=%g\n", oCar->_name, mTARGETWALLDIST);
|
||||
GfOut("%s: tractioncontrol=%d\n", oCar->_name, mTRACTIONCONTROL);
|
||||
LogDANDROID.info("%s: brakeforcefactor = %g\n", oCar->_name, mBRAKEFORCEFACTOR);
|
||||
LogDANDROID.info("%s: brakeforcemin = %g\n", oCar->_name, mBRAKEFORCEMIN);
|
||||
LogDANDROID.info("%s: bumpspeedfactor = %g\n", oCar->_name, mBUMPSPEEDFACTOR);
|
||||
LogDANDROID.info("%s: fuelpermeter = %g\n", oCar->_name, mFUELPERMETER);
|
||||
LogDANDROID.info("%s: fuelweightfactor = %g\n", oCar->_name, mFUELWEIGHTFACTOR);
|
||||
LogDANDROID.info("%s: pitdamage = %d\n", oCar->_name, mPITDAMAGE);
|
||||
LogDANDROID.info("%s: pitentrymargin = %g\n", oCar->_name, mPITENTRYMARGIN);
|
||||
LogDANDROID.info("%s: pitentryspeed = %g\n", oCar->_name, mPITENTRYSPEED);
|
||||
LogDANDROID.info("%s: pitexitspeed = %g\n", oCar->_name, mPITEXITSPEED);
|
||||
LogDANDROID.info("%s: targetfactor = %g\n", oCar->_name, mTARGETFACTOR);
|
||||
LogDANDROID.info("%s: targetwalldist = %g\n", oCar->_name, mTARGETWALLDIST);
|
||||
LogDANDROID.info("%s: tractioncontrol = %d\n", oCar->_name, mTRACTIONCONTROL);
|
||||
|
||||
GfOut("%s: maxleft=%g\n", oCar->_name, mMAXLEFT);
|
||||
GfOut("%s: maxright=%g\n", oCar->_name, mMAXRIGHT);
|
||||
GfOut("%s: margininside=%g\n", oCar->_name, mMARGININSIDE);
|
||||
GfOut("%s: marginoutside=%g\n", oCar->_name, mMARGINOUTSIDE);
|
||||
GfOut("%s: clothoidfactor=%g\n", oCar->_name, mCLOTHFACTOR);
|
||||
GfOut("%s: seglen=%g\n", oCar->_name, mSEGLEN);
|
||||
LogDANDROID.info("%s: maxleft = %g\n", oCar->_name, mMAXLEFT);
|
||||
LogDANDROID.info("%s: maxright = %g\n", oCar->_name, mMAXRIGHT);
|
||||
LogDANDROID.info("%s: margininside = %g\n", oCar->_name, mMARGININSIDE);
|
||||
LogDANDROID.info("%s: marginoutside = %g\n", oCar->_name, mMARGINOUTSIDE);
|
||||
LogDANDROID.info("%s: clothoidfactor = %g\n", oCar->_name, mCLOTHFACTOR);
|
||||
LogDANDROID.info("%s: seglen=%g\n", oCar->_name, mSEGLEN);
|
||||
|
||||
GfOut("%s: skill level global=%g\n", oCar->_name, mSkillGlobal);
|
||||
GfOut("%s: skill level driver=%g\n", oCar->_name, mSkillDriver);
|
||||
LogDANDROID.info("%s: skill level global = %g\n", oCar->_name, mSkillGlobal);
|
||||
LogDANDROID.info("%s: skill level driver = %g\n", oCar->_name, mSkillDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double TDriver::filterABS(double brake)
|
||||
{
|
||||
double ABS_MINSPEED = 3.0; // [m/s]
|
||||
|
@ -1544,7 +1571,6 @@ double TDriver::filterABS(double brake)
|
|||
return brake;
|
||||
}
|
||||
|
||||
|
||||
double TDriver::filterTCL(double accel)
|
||||
{
|
||||
if ((!mTRACTIONCONTROL && mDrvPath == PATH_O && mSpeed > 25) || (!mTRACTIONCONTROL && oCurrSimTime < 6.0)) {
|
||||
|
@ -1562,50 +1588,56 @@ double TDriver::filterTCL(double accel)
|
|||
return accel;
|
||||
}
|
||||
|
||||
|
||||
double TDriver::filterTCL_FWD()
|
||||
{
|
||||
return (oCar->_wheelSpinVel(FRNT_RGT) + oCar->_wheelSpinVel(FRNT_LFT)) *
|
||||
oCar->_wheelRadius(FRNT_LFT) / 2.0f;
|
||||
}
|
||||
|
||||
|
||||
double TDriver::filterTCL_RWD()
|
||||
{
|
||||
return (oCar->_wheelSpinVel(REAR_RGT) + oCar->_wheelSpinVel(REAR_LFT)) *
|
||||
oCar->_wheelRadius(REAR_LFT) / 2.0f;
|
||||
}
|
||||
|
||||
|
||||
double TDriver::filterTCLSideSlip(double accel)
|
||||
{
|
||||
if (!mTRACTIONCONTROL && mDrvPath == PATH_O && mSpeed > 25) {
|
||||
return accel;
|
||||
}
|
||||
double sideslip = (oCar->_wheelSlipSide(FRNT_RGT) + oCar->_wheelSlipSide(FRNT_LFT) + oCar->_wheelSlipSide(REAR_RGT) + oCar->_wheelSlipSide(REAR_LFT)) / 4.0f;
|
||||
if (sideslip > 2.0 && mSpeed < 50) {
|
||||
return accel *= 0.8;
|
||||
}
|
||||
if (!mTRACTIONCONTROL && mDrvPath == PATH_O && mSpeed > 25)
|
||||
{
|
||||
return accel;
|
||||
}
|
||||
|
||||
double sideslip = (oCar->_wheelSlipSide(FRNT_RGT) + oCar->_wheelSlipSide(FRNT_LFT) + oCar->_wheelSlipSide(REAR_RGT) + oCar->_wheelSlipSide(REAR_LFT)) / 4.0f;
|
||||
|
||||
if (sideslip > 2.0 && mSpeed < 50)
|
||||
{
|
||||
return accel *= 0.8;
|
||||
}
|
||||
|
||||
return accel;
|
||||
}
|
||||
|
||||
double TDriver::fromStart(double fromstart)
|
||||
{
|
||||
if (fromstart > -mTrack->length && fromstart < 2.0 * mTrack->length) {
|
||||
if (fromstart > mTrack->length) {
|
||||
if (fromstart > -mTrack->length && fromstart < 2.0 * mTrack->length)
|
||||
{
|
||||
if (fromstart > mTrack->length)
|
||||
{
|
||||
return fromstart - mTrack->length;
|
||||
} else if (fromstart < 0.0) {
|
||||
}
|
||||
else if (fromstart < 0.0) {
|
||||
return fromstart + mTrack->length;
|
||||
}
|
||||
|
||||
return fromstart;
|
||||
} else {
|
||||
GfOut("!!!!!!!!!!!!!There is a bug in %s, 'fromstart'=%g is out of range !!!!!!!!!!!!!!!", oCar->_name, fromstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDANDROID.info("!!!!!!!!!!!!!There is a bug in %s, 'fromstart'=%g is out of range !!!!!!!!!!!!!!!\n", oCar->_name, fromstart);
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double TDriver::getCurvature(double dist)
|
||||
{
|
||||
DanPoint p;
|
||||
|
@ -1614,7 +1646,6 @@ double TDriver::getCurvature(double dist)
|
|||
return 1 / p.radius;
|
||||
}
|
||||
|
||||
|
||||
void TDriver::updateSector()
|
||||
{
|
||||
for (int i = 0; i < (int)mSect.size(); i++) {
|
||||
|
@ -1626,7 +1657,6 @@ void TDriver::updateSector()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::learnSpeedFactors()
|
||||
{
|
||||
if (!mLearning || !mNewFile) {
|
||||
|
@ -1639,7 +1669,7 @@ void TDriver::learnSpeedFactors()
|
|||
if (mLearnedAll && mNewFile) {
|
||||
writeSectorSpeeds();
|
||||
mNewFile = false;
|
||||
driverMsg("saved learning data in csv file");
|
||||
LogDANDROID.info("saved learning data in csv file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1713,14 +1743,14 @@ void TDriver::learnSpeedFactors()
|
|||
mAllSectorsFaster = allSectorsFaster();
|
||||
if (mAllSectorsFaster) {
|
||||
// All speed factors still the same and still gaining time
|
||||
GfOut("lap: %d speedfactor: %g time gained: %g\n", oCar->_laps - 1, mSect[0].speedfactor, mBestLapTime - mLastLapTime);
|
||||
LogDANDROID.info("lap: %d speedfactor: %g time gained: %g\n", oCar->_laps - 1, mSect[0].speedfactor, mBestLapTime - mLastLapTime);
|
||||
for (int i = 0; i < (int)mSect.size(); i++) {
|
||||
mSect[i].bestspeedfactor = mSect[i].speedfactor;
|
||||
mSect[i].besttime = mSect[i].time;
|
||||
}
|
||||
} else {
|
||||
// All speed factors still the same and reached the limit
|
||||
GfOut("lap: %d speedfactor: %g not all sectors faster\n", oCar->_laps - 1, mSect[0].speedfactor);
|
||||
LogDANDROID.info("lap: %d speedfactor: %g not all sectors faster\n", oCar->_laps - 1, mSect[0].speedfactor);
|
||||
for (int i = 0; i < (int)mSect.size(); i++) {
|
||||
mSect[i].speedfactor -= delta;
|
||||
}
|
||||
|
@ -1729,21 +1759,24 @@ void TDriver::learnSpeedFactors()
|
|||
} else {
|
||||
// Changing only one sector speed factor per lap
|
||||
if (mLastLapTime < mBestLapTime) {
|
||||
GfOut("lap: %d sec: %d sf: %g gained: %g\n", oCar->_laps-1, mLearnSector, mSect[mLearnSector].speedfactor, mBestLapTime - mLastLapTime);
|
||||
LogDANDROID.info("lap: %d sec: %d sf: %g gained: %g\n", oCar->_laps-1, mLearnSector, mSect[mLearnSector].speedfactor, mBestLapTime - mLastLapTime);
|
||||
mSect[mLearnSector].bestspeedfactor = mSect[mLearnSector].speedfactor;
|
||||
// Update all best times
|
||||
for (int i = 0; i < (int)mSect.size(); i++) {
|
||||
mSect[i].besttime = mSect[i].time;
|
||||
}
|
||||
} else {
|
||||
GfOut("lap: %d sec: %d sf: %g lost: %g\n", oCar->_laps-1, mLearnSector, mSect[mLearnSector].speedfactor, mLastLapTime - mBestLapTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDANDROID.info("lap: %d sec: %d sf: %g lost: %g\n", oCar->_laps-1, mLearnSector, mSect[mLearnSector].speedfactor, mLastLapTime - mBestLapTime);
|
||||
mSect[mLearnSector].speedfactor = mSect[mLearnSector].bestspeedfactor;
|
||||
mSect[mLearnSector].time = mSect[mLearnSector].besttime;
|
||||
mSect[mLearnSector].learned = 1;
|
||||
driverMsgValue(0, "learned: ", mLearnSector);
|
||||
}
|
||||
}
|
||||
GfOut("lap: %d time total: %g best: %g\n", oCar->_laps-1, mLastLapTime, mBestLapTime);
|
||||
|
||||
LogDANDROID.info("lap: %d time total: %g best: %g\n", oCar->_laps-1, mLastLapTime, mBestLapTime);
|
||||
}
|
||||
|
||||
// Setup for the next lap
|
||||
|
@ -1768,7 +1801,6 @@ void TDriver::learnSpeedFactors()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool TDriver::offtrack()
|
||||
{
|
||||
// Offtrack situations
|
||||
|
@ -1781,14 +1813,14 @@ bool TDriver::offtrack()
|
|||
return true;
|
||||
}
|
||||
// Barrier collisions
|
||||
if (mDamageDiff > 0 && mWalldist - oCar->_dimension_y / 2.0 < 0.5) {
|
||||
GfOut("barrier coll damage: %d\n", mDamageDiff);
|
||||
if (mDamageDiff > 0 && mWalldist - oCar->_dimension_y / 2.0 < 0.5)
|
||||
{
|
||||
LogDANDROID.info("barrier coll damage: %d\n", mDamageDiff);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool TDriver::equalSpeedFactors()
|
||||
{
|
||||
for (int i = 0; i < (int)mSect.size(); i++) {
|
||||
|
@ -1799,7 +1831,6 @@ bool TDriver::equalSpeedFactors()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TDriver::allSectorsFaster()
|
||||
{
|
||||
for (int i = 0; i < (int)mSect.size(); i++) {
|
||||
|
@ -1810,7 +1841,6 @@ bool TDriver::allSectorsFaster()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
int TDriver::nextLearnSector(int sect)
|
||||
{
|
||||
sect = (sect < (int)mSect.size() - 1) ? sect + 1 : 0;
|
||||
|
@ -1826,7 +1856,6 @@ int TDriver::nextLearnSector(int sect)
|
|||
return sect;
|
||||
}
|
||||
|
||||
|
||||
void TDriver::increaseSpeedFactor(int sect, double inc)
|
||||
{
|
||||
if (!mLearnedAll) {
|
||||
|
@ -1837,7 +1866,6 @@ void TDriver::increaseSpeedFactor(int sect, double inc)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::getBrakedistfactor()
|
||||
{
|
||||
mBrakedistfactor = mSect[mSector].brakedistfactor;
|
||||
|
@ -1858,21 +1886,19 @@ void TDriver::getBrakedistfactor()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::getSpeedFactors()
|
||||
{
|
||||
mSectSpeedfactor = mSect[mSector].speedfactor;
|
||||
}
|
||||
|
||||
|
||||
void TDriver::updatePathCar(int path)
|
||||
{
|
||||
if (!mDanPath.getDanPos(path, mFromStart, mPath[path].carpos)) {
|
||||
driverMsg("error dandroid TDriver::updatePathCar");
|
||||
if (!mDanPath.getDanPos(path, mFromStart, mPath[path].carpos))
|
||||
{
|
||||
LogDANDROID.info("error dandroid TDriver::updatePathCar\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::updatePathTarget(int path)
|
||||
{
|
||||
if (mDrvState == STATE_RACE && path == PATH_O && mCatchedRaceLine) {
|
||||
|
@ -1883,7 +1909,7 @@ void TDriver::updatePathTarget(int path)
|
|||
mTargetFromstart = fromStart(mFromStart + mLOOKAHEAD_CONST + 0.3 * mSpeed);
|
||||
}
|
||||
if (!mDanPath.getDanPos(path, mTargetFromstart, mPath[path].tarpos)) {
|
||||
driverMsg("error dandroid TDriver::updatePathTarget");
|
||||
LogDANDROID.info("error dandroid TDriver::updatePathTarget\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1922,7 +1948,6 @@ void TDriver::updateCurveAhead()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::updateDrivingFast()
|
||||
{
|
||||
double maxspeed = mPath[mDrvPath].maxspeed;
|
||||
|
@ -1946,68 +1971,95 @@ void TDriver::updateDrivingFast()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::updateCatchedRaceLine()
|
||||
{
|
||||
if (mDrvState == STATE_RACE && !mPathChange) {
|
||||
if (fabs(mPathOffs) < 1.0) {
|
||||
if (mCatchedRaceLineTime > 1.0) {
|
||||
if (mDrvState == STATE_RACE && !mPathChange)
|
||||
{
|
||||
if (fabs(mPathOffs) < 1.0)
|
||||
{
|
||||
if (mCatchedRaceLineTime > 1.0)
|
||||
{
|
||||
mCatchedRaceLine = true;
|
||||
} else if (mTenthTimer) {
|
||||
}
|
||||
else if (mTenthTimer)
|
||||
{
|
||||
mCatchedRaceLineTime += 0.1;
|
||||
}
|
||||
} else if (!mCatchedRaceLine) {
|
||||
mCatchedRaceLineTime = 0.0;
|
||||
} else if (fabs(mPathOffs) > 4.5) {
|
||||
mCatchedRaceLine = false;
|
||||
}
|
||||
else if (!mCatchedRaceLine)
|
||||
{
|
||||
mCatchedRaceLineTime = 0.0;
|
||||
}
|
||||
} else {
|
||||
else if (fabs(mPathOffs) > 4.5)
|
||||
{
|
||||
mCatchedRaceLine = false;
|
||||
mCatchedRaceLineTime = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mCatchedRaceLine = false;
|
||||
mCatchedRaceLineTime = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::updateFrontCollFactor()
|
||||
{
|
||||
mFrontCollFactor = 1.0;
|
||||
if (mBackmarkerInFrontOfTeammate || mDrivingFast) {
|
||||
|
||||
if (mBackmarkerInFrontOfTeammate || mDrivingFast)
|
||||
{
|
||||
mFrontCollFactor = 1.5;
|
||||
}
|
||||
|
||||
if (fabs(mSpeed) < 5.0) {
|
||||
if (fabs(mSpeed) < 5.0)
|
||||
{
|
||||
mFrontCollFactor = 0.2;
|
||||
}
|
||||
|
||||
if (mOpp != NULL) {
|
||||
if (fabs(mOpp->mAngle) > 1.5) {
|
||||
if (mOpp != NULL)
|
||||
{
|
||||
if (fabs(mOpp->mAngle) > 1.5)
|
||||
{
|
||||
mFrontCollFactor = 2.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::calcMaxspeed()
|
||||
{
|
||||
double maxspeed = mPath[mDrvPath].maxspeed;
|
||||
switch (mDrvState) {
|
||||
case STATE_RACE: {
|
||||
if (mCatchedRaceLine && mDrvPath == PATH_O) {
|
||||
switch (mDrvState)
|
||||
{
|
||||
case STATE_RACE:
|
||||
{
|
||||
if (mCatchedRaceLine && mDrvPath == PATH_O)
|
||||
{
|
||||
mMaxspeed = maxspeed;
|
||||
} else if (mCatchedRaceLine) {
|
||||
if (mTargetOnCurveInside) {
|
||||
}
|
||||
else if (mCatchedRaceLine)
|
||||
{
|
||||
if (mTargetOnCurveInside)
|
||||
{
|
||||
mMaxspeed = 0.98 * maxspeed;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mMaxspeed = (0.95 - 0.01 * fabs(mToMiddle)) * maxspeed;
|
||||
}
|
||||
} else {
|
||||
if (mTargetOnCurveInside) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mTargetOnCurveInside)
|
||||
{
|
||||
mMaxspeed = 0.93 * maxspeed;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mMaxspeed = (0.9 - 0.01 * fabs(mToMiddle)) * maxspeed;
|
||||
}
|
||||
}
|
||||
|
||||
mMaxspeed = mSkillGlobal * mMaxspeed;
|
||||
// Special cases
|
||||
if (mLetPass) {
|
||||
|
@ -2036,35 +2088,45 @@ void TDriver::calcMaxspeed()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::limitSteerAngle(double& targetangle)
|
||||
{
|
||||
double v2 = mSpeed * mSpeed;
|
||||
double rmax = v2 / (mMu * GRAVITY + v2 * mCA * mMu / mMass);
|
||||
double maxangle = atan(mWHEELBASE / rmax);
|
||||
double maxanglefactor;
|
||||
if (mDrvState == STATE_OFFTRACK) {
|
||||
|
||||
if (mDrvState == STATE_OFFTRACK)
|
||||
{
|
||||
maxanglefactor = 1.0;
|
||||
} else if (!mCatchedRaceLine) {
|
||||
}
|
||||
else if (!mCatchedRaceLine)
|
||||
{
|
||||
maxanglefactor = 10.0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
maxanglefactor = 100.0;
|
||||
}
|
||||
|
||||
maxangle *= maxanglefactor;
|
||||
mMaxSteerAngle = false;
|
||||
if (fabs(targetangle) > maxangle) {
|
||||
|
||||
if (fabs(targetangle) > maxangle)
|
||||
{
|
||||
targetangle = SIGN(targetangle) * maxangle;
|
||||
NORM_PI_PI(targetangle);
|
||||
mMaxSteerAngle = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::calcGlobalTarget()
|
||||
{
|
||||
if (mTargetToMiddle == mNormalTargetToMiddle) {
|
||||
if (mTargetToMiddle == mNormalTargetToMiddle)
|
||||
{
|
||||
mGlobalTarget = mPath[mDrvPath].tarpos.pos;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
tTrkLocPos target_local;
|
||||
RtTrackGlobal2Local(oCar->_trkPos.seg, (tdble) mPath[mDrvPath].tarpos.pos.x, (tdble) mPath[mDrvPath].tarpos.pos.y, &target_local, TR_LPOS_MAIN);
|
||||
target_local.toMiddle = (tdble) mTargetToMiddle;
|
||||
|
@ -2075,14 +2137,12 @@ void TDriver::calcGlobalTarget()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::calcTargetAngle()
|
||||
{
|
||||
mTargetAngle = Utils::VecAngle(mGlobalTarget - mGlobalCarPos) - oCar->_yaw;
|
||||
NORM_PI_PI(mTargetAngle);
|
||||
}
|
||||
|
||||
|
||||
void TDriver::controlSpeed(double& accelerator, double maxspeed)
|
||||
{
|
||||
// Set parameters
|
||||
|
@ -2091,52 +2151,62 @@ void TDriver::controlSpeed(double& accelerator, double maxspeed)
|
|||
// Run controller
|
||||
double speeddiff = maxspeed - mSpeed;
|
||||
accelerator += mSpeedController.sample(speeddiff);
|
||||
if (accelerator > 1.0) {
|
||||
|
||||
if (accelerator > 1.0)
|
||||
{
|
||||
accelerator = 1.0;
|
||||
}
|
||||
if (accelerator < 0.0) {
|
||||
|
||||
if (accelerator < 0.0)
|
||||
{
|
||||
accelerator = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::updateAttackAngle()
|
||||
{
|
||||
double velAng = atan2(oCar->_speed_Y, oCar->_speed_X);
|
||||
mAttackAngle = velAng - oCar->_yaw;
|
||||
NORM_PI_PI(mAttackAngle);
|
||||
if (mSpeed < 1.0) {
|
||||
|
||||
if (mSpeed < 1.0)
|
||||
{
|
||||
mAttackAngle = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TDriver::controlAttackAngle(double& targetangle)
|
||||
{
|
||||
if (fabs(mAttackAngle) > 0.1
|
||||
|| mDrvState == STATE_OFFTRACK) {
|
||||
|| mDrvState == STATE_OFFTRACK)
|
||||
{
|
||||
mAttackAngleController.m_d = 4.0;
|
||||
mAttackAngleController.m_p = 0.3;
|
||||
targetangle += mAttackAngleController.sample(mAttackAngle);
|
||||
NORM_PI_PI(targetangle);
|
||||
mControlAttackAngle = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mAttackAngleController.sample(mAttackAngle);
|
||||
mControlAttackAngle = false;
|
||||
}
|
||||
|
||||
return mControlAttackAngle;
|
||||
}
|
||||
|
||||
|
||||
void TDriver::controlYawRate(double& targetangle)
|
||||
{
|
||||
mControlYawRate = false;
|
||||
if (mDrvState == STATE_RACE) {
|
||||
if (mDrvState == STATE_RACE)
|
||||
{
|
||||
double AvgK = 1 / mPath[mDrvPath].carpos.radius;
|
||||
// Control rotational velocity.
|
||||
double Omega = mSpeed * AvgK;
|
||||
double yawratediff = Omega - oCar->_yaw_rate;
|
||||
if (fabs(yawratediff) > 0.2) {
|
||||
|
||||
if (fabs(yawratediff) > 0.2)
|
||||
{
|
||||
mControlYawRate = true;
|
||||
targetangle += 0.09 * (Omega - oCar->_yaw_rate);
|
||||
NORM_PI_PI(targetangle);
|
||||
|
@ -2144,35 +2214,43 @@ void TDriver::controlYawRate(double& targetangle)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool TDriver::hysteresis(bool lastout, double in, double hyst)
|
||||
{
|
||||
if (lastout == false) {
|
||||
if (in > hyst) {
|
||||
if (lastout == false)
|
||||
{
|
||||
if (in > hyst)
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (in < -hyst) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in < -hyst)
|
||||
{
|
||||
return false;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double TDriver::getFuel(double dist)
|
||||
{
|
||||
double fuel = dist * mFUELPERMETER;
|
||||
if (mTestpitstop) {
|
||||
if (mTestpitstop)
|
||||
{
|
||||
fuel = 1.9 * mTrack->length * mFUELPERMETER;
|
||||
}
|
||||
|
||||
return fuel = MAX(MIN(fuel, mTANKVOL), 0.0);
|
||||
}
|
||||
|
||||
|
||||
void TDriver::writeSectorSpeeds()
|
||||
{
|
||||
char dirname[256];
|
||||
|
@ -2180,64 +2258,77 @@ void TDriver::writeSectorSpeeds()
|
|||
#ifdef DANDROID_TORCS
|
||||
if (GfCreateDir(strdup(dirname)) == GF_DIR_CREATED) {
|
||||
#else
|
||||
if (GfDirCreate(strdup(dirname)) == GF_DIR_CREATED) {
|
||||
if (GfDirCreate(strdup(dirname)) == GF_DIR_CREATED)
|
||||
{
|
||||
#endif
|
||||
char filename[256];
|
||||
sprintf(filename, "%sdrivers/%s/%s/learned/%s.csv", GetLocalDir(), MyBotName, mCarType.c_str(), mTrack->internalname);
|
||||
std::ofstream myfile;
|
||||
myfile.open (filename);
|
||||
for (int i = 0; i < (int)mSect.size(); i++) {
|
||||
for (int i = 0; i < (int)mSect.size(); i++)
|
||||
{
|
||||
myfile << mSect[i].sector << std::endl;
|
||||
myfile << mSect[i].fromstart << std::endl;
|
||||
myfile << mSect[i].brakedistfactor << std::endl;
|
||||
myfile << mSect[i].speedfactor << std::endl;
|
||||
}
|
||||
myfile.close();
|
||||
} else {
|
||||
driverMsg("Error saveFile: unable to create user dir");
|
||||
}
|
||||
}
|
||||
|
||||
myfile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDANDROID.info("Error saveFile: unable to create user dir\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool TDriver::readSectorSpeeds()
|
||||
{
|
||||
char filename[256];
|
||||
if (mLearning) {
|
||||
if (mLearning)
|
||||
{
|
||||
sprintf(filename, "%sdrivers/%s/%s/learned/%s.csv", GetLocalDir(), MyBotName, mCarType.c_str(), mTrack->internalname);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(filename, "%sdrivers/%s/%s/learned/%s.csv", GetDataDir(), MyBotName, mCarType.c_str(), mTrack->internalname);
|
||||
}
|
||||
|
||||
DanSector sect;
|
||||
std::ifstream myfile(filename);
|
||||
if (myfile.is_open()) {
|
||||
if (myfile.is_open())
|
||||
{
|
||||
while (myfile >> sect.sector
|
||||
>> sect.fromstart
|
||||
>> sect.brakedistfactor
|
||||
>> sect.speedfactor) {
|
||||
if (mLearning) {
|
||||
>> sect.speedfactor)
|
||||
{
|
||||
if (mLearning)
|
||||
{
|
||||
GfOut("S:%d l:%d fs:%g bdf:%g t:%g bt:%g sf:%g bsf:%g\n", sect.sector, sect.learned, sect.fromstart, sect.brakedistfactor, sect.time, sect.besttime, sect.speedfactor, sect.bestspeedfactor);
|
||||
}
|
||||
|
||||
mSect.push_back(sect);
|
||||
}
|
||||
|
||||
myfile.close();
|
||||
return true;
|
||||
} else {
|
||||
driverMsg("readSectorSpeeds(): no csv file found");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDANDROID.info("readSectorSpeeds(): no csv file found\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TDriver::driverMsg(const std::string &desc)
|
||||
{
|
||||
GfOut("%s %s\n", oCar->_name, desc.c_str());
|
||||
LogDANDROID.info("%s %s\n", oCar->_name, desc.c_str());
|
||||
}
|
||||
|
||||
|
||||
void TDriver::driverMsgValue(int priority, const std::string &desc, double value)
|
||||
{
|
||||
if (priority <= mDriverMsgLevel && mCarIndex == mDriverMsgCarIndex) {
|
||||
GfOut("%dm %s s:%d p:%d %s %g\n", (int)mFromStart, oCar->_name, mDrvState, mDrvPath, desc.c_str(), value);
|
||||
if (priority <= mDriverMsgLevel && mCarIndex == mDriverMsgCarIndex)
|
||||
{
|
||||
LogDANDROID.info("%dm %s s:%d p:%d %s %g\n", (int)mFromStart, oCar->_name, mDrvState, mDrvPath, desc.c_str(), value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,12 @@
|
|||
#include "danpath.h"
|
||||
#include "pidcontroller.h"
|
||||
|
||||
// The "DANDROID" logger instance.
|
||||
extern GfLogger* PLogDANDROID;
|
||||
#define LogDANDROID (*PLogDANDROID)
|
||||
|
||||
class PathInfo {
|
||||
class PathInfo
|
||||
{
|
||||
public:
|
||||
DanPoint carpos;
|
||||
DanPoint tarpos;
|
||||
|
@ -37,7 +41,8 @@ class PathInfo {
|
|||
};
|
||||
|
||||
|
||||
class TDriver {
|
||||
class TDriver
|
||||
{
|
||||
public:
|
||||
TDriver(int index);
|
||||
~TDriver();
|
||||
|
|
Loading…
Reference in a new issue