Re: Patch for wheel spin velocity traction
David Savinkoff <[email protected]> Fri, 26 Feb 2016 13:00:10 -0700 (MST)
| Newsgroups | gmane.games.torcs.general |
|---|---|
| Message-ID | <[email protected]> |
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.2016feb26.diff
(text/x-patch, 8.4 KB)
diff -ur torcs-1.3.6/src/modules/simu/simuv2/car.cpp torcs-1.3.6/src/modules/simu/simuv2/car.cpp
--- 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
diff -ur torcs-1.3.6/src/modules/simu/simuv2/collide.cpp torcs-1.3.6/src/modules/simu/simuv2/collide.cpp
--- 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;
diff -ur torcs-1.3.6/src/modules/simu/simuv2/susp.cpp torcs-1.3.6/src/modules/simu/simuv2/susp.cpp
--- 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:38:36.342069596 -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
}
}
diff -ur torcs-1.3.6/src/modules/simu/simuv2/wheel.cpp torcs-1.3.6/src/modules/simu/simuv2/wheel.cpp
--- 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;