- 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:
torcs-ng 2020-05-19 21:06:27 +00:00
parent 2ce184fb36
commit 35d96145e8
4 changed files with 2059 additions and 1895 deletions

View file

@ -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++) {

View file

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

View file

@ -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
@ -138,14 +139,23 @@ void TDriver::InitTrack(PTrack Track, PCarHandle CarHandle, PCarSettings *CarPar
mTestpitstop = GfParmGetNum(handle, "private", "test pitstop", (char*)NULL, 0.0) != 0;
//mTestpitstop = 1;
mTestLine = (int)GfParmGetNum(handle, "private", "test line", (char*)NULL, 0.0);
mDriverMsgLevel = (int)GfParmGetNum(handle, "private", "driver message", (char*)NULL, 0.0);
mDriverMsgLevel = (int)GfParmGetNum(handle, "private", "driver message", (char*) NULL, 0.0);
mDriverMsgCarIndex = (int)GfParmGetNum(handle, "private", "driver message car index", (char*)NULL, 0.0);
mFRONTCOLL_MARGIN = GfParmGetNum(handle, "private", "frontcollmargin", (char*)NULL, 4.0);
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) {
@ -1301,7 +1327,7 @@ bool TDriver::onCollision()
}
}
}
/*
/*
// collision braking test
if (mFromStart < 4410.0) {
//mCollDist = 1019.0 - mFromStart;
@ -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) {
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) {
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) {
}
else if (!mCatchedRaceLine)
{
mCatchedRaceLineTime = 0.0;
} else if (fabs(mPathOffs) > 4.5) {
}
else if (fabs(mPathOffs) > 4.5)
{
mCatchedRaceLine = false;
mCatchedRaceLineTime = 0.0;
}
} else {
}
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");
}
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);
}
}

View file

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