Re: (Patch) Automatic gear shift
David Savinkoff <[email protected]> Fri, 25 Oct 2013 21:27:11 -0600 (MDT)
| Newsgroups | gmane.games.torcs.general |
|---|---|
| Message-ID | <[email protected]> |
Bernhard Wymann wrote: > Hi David > > Thank you for the patch, it looks reasonable and I will take a note to > put it into 1.3.6. > > Best regards > > Bernhard > > On 10/09/2013 08:30 AM, David Savinkoff wrote: > > Hi Bernhard, > > > > This patch improves human automatic gear shifting, making controlled > > drifting in TORCS much better. TORCS currently shifts gears by using > > car->_speed_x (a single component of a 3D vector). This is correct > > only when the car is traveling in the direction that is pointed, > > not when drifting or flying off-angle. Loss of control can no longer > > be attributed to improper automatic down-shifting while drifting. > > > > BTW using x, y and z vector components work better than just x and y > > (I drove various tracks for the past day to test TORCS). > > > > Note that this patch is more-or-less a hack-ish proof of concept. > > > > TORCS has been my high velocity entertainment for four years. > > > > Thanks, > > David > > Hi Bernhard, Here is a new patch that incorporates my previous gear-shifting patch in a more generalized way, allowing for the speed calculation to be used throughout torcs (not only for gear shifting). I applied the speed calculation to steering for an improvement too. (I got a hint from speed-dreams for this one) Note the gear shifting improvement and steering improvement in: torcs-1.3.5-test1/src/drivers/human/human.cpp The speed calculation is also applied for improvements in: torcs-1.3.5-test1/src/libs/raceengineclient/raceengine.cpp torcs-1.3.5-test1/src/modules/graphic/ssggraph/CarSoundData.cpp torcs-1.3.5-test1/src/modules/graphic/ssggraph/grskidmarks.cpp torcs-1.3.5-test1/src/modules/graphic/ssggraph/grsmoke.cpp The speed calculation could also be applied for improvements in: torcs-1.3.5-test1/src/drivers The speed calculation is made in: torcs-1.3.5-test1/src/interfaces/car.h torcs-1.3.5-test1/src/modules/simu/simuv2/car.cpp A constant for the yaw, pitch and roll inertial moments were experimented with, and changed for an improvement in: torcs-1.3.5-test1/src/modules/simu/simuv2/car.cpp Maybe these values could be made user configurable. All of the improvements make for a better driving experience. Please try this patch. I developed these patches on a modified car4-trb1, and tested them on car5-trb1 afterwards. car5-trb1 works excellently, and I recommend you do some drift-passing on corners around the robots. Now you can realistically scramble to save your bacon after pushing it too far. Sincerely, David Savinkoff ps. :) If the 12.0 constant used in the Inverse Moment of Inertia is mathematically derived and not negotiable, here is my argument: I tried 6.0 and found that the moment of inertia was too high, and 18.0 found it too low (subjectively tested by driving). Thus, 12.0 must be the best value since it is half-way-between. However, half-way-between seems to have the worst of too-high and too-low. It is perfectly-bad. So, maybe halfway between perfectly-bad and too-something is the answer... 15.0 is halfway between perfectly-bad (12.0) and too-low (18.0), and it seems to be approximately the best value. The Derivation of 15.28 :) Given that 12.0 is the mathematically correct constant for this inverse moment of inertia formula: Constant for Moment of Inertia = 1/12 1/12 * pi/4 = 0.06545 ; pi/4 [rads] works good and looks good too! 1/.06545 = 15.28 ------------------------------------------------------------------------------ October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register > http://pubads.g.doubleclick.net/gampad/clk?id=60135991&iu=/4140/ostg.clktrk _______________________________________________ Torcs-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/torcs-users
torcs-1.3.5-test1.drift.diff
(text/x-patch, 12.1 KB)
diff -ur torcs-1.3.5-test1/src/drivers/human/human.cpp torcs-1.3.5-test1/src/drivers/human/human.cpp
--- torcs-1.3.5-test1/src/drivers/human/human.cpp 2013-10-19 17:48:32.000000000 -0700
+++ torcs-1.3.5-test1/src/drivers/human/human.cpp 2013-10-19 19:12:41.000000000 -0700
@@ -361,7 +361,7 @@
RtTelemNewChannel("Throttle", &car->ctrl->accelCmd, 0, 0);
RtTelemNewChannel("Brake", &car->ctrl->brakeCmd, 0, 0);
RtTelemNewChannel("Gear", &HCtx[idx]->Gear, 0, 0);
- RtTelemNewChannel("Speed", &car->_speed_x, 0, 0);
+ RtTelemNewChannel("Speed", &car->_Speed, 0, 0);
}
#endif
#endif
@@ -467,7 +467,6 @@
const int BUFSIZE = 1024;
char sstring[BUFSIZE];
-
static int firstTime = 1;
if (firstTime) {
@@ -565,7 +564,7 @@
// normalize ax0 to -1..0
ax0 = (ax0 - cmd[CMD_LEFTSTEER].max) / (cmd[CMD_LEFTSTEER].max - cmd[CMD_LEFTSTEER].min);
- leftSteer = -SIGN(ax0) * cmd[CMD_LEFTSTEER].pow * pow(fabs(ax0), cmd[CMD_LEFTSTEER].sens) / (1.0 + cmd[CMD_LEFTSTEER].spdSens * car->_speed_x);
+ leftSteer = -SIGN(ax0) * cmd[CMD_LEFTSTEER].pow * pow(fabs(ax0), cmd[CMD_LEFTSTEER].sens) / (1.0 + cmd[CMD_LEFTSTEER].spdSens * car->_Speed);
break;
case GFCTRL_TYPE_MOUSE_AXIS:
ax0 = mouseInfo->ax[cmd[CMD_LEFTSTEER].val] - cmd[CMD_LEFTSTEER].deadZone; //FIXME: correct?
@@ -575,7 +574,7 @@
ax0 = cmd[CMD_LEFTSTEER].min;
}
ax0 = ax0 * cmd[CMD_LEFTSTEER].pow;
- leftSteer = pow(fabs(ax0), cmd[CMD_LEFTSTEER].sens) / (1.0 + cmd[CMD_LEFTSTEER].spdSens * car->_speed_x / 10.0);
+ leftSteer = pow(fabs(ax0), cmd[CMD_LEFTSTEER].sens) / (1.0 + cmd[CMD_LEFTSTEER].spdSens * car->_Speed / 10.0);
break;
case GFCTRL_TYPE_KEYBOARD:
case GFCTRL_TYPE_SKEYBOARD:
@@ -613,7 +612,7 @@
// normalize ax to 0..1
ax0 = (ax0 - cmd[CMD_RIGHTSTEER].min) / (cmd[CMD_RIGHTSTEER].max - cmd[CMD_RIGHTSTEER].min);
- rightSteer = -SIGN(ax0) * cmd[CMD_RIGHTSTEER].pow * pow(fabs(ax0), cmd[CMD_RIGHTSTEER].sens) / (1.0 + cmd[CMD_RIGHTSTEER].spdSens * car->_speed_x);
+ rightSteer = -SIGN(ax0) * cmd[CMD_RIGHTSTEER].pow * pow(fabs(ax0), cmd[CMD_RIGHTSTEER].sens) / (1.0 + cmd[CMD_RIGHTSTEER].spdSens * car->_Speed);
break;
case GFCTRL_TYPE_MOUSE_AXIS:
ax0 = mouseInfo->ax[cmd[CMD_RIGHTSTEER].val] - cmd[CMD_RIGHTSTEER].deadZone;
@@ -623,7 +622,7 @@
ax0 = cmd[CMD_RIGHTSTEER].min;
}
ax0 = ax0 * cmd[CMD_RIGHTSTEER].pow;
- rightSteer = - pow(fabs(ax0), cmd[CMD_RIGHTSTEER].sens) / (1.0 + cmd[CMD_RIGHTSTEER].spdSens * car->_speed_x / 10.0);
+ rightSteer = - pow(fabs(ax0), cmd[CMD_RIGHTSTEER].sens) / (1.0 + cmd[CMD_RIGHTSTEER].spdSens * car->_Speed / 10.0);
break;
case GFCTRL_TYPE_KEYBOARD:
case GFCTRL_TYPE_SKEYBOARD:
@@ -1043,6 +1042,7 @@
{
int gear, i;
int idx = index - 1;
+
tControlCmd *cmd = HCtx[idx]->CmdControl;
common_drive(index, car, s);
@@ -1110,10 +1110,10 @@
shiftThld = omega / car->_gearRatio[gear];
}
- if (car->_speed_x > shiftThld) {
+ if (car->_Speed > shiftThld) {
car->_gearCmd++;
} else if (car->_gearCmd > 1) {
- if (car->_speed_x < (omega / car->_gearRatio[gear-1] - 4.0)) {
+ if (car->_Speed < (omega / car->_gearRatio[gear-1] - 4.0)) {
car->_gearCmd--;
}
}
@@ -1126,13 +1126,13 @@
if (HCtx[idx]->AutoReverse) {
/* Automatic Reverse Gear Mode */
if (!HCtx[idx]->AutoReverseEngaged) {
- if ((car->_brakeCmd > car->_accelCmd) && (car->_speed_x < 1.0)) {
+ if ((car->_brakeCmd > car->_accelCmd) && (car->_Speed < 1.0)) {
HCtx[idx]->AutoReverseEngaged = 1;
car->_gearCmd = CMD_GEAR_R - CMD_GEAR_N;
}
} else {
/* currently in autoreverse mode */
- if ((car->_brakeCmd > car->_accelCmd) && (car->_speed_x > -1.0) && (car->_speed_x < 1.0)) {
+ if ((car->_brakeCmd > car->_accelCmd) && (car->_Speed > -1.0) && (car->_Speed < 1.0)) {
HCtx[idx]->AutoReverseEngaged = 0;
car->_gearCmd = CMD_GEAR_1 - CMD_GEAR_N;
} else {
diff -ur torcs-1.3.5-test1/src/interfaces/car.h torcs-1.3.5-test1/src/interfaces/car.h
--- torcs-1.3.5-test1/src/interfaces/car.h 2013-10-19 17:43:47.000000000 -0700
+++ torcs-1.3.5-test1/src/interfaces/car.h 2013-10-19 17:43:40.000000000 -0700
@@ -190,6 +190,7 @@
tDynPt DynGCg; /**< GC data (world axis) */
sgMat4 posMat; /**< position matrix */
tTrkLocPos trkPos; /**< current track position. The segment is the track segment (not sides)*/
+ tdble Speed; /**< car speed = sqrt(DynGCg.vel.x^2 + DynGCg.vel.y^2 + DynGCg.vel.z^2) */
int state; /**< state of the car.
<br>The states are:
- RM_CAR_STATE_FINISH
@@ -233,6 +234,7 @@
#define _accel_x pub.DynGC.acc.x
#define _accel_y pub.DynGC.acc.y
#define _accel_z pub.DynGC.acc.z
+#define _Speed pub.Speed
#define _state pub.state
#define _trkPos pub.trkPos
#define _speed_X pub.DynGCg.vel.x
diff -ur torcs-1.3.5-test1/src/libs/raceengineclient/raceengine.cpp torcs-1.3.5-test1/src/libs/raceengineclient/raceengine.cpp
--- torcs-1.3.5-test1/src/libs/raceengineclient/raceengine.cpp 2013-10-19 17:50:35.000000000 -0700
+++ torcs-1.3.5-test1/src/libs/raceengineclient/raceengine.cpp 2013-10-19 17:50:24.000000000 -0700
@@ -135,17 +135,17 @@
tReCarInfo *info = &(ReInfo->_reCarInfo[car->index]);
- if (car->_speed_x > car->_topSpeed) {
- car->_topSpeed = car->_speed_x;
+ if (car->_Speed > car->_topSpeed) {
+ car->_topSpeed = car->_Speed;
}
// For practice and qualif.
- if (car->_speed_x > info->topSpd) {
- info->topSpd = car->_speed_x;
+ if (car->_Speed > info->topSpd) {
+ info->topSpd = car->_Speed;
}
- if (car->_speed_x < info->botSpd) {
- info->botSpd = car->_speed_x;
+ if (car->_Speed < info->botSpd) {
+ info->botSpd = car->_Speed;
}
// Pitstop.
@@ -204,8 +204,7 @@
wseg += RtTrackGetWidth(sseg, car->_trkPos.toStart);
}
if (((toBorder + wseg) < (ReInfo->track->pits.width - car->_dimension_y / 2.0)) &&
- (fabs(car->_speed_x) < 1.0) &&
- (fabs(car->_speed_y) < 1.0))
+ (car->_Speed < 1.0))
{
pitok = 1;
}
@@ -300,8 +299,8 @@
}
}
- info->topSpd = car->_speed_x;
- info->botSpd = car->_speed_x;
+ info->topSpd = car->_Speed;
+ info->botSpd = car->_Speed;
if ((car->_remainingLaps < 0) || (s->_raceState == RM_RACE_FINISHING)) {
car->_state |= RM_CAR_STATE_FINISH;
s->_raceState = RM_RACE_FINISHING;
@@ -577,7 +576,7 @@
}
if (seg->raceInfo & TR_SPEEDLIMIT) {
- if (!(rules->ruleState & (RM_PNST_SPD | RM_PNST_STNGO)) && (car->_speed_x > track->pits.speedLimit)) {
+ if (!(rules->ruleState & (RM_PNST_SPD | RM_PNST_STNGO)) && (car->_Speed > track->pits.speedLimit)) {
snprintf(buf, BUFSIZE, "%s DRIVE THROUGH PENALTY", car->_name);
ReRaceMsgSet(buf, 5);
rules->ruleState |= RM_PNST_SPD;
diff -ur torcs-1.3.5-test1/src/modules/graphic/ssggraph/CarSoundData.cpp torcs-1.3.5-test1/src/modules/graphic/ssggraph/CarSoundData.cpp
--- torcs-1.3.5-test1/src/modules/graphic/ssggraph/CarSoundData.cpp 2013-10-20 13:00:43.000000000 -0700
+++ torcs-1.3.5-test1/src/modules/graphic/ssggraph/CarSoundData.cpp 2013-10-20 13:00:54.000000000 -0700
@@ -202,7 +202,6 @@
grass.f = 1.0f;
road.a = 0.0;
road.f = 0.0f;
- float car_speed2 = car->_speed_x * car->_speed_x + car->_speed_y * car->_speed_y;
bool flag = false;
int i;
for (i = 0; i<4; i++) {
@@ -222,7 +221,7 @@
if (
(car->_state & RM_CAR_STATE_NO_SIMU) ||
- (((car->_speed_x*car->_speed_x + car->_speed_y*car->_speed_y) < 0.1f) &&
+ (((car->_Speed * car->_Speed) < 0.1f) &&
(flag == false))
) {
return;
@@ -233,7 +232,7 @@
tdble roughness = 0.0f;
tdble roughnessFreq = 1.0f;
float ride = 0.0001f;
- float tmpvol = sqrt(car_speed2)*0.01f;
+ float tmpvol = car->_Speed * 0.01f;
if (car==NULL) {
fprintf (stderr, "Error: (grsound.c) no car\n");
continue;
@@ -369,7 +368,7 @@
int collision = car->priv.collision;
if (collision) {
if (collision & 1) {
- skid_metal.a = sqrt(car->_speed_x * car->_speed_x + car->_speed_y * car->_speed_y)*0.01;
+ skid_metal.a = car->_Speed * 0.01;
skid_metal.f = .5+0.5*skid_metal.a;
drag_collision.f = skid_metal.f;
} else {
diff -ur torcs-1.3.5-test1/src/modules/graphic/ssggraph/grskidmarks.cpp torcs-1.3.5-test1/src/modules/graphic/ssggraph/grskidmarks.cpp
--- torcs-1.3.5-test1/src/modules/graphic/ssggraph/grskidmarks.cpp 2013-10-20 12:36:33.000000000 -0700
+++ torcs-1.3.5-test1/src/modules/graphic/ssggraph/grskidmarks.cpp 2013-10-20 12:36:21.000000000 -0700
@@ -215,7 +215,7 @@
continue;
}
- if ((car->_speed_x * car->_speed_x + car->_speed_y * car->_speed_y) > 1.0f) {
+ if (car->_Speed > 1.0f) {
if (cur_clr[3] > 0.1f) {
basevtx = new ssgVertexArray(4 * 2 + 1);
diff -ur torcs-1.3.5-test1/src/modules/graphic/ssggraph/grsmoke.cpp torcs-1.3.5-test1/src/modules/graphic/ssggraph/grsmoke.cpp
--- torcs-1.3.5-test1/src/modules/graphic/ssggraph/grsmoke.cpp 2013-10-20 13:10:43.000000000 -0700
+++ torcs-1.3.5-test1/src/modules/graphic/ssggraph/grsmoke.cpp 2013-10-20 13:10:34.000000000 -0700
@@ -226,17 +226,14 @@
ssgVertexArray *shd_vtx ;
tgrCarInstrument *curInst;
tdble val;
- tdble spd2;
int index;
if (!grSmokeMaxNumber) {
return;
}
- spd2 = car->_speed_x * car->_speed_x + car->_speed_y * car->_speed_y;
-
for (i = 0; i < 4; i++) {
- if (spd2 > 0.001f) {
+ if ((car->_Speed * car->_Speed) > 0.001f) {
if (smokeManager->number < grSmokeMaxNumber) {
if ((t - timeSmoke[car->index*4+i]) < grSmokeDeltaT) {
continue;
@@ -302,7 +299,7 @@
}
smoke_life_coefficient = smoke_life_coefficient * (1.0f - urandom()*urandom());
- tdble spd_fx=tanh(0.001f*car->_reaction[i])*smoke_speed_coefficient*sqrt(spd2);
+ tdble spd_fx=tanh(0.001f*car->_reaction[i])*smoke_speed_coefficient*car->_Speed;
if (car->_skid[i] + 0.025f*urandom()*spd_fx>urandom() + threshold) {// instead of 0.3, to randomize
float init_speed_z = 0.1f;
@@ -339,7 +336,7 @@
//printf("%f\n", car->_reaction[i]);
tmp->smoke->max_life = grSmokeLife *
- (car->_skid[i]*sqrt(spd2)+urandom()*spd_fx)/ smoke_life_coefficient;
+ (car->_skid[i]*car->_Speed+urandom()*spd_fx)/ smoke_life_coefficient;
for (int c = 0; c < 3; c++) {
tmp->smoke->cur_col[c] = cur_clr[c];
}
@@ -369,7 +366,7 @@
}
}
- if (car->_exhaustNb && (spd2 > 10.0)) {
+ if (car->_exhaustNb && ((car->_Speed * car->_Speed) > 10.0)) {
if (smokeManager->number < grSmokeMaxNumber) {
index = car->index; /* current car's index */
if ((t - timeFire[index]) > grFireDeltaT) {
diff -ur torcs-1.3.5-test1/src/modules/simu/simuv2/car.cpp torcs-1.3.5-test1/src/modules/simu/simuv2/car.cpp
--- torcs-1.3.5-test1/src/modules/simu/simuv2/car.cpp 2013-10-19 17:46:44.000000000 -0700
+++ torcs-1.3.5-test1/src/modules/simu/simuv2/car.cpp 2013-10-25 13:56:11.000000000 -0700
@@ -63,9 +63,9 @@
car->fuel = car->tank;
}
k = k * k;
- car->Iinv.x = 12.0 / (car->mass * (car->dimension.y * car->dimension.y + car->dimension.z * car->dimension.z));
- car->Iinv.y = 12.0 / (car->mass * (car->dimension.x * car->dimension.x + car->dimension.z * car->dimension.z));
- car->Iinv.z = 12.0 / (car->mass * (car->dimension.y * car->dimension.y + k * car->dimension.x * car->dimension.x));
+ car->Iinv.x = 15.28 / (car->mass * (car->dimension.y * car->dimension.y + car->dimension.z * car->dimension.z));
+ car->Iinv.y = 15.28 / (car->mass * (car->dimension.x * car->dimension.x + car->dimension.z * car->dimension.z));
+ car->Iinv.z = 15.28 / (car->mass * (car->dimension.y * car->dimension.y + k * car->dimension.x * car->dimension.x));
/* configure components */
w = car->mass * G;
@@ -239,6 +239,7 @@
static void
SimCarUpdateSpeed(tCar *car)
{
+ tCarElt *carElt = car->carElt;
tdble Cosz, Sinz;
//tdble mass;
@@ -267,6 +268,11 @@
car->DynGC.vel.x = car->DynGCg.vel.x * Cosz + car->DynGCg.vel.y * Sinz;
car->DynGC.vel.y = -car->DynGCg.vel.x * Sinz + car->DynGCg.vel.y * Cosz;
car->DynGC.vel.z = car->DynGCg.vel.z;
+
+ /* 3D speed */
+ carElt->_Speed = sqrt(car->DynGCg.vel.x * car->DynGCg.vel.x +
+ car->DynGCg.vel.y * car->DynGCg.vel.y +
+ car->DynGCg.vel.z * car->DynGCg.vel.z);
}
void