Re: Patch for wheel spin velocity traction

David Savinkoff <[email protected]> Fri, 27 Nov 2015 20:33:40 -0700 (MST)
Newsgroups gmane.games.torcs.general
Message-ID <1589533232.10432988.1448681620851.JavaMail.zimbra@mailid.telus.net>
----- David Savinkoff wrote:
> Hi,
> 
> In my last patch I had the following code:
> slip_magnitude = 0.000001f + sqrt( MAX(MAX((vn*vn + vt*vt)
> 
> Where (v2) should be equal to (vn*vn + vt*vt) but is not,
> because of lack of precision of the float data type.
> 
> Here I use (v2) for velocity squared because the car drives
> noticeably better, and (v2) is obviously more accurate.
> 
> slip_magnitude = 0.000001f + sqrt( MAX(MAX((v2)
> 
> BTW is there somewhere I can find recent TORCS source code
> changes so that I can test and experiment?
> 
> Sincerely,
> David Savinkoff

Hi,

Here is another patch for floating point improvements.

I used sqrtf() where it seemed to make a speed improvement
on my slow computer.

I used (double) to get more accuracy for CosA and SinA

It is obvious that (float) is not sufficient in some
circumstances, and that (double) is slower in others.

I hope these improvements in wheel.cpp help with making
other problems more characterizable.

Sincerely,
David Savinkoff

ps.

Speed Dreams should incorporate this patch too.
Note that this patch will give you deja vu a few times
per lap (even if you do motocross).

------------------------------------------------------------------------------

_______________________________________________
Torcs-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/torcs-users
wheel.cpp.2015nov27.diff (text/x-patch, 2.8 KB)
--- torcs-1.3.6/src/modules/simu/simuv2/wheel.cpp	2013-08-29 06:01:32.000000000 -0700
+++ torcs-1.3.6/src/modules/simu/simuv2/wheel.cpp	2015-11-27 18:07:09.910355230 -0800
@@ -174,12 +174,12 @@
 {
 	tWheel *wheel = &(car->wheel[index]);
 	tdble axleFz = wheel->axleFz;
-	tdble vt, v, v2, wrl; // wheel related velocity
+	tdble vt, vn, v, v2, wrl, slip_magnitude; // wheel related velocity
 	tdble Fn, Ft;
 	tdble waz;
-	tdble CosA, SinA;
+	double CosA, SinA;
 	tdble s, sa, sx, sy; // slip vector
-	tdble stmp, F, Bx;
+	tdble F, Bx;
 	tdble mu;
 	wheel->state = 0;
 
@@ -215,8 +215,9 @@
 
 	// tangent velocity.
 	vt = wheel->bodyVel.x * CosA + wheel->bodyVel.y * SinA;
+	vn = wheel->bodyVel.y * CosA - wheel->bodyVel.x * SinA;
 	v2 = wheel->bodyVel.x * wheel->bodyVel.x + wheel->bodyVel.y * wheel->bodyVel.y;
-	v = sqrt(v2);
+	v = sqrtf(v2);
 
 	// slip angle
 	if (v < 0.000001f) {
@@ -227,34 +228,31 @@
 	NORM_PI_PI(sa);
 
 	wrl = wheel->spinVel * wheel->radius;
+
 	if ((wheel->state & SIM_WH_ONAIR) != 0) {
 		sx = sy = 0.0f;
-	} else if (v < 0.000001f) {
-		sx = wrl;
-		sy = 0.0f;
 	} else {
-		sx = (vt - wrl) / fabs(vt);
-		sy = sin(sa);
+		// Normalize the friction circle to get normalized vector components (sx, sy) while
+		// braking (vt), accelerating (wrl), or wheel counter spin (vt - wrl) for any angle.
+		slip_magnitude = 0.000001f + sqrt( MAX(MAX((v2), (vn*vn + wrl*wrl)), (vn*vn + (vt - wrl)*(vt - wrl))) );
+		sx = (vt - wrl) / slip_magnitude;
+		sy = vn / slip_magnitude;
 	}
 
-	Ft = 0.0f;
-	Fn = 0.0f;
-	s = sqrt(sx*sx+sy*sy);
+	s = sqrtf(sx*sx+sy*sy);
 
 	{
 		// calculate _skid and _reaction for sound.
-		if (v < 2.0f) {
+		if ((v < 2.0f) || (zforce < 0.0002f)) {
 			car->carElt->_skid[index] = 0.0f;
 		} else {
-			car->carElt->_skid[index] =  MIN(1.0f, (s*zforce*0.0002f));
+			car->carElt->_skid[index] =  2.0*s*s; // skid energy :: F*d :: v*v :: s*s
 		}
 	}
 
-	stmp = MIN(s, 1.5f);
-	
 	// MAGIC FORMULA
-	Bx = wheel->mfB * stmp;
-	F = sin(wheel->mfC * atan(Bx * (1.0f - wheel->mfE) + wheel->mfE * atan(Bx))) * (1.0f + stmp * simSkidFactor[car->carElt->_skillLevel]);
+	Bx = wheel->mfB * s;
+	F = sin(wheel->mfC * atan(Bx * (1.0f - wheel->mfE) + wheel->mfE * atan(Bx))) * (1.0f + s * simSkidFactor[car->carElt->_skillLevel]);
 
 	// load sensitivity
 	mu = wheel->mu * (wheel->lfMin + (wheel->lfMax - wheel->lfMin) * exp(wheel->lfK * zforce / wheel->opLoad));
@@ -264,11 +262,10 @@
 	wheel->rollRes = zforce * wheel->trkPos.seg->surface->kRollRes;
     car->carElt->priv.wheel[index].rollRes = wheel->rollRes;
 
-	if (s > 0.000001f) {
-		// wheel axis based
-		Ft -= F * sx / s;
-		Fn -= F * sy / s;
-	}
+	// wheel axis based
+	s = -0.000001f - s; // make Ft, Fn and s negative with stable divide by zero avoidance.
+	Ft = F * sx/s;
+	Fn = F * sy/s;
 
 	RELAXATION2(Fn, wheel->preFn, 50.0f);
 	RELAXATION2(Ft, wheel->preFt, 50.0f);