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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.