Re: Patch for wheel spin velocity traction
David Savinkoff <[email protected]> Tue, 1 Mar 2016 17:46:02 -0700 (MST)
| Newsgroups | gmane.games.torcs.general |
|---|---|
| Message-ID | <[email protected]> |
Hi, This patch fixes a performance issue without compromise. Smaller, Faster, and Better sound and driving performance. You can hear which tire is squealing as you drift past another car. Yahoo! ----- David Savinkoff wrote: > OK, > > This patch goes beyond traction; it includes 2 bug fixes > from Speed Dreams. > > Yes, two serious physics impacting bugs. > > Now you can get twice the realism by driving to the > track in one car, and racing at the track in another. > > ----- David Savinkoff wrote: > > Hi, > > This patch implements rolling resistance correctly along > > with some small changes. (wheel.cpp car.cpp) > > > > Massive improvement. The TORCS simuv2 reference > > measure 'is' about to show all car sims 'how it is done'. > > > > ----- David Savinkoff wrote: > > > Hi, > > > > > > Yet another small improvement. Note that if some of these > > > improvements appear odd, they are indicating problems > > > hidden elsewhere. > > > > > > ----- David Savinkoff wrote: > > > > Hi, > > > > This patch will probably be the last I make for > > > > wheel.cpp because I've meticulously examined and > > > > tested the code here repeatedly with results that have > > > > converged to perfection. > > > > > > > > Please apply this patch. > > > > > > > > ----- David Savinkoff wrote: > > > > > This patch removes legacy duct tape which was used as a > > > > > work-around for a previously nonexistent friction circle. > > > > > > > > > > There is another piece of duct tape which impedes the car > > > > > from accelerating forward while allowing unimpeded sideways > > > > > acceleration when drifting. I'll remove that when I find it. > > > > > > > > > This problem seems to be diminished as TORCS is made more > > > > correct. > > > > > > > > > > Note that RELAXATION2 is a low-pass Infinite Impulse Response > > > > > filter of the form: f(s) = (1/as) / (b+1/as) where s is in the s-domain, > > > > > 'a' is a spring-constant, and 'b' is a friction constant > > > > > mechanically acting on the rotation of the wheel. This will > > > > > certainly affect the physics of TORCS. > > > > > > > > > > ----- David Savinkoff wrote: > > > > > > Hi Everybody, > > > > > > > > > > > > This patch makes TORCS the best simulator wherever > > > > > > 'The Rubber meets the Road' is concerned. Try it. > > > > > > > > > > > > ----- David Savinkoff wrote: > > > > > > > ----- David Savinkoff wrote: > > > > > > > > Hi, > > > > > > > > > > > > > > > > In my last patch I had the following code: > > > > > > > > slip_magnitude = 0.3f + 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.3f + 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. > > > > > > > > > > > > > > > > > > > > > ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140 _______________________________________________ Torcs-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/torcs-users
torcs-1.3.6.2016mar01.diff
(text/x-patch, 9.6 KB)
--- torcs-1.3.6/src/modules/graphic/ssggraph/CarSoundData.cpp 2014-02-10 03:16:18.000000000 -0800
+++ torcs-1.3.6/src/modules/graphic/ssggraph/CarSoundData.cpp 2016-03-01 15:55:14.000000000 -0800
@@ -315,29 +315,30 @@
}
+// Calculate road-tire contact noise positions with an efficient formula.
+// note that sin(az) is nearly equal to az [in radians].
+// note that cos(az) is close to 1.0 for moderate yaw angles.
+// note that the contact patch is beneath GC (thus -0.3).
+ tdble az = car->_yaw;
for (i = 0; i<4; i++) {
- tdble az = car->_yaw;
- tdble Sinz = sin(az);
- tdble Cosz = cos(az);
-
tdble x = car->priv.wheel[i].relPos.x;
tdble y = car->priv.wheel[i].relPos.y;
- tdble dx = x * Cosz - y * Sinz;
- tdble dy = x * Sinz + y * Cosz;
+ tdble dx = x - y*az; // x*cos(az) - y*sin(az)
+ tdble dy = x*az + y;
tdble dux = -car->_yaw_rate * y;
tdble duy = car->_yaw_rate * x;
- dux = dux * Cosz - duy * Sinz;
- duy = dux * Sinz + duy * Cosz;
+ dux = dux - duy*az;
+ duy = dux*az + duy;
wheel[i].u[0] = car->pub.DynGCg.vel.x + dux;
wheel[i].u[1] = car->pub.DynGCg.vel.y + duy;
wheel[i].u[2] = car->pub.DynGCg.vel.z;
wheel[i].p[0] = car->pub.DynGCg.pos.x + dx;
wheel[i].p[1] = car->pub.DynGCg.pos.y + dy;
- wheel[i].p[2] = car->pub.DynGCg.pos.z;
+ wheel[i].p[2] = car->pub.DynGCg.pos.z - 0.3f;
}
}
--- torcs-1.3.6/src/modules/simu/simuv2/car.cpp 2014-02-10 02:06:30.000000000 -0800
+++ torcs-1.3.6/src/modules/simu/simuv2/car.cpp 2016-02-19 17:53:01.000000000 -0800
@@ -146,7 +146,6 @@
tdble m, w, minv;
tdble SinTheta;
tdble Cosz, Sinz;
- tdble v, R, Rv, Rm, Rx, Ry;
Cosz = car->Cosz = cos(car->DynGCg.pos.az);
Sinz = car->Sinz = sin(car->DynGCg.pos.az);
@@ -199,41 +198,18 @@
F.M.y -= car->aero.lift[i] * (car->axle[i].xpos - car->statGC.x);
}
- /* Rolling Resistance */
- v = sqrt(car->DynGCg.vel.x * car->DynGCg.vel.x + car->DynGCg.vel.y * car->DynGCg.vel.y);
- R = 0;
- for (i = 0; i < 4; i++) {
- R += car->wheel[i].rollRes;
- }
- if (v > 0.00001) {
- Rv = R / v;
- if ((Rv * minv * SimDeltaTime) > v) {
- Rv = v * m / SimDeltaTime;
- }
- } else {
- Rv = 0;
- }
- Rx = Rv * car->DynGCg.vel.x;
- Ry = Rv * car->DynGCg.vel.y;
-
- if ((R * car->wheelbase / 2.0 * car->Iinv.z) > fabs(car->DynGCg.vel.az)) {
- Rm = car->DynGCg.vel.az / car->Iinv.z;
- } else {
- Rm = SIGN(car->DynGCg.vel.az) * R * car->wheelbase / 2.0;
- }
-
/* compute accelerations */
car->DynGC.acc.x = F.F.x * minv;
car->DynGC.acc.y = F.F.y * minv;
car->DynGC.acc.z = F.F.z * minv;
- car->DynGCg.acc.x = (F.F.x * Cosz - F.F.y * Sinz - Rx) * minv;
- car->DynGCg.acc.y = (F.F.x * Sinz + F.F.y * Cosz - Ry) * minv;
+ car->DynGCg.acc.x = (F.F.x * Cosz - F.F.y * Sinz) * minv;
+ car->DynGCg.acc.y = (F.F.x * Sinz + F.F.y * Cosz) * minv;
car->DynGCg.acc.z = car->DynGC.acc.z;
car->DynGCg.acc.ax = car->DynGC.acc.ax = F.M.x * car->Iinv.x;
car->DynGCg.acc.ay = car->DynGC.acc.ay = F.M.y * car->Iinv.y;
- car->DynGCg.acc.az = car->DynGC.acc.az = (F.M.z - Rm) * car->Iinv.z;
+ car->DynGCg.acc.az = car->DynGC.acc.az = F.M.z * car->Iinv.z;
}
static void
--- torcs-1.3.6/src/modules/simu/simuv2/collide.cpp 2014-04-12 06:55:29.000000000 -0700
+++ torcs-1.3.6/src/modules/simu/simuv2/collide.cpp 2016-02-26 11:36:54.224354425 -0800
@@ -29,6 +29,7 @@
tdble dotProd;
tWheel *wheel;
const float CRASH_THRESHOLD = -5.0f;
+ tdble dz = 0.0f;
if (car->carElt->_state & RM_CAR_STATE_NO_SIMU) {
return;
@@ -36,8 +37,9 @@
for (i = 0; i < 4; i++) {
wheel = &(car->wheel[i]);
- if (wheel->state & SIM_SUSP_COMP) {
- car->DynGCg.pos.z += wheel->susp.spring.packers - wheel->rideHeight;
+ if ( (wheel->state & SIM_SUSP_COMP)&&(!(wheel->state & SIM_WH_ONAIR)) ) {
+ dz = MAX(dz, wheel->susp.spring.packers - wheel->rideHeight);
+ wheel->rideHeight = wheel->susp.spring.packers;
RtTrackSurfaceNormalL(&(wheel->trkPos), &normal);
dotProd = (car->DynGCg.vel.x * normal.x + car->DynGCg.vel.y * normal.y + car->DynGCg.vel.z * normal.z) * wheel->trkPos.seg->surface->kRebound;
if (dotProd < 0.0f) {
@@ -54,6 +56,7 @@
}
}
}
+ car->DynGCg.pos.z += dz; // elevate car when it has slightly impacted into ground. (SD r6312)
}
const tdble BorderFriction = 0.0f;
--- torcs-1.3.6/src/modules/simu/simuv2/susp.cpp 2014-02-09 23:53:35.000000000 -0800
+++ torcs-1.3.6/src/modules/simu/simuv2/susp.cpp 2016-02-26 11:41:37.739789152 -0800
@@ -97,14 +97,14 @@
void SimSuspCheckIn(tSuspension *susp)
{
susp->state = 0;
- if (susp->x < susp->spring.packers) {
+ if (susp->x < susp->spring.packers) { // Tested best with '<'
susp->x = susp->spring.packers;
susp->state = SIM_SUSP_COMP;
}
susp->x *= susp->spring.bellcrank;
- if (susp->x > susp->spring.xMax) {
+ if (susp->x >= susp->spring.xMax) { // Tested OK with '>=' (SD r6020)
susp->x = susp->spring.xMax;
- susp->state = SIM_SUSP_EXT;
+ susp->state = SIM_SUSP_EXT; // susp->state updated also
}
}
--- 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 2016-02-22 12:56:00.000000000 -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;
- tdble s, sa, sx, sy; // slip vector
- tdble stmp, F, Bx;
+ double CosA, SinA;
+ tdble s, sx, sy; // slip vector
+ tdble F, Bx;
tdble mu;
wheel->state = 0;
@@ -215,78 +215,69 @@
// 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);
-
- // slip angle
- if (v < 0.000001f) {
- sa = 0.0f;
- } else {
- sa = atan2(wheel->bodyVel.y, wheel->bodyVel.x) - waz;
- }
- NORM_PI_PI(sa);
+ v = sqrtf(v2);
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.
+ // Softening factor 0.3 added to slip_magnitude affects low velocities and divide by zero.
+ slip_magnitude = 0.3f + 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) {
+ // calculate _skid and _reaction for sound (importantly; affects traction also).
+ if ((v < 0.01f) || (zforce < 0.0002f)) {
car->carElt->_skid[index] = 0.0f;
} else {
- car->carElt->_skid[index] = MIN(1.0f, (s*zforce*0.0002f));
+ // skid energy :: F*d :: v*v :: s*s ... the empirical equation:
+ // n*(s*s + s) is represented in Damped Simple Harmonic Motion
+ car->carElt->_skid[index] = (s*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));
F *= zforce * mu * wheel->trkPos.seg->surface->kFriction * (1.0f + 0.05f * sin(-wheel->staticPos.ax * 18.0f)); /* coeff */
- wheel->rollRes = zforce * wheel->trkPos.seg->surface->kRollRes;
- car->carElt->priv.wheel[index].rollRes = wheel->rollRes;
+ wheel->rollRes = zforce * wheel->trkPos.seg->surface->kRollRes; // TODO: improve rolling resistance formula
- if (s > 0.000001f) {
- // wheel axis based
- Ft -= F * sx / s;
- Fn -= F * sy / s;
- }
+ // wheel axis based
+ s += 0.000001f; // stable divide by zero avoidance.
+ Ft = -(F - wheel->rollRes) * sx/s; // corrected rolling resistance vector component
+ Fn = -F * sy/s;
- RELAXATION2(Fn, wheel->preFn, 50.0f);
- RELAXATION2(Ft, wheel->preFt, 50.0f);
+ wheel->rollRes *= fabs(sx/s); // not used (removed from /src/modules/simu/simuv2/car.cpp)
+ car->carElt->priv.wheel[index].rollRes = wheel->rollRes; // not used in /src/modules/graphic/ssggraph/CarSoundData.cpp
wheel->relPos.az = waz;
wheel->forces.x = Ft * CosA - Fn * SinA;
wheel->forces.y = Ft * SinA + Fn * CosA;
wheel->spinTq = Ft * wheel->radius;
- wheel->sa = sa;
- wheel->sx = sx;
+ wheel->sa = atan2(sy, sx); // atan2(sy, sx) == atan2(sy/s, sx/s)
+ wheel->sx = sx/s;
wheel->feedBack.spinVel = wheel->spinVel;
wheel->feedBack.Tq = wheel->spinTq;
wheel->feedBack.brkTq = wheel->brake.Tq;
+ car->carElt->_wheelSlipSide(index) = vn;
+ car->carElt->_wheelSlipAccel(index) = vt-wrl;
- car->carElt->_wheelSlipSide(index) = sy*v;
- car->carElt->_wheelSlipAccel(index) = sx*v;
car->carElt->_reaction[index] = zforce;
}
@@ -301,8 +292,6 @@
wheel = &(car->wheel[i]);
wheel->spinVel = wheel->in.spinVel;
- RELAXATION2(wheel->spinVel, wheel->prespinVel, 50.0f);
-
wheel->relPos.ay += wheel->spinVel * SimDeltaTime;
NORM_PI_PI(wheel->relPos.ay);
car->carElt->_wheelSpinVel(i) = wheel->spinVel;