Patching latest TORCS changes in CVS
David Savinkoff <[email protected]> Sat, 25 Feb 2017 01:52:16 -0700 (MST)
| Newsgroups | gmane.games.torcs.general |
|---|---|
| Message-ID | <316074698.53138712.1488012736232.JavaMail.zimbra@mailid.telus.net> |
Here is a patch to play with. Correctly combined longitudinal, lateral, and yaw tire friction forces. (realistic and predictable vehicular response where the rubber meets the road) ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Torcs-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/torcs-users
torcs-1.3.8.contact.patch
(text/x-patch, 12.6 KB)
--- torcs/src/modules/graphic/ssggraph/CarSoundData.cpp 2014-02-10 03:16:18.000000000 -0800
+++ torcs/src/modules/graphic/ssggraph/CarSoundData.cpp 2017-02-24 20:37:21.212075558 -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 (approx -0.3 metres).
+ 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/src/modules/graphic/ssggraph/grskidmarks.cpp 2014-02-10 03:09:36.000000000 -0800
+++ torcs/src/modules/graphic/ssggraph/grskidmarks.cpp 2017-02-24 20:37:21.213075570 -0800
@@ -199,11 +199,7 @@
}
}
- if (car->_skid[i] > 0.1f) {
- cur_clr[3] = tanh(skid_sensitivity*car->_skid[i]);
- } else {
- cur_clr[3] = 0.0f;
- }
+ cur_clr[3] = skid_sensitivity*car->_skid[i]; // linear (tanh removed, see wheel.cpp)
for (int c = 0; c < 3; c++) {
tdble tmp = grCarInfo[car->index].skidmarks->strips[i].smooth_colour[c];
@@ -216,7 +212,7 @@
}
if (car->pub.speed > 1.0f) {
- if (cur_clr[3] > 0.1f) {
+ if (cur_clr[3] > 0.1f) { // 0.06 works better than 0.1 // something here improves traction ?!
basevtx = new ssgVertexArray(4 * 2 + 1);
tdble sling_left = 0.0f;
--- torcs/src/modules/simu/simuv2/car.cpp 2017-02-12 09:45:57.000000000 -0800
+++ torcs/src/modules/simu/simuv2/car.cpp 2017-02-24 20:37:21.214075587 -0800
@@ -64,7 +64,7 @@
}
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.y = 12.0 / (car->mass * (k * 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));
/* configure components */
@@ -145,10 +145,7 @@
tForces F;
int i;
tdble m, w, minv;
- tdble v, R, Rv, Rm, Rx, Ry, Rz;
- car->preDynGC = car->DynGCg;
-
/* total mass */
m = car->mass + car->fuel;
minv = 1.0 / m;
@@ -200,34 +197,10 @@
F.M.y -= car->aero.lift[i] * (car->axle[i].xpos - car->statGC.x);
}
- /* Rolling Resistance */
- v = car->speed;
- R = 0.0f;
- for (i = 0; i < 4; i++) {
- R += car->wheel[i].rollRes;
- }
- if (v > 0.00001f) {
- Rv = R / v;
- if ((Rv * minv * SimDeltaTime) > v) {
- Rv = v * m / SimDeltaTime;
- }
- } else {
- Rv = 0.0f;
- }
- Rx = Rv * car->DynGC.vel.x;
- Ry = Rv * car->DynGC.vel.y;
- Rz = Rv * car->DynGC.vel.z;
-
- 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 - Rx) * minv;
- car->DynGC.acc.y = (F.F.y - Ry) * minv;
- car->DynGC.acc.z = (F.F.z - Rz) * minv;
+ car->DynGC.acc.x = F.F.x * minv;
+ car->DynGC.acc.y = F.F.y * minv;
+ car->DynGC.acc.z = F.F.z * minv;
sgVec3 accel = {car->DynGC.acc.x, car->DynGC.acc.y, car->DynGC.acc.z};
sgXformVec3(accel, dst);
@@ -238,7 +211,7 @@
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; // += see torcs/src/modules/simu/simuv2/simu.cpp :: SimUpdate()
}
static void
@@ -256,7 +229,15 @@
if (fabs(car->DynGCg.vel.az) > 9.0) {
car->DynGCg.vel.az = SIGN(car->DynGCg.vel.az) * 9.0;
}
-
+
+ /* FIXME: Hack to stop stationary car from rotating */
+ if (( car->DynGCg.vel.x*car->DynGCg.vel.x +
+ car->DynGCg.vel.y*car->DynGCg.vel.y +
+ car->DynGCg.vel.z*car->DynGCg.vel.z) < 0.01f )
+ {
+ car->DynGCg.vel.ax = car->DynGCg.vel.ay = car->DynGCg.vel.az = 0.0f;
+ }
+
car->DynGC.vel.ax = car->DynGCg.vel.ax;
car->DynGC.vel.ay = car->DynGCg.vel.ay;
car->DynGC.vel.az = car->DynGCg.vel.az;
--- torcs/src/modules/simu/simuv2/simu.cpp 2017-02-19 05:09:00.000000000 -0800
+++ torcs/src/modules/simu/simuv2/simu.cpp 2017-02-24 20:37:21.215075600 -0800
@@ -385,6 +385,7 @@
SimAxleUpdate(car, i);
}
CHECK(car);
+ car->DynGC.acc.az = 0.0f; // see torcs/src/modules/simu/simuv2/wheel.cpp :: SimWheelUpdateForce()
for (i = 0; i < 4; i++){
SimWheelUpdateForce(car, i);
SimWheelUpdateTire(car, i);
--- torcs/src/modules/simu/simuv2/susp.cpp 2017-01-15 04:52:16.000000000 -0800
+++ torcs/src/modules/simu/simuv2/susp.cpp 2017-02-24 20:37:21.216075618 -0800
@@ -107,9 +107,9 @@
}
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/src/modules/simu/simuv2/wheel.cpp 2017-02-13 15:51:07.000000000 -0800
+++ torcs/src/modules/simu/simuv2/wheel.cpp 2017-02-24 20:37:21.217075619 -0800
@@ -47,9 +47,9 @@
Ca = GfParmGetNum(hdle, WheelSect[index], PRM_CA, (char*)NULL, 30.0f);
RFactor = GfParmGetNum(hdle, WheelSect[index], PRM_RFACTOR, (char*)NULL, 0.8f);
EFactor = GfParmGetNum(hdle, WheelSect[index], PRM_EFACTOR, (char*)NULL, 0.7f);
- wheel->lfMax = GfParmGetNum(hdle, WheelSect[index], PRM_LOADFMAX, (char*)NULL, 1.6f);
- wheel->lfMin = GfParmGetNum(hdle, WheelSect[index], PRM_LOADFMIN, (char*)NULL, 0.8f);
- wheel->opLoad = GfParmGetNum(hdle, WheelSect[index], PRM_OPLOAD, (char*)NULL, wheel->weight0 * 1.2f);
+ wheel->lfMax = GfParmGetNum(hdle, WheelSect[index], PRM_LOADFMAX, (char*)NULL, 1.4f);
+ wheel->lfMin = GfParmGetNum(hdle, WheelSect[index], PRM_LOADFMIN, (char*)NULL, 1.0f);
+ wheel->opLoad = GfParmGetNum(hdle, WheelSect[index], PRM_OPLOAD, (char*)NULL, wheel->weight0 * 1.618f);
wheel->mass = GfParmGetNum(hdle, WheelSect[index], PRM_MASS, (char*)NULL, 20.0f);
wheel->lfMin = MIN(0.8f, wheel->lfMin);
@@ -213,12 +213,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 = 0.000000f; // 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, saz; // slip vector
+ tdble F, Bx;
tdble mu;
wheel->state = 0;
@@ -248,44 +248,45 @@
}
// HORIZONTAL FORCES
- waz = wheel->steer + wheel->staticPos.az;
+ waz = wheel->steer + wheel->staticPos.az - (SimDeltaTime*car->DynGC.vel.az /* account for yaw induced wheel direction */);
CosA = cos(waz);
SinA = sin(waz);
// 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) {
- sa = 0.0f;
- } else {
- sa = atan2(wheel->bodyVel.y, wheel->bodyVel.x) - waz;
+ wrl = wheel->spinVel * wheel->radius;
+
+ if (fabsf(vt - wrl) <= 0.1f) { // Adds numerical stability by catching adhesion
+ vt = wrl;
}
- 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;
+ sx = sy = saz = 0.0f;
} else {
- sx = (vt - wrl) / fabs(vt);
- sy = sin(sa);
+ // COMBINED LONGITUDINAL, LATERAL, and YAWING TIRE SLIP FORCES:
+ // 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.
+ // saz slip speed accounts for rotating the contact patch (yaw). * add steering speed and self aligning torque.
+ saz = (1.1f*3.1416f) * car->DynGC.vel.az * car->carElt->_tireWidth(index); // yaw slip speed.
+ slip_magnitude = 0.000001f + /* Softening factor 0.000001 prevents divide by zero */
+ sqrt( MAX(MAX((v2 + saz*saz), (vn*vn + wrl*wrl + saz*saz)), (vn*vn + (vt - wrl)*(vt - wrl) + saz*saz)) );
+ sx = (vt - wrl) / slip_magnitude;
+ sy = vn / slip_magnitude;
+ saz /= slip_magnitude;
}
-
- Ft = 0.0f;
- Fn = 0.0f;
- s = sqrt(sx*sx+sy*sy);
+
+ s = sqrtf(sx*sx+sy*sy+saz*saz);
{
- // calculate _skid and _reaction for sound.
- if (v < 2.0f) {
+ // calculate _skid and _reaction for sound (suspiciously; affects traction also).
+ if ((v < 0.01f) || (zforce < 0.002f)) {
car->carElt->_skid[index] = 0.0f;
} else {
- car->carElt->_skid[index] = MIN(1.0f, (s*zforce*0.0002f));
+ car->carElt->_skid[index] = s; // linear (tanh removed in grskidmarks.cpp)
}
}
@@ -299,47 +300,48 @@
camberDelta = casterCamber;
}
- 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]);
+ // MAGIC FORMULA // Note: F = sin(...) below returns normalized force!
+ 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 + camberDelta) * 18.0f)); /* coeff */
F *= wheel->currentGripFactor;
-
+
wheel->rollRes = zforce * wheel->trkPos.seg->surface->kRollRes;
- car->carElt->priv.wheel[index].rollRes = wheel->rollRes;
+ // wheel axis based
+ s += 0.000001f; // add 0.000001 to avoid divide by zero later.
+ Ft = -(F - wheel->rollRes) * sx/s; // rolling resistance is the rolling vector component only.
+ Fn = -F * sy/s;
- if (s > 0.000001f) {
- // wheel axis based
- Ft -= F * sx / s;
- Fn -= F * sy / s;
- }
+ car->DynGC.acc.az += -F * saz/s * SimDeltaTime * car->Iinv.z; // see torcs/src/modules/simu/simuv2/simu.cpp :: SimUpdate()
- RELAXATION2(Fn, wheel->preFn, 50.0f);
- RELAXATION2(Ft, wheel->preFt, 50.0f);
+ wheel->rollRes *= fabsf(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
+
+ waz = wheel->steer + wheel->staticPos.az; /* don't include yaw induced wheel direction here */
+ CosA = cos(waz);
+ SinA = sin(waz);
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->sa = atan2(wheel->bodyVel.y, wheel->bodyVel.x) - waz;
wheel->sx = sx;
wheel->tireZForce = zforce;
- wheel->tireSlip = stmp;
+ wheel->tireSlip = s;
wheel->feedBack.spinVel = wheel->spinVel;
wheel->feedBack.Tq = wheel->spinTq;
wheel->feedBack.brkTq = wheel->brake.Tq;
- car->carElt->_wheelSlipSide(index) = sy*v;
- car->carElt->_wheelSlipAccel(index) = sx*v;
+ car->carElt->_wheelSlipSide(index) = vn;
+ car->carElt->_wheelSlipAccel(index) = vt*(1.0f-sx); // Is wheelSlipAccel the wheel tangent velocity times adhesion ?
car->carElt->_reaction[index] = zforce;
}
@@ -354,8 +356,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;