reformat simu4 and simu4.1 to match simu5 so you can see the actual diffences between them
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@9318 30fe4595-0a0c-4342-8851-515496e4dcbd
This commit is contained in:
parent
8579c811a6
commit
6dc546b74d
|
@ -94,6 +94,7 @@ SimAeroConfig(tCar *car)
|
||||||
|
|
||||||
float max_lift = MaximumLiftGivenDrag (0.5f * rho * Cx * FrntArea, FrntArea);
|
float max_lift = MaximumLiftGivenDrag (0.5f * rho * Cx * FrntArea, FrntArea);
|
||||||
float current_lift = 2.0f * (car->aero.Clift[0] + car->aero.Clift[1]);
|
float current_lift = 2.0f * (car->aero.Clift[0] + car->aero.Clift[1]);
|
||||||
|
|
||||||
if (current_lift > max_lift)
|
if (current_lift > max_lift)
|
||||||
{
|
{
|
||||||
if (car->features & FEAT_LIMITEDGROUNDEFFECT)
|
if (car->features & FEAT_LIMITEDGROUNDEFFECT)
|
||||||
|
@ -152,36 +153,49 @@ SimAeroUpdate(tCar *car, tSituation *s)
|
||||||
airSpeed = car->DynGC.vel.x;
|
airSpeed = car->DynGC.vel.x;
|
||||||
spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);
|
spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);
|
||||||
|
|
||||||
if (airSpeed > 10.0) {
|
if (airSpeed > 10.0)
|
||||||
for (i = 0; i < s->_ncars; i++) {
|
{
|
||||||
if (i == car->carElt->index) {
|
for (i = 0; i < s->_ncars; i++)
|
||||||
|
{
|
||||||
|
if (i == car->carElt->index)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
otherCar = &(SimCarTable[i]);
|
otherCar = &(SimCarTable[i]);
|
||||||
otherYaw = otherCar->DynGCg.pos.az;
|
otherYaw = otherCar->DynGCg.pos.az;
|
||||||
tmpsdpang = spdang - atan2(y - otherCar->DynGCg.pos.y, x - otherCar->DynGCg.pos.x);
|
tmpsdpang = spdang - atan2(y - otherCar->DynGCg.pos.y, x - otherCar->DynGCg.pos.x);
|
||||||
FLOAT_NORM_PI_PI(tmpsdpang);
|
FLOAT_NORM_PI_PI(tmpsdpang);
|
||||||
dyaw = yaw - otherYaw;
|
dyaw = yaw - otherYaw;
|
||||||
FLOAT_NORM_PI_PI(dyaw);
|
FLOAT_NORM_PI_PI(dyaw);
|
||||||
|
|
||||||
if ((otherCar->DynGC.vel.x > 10.0) &&
|
if ((otherCar->DynGC.vel.x > 10.0) &&
|
||||||
(fabs(dyaw) < 0.1396)) {
|
(fabs(dyaw) < 0.1396))
|
||||||
if (fabs(tmpsdpang) > 2.9671) { /* 10 degrees */
|
{
|
||||||
|
if (fabs(tmpsdpang) > 2.9671)
|
||||||
|
{ /* 10 degrees */
|
||||||
/* behind another car */
|
/* behind another car */
|
||||||
tmpas = (tdble) (1.0 - exp(- 2.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) /
|
tmpas = (tdble) (1.0 - exp(- 2.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) /
|
||||||
(otherCar->aero.Cd * otherCar->DynGC.vel.x)));
|
(otherCar->aero.Cd * otherCar->DynGC.vel.x)));
|
||||||
if (tmpas < dragK) {
|
if (tmpas < dragK)
|
||||||
|
{
|
||||||
dragK = tmpas;
|
dragK = tmpas;
|
||||||
}
|
}
|
||||||
} else if (fabs(tmpsdpang) < 0.1396) { /* 8 degrees */
|
}
|
||||||
|
else if (fabs(tmpsdpang) < 0.1396)
|
||||||
|
{ /* 8 degrees */
|
||||||
/* before another car [not sure how much the drag should be reduced in this case. In no case it should be lowered more than 50% I think. - Christos] */
|
/* before another car [not sure how much the drag should be reduced in this case. In no case it should be lowered more than 50% I think. - Christos] */
|
||||||
tmpas = (tdble) (1.0 - 0.5f * exp(- 8.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) / (car->aero.Cd * car->DynGC.vel.x)));
|
tmpas = (tdble) (1.0 - 0.5f * exp(- 8.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) / (car->aero.Cd * car->DynGC.vel.x)));
|
||||||
if (tmpas < dragK) {
|
|
||||||
|
if (tmpas < dragK)
|
||||||
|
{
|
||||||
dragK = tmpas;
|
dragK = tmpas;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
car->airSpeed2 = airSpeed * airSpeed;
|
car->airSpeed2 = airSpeed * airSpeed;
|
||||||
tdble v2 = car->airSpeed2;
|
tdble v2 = car->airSpeed2;
|
||||||
|
|
||||||
|
@ -339,8 +353,11 @@ SimWingConfig(tCar *car, int index)
|
||||||
}
|
}
|
||||||
else if (wing->WingType == 2)
|
else if (wing->WingType == 2)
|
||||||
{
|
{
|
||||||
if (wing->AR > 0.001) wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
|
if (wing->AR > 0.001)
|
||||||
else wing->Kz1 = (tdble)(2 * PI);
|
wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
|
||||||
|
else
|
||||||
|
wing->Kz1 = (tdble)(2 * PI);
|
||||||
|
|
||||||
wing->Kx = (tdble) (0.5 * rho * area);
|
wing->Kx = (tdble) (0.5 * rho * area);
|
||||||
wing->Kz2 = 1.05f;
|
wing->Kz2 = 1.05f;
|
||||||
wing->Kz3 = 0.05f;
|
wing->Kz3 = 0.05f;
|
||||||
|
@ -357,18 +374,24 @@ SimWingReConfig(tCar *car, int index)
|
||||||
tWing *wing = &(car->wing[index]);
|
tWing *wing = &(car->wing[index]);
|
||||||
tCarSetupItem *angle = &(car->carElt->setup.wingAngle[index]);
|
tCarSetupItem *angle = &(car->carElt->setup.wingAngle[index]);
|
||||||
|
|
||||||
if (angle->changed) {
|
if (angle->changed)
|
||||||
|
{
|
||||||
wing->angle = MIN(angle->max,MAX(angle->min,angle->desired_value));
|
wing->angle = MIN(angle->max,MAX(angle->min,angle->desired_value));
|
||||||
angle->value = wing->angle;
|
angle->value = wing->angle;
|
||||||
|
|
||||||
if (wing->WingType == 0) {
|
if (wing->WingType == 0)
|
||||||
if (index==1) {
|
{
|
||||||
|
if (index==1)
|
||||||
|
{
|
||||||
car->aero.Cd = car->aero.CdBody - wing->Kx*sin(wing->angle);
|
car->aero.Cd = car->aero.CdBody - wing->Kx*sin(wing->angle);
|
||||||
}
|
}
|
||||||
} else if (wing->WingType == 1) {
|
}
|
||||||
|
else if (wing->WingType == 1)
|
||||||
|
{
|
||||||
tWing *otherwing = &(car->wing[1-index]);
|
tWing *otherwing = &(car->wing[1-index]);
|
||||||
car->aero.Cd = (tdble)(car->aero.CdBody - wing->Kx*sin(wing->angle - wing->AoAatZRad) - otherwing->Kx*sin(otherwing->angle - otherwing->AoAatZRad));
|
car->aero.Cd = (tdble)(car->aero.CdBody - wing->Kx*sin(wing->angle - wing->AoAatZRad) - otherwing->Kx*sin(otherwing->angle - otherwing->AoAatZRad));
|
||||||
}
|
}
|
||||||
|
|
||||||
angle->changed = false;
|
angle->changed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,12 +402,14 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
tWing *wing = &(car->wing[index]);
|
tWing *wing = &(car->wing[index]);
|
||||||
|
|
||||||
/* return with 0 if no wing present */
|
/* return with 0 if no wing present */
|
||||||
if (wing->WingType == -1) {
|
if (wing->WingType == -1)
|
||||||
|
{
|
||||||
wing->forces.x = wing->forces.z = 0.0f;
|
wing->forces.x = wing->forces.z = 0.0f;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == 1) {
|
if (index == 1)
|
||||||
|
{
|
||||||
// Check wing angle controller
|
// Check wing angle controller
|
||||||
if (car->ctrl->wingControlMode == 2)
|
if (car->ctrl->wingControlMode == 2)
|
||||||
// Update wing angle
|
// Update wing angle
|
||||||
|
@ -424,8 +449,11 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
}
|
}
|
||||||
else if (aoa > 0)
|
else if (aoa > 0)
|
||||||
{
|
{
|
||||||
if (aoa < wing->AoStall) wing->forces.x = wing->Kx1 * aoa * aoa + wing->Kx2;
|
if (aoa < wing->AoStall)
|
||||||
else wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
wing->forces.x = wing->Kx1 * aoa * aoa + wing->Kx2;
|
||||||
|
else
|
||||||
|
wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
||||||
|
|
||||||
if (aoa < wing->AoStall - wing->Stallw)
|
if (aoa < wing->AoStall - wing->Stallw)
|
||||||
{x = (tdble)0.0;}
|
{x = (tdble)0.0;}
|
||||||
else
|
else
|
||||||
|
@ -433,12 +461,16 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
x = aoa - wing->AoStall + wing->Stallw;
|
x = aoa - wing->AoStall + wing->Stallw;
|
||||||
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
||||||
}
|
}
|
||||||
|
|
||||||
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) + wing->Kz3);
|
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) + wing->Kz3);
|
||||||
}
|
}
|
||||||
else if (aoa > -PI_2)
|
else if (aoa > -PI_2)
|
||||||
{
|
{
|
||||||
if (aoa > -wing->AoStall) wing->forces.x = wing->Kx1 * aoa * aoa + wing->Kx2;
|
if (aoa > -wing->AoStall)
|
||||||
else wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
wing->forces.x = wing->Kx1 * aoa * aoa + wing->Kx2;
|
||||||
|
else
|
||||||
|
wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
||||||
|
|
||||||
if (aoa > -wing->AoStall + wing->Stallw)
|
if (aoa > -wing->AoStall + wing->Stallw)
|
||||||
{x = (tdble)0.0;}
|
{x = (tdble)0.0;}
|
||||||
else
|
else
|
||||||
|
@ -446,12 +478,16 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
x = aoa + wing->AoStall - wing->Stallw;
|
x = aoa + wing->AoStall - wing->Stallw;
|
||||||
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
||||||
}
|
}
|
||||||
|
|
||||||
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3);
|
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (aoa < wing->AoStall - PI) wing->forces.x = (tdble) (wing->Kx1 * (PI + aoa) * (PI + aoa) + wing->Kx2);
|
if (aoa < wing->AoStall - PI)
|
||||||
else wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
wing->forces.x = (tdble) (wing->Kx1 * (PI + aoa) * (PI + aoa) + wing->Kx2);
|
||||||
|
else
|
||||||
|
wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
||||||
|
|
||||||
if (aoa < wing->AoStall - wing->Stallw - PI)
|
if (aoa < wing->AoStall - wing->Stallw - PI)
|
||||||
{x = (tdble)0.0;}
|
{x = (tdble)0.0;}
|
||||||
else
|
else
|
||||||
|
@ -459,6 +495,7 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
x = (tdble) (aoa - wing->AoStall + wing->Stallw + PI);
|
x = (tdble) (aoa - wing->AoStall + wing->Stallw + PI);
|
||||||
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
||||||
}
|
}
|
||||||
|
|
||||||
wing->forces.z = (tdble) (-(1-x) * wing->Kz1 * (aoa + wing->AoAatZero + PI) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3));
|
wing->forces.z = (tdble) (-(1-x) * wing->Kz1 * (aoa + wing->AoAatZero + PI) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +504,8 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
{
|
{
|
||||||
if (wing->forces.x > 0.0)
|
if (wing->forces.x > 0.0)
|
||||||
wing->forces.x += (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274)); //0.9*PI
|
wing->forces.x += (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274)); //0.9*PI
|
||||||
else wing->forces.x -= (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274));
|
else
|
||||||
|
wing->forces.x -= (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* then multiply with 0.5*rho*area and the square of velocity */
|
/* then multiply with 0.5*rho*area and the square of velocity */
|
||||||
|
@ -513,4 +551,3 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
else
|
else
|
||||||
wing->forces.x = wing->forces.z = 0.0f;
|
wing->forces.x = wing->forces.z = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
* *
|
* *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
@ -61,6 +59,7 @@ SimCarConfig(tCar *car)
|
||||||
car->TCL_SlipScale = 1.0f;
|
car->TCL_SlipScale = 1.0f;
|
||||||
car->ABS_SlipScale = 0.1f;
|
car->ABS_SlipScale = 0.1f;
|
||||||
car->ABS_BrakeScale = 1.0f;
|
car->ABS_BrakeScale = 1.0f;
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_AEROTOCG, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_AEROTOCG, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0)
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
{
|
{
|
||||||
|
@ -98,27 +97,32 @@ SimCarConfig(tCar *car)
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_FIXEDWHEELFORCE, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_FIXEDWHEELFORCE, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_FIXEDWHEELFORCE;
|
car->features = car->features | FEAT_FIXEDWHEELFORCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_TCLINSIMU, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_TCLINSIMU, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_TCLINSIMU;
|
car->features = car->features | FEAT_TCLINSIMU;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_ABSINSIMU, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_ABSINSIMU, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_ABSINSIMU;
|
car->features = car->features | FEAT_ABSINSIMU;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_ESPINSIMU, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_ESPINSIMU, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_ESPINSIMU;
|
car->features = car->features | FEAT_ESPINSIMU;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_LIMITEDGROUNDEFFECT, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_LIMITEDGROUNDEFFECT, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_LIMITEDGROUNDEFFECT;
|
car->features = car->features | FEAT_LIMITEDGROUNDEFFECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +193,9 @@ SimCarConfig(tCar *car)
|
||||||
/* configure components */
|
/* configure components */
|
||||||
tCarSetupItem *setupSpring;
|
tCarSetupItem *setupSpring;
|
||||||
tdble K[4], Kfheave, Krheave;
|
tdble K[4], Kfheave, Krheave;
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
setupSpring = &(car->carElt->setup.suspSpring[i]);
|
setupSpring = &(car->carElt->setup.suspSpring[i]);
|
||||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
||||||
GfParmGetNumWithLimits(hdle, SuspSect[i], PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
GfParmGetNumWithLimits(hdle, SuspSect[i], PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
||||||
|
@ -197,6 +203,7 @@ SimCarConfig(tCar *car)
|
||||||
setupSpring->stepsize = 1000;
|
setupSpring->stepsize = 1000;
|
||||||
K[i] = setupSpring->desired_value;
|
K[i] = setupSpring->desired_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
setupSpring = &(car->carElt->setup.heaveSpring[0]);
|
setupSpring = &(car->carElt->setup.heaveSpring[0]);
|
||||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
||||||
GfParmGetNumWithLimits(hdle, SECT_FRNTHEAVE, PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
GfParmGetNumWithLimits(hdle, SECT_FRNTHEAVE, PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
||||||
|
@ -224,11 +231,13 @@ SimCarConfig(tCar *car)
|
||||||
car->wheel[REAR_RGT].weight0 = wr0 * gcrl * K[REAR_RGT] / (K[REAR_RGT] + 0.5f*Krheave);
|
car->wheel[REAR_RGT].weight0 = wr0 * gcrl * K[REAR_RGT] / (K[REAR_RGT] + 0.5f*Krheave);
|
||||||
car->wheel[REAR_LFT].weight0 = wr0 * (1 - gcrl) * K[REAR_LFT] / (K[REAR_LFT] + 0.5f*Krheave);
|
car->wheel[REAR_LFT].weight0 = wr0 * (1 - gcrl) * K[REAR_LFT] / (K[REAR_LFT] + 0.5f*Krheave);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
SimAxleConfig(car, i);
|
SimAxleConfig(car, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
SimWheelConfig(car, i);
|
SimWheelConfig(car, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +246,9 @@ SimCarConfig(tCar *car)
|
||||||
SimSteerConfig(car);
|
SimSteerConfig(car);
|
||||||
SimBrakeSystemConfig(car);
|
SimBrakeSystemConfig(car);
|
||||||
SimAeroConfig(car);
|
SimAeroConfig(car);
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
SimWingConfig(car, i);
|
SimWingConfig(car, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,11 +262,13 @@ SimCarConfig(tCar *car)
|
||||||
carElt->_dimension = car->dimension;
|
carElt->_dimension = car->dimension;
|
||||||
carElt->_statGC = car->statGC;
|
carElt->_statGC = car->statGC;
|
||||||
carElt->_tank = car->tank;
|
carElt->_tank = car->tank;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
carElt->priv.wheel[i].relPos = car->wheel[i].relPos;
|
carElt->priv.wheel[i].relPos = car->wheel[i].relPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
car->wheel[i].staticPos.x -= car->statGC.x;
|
car->wheel[i].staticPos.x -= car->statGC.x;
|
||||||
car->wheel[i].staticPos.y -= car->statGC.y;
|
car->wheel[i].staticPos.y -= car->statGC.y;
|
||||||
}
|
}
|
||||||
|
@ -286,8 +299,10 @@ SimCarConfig(tCar *car)
|
||||||
car->corner[REAR_LFT].pos.z = 0;
|
car->corner[REAR_LFT].pos.z = 0;
|
||||||
|
|
||||||
/* set wing positions */
|
/* set wing positions */
|
||||||
if (car->features & FEAT_AEROTOCG) {
|
if (car->features & FEAT_AEROTOCG)
|
||||||
for (i = 0; i < 2; i++) {
|
{
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
car->wing[i].staticPos.x -= car->statGC.x;
|
car->wing[i].staticPos.x -= car->statGC.x;
|
||||||
car->wing[i].staticPos.y -= car->statGC.y;
|
car->wing[i].staticPos.y -= car->statGC.y;
|
||||||
car->wing[i].staticPos.z -= car->statGC.z;
|
car->wing[i].staticPos.z -= car->statGC.z;
|
||||||
|
@ -305,7 +320,9 @@ SimCarConfig(tCar *car)
|
||||||
priv->dashboardInstant[i].type = DI_NONE;
|
priv->dashboardInstant[i].type = DI_NONE;
|
||||||
priv->dashboardInstant[i].setup = NULL;
|
priv->dashboardInstant[i].setup = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (setup->brakeRepartition.min != setup->brakeRepartition.max)
|
if (setup->brakeRepartition.min != setup->brakeRepartition.max)
|
||||||
{
|
{
|
||||||
priv->dashboardInstant[i].type = DI_BRAKE_REPARTITION;
|
priv->dashboardInstant[i].type = DI_BRAKE_REPARTITION;
|
||||||
|
|
|
@ -29,12 +29,12 @@ SimEngineConfig(tCar *car)
|
||||||
char idx[64];
|
char idx[64];
|
||||||
tEngineCurveElem *data;
|
tEngineCurveElem *data;
|
||||||
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
||||||
struct tEdesc {
|
struct tEdesc
|
||||||
|
{
|
||||||
tdble rpm;
|
tdble rpm;
|
||||||
tdble tq;
|
tdble tq;
|
||||||
} *edesc;
|
} *edesc;
|
||||||
|
|
||||||
|
|
||||||
setupRevLimit->desired_value = setupRevLimit->min = setupRevLimit->max = 800;
|
setupRevLimit->desired_value = setupRevLimit->min = setupRevLimit->max = 800;
|
||||||
GfParmGetNumWithLimits(hdle, SECT_ENGINE, PRM_REVSLIM, (char*)NULL, &(setupRevLimit->desired_value), &(setupRevLimit->min), &(setupRevLimit->max));
|
GfParmGetNumWithLimits(hdle, SECT_ENGINE, PRM_REVSLIM, (char*)NULL, &(setupRevLimit->desired_value), &(setupRevLimit->min), &(setupRevLimit->max));
|
||||||
setupRevLimit->changed = true;
|
setupRevLimit->changed = true;
|
||||||
|
@ -59,7 +59,7 @@ SimEngineConfig(tCar *car)
|
||||||
{
|
{
|
||||||
car->engine.TCL = 1.0f;
|
car->engine.TCL = 1.0f;
|
||||||
car->engine.EnableTCL = GfParmGetNum(hdle, SECT_ENGINE, PRM_TCLINSIMU, (char*)NULL, 0.0f) > 0;
|
car->engine.EnableTCL = GfParmGetNum(hdle, SECT_ENGINE, PRM_TCLINSIMU, (char*)NULL, 0.0f) > 0;
|
||||||
/*
|
/*
|
||||||
if (car->engine.EnableTCL)
|
if (car->engine.EnableTCL)
|
||||||
fprintf(stderr,"TCL: Enabled\n");
|
fprintf(stderr,"TCL: Enabled\n");
|
||||||
else
|
else
|
||||||
|
@ -72,12 +72,15 @@ SimEngineConfig(tCar *car)
|
||||||
car->engine.curve.nbPts = GfParmGetEltNb(hdle, idx);
|
car->engine.curve.nbPts = GfParmGetEltNb(hdle, idx);
|
||||||
edesc = (struct tEdesc*)malloc((car->engine.curve.nbPts + 1) * sizeof(struct tEdesc));
|
edesc = (struct tEdesc*)malloc((car->engine.curve.nbPts + 1) * sizeof(struct tEdesc));
|
||||||
|
|
||||||
for (i = 0; i < car->engine.curve.nbPts; i++) {
|
for (i = 0; i < car->engine.curve.nbPts; i++)
|
||||||
|
{
|
||||||
sprintf(idx, "%s/%s/%d", SECT_ENGINE, ARR_DATAPTS, i+1);
|
sprintf(idx, "%s/%s/%d", SECT_ENGINE, ARR_DATAPTS, i+1);
|
||||||
edesc[i].rpm = GfParmGetNum(hdle, idx, PRM_RPM, (char*)NULL, car->engine.revsMax);
|
edesc[i].rpm = GfParmGetNum(hdle, idx, PRM_RPM, (char*)NULL, car->engine.revsMax);
|
||||||
edesc[i].tq = GfParmGetNum(hdle, idx, PRM_TQ, (char*)NULL, 0);
|
edesc[i].tq = GfParmGetNum(hdle, idx, PRM_TQ, (char*)NULL, 0);
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
edesc[i].rpm = edesc[i - 1].rpm;
|
edesc[i].rpm = edesc[i - 1].rpm;
|
||||||
edesc[i].tq = edesc[i - 1].tq;
|
edesc[i].tq = edesc[i - 1].tq;
|
||||||
}
|
}
|
||||||
|
@ -85,19 +88,25 @@ SimEngineConfig(tCar *car)
|
||||||
maxTq = 0;
|
maxTq = 0;
|
||||||
car->engine.curve.maxPw = 0;
|
car->engine.curve.maxPw = 0;
|
||||||
car->engine.curve.data = (tEngineCurveElem *)malloc(car->engine.curve.nbPts * sizeof(tEngineCurveElem));
|
car->engine.curve.data = (tEngineCurveElem *)malloc(car->engine.curve.nbPts * sizeof(tEngineCurveElem));
|
||||||
for(i = 0; i < car->engine.curve.nbPts; i++) {
|
|
||||||
|
for(i = 0; i < car->engine.curve.nbPts; i++)
|
||||||
|
{
|
||||||
data = &(car->engine.curve.data[i]);
|
data = &(car->engine.curve.data[i]);
|
||||||
|
|
||||||
data->rads = edesc[i+1].rpm;
|
data->rads = edesc[i+1].rpm;
|
||||||
|
|
||||||
if ((data->rads>=car->engine.tickover)
|
if ((data->rads>=car->engine.tickover)
|
||||||
&& (edesc[i+1].tq > maxTq)
|
&& (edesc[i+1].tq > maxTq)
|
||||||
&& (data->rads < car->engine.revsLimiter)) {
|
&& (data->rads < car->engine.revsLimiter))
|
||||||
|
{
|
||||||
maxTq = edesc[i+1].tq;
|
maxTq = edesc[i+1].tq;
|
||||||
rpmMaxTq = data->rads;
|
rpmMaxTq = data->rads;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((data->rads>=car->engine.tickover)
|
if ((data->rads>=car->engine.tickover)
|
||||||
&& (data->rads * edesc[i+1].tq > car->engine.curve.maxPw)
|
&& (data->rads * edesc[i+1].tq > car->engine.curve.maxPw)
|
||||||
&& (data->rads < car->engine.revsLimiter)) {
|
&& (data->rads < car->engine.revsLimiter))
|
||||||
|
{
|
||||||
car->engine.curve.TqAtMaxPw = edesc[i+1].tq;
|
car->engine.curve.TqAtMaxPw = edesc[i+1].tq;
|
||||||
car->engine.curve.maxPw = data->rads * edesc[i+1].tq;
|
car->engine.curve.maxPw = data->rads * edesc[i+1].tq;
|
||||||
car->engine.curve.rpmMaxPw = data->rads;
|
car->engine.curve.rpmMaxPw = data->rads;
|
||||||
|
@ -119,21 +128,30 @@ SimEngineConfig(tCar *car)
|
||||||
|
|
||||||
/* check engine brake */
|
/* check engine brake */
|
||||||
if ( car->engine.brakeCoeff < 0.0 )
|
if ( car->engine.brakeCoeff < 0.0 )
|
||||||
{car->engine.brakeCoeff = 0.0;}
|
{
|
||||||
|
car->engine.brakeCoeff = 0.0;
|
||||||
|
}
|
||||||
car->engine.brakeCoeff *= maxTq;
|
car->engine.brakeCoeff *= maxTq;
|
||||||
/*sanity check of rev limits*/
|
/*sanity check of rev limits*/
|
||||||
if (car->engine.curve.nbPts > 0 && car->engine.revsMax > car->engine.curve.data[car->engine.curve.nbPts-1].rads) {
|
if (car->engine.curve.nbPts > 0 && car->engine.revsMax > car->engine.curve.data[car->engine.curve.nbPts-1].rads)
|
||||||
|
{
|
||||||
car->engine.revsMax = car->engine.curve.data[car->engine.curve.nbPts-1].rads;
|
car->engine.revsMax = car->engine.curve.data[car->engine.curve.nbPts-1].rads;
|
||||||
GfLogWarning("Revs maxi bigger than the maximum RPM in the curve data.\nIt is set to %g.\n",car->engine.revsMax);
|
GfLogWarning("Revs maxi bigger than the maximum RPM in the curve data.\nIt is set to %g.\n",car->engine.revsMax);
|
||||||
}
|
}
|
||||||
if (car->engine.revsLimiter > car->engine.revsMax) {
|
|
||||||
|
if (car->engine.revsLimiter > car->engine.revsMax)
|
||||||
|
{
|
||||||
car->engine.revsLimiter = car->engine.revsMax;
|
car->engine.revsLimiter = car->engine.revsMax;
|
||||||
GfLogWarning("Revs limiter is bigger than revs maxi.\nIt is set to %g.\n",car->engine.revsLimiter);
|
GfLogWarning("Revs limiter is bigger than revs maxi.\nIt is set to %g.\n",car->engine.revsLimiter);
|
||||||
}
|
}
|
||||||
if (setupRevLimit->max > car->engine.revsMax) {
|
|
||||||
|
if (setupRevLimit->max > car->engine.revsMax)
|
||||||
|
{
|
||||||
setupRevLimit->max = car->engine.revsMax;
|
setupRevLimit->max = car->engine.revsMax;
|
||||||
if (setupRevLimit->min > setupRevLimit->max)
|
if (setupRevLimit->min > setupRevLimit->max)
|
||||||
{setupRevLimit->min = setupRevLimit->max;}
|
{
|
||||||
|
setupRevLimit->min = setupRevLimit->max;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +160,8 @@ SimEngineReConfig(tCar *car)
|
||||||
{/* called by SimCarReConfig in car.cpp */
|
{/* called by SimCarReConfig in car.cpp */
|
||||||
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
||||||
|
|
||||||
if (setupRevLimit->changed) {
|
if (setupRevLimit->changed)
|
||||||
|
{
|
||||||
car->engine.revsLimiter = MIN(setupRevLimit->max, MAX(setupRevLimit->min, setupRevLimit->desired_value));
|
car->engine.revsLimiter = MIN(setupRevLimit->max, MAX(setupRevLimit->min, setupRevLimit->desired_value));
|
||||||
car->carElt->_enginerpmRedLine = car->engine.revsLimiter;
|
car->carElt->_enginerpmRedLine = car->engine.revsLimiter;
|
||||||
setupRevLimit->value = car->engine.revsLimiter;
|
setupRevLimit->value = car->engine.revsLimiter;
|
||||||
|
@ -160,14 +179,16 @@ SimEngineUpdateTq(tCar *car)
|
||||||
tTransmission *trans = &(car->transmission);
|
tTransmission *trans = &(car->transmission);
|
||||||
tClutch *clutch = &(trans->clutch);
|
tClutch *clutch = &(trans->clutch);
|
||||||
|
|
||||||
if ((car->fuel <= 0.0f) || (car->carElt->_state & (RM_CAR_STATE_BROKEN | RM_CAR_STATE_ELIMINATED))) {
|
if ((car->fuel <= 0.0f) || (car->carElt->_state & (RM_CAR_STATE_BROKEN | RM_CAR_STATE_ELIMINATED)))
|
||||||
|
{
|
||||||
engine->rads = 0;
|
engine->rads = 0;
|
||||||
engine->Tq = 0;
|
engine->Tq = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set clutch on when engine revs too low
|
// set clutch on when engine revs too low
|
||||||
if (engine->rads < engine->tickover) {
|
if (engine->rads < engine->tickover)
|
||||||
|
{
|
||||||
clutch->state = CLUTCH_APPLIED;
|
clutch->state = CLUTCH_APPLIED;
|
||||||
clutch->transferValue = 0.0f;
|
clutch->transferValue = 0.0f;
|
||||||
// engine->rads = engine->tickover;
|
// engine->rads = engine->tickover;
|
||||||
|
@ -177,52 +198,67 @@ SimEngineUpdateTq(tCar *car)
|
||||||
tdble EngBrkK = engine->brakeLinCoeff * engine->rads;
|
tdble EngBrkK = engine->brakeLinCoeff * engine->rads;
|
||||||
|
|
||||||
if ( (engine->rads < engine->tickover) ||
|
if ( (engine->rads < engine->tickover) ||
|
||||||
( (engine->rads == engine->tickover) && (car->ctrl->accelCmd <= 1e-6) ) ) {
|
( (engine->rads == engine->tickover) && (car->ctrl->accelCmd <= 1e-6) ) )
|
||||||
|
{
|
||||||
engine->Tq = 0.0f;
|
engine->Tq = 0.0f;
|
||||||
engine->rads = engine->tickover;
|
engine->rads = engine->tickover;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tdble Tq_max = 0.0;
|
tdble Tq_max = 0.0;
|
||||||
for (i = 0; i < car->engine.curve.nbPts; i++) {
|
for (i = 0; i < car->engine.curve.nbPts; i++)
|
||||||
if (engine->rads < curve->data[i].rads) {
|
{
|
||||||
|
if (engine->rads < curve->data[i].rads)
|
||||||
|
{
|
||||||
Tq_max = engine->rads * curve->data[i].a + curve->data[i].b;
|
Tq_max = engine->rads * curve->data[i].a + curve->data[i].b;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tdble alpha = car->ctrl->accelCmd;
|
tdble alpha = car->ctrl->accelCmd;
|
||||||
if (engine->rads > engine->revsLimiter) {
|
|
||||||
|
if (engine->rads > engine->revsLimiter)
|
||||||
|
{
|
||||||
alpha = 0.0;
|
alpha = 0.0;
|
||||||
if (car->features & FEAT_REVLIMIT) {
|
if (car->features & FEAT_REVLIMIT)
|
||||||
engine->timeInLimiter = 0.1f;
|
{
|
||||||
}
|
engine->timeInLimiter = 0.1f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option TCL ...
|
// Option TCL ...
|
||||||
if (car->features & FEAT_TCLINSIMU)
|
if (car->features & FEAT_TCLINSIMU)
|
||||||
{
|
{
|
||||||
if (engine->EnableTCL)
|
if (engine->EnableTCL)
|
||||||
Tq_max *= (tdble) MAX(0.0,MIN(1.0,engine->TCL));
|
Tq_max *= (tdble) MAX(0.0,MIN(1.0, engine->TCL));
|
||||||
/*
|
/*
|
||||||
if (engine->EnableTCL)
|
if (engine->EnableTCL)
|
||||||
fprintf(stderr,"TCL: %.1f %%\n", engine->TCL * 100);
|
fprintf(stderr,"TCL: %.1f %%\n", engine->TCL * 100);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
// ... Option TCL
|
// ... Option TCL
|
||||||
|
|
||||||
|
if ( (car->features & FEAT_REVLIMIT) && (engine->timeInLimiter > 0.0f) )
|
||||||
|
{
|
||||||
|
alpha = 0.0;
|
||||||
|
engine->timeInLimiter -= SimDeltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (car->features & FEAT_REVLIMIT) && (engine->timeInLimiter > 0.0f) ) {
|
|
||||||
alpha = 0.0;
|
|
||||||
engine->timeInLimiter -= SimDeltaTime;
|
|
||||||
}
|
|
||||||
tdble Tq_cur = (Tq_max + EngBrkK) * alpha;
|
tdble Tq_cur = (Tq_max + EngBrkK) * alpha;
|
||||||
engine->Tq = Tq_cur;
|
engine->Tq = Tq_cur;
|
||||||
engine->Tq -= EngBrkK;
|
engine->Tq -= EngBrkK;
|
||||||
if (alpha <= 1e-6) {
|
|
||||||
|
if (alpha <= 1e-6)
|
||||||
|
{
|
||||||
engine->Tq -= engine->brakeCoeff;
|
engine->Tq -= engine->brakeCoeff;
|
||||||
}
|
}
|
||||||
|
|
||||||
tdble cons = Tq_cur * 0.75f;
|
tdble cons = Tq_cur * 0.75f;
|
||||||
if (cons > 0) {
|
if (cons > 0)
|
||||||
|
{
|
||||||
car->fuel -= (tdble) (cons * engine->rads * engine->fuelcons * 0.0000001 * SimDeltaTime);
|
car->fuel -= (tdble) (cons * engine->rads * engine->fuelcons * 0.0000001 * SimDeltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
car->fuel = (tdble) MAX(car->fuel, 0.0);
|
car->fuel = (tdble) MAX(car->fuel, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,86 +280,103 @@ SimEngineUpdateTq(tCar *car)
|
||||||
tdble
|
tdble
|
||||||
SimEngineUpdateRpm(tCar *car, tdble axleRpm)
|
SimEngineUpdateRpm(tCar *car, tdble axleRpm)
|
||||||
{
|
{
|
||||||
tTransmission *trans = &(car->transmission);
|
tTransmission *trans = &(car->transmission);
|
||||||
tClutch *clutch = &(trans->clutch);
|
tClutch *clutch = &(trans->clutch);
|
||||||
tEngine *engine = &(car->engine);
|
tEngine *engine = &(car->engine);
|
||||||
float freerads;
|
float freerads;
|
||||||
float transfer;
|
float transfer;
|
||||||
|
|
||||||
|
|
||||||
if (car->fuel <= 0.0) {
|
if (car->fuel <= 0.0)
|
||||||
engine->rads = 0;
|
{
|
||||||
clutch->state = CLUTCH_APPLIED;
|
engine->rads = 0;
|
||||||
clutch->transferValue = 0.0;
|
clutch->state = CLUTCH_APPLIED;
|
||||||
return 0.0;
|
clutch->transferValue = 0.0;
|
||||||
}
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
freerads = engine->rads;
|
freerads = engine->rads;
|
||||||
freerads += engine->Tq / engine->I * SimDeltaTime;
|
freerads += engine->Tq / engine->I * SimDeltaTime;
|
||||||
{
|
{
|
||||||
tdble dp = engine->pressure;
|
tdble dp = engine->pressure;
|
||||||
engine->pressure = engine->pressure*0.9f + 0.1f*engine->Tq;
|
engine->pressure = engine->pressure*0.9f + 0.1f*engine->Tq;
|
||||||
dp = (0.001f*fabs(engine->pressure - dp));
|
dp = (0.001f*fabs(engine->pressure - dp));
|
||||||
dp = fabs(dp);
|
dp = fabs(dp);
|
||||||
tdble rth = urandom();
|
tdble rth = urandom();
|
||||||
if (dp > rth) {
|
|
||||||
engine->exhaust_pressure += rth;
|
|
||||||
}
|
|
||||||
engine->exhaust_pressure *= 0.9f;
|
|
||||||
car->carElt->priv.smoke += 5.0f*engine->exhaust_pressure;
|
|
||||||
car->carElt->priv.smoke *= 0.99f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (dp > rth)
|
||||||
|
{
|
||||||
|
engine->exhaust_pressure += rth;
|
||||||
|
}
|
||||||
|
|
||||||
// This is a method for the joint torque that the engine experiences
|
engine->exhaust_pressure *= 0.9f;
|
||||||
// to be changed smoothly and not instantaneously.
|
car->carElt->priv.smoke += 5.0f*engine->exhaust_pressure;
|
||||||
// The closest alpha is to 1, the faster the transition is.
|
car->carElt->priv.smoke *= 0.99f;
|
||||||
transfer = 0.0;
|
}
|
||||||
float ttq = 0.0;
|
|
||||||
float I_response = trans->differential[0].feedBack.I + trans->differential[1].feedBack.I;
|
|
||||||
engine->Tq_response = 0.0;
|
|
||||||
tdble dI = fabs(trans->curI - engine->I_joint);
|
|
||||||
tdble sdI = dI;
|
|
||||||
|
|
||||||
// limit the difference to avoid model instability
|
// This is a method for the joint torque that the engine experiences
|
||||||
if (sdI>1.0) {
|
// to be changed smoothly and not instantaneously.
|
||||||
sdI = 1.0;
|
// The closest alpha is to 1, the faster the transition is.
|
||||||
}
|
transfer = 0.0;
|
||||||
|
float ttq = 0.0;
|
||||||
|
float I_response = trans->differential[0].feedBack.I + trans->differential[1].feedBack.I;
|
||||||
|
engine->Tq_response = 0.0;
|
||||||
|
tdble dI = fabs(trans->curI - engine->I_joint);
|
||||||
|
tdble sdI = dI;
|
||||||
|
|
||||||
float alpha = 0.1f; // transition coefficient
|
// limit the difference to avoid model instability
|
||||||
engine->I_joint = (tdble) (engine->I_joint*(1.0-alpha) + alpha*trans->curI);
|
if (sdI>1.0)
|
||||||
|
{
|
||||||
|
sdI = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
// only use these values when the clutch is engaged or the gear
|
float alpha = 0.1f; // transition coefficient
|
||||||
// has changed.
|
engine->I_joint = (tdble) (engine->I_joint*(1.0-alpha) + alpha*trans->curI);
|
||||||
if ((clutch->transferValue > 0.01) && (trans->gearbox.gear)) {
|
|
||||||
|
|
||||||
transfer = clutch->transferValue * clutch->transferValue * clutch->transferValue * clutch->transferValue;
|
// only use these values when the clutch is engaged or the gear
|
||||||
|
// has changed.
|
||||||
|
if ((clutch->transferValue > 0.01) && (trans->gearbox.gear))
|
||||||
|
{
|
||||||
|
transfer = clutch->transferValue * clutch->transferValue * clutch->transferValue * clutch->transferValue;
|
||||||
|
|
||||||
ttq = (float) (dI* tanh(0.01*(axleRpm * trans->curOverallRatio * transfer + freerads * (1.0-transfer) -engine->rads))*100.0);
|
ttq = (float) (dI* tanh(0.01*(axleRpm * trans->curOverallRatio * transfer + freerads * (1.0-transfer) -engine->rads))*100.0);
|
||||||
engine->rads = (tdble) ((1.0-sdI) * (axleRpm * trans->curOverallRatio * transfer + freerads * (1.0-transfer)) + sdI *(engine->rads + ((ttq)*SimDeltaTime)/(engine->I)));
|
engine->rads = (tdble) ((1.0-sdI) * (axleRpm * trans->curOverallRatio * transfer + freerads * (1.0-transfer)) + sdI *(engine->rads + ((ttq)*SimDeltaTime)/(engine->I)));
|
||||||
if (engine->rads < 0.0) {
|
if (engine->rads < 0.0)
|
||||||
engine->rads = 0;
|
{
|
||||||
engine->Tq = 0.0;
|
engine->rads = 0;
|
||||||
}
|
engine->Tq = 0.0;
|
||||||
} else {
|
}
|
||||||
engine->rads = freerads;
|
}
|
||||||
}
|
else
|
||||||
if (engine->rads < engine->tickover) {
|
{
|
||||||
engine->rads = engine->tickover;
|
engine->rads = freerads;
|
||||||
engine->Tq = 0.0;
|
}
|
||||||
} else if (engine->rads > engine->revsMax) {
|
|
||||||
engine->rads = engine->revsMax;
|
|
||||||
if ( (clutch->transferValue > 0.01) &&
|
|
||||||
((trans->curOverallRatio > 0.01) || (trans->curOverallRatio < -0.01)) )
|
|
||||||
return engine->revsMax / trans->curOverallRatio;
|
|
||||||
else {return 0.0;}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((trans->curOverallRatio!=0.0) && (I_response > 0)) {
|
if (engine->rads < engine->tickover)
|
||||||
return axleRpm - sdI * ttq * trans->curOverallRatio * SimDeltaTime / ( I_response);
|
{
|
||||||
} else {
|
engine->rads = engine->tickover;
|
||||||
return 0.0;
|
engine->Tq = 0.0;
|
||||||
}
|
}
|
||||||
|
else if (engine->rads > engine->revsMax)
|
||||||
|
{
|
||||||
|
engine->rads = engine->revsMax;
|
||||||
|
if ( (clutch->transferValue > 0.01) &&
|
||||||
|
((trans->curOverallRatio > 0.01) || (trans->curOverallRatio < -0.01)) )
|
||||||
|
return engine->revsMax / trans->curOverallRatio;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((trans->curOverallRatio!=0.0) && (I_response > 0))
|
||||||
|
{
|
||||||
|
return axleRpm - sdI * ttq * trans->curOverallRatio * SimDeltaTime / ( I_response);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -20,13 +20,15 @@
|
||||||
#ifndef _ENGINE_H_
|
#ifndef _ENGINE_H_
|
||||||
#define _ENGINE_H_
|
#define _ENGINE_H_
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
tdble rads;
|
tdble rads;
|
||||||
tdble a;
|
tdble a;
|
||||||
tdble b;
|
tdble b;
|
||||||
} tEngineCurveElem;
|
} tEngineCurveElem;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
tdble maxTq;
|
tdble maxTq;
|
||||||
tdble maxPw;
|
tdble maxPw;
|
||||||
tdble rpmMaxPw;
|
tdble rpmMaxPw;
|
||||||
|
@ -60,6 +62,3 @@ typedef struct
|
||||||
} tEngine;
|
} tEngine;
|
||||||
|
|
||||||
#endif /* _ENGINE_H_ */
|
#endif /* _ENGINE_H_ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,8 @@ extern float SimAirPressure;
|
||||||
extern float SimAirDensity;
|
extern float SimAirDensity;
|
||||||
|
|
||||||
/// return a number drawn uniformly from [0,1]
|
/// return a number drawn uniformly from [0,1]
|
||||||
inline float urandom() {
|
inline float urandom()
|
||||||
|
{
|
||||||
return ((((float)rand()-1)/((float)RAND_MAX)));
|
return ((((float)rand()-1)/((float)RAND_MAX)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include "sim.h"
|
#include "sim.h"
|
||||||
|
|
||||||
|
|
||||||
tCar *SimCarTable = 0;
|
tCar *SimCarTable = 0;
|
||||||
|
|
||||||
tdble SimDeltaTime;
|
tdble SimDeltaTime;
|
||||||
|
@ -320,9 +319,11 @@ SimInstantReConfig(tCar *car)
|
||||||
{
|
{
|
||||||
setup = (car->ctrl->setupChangeCmd->setup);
|
setup = (car->ctrl->setupChangeCmd->setup);
|
||||||
}
|
}
|
||||||
else return;
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
switch (car->ctrl->setupChangeCmd->type) {
|
switch (car->ctrl->setupChangeCmd->type)
|
||||||
|
{
|
||||||
case DI_BRAKE_REPARTITION:
|
case DI_BRAKE_REPARTITION:
|
||||||
SimBrakeSystemReConfig(car);
|
SimBrakeSystemReConfig(car);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -32,9 +32,6 @@ static void initDamper(tSuspension *susp)
|
||||||
damp->rebound.b2 = (damp->rebound.C1 - damp->rebound.C2) * damp->rebound.v1 + damp->rebound.b1;
|
damp->rebound.b2 = (damp->rebound.C1 - damp->rebound.C2) * damp->rebound.v1 + damp->rebound.b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get damper force
|
* get damper force
|
||||||
*/
|
*/
|
||||||
|
@ -47,22 +44,29 @@ static tdble damperForce(tSuspension *susp)
|
||||||
|
|
||||||
v = susp->v;
|
v = susp->v;
|
||||||
|
|
||||||
if (fabs(v) > 10.0f) {
|
if (fabs(v) > 10.0f)
|
||||||
|
{
|
||||||
v = (float)(SIGN(v) * 10.0);
|
v = (float)(SIGN(v) * 10.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v < 0.0f) {
|
if (v < 0.0f)
|
||||||
|
{
|
||||||
/* rebound */
|
/* rebound */
|
||||||
dampdef = &(susp->damper.rebound);
|
dampdef = &(susp->damper.rebound);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* bump */
|
/* bump */
|
||||||
dampdef = &(susp->damper.bump);
|
dampdef = &(susp->damper.bump);
|
||||||
}
|
}
|
||||||
|
|
||||||
av = fabs(v);
|
av = fabs(v);
|
||||||
if (av < dampdef->v1) {
|
if (av < dampdef->v1)
|
||||||
|
{
|
||||||
f = (dampdef->C1 * av + dampdef->b1);
|
f = (dampdef->C1 * av + dampdef->b1);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
f = (dampdef->C2 * av + dampdef->b2);
|
f = (dampdef->C2 * av + dampdef->b2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +75,6 @@ static tdble damperForce(tSuspension *susp)
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get spring force
|
* get spring force
|
||||||
*/
|
*/
|
||||||
|
@ -92,36 +93,35 @@ static tdble springForce(tSuspension *susp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SimSuspCheckIn(tSuspension *susp)
|
void SimSuspCheckIn(tSuspension *susp)
|
||||||
{
|
{
|
||||||
/*susp->state = 0;*/
|
/*susp->state = 0;*/
|
||||||
/* note: susp->state is reset in SimWheelUpdateRide in wheel.cpp */
|
/* note: susp->state is reset in SimWheelUpdateRide in wheel.cpp */
|
||||||
if (susp->x < susp->spring.packers) {
|
if (susp->x < susp->spring.packers)
|
||||||
|
{
|
||||||
susp->x = susp->spring.packers;
|
susp->x = susp->spring.packers;
|
||||||
susp->state |= SIM_SUSP_COMP;
|
susp->state |= SIM_SUSP_COMP;
|
||||||
}
|
}
|
||||||
if (susp->x >= susp->spring.xMax) {
|
|
||||||
|
if (susp->x >= susp->spring.xMax)
|
||||||
|
{
|
||||||
susp->x = susp->spring.xMax;
|
susp->x = susp->spring.xMax;
|
||||||
susp->state |= SIM_SUSP_EXT;
|
susp->state |= SIM_SUSP_EXT;
|
||||||
}
|
}
|
||||||
susp->x *= susp->spring.bellcrank;
|
susp->x *= susp->spring.bellcrank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SimSuspUpdate(tSuspension *susp)
|
void SimSuspUpdate(tSuspension *susp)
|
||||||
{
|
{
|
||||||
tdble prevforce = susp->force;
|
tdble prevforce = susp->force;
|
||||||
susp->force = (springForce(susp) + damperForce(susp) + susp->inertance * susp->a) * susp->spring.bellcrank;
|
susp->force = (springForce(susp) + damperForce(susp) + susp->inertance * susp->a) * susp->spring.bellcrank;
|
||||||
if (susp->force * prevforce < 0.0) {susp->force = 0.0;}
|
|
||||||
|
if (susp->force * prevforce < 0.0)
|
||||||
|
{
|
||||||
|
susp->force = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp, int index)
|
void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp, int index)
|
||||||
{
|
{
|
||||||
tCarSetupItem *setupSpring, *setupBellcrank, *setupInertance;
|
tCarSetupItem *setupSpring, *setupBellcrank, *setupInertance;
|
||||||
|
@ -129,7 +129,8 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
||||||
tCarSetupItem *setupFastReb, *setupSlowReb, *setupRebLvel;
|
tCarSetupItem *setupFastReb, *setupSlowReb, *setupRebLvel;
|
||||||
tCarSetupItem *setupCourse, *setupPacker;
|
tCarSetupItem *setupCourse, *setupPacker;
|
||||||
|
|
||||||
if (index < 4) {//corner spring
|
if (index < 4)
|
||||||
|
{//corner spring
|
||||||
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
||||||
setupBellcrank = &(car->carElt->setup.suspBellcrank[index]);
|
setupBellcrank = &(car->carElt->setup.suspBellcrank[index]);
|
||||||
setupInertance = &(car->carElt->setup.suspInertance[index]);
|
setupInertance = &(car->carElt->setup.suspInertance[index]);
|
||||||
|
@ -141,7 +142,9 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
||||||
setupRebLvel = &(car->carElt->setup.suspReboundLvel[index]);
|
setupRebLvel = &(car->carElt->setup.suspReboundLvel[index]);
|
||||||
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
||||||
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
||||||
} else {//heave spring
|
}
|
||||||
|
else
|
||||||
|
{//heave spring
|
||||||
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
||||||
setupBellcrank = &(car->carElt->setup.heaveBellcrank[index-4]);
|
setupBellcrank = &(car->carElt->setup.heaveBellcrank[index-4]);
|
||||||
setupInertance = &(car->carElt->setup.heaveInertance[index-4]);
|
setupInertance = &(car->carElt->setup.heaveInertance[index-4]);
|
||||||
|
@ -155,9 +158,12 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
||||||
setupPacker = NULL;
|
setupPacker = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( index < 4 ) {
|
if ( index < 4 )
|
||||||
|
{
|
||||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
||||||
} else {/* default heave = 0 */
|
}
|
||||||
|
else
|
||||||
|
{/* default heave = 0 */
|
||||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
||||||
}
|
}
|
||||||
GfParmGetNumWithLimits(hdle, section, PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
GfParmGetNumWithLimits(hdle, section, PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
||||||
|
@ -204,7 +210,8 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
||||||
setupRebLvel->changed = true;
|
setupRebLvel->changed = true;
|
||||||
setupRebLvel->stepsize = 0.01f;
|
setupRebLvel->stepsize = 0.01f;
|
||||||
|
|
||||||
if (index<4) {
|
if (index<4)
|
||||||
|
{
|
||||||
setupCourse->desired_value = setupCourse->min = setupCourse->max = 0.5f;
|
setupCourse->desired_value = setupCourse->min = setupCourse->max = 0.5f;
|
||||||
GfParmGetNumWithLimits(hdle, section, PRM_SUSPCOURSE, (char*)NULL, &(setupCourse->desired_value), &(setupCourse->min), &(setupCourse->max));
|
GfParmGetNumWithLimits(hdle, section, PRM_SUSPCOURSE, (char*)NULL, &(setupCourse->desired_value), &(setupCourse->min), &(setupCourse->max));
|
||||||
setupCourse->changed = true;
|
setupCourse->changed = true;
|
||||||
|
@ -226,7 +233,8 @@ void SimSuspReConfig(tCar *car, tSuspension *susp, int index, tdble F0, tdble X0
|
||||||
tCarSetupItem *setupCourse, *setupPacker;
|
tCarSetupItem *setupCourse, *setupPacker;
|
||||||
bool damperchanged = false;
|
bool damperchanged = false;
|
||||||
|
|
||||||
if (index < 4) {//corner springs
|
if (index < 4)
|
||||||
|
{//corner springs
|
||||||
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
||||||
setupBellcrank = &(car->carElt->setup.suspBellcrank[index]);
|
setupBellcrank = &(car->carElt->setup.suspBellcrank[index]);
|
||||||
setupInertance = &(car->carElt->setup.suspInertance[index]);
|
setupInertance = &(car->carElt->setup.suspInertance[index]);
|
||||||
|
@ -238,7 +246,9 @@ void SimSuspReConfig(tCar *car, tSuspension *susp, int index, tdble F0, tdble X0
|
||||||
setupRebLvel = &(car->carElt->setup.suspReboundLvel[index]);
|
setupRebLvel = &(car->carElt->setup.suspReboundLvel[index]);
|
||||||
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
||||||
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
||||||
} else {//heave springs: 4 = front heave, 5 = rear heave
|
}
|
||||||
|
else
|
||||||
|
{//heave springs: 4 = front heave, 5 = rear heave
|
||||||
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
||||||
setupBellcrank = &(car->carElt->setup.heaveBellcrank[index-4]);
|
setupBellcrank = &(car->carElt->setup.heaveBellcrank[index-4]);
|
||||||
setupInertance = &(car->carElt->setup.heaveInertance[index-4]);
|
setupInertance = &(car->carElt->setup.heaveInertance[index-4]);
|
||||||
|
@ -252,82 +262,97 @@ void SimSuspReConfig(tCar *car, tSuspension *susp, int index, tdble F0, tdble X0
|
||||||
setupPacker = NULL;
|
setupPacker = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupSpring->changed) {
|
if (setupSpring->changed)
|
||||||
|
{
|
||||||
susp->spring.K = - MIN(setupSpring->max, MAX(setupSpring->min, setupSpring->desired_value));
|
susp->spring.K = - MIN(setupSpring->max, MAX(setupSpring->min, setupSpring->desired_value));
|
||||||
setupSpring->value = - susp->spring.K;
|
setupSpring->value = - susp->spring.K;
|
||||||
setupSpring->changed = false;
|
setupSpring->changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupBellcrank->changed) {
|
if (setupBellcrank->changed)
|
||||||
|
{
|
||||||
susp->spring.bellcrank = MIN(setupBellcrank->max, MAX(setupBellcrank->min, setupBellcrank->desired_value));
|
susp->spring.bellcrank = MIN(setupBellcrank->max, MAX(setupBellcrank->min, setupBellcrank->desired_value));
|
||||||
setupBellcrank->value = susp->spring.bellcrank;
|
setupBellcrank->value = susp->spring.bellcrank;
|
||||||
setupBellcrank->changed = false;
|
setupBellcrank->changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
susp->spring.x0 = susp->spring.bellcrank * X0;
|
susp->spring.x0 = susp->spring.bellcrank * X0;
|
||||||
susp->spring.F0 = F0 / susp->spring.bellcrank;
|
susp->spring.F0 = F0 / susp->spring.bellcrank;
|
||||||
|
|
||||||
if (setupInertance->changed) {
|
if (setupInertance->changed)
|
||||||
|
{
|
||||||
susp->inertance = MIN(setupInertance->max, MAX(setupInertance->min, setupInertance->desired_value));
|
susp->inertance = MIN(setupInertance->max, MAX(setupInertance->min, setupInertance->desired_value));
|
||||||
setupInertance->value = susp->inertance;
|
setupInertance->value = susp->inertance;
|
||||||
setupInertance->changed = false;
|
setupInertance->changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupSlowBump->changed) {
|
if (setupSlowBump->changed)
|
||||||
|
{
|
||||||
susp->damper.bump.C1 = MIN(setupSlowBump->max, MAX(setupSlowBump->min, setupSlowBump->desired_value));
|
susp->damper.bump.C1 = MIN(setupSlowBump->max, MAX(setupSlowBump->min, setupSlowBump->desired_value));
|
||||||
setupSlowBump->value = susp->damper.bump.C1;
|
setupSlowBump->value = susp->damper.bump.C1;
|
||||||
setupSlowBump->changed = false;
|
setupSlowBump->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupSlowReb->changed) {
|
if (setupSlowReb->changed)
|
||||||
|
{
|
||||||
susp->damper.rebound.C1 = MIN(setupSlowReb->max, MAX(setupSlowReb->min, setupSlowReb->desired_value));
|
susp->damper.rebound.C1 = MIN(setupSlowReb->max, MAX(setupSlowReb->min, setupSlowReb->desired_value));
|
||||||
setupSlowReb->value = susp->damper.rebound.C1;
|
setupSlowReb->value = susp->damper.rebound.C1;
|
||||||
setupSlowReb->changed = false;
|
setupSlowReb->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupFastBump->changed) {
|
if (setupFastBump->changed)
|
||||||
|
{
|
||||||
susp->damper.bump.C2 = MIN(setupFastBump->max, MAX(setupFastBump->min, setupFastBump->desired_value));
|
susp->damper.bump.C2 = MIN(setupFastBump->max, MAX(setupFastBump->min, setupFastBump->desired_value));
|
||||||
setupFastBump->value = susp->damper.bump.C2;
|
setupFastBump->value = susp->damper.bump.C2;
|
||||||
setupFastBump->changed = false;
|
setupFastBump->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupFastReb->changed) {
|
if (setupFastReb->changed)
|
||||||
|
{
|
||||||
susp->damper.rebound.C2 = MIN(setupFastReb->max, MAX(setupFastReb->min, setupFastReb->desired_value));
|
susp->damper.rebound.C2 = MIN(setupFastReb->max, MAX(setupFastReb->min, setupFastReb->desired_value));
|
||||||
setupFastReb->value = susp->damper.rebound.C2;
|
setupFastReb->value = susp->damper.rebound.C2;
|
||||||
setupFastReb->changed = false;
|
setupFastReb->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupBumpLvel->changed) {
|
if (setupBumpLvel->changed)
|
||||||
|
{
|
||||||
susp->damper.bump.v1 = MIN(setupBumpLvel->max, MAX(setupBumpLvel->min, setupBumpLvel->desired_value));
|
susp->damper.bump.v1 = MIN(setupBumpLvel->max, MAX(setupBumpLvel->min, setupBumpLvel->desired_value));
|
||||||
setupBumpLvel->value = susp->damper.bump.v1;
|
setupBumpLvel->value = susp->damper.bump.v1;
|
||||||
setupBumpLvel->changed = false;
|
setupBumpLvel->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupRebLvel->changed) {
|
if (setupRebLvel->changed)
|
||||||
|
{
|
||||||
susp->damper.rebound.v1 = MIN(setupRebLvel->max, MAX(setupRebLvel->min, setupRebLvel->desired_value));
|
susp->damper.rebound.v1 = MIN(setupRebLvel->max, MAX(setupRebLvel->min, setupRebLvel->desired_value));
|
||||||
setupRebLvel->value = susp->damper.rebound.v1;
|
setupRebLvel->value = susp->damper.rebound.v1;
|
||||||
setupRebLvel->changed = false;
|
setupRebLvel->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damperchanged) {
|
if (damperchanged)
|
||||||
|
{
|
||||||
susp->damper.bump.b1 = 0.0f;
|
susp->damper.bump.b1 = 0.0f;
|
||||||
susp->damper.rebound.b1 = 0.0f;
|
susp->damper.rebound.b1 = 0.0f;
|
||||||
|
|
||||||
initDamper(susp);
|
initDamper(susp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index<4) {
|
if (index<4)
|
||||||
if (setupCourse->changed) {
|
{
|
||||||
|
if (setupCourse->changed)
|
||||||
|
{
|
||||||
susp->spring.xMax = MIN(setupCourse->max, MAX(setupCourse->min, setupCourse->desired_value));
|
susp->spring.xMax = MIN(setupCourse->max, MAX(setupCourse->min, setupCourse->desired_value));
|
||||||
setupCourse->value = susp->spring.xMax;
|
setupCourse->value = susp->spring.xMax;
|
||||||
setupCourse->changed = false;
|
setupCourse->changed = false;
|
||||||
}
|
}
|
||||||
if (setupPacker->changed) {
|
|
||||||
|
if (setupPacker->changed)
|
||||||
|
{
|
||||||
susp->spring.packers = MIN(setupPacker->max, MAX(setupPacker->min, setupPacker->desired_value));
|
susp->spring.packers = MIN(setupPacker->max, MAX(setupPacker->min, setupPacker->desired_value));
|
||||||
setupPacker->value = susp->spring.packers;
|
setupPacker->value = susp->spring.packers;
|
||||||
setupPacker->changed = false;
|
setupPacker->changed = false;
|
||||||
|
|
|
@ -94,6 +94,7 @@ SimAeroConfig(tCar *car)
|
||||||
|
|
||||||
float max_lift = MaximumLiftGivenDrag (0.5f * rho * Cx * FrntArea, FrntArea);
|
float max_lift = MaximumLiftGivenDrag (0.5f * rho * Cx * FrntArea, FrntArea);
|
||||||
float current_lift = 2.0f * (car->aero.Clift[0] + car->aero.Clift[1]);
|
float current_lift = 2.0f * (car->aero.Clift[0] + car->aero.Clift[1]);
|
||||||
|
|
||||||
if (current_lift > max_lift)
|
if (current_lift > max_lift)
|
||||||
{
|
{
|
||||||
if (car->features & FEAT_LIMITEDGROUNDEFFECT)
|
if (car->features & FEAT_LIMITEDGROUNDEFFECT)
|
||||||
|
@ -152,36 +153,49 @@ SimAeroUpdate(tCar *car, tSituation *s)
|
||||||
airSpeed = car->DynGC.vel.x;
|
airSpeed = car->DynGC.vel.x;
|
||||||
spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);
|
spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);
|
||||||
|
|
||||||
if (airSpeed > 10.0) {
|
if (airSpeed > 10.0)
|
||||||
for (i = 0; i < s->_ncars; i++) {
|
{
|
||||||
if (i == car->carElt->index) {
|
for (i = 0; i < s->_ncars; i++)
|
||||||
|
{
|
||||||
|
if (i == car->carElt->index)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
otherCar = &(SimCarTable[i]);
|
otherCar = &(SimCarTable[i]);
|
||||||
otherYaw = otherCar->DynGCg.pos.az;
|
otherYaw = otherCar->DynGCg.pos.az;
|
||||||
tmpsdpang = spdang - atan2(y - otherCar->DynGCg.pos.y, x - otherCar->DynGCg.pos.x);
|
tmpsdpang = spdang - atan2(y - otherCar->DynGCg.pos.y, x - otherCar->DynGCg.pos.x);
|
||||||
FLOAT_NORM_PI_PI(tmpsdpang);
|
FLOAT_NORM_PI_PI(tmpsdpang);
|
||||||
dyaw = yaw - otherYaw;
|
dyaw = yaw - otherYaw;
|
||||||
FLOAT_NORM_PI_PI(dyaw);
|
FLOAT_NORM_PI_PI(dyaw);
|
||||||
|
|
||||||
if ((otherCar->DynGC.vel.x > 10.0) &&
|
if ((otherCar->DynGC.vel.x > 10.0) &&
|
||||||
(fabs(dyaw) < 0.1396)) {
|
(fabs(dyaw) < 0.1396))
|
||||||
if (fabs(tmpsdpang) > 2.9671) { /* 10 degrees */
|
{
|
||||||
|
if (fabs(tmpsdpang) > 2.9671)
|
||||||
|
{ /* 10 degrees */
|
||||||
/* behind another car */
|
/* behind another car */
|
||||||
tmpas = (tdble) (1.0 - exp(- 2.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) /
|
tmpas = (tdble) (1.0 - exp(- 2.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) /
|
||||||
(otherCar->aero.Cd * otherCar->DynGC.vel.x)));
|
(otherCar->aero.Cd * otherCar->DynGC.vel.x)));
|
||||||
if (tmpas < dragK) {
|
if (tmpas < dragK)
|
||||||
|
{
|
||||||
dragK = tmpas;
|
dragK = tmpas;
|
||||||
}
|
}
|
||||||
} else if (fabs(tmpsdpang) < 0.1396) { /* 8 degrees */
|
}
|
||||||
|
else if (fabs(tmpsdpang) < 0.1396)
|
||||||
|
{ /* 8 degrees */
|
||||||
/* before another car [not sure how much the drag should be reduced in this case. In no case it should be lowered more than 50% I think. - Christos] */
|
/* before another car [not sure how much the drag should be reduced in this case. In no case it should be lowered more than 50% I think. - Christos] */
|
||||||
tmpas = (tdble) (1.0 - 0.5f * exp(- 8.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) / (car->aero.Cd * car->DynGC.vel.x)));
|
tmpas = (tdble) (1.0 - 0.5f * exp(- 8.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) / (car->aero.Cd * car->DynGC.vel.x)));
|
||||||
if (tmpas < dragK) {
|
|
||||||
|
if (tmpas < dragK)
|
||||||
|
{
|
||||||
dragK = tmpas;
|
dragK = tmpas;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
car->airSpeed2 = airSpeed * airSpeed;
|
car->airSpeed2 = airSpeed * airSpeed;
|
||||||
tdble v2 = car->airSpeed2;
|
tdble v2 = car->airSpeed2;
|
||||||
|
|
||||||
|
@ -339,8 +353,11 @@ SimWingConfig(tCar *car, int index)
|
||||||
}
|
}
|
||||||
else if (wing->WingType == 2)
|
else if (wing->WingType == 2)
|
||||||
{
|
{
|
||||||
if (wing->AR > 0.001) wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
|
if (wing->AR > 0.001)
|
||||||
else wing->Kz1 = (tdble)(2 * PI);
|
wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
|
||||||
|
else
|
||||||
|
wing->Kz1 = (tdble)(2 * PI);
|
||||||
|
|
||||||
wing->Kx = (tdble) (0.5 * rho * area);
|
wing->Kx = (tdble) (0.5 * rho * area);
|
||||||
wing->Kz2 = 1.05f;
|
wing->Kz2 = 1.05f;
|
||||||
wing->Kz3 = 0.05f;
|
wing->Kz3 = 0.05f;
|
||||||
|
@ -357,18 +374,24 @@ SimWingReConfig(tCar *car, int index)
|
||||||
tWing *wing = &(car->wing[index]);
|
tWing *wing = &(car->wing[index]);
|
||||||
tCarSetupItem *angle = &(car->carElt->setup.wingAngle[index]);
|
tCarSetupItem *angle = &(car->carElt->setup.wingAngle[index]);
|
||||||
|
|
||||||
if (angle->changed) {
|
if (angle->changed)
|
||||||
|
{
|
||||||
wing->angle = MIN(angle->max,MAX(angle->min,angle->desired_value));
|
wing->angle = MIN(angle->max,MAX(angle->min,angle->desired_value));
|
||||||
angle->value = wing->angle;
|
angle->value = wing->angle;
|
||||||
|
|
||||||
if (wing->WingType == 0) {
|
if (wing->WingType == 0)
|
||||||
if (index==1) {
|
{
|
||||||
|
if (index==1)
|
||||||
|
{
|
||||||
car->aero.Cd = car->aero.CdBody - wing->Kx*sin(wing->angle);
|
car->aero.Cd = car->aero.CdBody - wing->Kx*sin(wing->angle);
|
||||||
}
|
}
|
||||||
} else if (wing->WingType == 1) {
|
}
|
||||||
|
else if (wing->WingType == 1)
|
||||||
|
{
|
||||||
tWing *otherwing = &(car->wing[1-index]);
|
tWing *otherwing = &(car->wing[1-index]);
|
||||||
car->aero.Cd = (tdble)(car->aero.CdBody - wing->Kx*sin(wing->angle - wing->AoAatZRad) - otherwing->Kx*sin(otherwing->angle - otherwing->AoAatZRad));
|
car->aero.Cd = (tdble)(car->aero.CdBody - wing->Kx*sin(wing->angle - wing->AoAatZRad) - otherwing->Kx*sin(otherwing->angle - otherwing->AoAatZRad));
|
||||||
}
|
}
|
||||||
|
|
||||||
angle->changed = false;
|
angle->changed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,12 +402,14 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
tWing *wing = &(car->wing[index]);
|
tWing *wing = &(car->wing[index]);
|
||||||
|
|
||||||
/* return with 0 if no wing present */
|
/* return with 0 if no wing present */
|
||||||
if (wing->WingType == -1) {
|
if (wing->WingType == -1)
|
||||||
|
{
|
||||||
wing->forces.x = wing->forces.z = 0.0f;
|
wing->forces.x = wing->forces.z = 0.0f;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == 1) {
|
if (index == 1)
|
||||||
|
{
|
||||||
// Check wing angle controller
|
// Check wing angle controller
|
||||||
if (car->ctrl->wingControlMode == 2)
|
if (car->ctrl->wingControlMode == 2)
|
||||||
// Update wing angle
|
// Update wing angle
|
||||||
|
@ -424,8 +449,11 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
}
|
}
|
||||||
else if (aoa > 0)
|
else if (aoa > 0)
|
||||||
{
|
{
|
||||||
if (aoa < wing->AoStall) wing->forces.x = wing->Kx1 * aoa * aoa + wing->Kx2;
|
if (aoa < wing->AoStall)
|
||||||
else wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
wing->forces.x = wing->Kx1 * aoa * aoa + wing->Kx2;
|
||||||
|
else
|
||||||
|
wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
||||||
|
|
||||||
if (aoa < wing->AoStall - wing->Stallw)
|
if (aoa < wing->AoStall - wing->Stallw)
|
||||||
{x = (tdble)0.0;}
|
{x = (tdble)0.0;}
|
||||||
else
|
else
|
||||||
|
@ -433,12 +461,16 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
x = aoa - wing->AoStall + wing->Stallw;
|
x = aoa - wing->AoStall + wing->Stallw;
|
||||||
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
||||||
}
|
}
|
||||||
|
|
||||||
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) + wing->Kz3);
|
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) + wing->Kz3);
|
||||||
}
|
}
|
||||||
else if (aoa > -PI_2)
|
else if (aoa > -PI_2)
|
||||||
{
|
{
|
||||||
if (aoa > -wing->AoStall) wing->forces.x = wing->Kx1 * aoa * aoa + wing->Kx2;
|
if (aoa > -wing->AoStall)
|
||||||
else wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
wing->forces.x = wing->Kx1 * aoa * aoa + wing->Kx2;
|
||||||
|
else
|
||||||
|
wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
||||||
|
|
||||||
if (aoa > -wing->AoStall + wing->Stallw)
|
if (aoa > -wing->AoStall + wing->Stallw)
|
||||||
{x = (tdble)0.0;}
|
{x = (tdble)0.0;}
|
||||||
else
|
else
|
||||||
|
@ -446,12 +478,16 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
x = aoa + wing->AoStall - wing->Stallw;
|
x = aoa + wing->AoStall - wing->Stallw;
|
||||||
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
||||||
}
|
}
|
||||||
|
|
||||||
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3);
|
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (aoa < wing->AoStall - PI) wing->forces.x = (tdble) (wing->Kx1 * (PI + aoa) * (PI + aoa) + wing->Kx2);
|
if (aoa < wing->AoStall - PI)
|
||||||
else wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
wing->forces.x = (tdble) (wing->Kx1 * (PI + aoa) * (PI + aoa) + wing->Kx2);
|
||||||
|
else
|
||||||
|
wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
|
||||||
|
|
||||||
if (aoa < wing->AoStall - wing->Stallw - PI)
|
if (aoa < wing->AoStall - wing->Stallw - PI)
|
||||||
{x = (tdble)0.0;}
|
{x = (tdble)0.0;}
|
||||||
else
|
else
|
||||||
|
@ -459,6 +495,7 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
x = (tdble) (aoa - wing->AoStall + wing->Stallw + PI);
|
x = (tdble) (aoa - wing->AoStall + wing->Stallw + PI);
|
||||||
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
x = x * x / (x * x + wing->Stallw * wing->Stallw);
|
||||||
}
|
}
|
||||||
|
|
||||||
wing->forces.z = (tdble) (-(1-x) * wing->Kz1 * (aoa + wing->AoAatZero + PI) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3));
|
wing->forces.z = (tdble) (-(1-x) * wing->Kz1 * (aoa + wing->AoAatZero + PI) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +504,8 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
{
|
{
|
||||||
if (wing->forces.x > 0.0)
|
if (wing->forces.x > 0.0)
|
||||||
wing->forces.x += (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274)); //0.9*PI
|
wing->forces.x += (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274)); //0.9*PI
|
||||||
else wing->forces.x -= (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274));
|
else
|
||||||
|
wing->forces.x -= (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* then multiply with 0.5*rho*area and the square of velocity */
|
/* then multiply with 0.5*rho*area and the square of velocity */
|
||||||
|
@ -513,4 +551,3 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
||||||
else
|
else
|
||||||
wing->forces.x = wing->forces.z = 0.0f;
|
wing->forces.x = wing->forces.z = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
* *
|
* *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
@ -99,27 +97,32 @@ SimCarConfig(tCar *car)
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_FIXEDWHEELFORCE, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_FIXEDWHEELFORCE, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_FIXEDWHEELFORCE;
|
car->features = car->features | FEAT_FIXEDWHEELFORCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_TCLINSIMU, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_TCLINSIMU, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_TCLINSIMU;
|
car->features = car->features | FEAT_TCLINSIMU;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_ABSINSIMU, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_ABSINSIMU, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_ABSINSIMU;
|
car->features = car->features | FEAT_ABSINSIMU;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_ESPINSIMU, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_ESPINSIMU, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_ESPINSIMU;
|
car->features = car->features | FEAT_ESPINSIMU;
|
||||||
}
|
}
|
||||||
|
|
||||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_LIMITEDGROUNDEFFECT, VAL_NO);
|
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_LIMITEDGROUNDEFFECT, VAL_NO);
|
||||||
if (strcmp(enabling, VAL_YES) == 0) {
|
if (strcmp(enabling, VAL_YES) == 0)
|
||||||
|
{
|
||||||
car->features = car->features | FEAT_LIMITEDGROUNDEFFECT;
|
car->features = car->features | FEAT_LIMITEDGROUNDEFFECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +193,9 @@ SimCarConfig(tCar *car)
|
||||||
/* configure components */
|
/* configure components */
|
||||||
tCarSetupItem *setupSpring;
|
tCarSetupItem *setupSpring;
|
||||||
tdble K[4], Kfheave, Krheave;
|
tdble K[4], Kfheave, Krheave;
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
setupSpring = &(car->carElt->setup.suspSpring[i]);
|
setupSpring = &(car->carElt->setup.suspSpring[i]);
|
||||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
||||||
GfParmGetNumWithLimits(hdle, SuspSect[i], PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
GfParmGetNumWithLimits(hdle, SuspSect[i], PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
||||||
|
@ -198,6 +203,7 @@ SimCarConfig(tCar *car)
|
||||||
setupSpring->stepsize = 1000;
|
setupSpring->stepsize = 1000;
|
||||||
K[i] = setupSpring->desired_value;
|
K[i] = setupSpring->desired_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
setupSpring = &(car->carElt->setup.heaveSpring[0]);
|
setupSpring = &(car->carElt->setup.heaveSpring[0]);
|
||||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
||||||
GfParmGetNumWithLimits(hdle, SECT_FRNTHEAVE, PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
GfParmGetNumWithLimits(hdle, SECT_FRNTHEAVE, PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
||||||
|
@ -225,11 +231,13 @@ SimCarConfig(tCar *car)
|
||||||
car->wheel[REAR_RGT].weight0 = wr0 * gcrl * K[REAR_RGT] / (K[REAR_RGT] + 0.5f*Krheave);
|
car->wheel[REAR_RGT].weight0 = wr0 * gcrl * K[REAR_RGT] / (K[REAR_RGT] + 0.5f*Krheave);
|
||||||
car->wheel[REAR_LFT].weight0 = wr0 * (1 - gcrl) * K[REAR_LFT] / (K[REAR_LFT] + 0.5f*Krheave);
|
car->wheel[REAR_LFT].weight0 = wr0 * (1 - gcrl) * K[REAR_LFT] / (K[REAR_LFT] + 0.5f*Krheave);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
SimAxleConfig(car, i);
|
SimAxleConfig(car, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
SimWheelConfig(car, i);
|
SimWheelConfig(car, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +246,9 @@ SimCarConfig(tCar *car)
|
||||||
SimSteerConfig(car);
|
SimSteerConfig(car);
|
||||||
SimBrakeSystemConfig(car);
|
SimBrakeSystemConfig(car);
|
||||||
SimAeroConfig(car);
|
SimAeroConfig(car);
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
SimWingConfig(car, i);
|
SimWingConfig(car, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,11 +262,13 @@ SimCarConfig(tCar *car)
|
||||||
carElt->_dimension = car->dimension;
|
carElt->_dimension = car->dimension;
|
||||||
carElt->_statGC = car->statGC;
|
carElt->_statGC = car->statGC;
|
||||||
carElt->_tank = car->tank;
|
carElt->_tank = car->tank;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
carElt->priv.wheel[i].relPos = car->wheel[i].relPos;
|
carElt->priv.wheel[i].relPos = car->wheel[i].relPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
car->wheel[i].staticPos.x -= car->statGC.x;
|
car->wheel[i].staticPos.x -= car->statGC.x;
|
||||||
car->wheel[i].staticPos.y -= car->statGC.y;
|
car->wheel[i].staticPos.y -= car->statGC.y;
|
||||||
}
|
}
|
||||||
|
@ -287,8 +299,10 @@ SimCarConfig(tCar *car)
|
||||||
car->corner[REAR_LFT].pos.z = 0;
|
car->corner[REAR_LFT].pos.z = 0;
|
||||||
|
|
||||||
/* set wing positions */
|
/* set wing positions */
|
||||||
if (car->features & FEAT_AEROTOCG) {
|
if (car->features & FEAT_AEROTOCG)
|
||||||
for (i = 0; i < 2; i++) {
|
{
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
car->wing[i].staticPos.x -= car->statGC.x;
|
car->wing[i].staticPos.x -= car->statGC.x;
|
||||||
car->wing[i].staticPos.y -= car->statGC.y;
|
car->wing[i].staticPos.y -= car->statGC.y;
|
||||||
car->wing[i].staticPos.z -= car->statGC.z;
|
car->wing[i].staticPos.z -= car->statGC.z;
|
||||||
|
@ -306,7 +320,9 @@ SimCarConfig(tCar *car)
|
||||||
priv->dashboardInstant[i].type = DI_NONE;
|
priv->dashboardInstant[i].type = DI_NONE;
|
||||||
priv->dashboardInstant[i].setup = NULL;
|
priv->dashboardInstant[i].setup = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (setup->brakeRepartition.min != setup->brakeRepartition.max)
|
if (setup->brakeRepartition.min != setup->brakeRepartition.max)
|
||||||
{
|
{
|
||||||
priv->dashboardInstant[i].type = DI_BRAKE_REPARTITION;
|
priv->dashboardInstant[i].type = DI_BRAKE_REPARTITION;
|
||||||
|
|
|
@ -29,12 +29,12 @@ SimEngineConfig(tCar *car)
|
||||||
char idx[64];
|
char idx[64];
|
||||||
tEngineCurveElem *data;
|
tEngineCurveElem *data;
|
||||||
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
||||||
struct tEdesc {
|
struct tEdesc
|
||||||
|
{
|
||||||
tdble rpm;
|
tdble rpm;
|
||||||
tdble tq;
|
tdble tq;
|
||||||
} *edesc;
|
} *edesc;
|
||||||
|
|
||||||
|
|
||||||
setupRevLimit->desired_value = setupRevLimit->min = setupRevLimit->max = 800;
|
setupRevLimit->desired_value = setupRevLimit->min = setupRevLimit->max = 800;
|
||||||
GfParmGetNumWithLimits(hdle, SECT_ENGINE, PRM_REVSLIM, (char*)NULL, &(setupRevLimit->desired_value), &(setupRevLimit->min), &(setupRevLimit->max));
|
GfParmGetNumWithLimits(hdle, SECT_ENGINE, PRM_REVSLIM, (char*)NULL, &(setupRevLimit->desired_value), &(setupRevLimit->min), &(setupRevLimit->max));
|
||||||
setupRevLimit->changed = true;
|
setupRevLimit->changed = true;
|
||||||
|
@ -59,7 +59,7 @@ SimEngineConfig(tCar *car)
|
||||||
{
|
{
|
||||||
car->engine.TCL = 1.0f;
|
car->engine.TCL = 1.0f;
|
||||||
car->engine.EnableTCL = GfParmGetNum(hdle, SECT_ENGINE, PRM_TCLINSIMU, (char*)NULL, 0.0f) > 0;
|
car->engine.EnableTCL = GfParmGetNum(hdle, SECT_ENGINE, PRM_TCLINSIMU, (char*)NULL, 0.0f) > 0;
|
||||||
/*
|
/*
|
||||||
if (car->engine.EnableTCL)
|
if (car->engine.EnableTCL)
|
||||||
fprintf(stderr,"TCL: Enabled\n");
|
fprintf(stderr,"TCL: Enabled\n");
|
||||||
else
|
else
|
||||||
|
@ -72,12 +72,15 @@ SimEngineConfig(tCar *car)
|
||||||
car->engine.curve.nbPts = GfParmGetEltNb(hdle, idx);
|
car->engine.curve.nbPts = GfParmGetEltNb(hdle, idx);
|
||||||
edesc = (struct tEdesc*)malloc((car->engine.curve.nbPts + 1) * sizeof(struct tEdesc));
|
edesc = (struct tEdesc*)malloc((car->engine.curve.nbPts + 1) * sizeof(struct tEdesc));
|
||||||
|
|
||||||
for (i = 0; i < car->engine.curve.nbPts; i++) {
|
for (i = 0; i < car->engine.curve.nbPts; i++)
|
||||||
|
{
|
||||||
sprintf(idx, "%s/%s/%d", SECT_ENGINE, ARR_DATAPTS, i+1);
|
sprintf(idx, "%s/%s/%d", SECT_ENGINE, ARR_DATAPTS, i+1);
|
||||||
edesc[i].rpm = GfParmGetNum(hdle, idx, PRM_RPM, (char*)NULL, car->engine.revsMax);
|
edesc[i].rpm = GfParmGetNum(hdle, idx, PRM_RPM, (char*)NULL, car->engine.revsMax);
|
||||||
edesc[i].tq = GfParmGetNum(hdle, idx, PRM_TQ, (char*)NULL, 0);
|
edesc[i].tq = GfParmGetNum(hdle, idx, PRM_TQ, (char*)NULL, 0);
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
edesc[i].rpm = edesc[i - 1].rpm;
|
edesc[i].rpm = edesc[i - 1].rpm;
|
||||||
edesc[i].tq = edesc[i - 1].tq;
|
edesc[i].tq = edesc[i - 1].tq;
|
||||||
}
|
}
|
||||||
|
@ -85,19 +88,25 @@ SimEngineConfig(tCar *car)
|
||||||
maxTq = 0;
|
maxTq = 0;
|
||||||
car->engine.curve.maxPw = 0;
|
car->engine.curve.maxPw = 0;
|
||||||
car->engine.curve.data = (tEngineCurveElem *)malloc(car->engine.curve.nbPts * sizeof(tEngineCurveElem));
|
car->engine.curve.data = (tEngineCurveElem *)malloc(car->engine.curve.nbPts * sizeof(tEngineCurveElem));
|
||||||
for(i = 0; i < car->engine.curve.nbPts; i++) {
|
|
||||||
|
for(i = 0; i < car->engine.curve.nbPts; i++)
|
||||||
|
{
|
||||||
data = &(car->engine.curve.data[i]);
|
data = &(car->engine.curve.data[i]);
|
||||||
|
|
||||||
data->rads = edesc[i+1].rpm;
|
data->rads = edesc[i+1].rpm;
|
||||||
|
|
||||||
if ((data->rads>=car->engine.tickover)
|
if ((data->rads>=car->engine.tickover)
|
||||||
&& (edesc[i+1].tq > maxTq)
|
&& (edesc[i+1].tq > maxTq)
|
||||||
&& (data->rads < car->engine.revsLimiter)) {
|
&& (data->rads < car->engine.revsLimiter))
|
||||||
|
{
|
||||||
maxTq = edesc[i+1].tq;
|
maxTq = edesc[i+1].tq;
|
||||||
rpmMaxTq = data->rads;
|
rpmMaxTq = data->rads;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((data->rads>=car->engine.tickover)
|
if ((data->rads>=car->engine.tickover)
|
||||||
&& (data->rads * edesc[i+1].tq > car->engine.curve.maxPw)
|
&& (data->rads * edesc[i+1].tq > car->engine.curve.maxPw)
|
||||||
&& (data->rads < car->engine.revsLimiter)) {
|
&& (data->rads < car->engine.revsLimiter))
|
||||||
|
{
|
||||||
car->engine.curve.TqAtMaxPw = edesc[i+1].tq;
|
car->engine.curve.TqAtMaxPw = edesc[i+1].tq;
|
||||||
car->engine.curve.maxPw = data->rads * edesc[i+1].tq;
|
car->engine.curve.maxPw = data->rads * edesc[i+1].tq;
|
||||||
car->engine.curve.rpmMaxPw = data->rads;
|
car->engine.curve.rpmMaxPw = data->rads;
|
||||||
|
@ -119,21 +128,30 @@ SimEngineConfig(tCar *car)
|
||||||
|
|
||||||
/* check engine brake */
|
/* check engine brake */
|
||||||
if ( car->engine.brakeCoeff < 0.0 )
|
if ( car->engine.brakeCoeff < 0.0 )
|
||||||
{car->engine.brakeCoeff = 0.0;}
|
{
|
||||||
|
car->engine.brakeCoeff = 0.0;
|
||||||
|
}
|
||||||
car->engine.brakeCoeff *= maxTq;
|
car->engine.brakeCoeff *= maxTq;
|
||||||
/*sanity check of rev limits*/
|
/*sanity check of rev limits*/
|
||||||
if (car->engine.curve.nbPts > 0 && car->engine.revsMax > car->engine.curve.data[car->engine.curve.nbPts-1].rads) {
|
if (car->engine.curve.nbPts > 0 && car->engine.revsMax > car->engine.curve.data[car->engine.curve.nbPts-1].rads)
|
||||||
|
{
|
||||||
car->engine.revsMax = car->engine.curve.data[car->engine.curve.nbPts-1].rads;
|
car->engine.revsMax = car->engine.curve.data[car->engine.curve.nbPts-1].rads;
|
||||||
GfLogWarning("Revs maxi bigger than the maximum RPM in the curve data.\nIt is set to %g.\n",car->engine.revsMax);
|
GfLogWarning("Revs maxi bigger than the maximum RPM in the curve data.\nIt is set to %g.\n",car->engine.revsMax);
|
||||||
}
|
}
|
||||||
if (car->engine.revsLimiter > car->engine.revsMax) {
|
|
||||||
|
if (car->engine.revsLimiter > car->engine.revsMax)
|
||||||
|
{
|
||||||
car->engine.revsLimiter = car->engine.revsMax;
|
car->engine.revsLimiter = car->engine.revsMax;
|
||||||
GfLogWarning("Revs limiter is bigger than revs maxi.\nIt is set to %g.\n",car->engine.revsLimiter);
|
GfLogWarning("Revs limiter is bigger than revs maxi.\nIt is set to %g.\n",car->engine.revsLimiter);
|
||||||
}
|
}
|
||||||
if (setupRevLimit->max > car->engine.revsMax) {
|
|
||||||
|
if (setupRevLimit->max > car->engine.revsMax)
|
||||||
|
{
|
||||||
setupRevLimit->max = car->engine.revsMax;
|
setupRevLimit->max = car->engine.revsMax;
|
||||||
if (setupRevLimit->min > setupRevLimit->max)
|
if (setupRevLimit->min > setupRevLimit->max)
|
||||||
{setupRevLimit->min = setupRevLimit->max;}
|
{
|
||||||
|
setupRevLimit->min = setupRevLimit->max;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +160,8 @@ SimEngineReConfig(tCar *car)
|
||||||
{/* called by SimCarReConfig in car.cpp */
|
{/* called by SimCarReConfig in car.cpp */
|
||||||
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
||||||
|
|
||||||
if (setupRevLimit->changed) {
|
if (setupRevLimit->changed)
|
||||||
|
{
|
||||||
car->engine.revsLimiter = MIN(setupRevLimit->max, MAX(setupRevLimit->min, setupRevLimit->desired_value));
|
car->engine.revsLimiter = MIN(setupRevLimit->max, MAX(setupRevLimit->min, setupRevLimit->desired_value));
|
||||||
car->carElt->_enginerpmRedLine = car->engine.revsLimiter;
|
car->carElt->_enginerpmRedLine = car->engine.revsLimiter;
|
||||||
setupRevLimit->value = car->engine.revsLimiter;
|
setupRevLimit->value = car->engine.revsLimiter;
|
||||||
|
@ -160,14 +179,16 @@ SimEngineUpdateTq(tCar *car)
|
||||||
tTransmission *trans = &(car->transmission);
|
tTransmission *trans = &(car->transmission);
|
||||||
tClutch *clutch = &(trans->clutch);
|
tClutch *clutch = &(trans->clutch);
|
||||||
|
|
||||||
if ((car->fuel <= 0.0f) || (car->carElt->_state & (RM_CAR_STATE_BROKEN | RM_CAR_STATE_ELIMINATED))) {
|
if ((car->fuel <= 0.0f) || (car->carElt->_state & (RM_CAR_STATE_BROKEN | RM_CAR_STATE_ELIMINATED)))
|
||||||
|
{
|
||||||
engine->rads = 0;
|
engine->rads = 0;
|
||||||
engine->Tq = 0;
|
engine->Tq = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set clutch on when engine revs too low
|
// set clutch on when engine revs too low
|
||||||
if (engine->rads < engine->tickover) {
|
if (engine->rads < engine->tickover)
|
||||||
|
{
|
||||||
clutch->state = CLUTCH_APPLIED;
|
clutch->state = CLUTCH_APPLIED;
|
||||||
clutch->transferValue = 0.0f;
|
clutch->transferValue = 0.0f;
|
||||||
// engine->rads = engine->tickover;
|
// engine->rads = engine->tickover;
|
||||||
|
@ -177,52 +198,67 @@ SimEngineUpdateTq(tCar *car)
|
||||||
tdble EngBrkK = engine->brakeLinCoeff * engine->rads;
|
tdble EngBrkK = engine->brakeLinCoeff * engine->rads;
|
||||||
|
|
||||||
if ( (engine->rads < engine->tickover) ||
|
if ( (engine->rads < engine->tickover) ||
|
||||||
( (engine->rads == engine->tickover) && (car->ctrl->accelCmd <= 1e-6) ) ) {
|
( (engine->rads == engine->tickover) && (car->ctrl->accelCmd <= 1e-6) ) )
|
||||||
|
{
|
||||||
engine->Tq = 0.0f;
|
engine->Tq = 0.0f;
|
||||||
engine->rads = engine->tickover;
|
engine->rads = engine->tickover;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tdble Tq_max = 0.0;
|
tdble Tq_max = 0.0;
|
||||||
for (i = 0; i < car->engine.curve.nbPts; i++) {
|
for (i = 0; i < car->engine.curve.nbPts; i++)
|
||||||
if (engine->rads < curve->data[i].rads) {
|
{
|
||||||
|
if (engine->rads < curve->data[i].rads)
|
||||||
|
{
|
||||||
Tq_max = engine->rads * curve->data[i].a + curve->data[i].b;
|
Tq_max = engine->rads * curve->data[i].a + curve->data[i].b;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tdble alpha = car->ctrl->accelCmd;
|
tdble alpha = car->ctrl->accelCmd;
|
||||||
if (engine->rads > engine->revsLimiter) {
|
|
||||||
|
if (engine->rads > engine->revsLimiter)
|
||||||
|
{
|
||||||
alpha = 0.0;
|
alpha = 0.0;
|
||||||
if (car->features & FEAT_REVLIMIT) {
|
if (car->features & FEAT_REVLIMIT)
|
||||||
engine->timeInLimiter = 0.1f;
|
{
|
||||||
}
|
engine->timeInLimiter = 0.1f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option TCL ...
|
// Option TCL ...
|
||||||
if (car->features & FEAT_TCLINSIMU)
|
if (car->features & FEAT_TCLINSIMU)
|
||||||
{
|
{
|
||||||
if (engine->EnableTCL)
|
if (engine->EnableTCL)
|
||||||
Tq_max *= (tdble) MAX(0.0,MIN(1.0,engine->TCL));
|
Tq_max *= (tdble) MAX(0.0,MIN(1.0, engine->TCL));
|
||||||
/*
|
/*
|
||||||
if (engine->EnableTCL)
|
if (engine->EnableTCL)
|
||||||
fprintf(stderr,"TCL: %.1f %%\n", engine->TCL * 100);
|
fprintf(stderr,"TCL: %.1f %%\n", engine->TCL * 100);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
// ... Option TCL
|
// ... Option TCL
|
||||||
|
|
||||||
|
if ( (car->features & FEAT_REVLIMIT) && (engine->timeInLimiter > 0.0f) )
|
||||||
|
{
|
||||||
|
alpha = 0.0;
|
||||||
|
engine->timeInLimiter -= SimDeltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (car->features & FEAT_REVLIMIT) && (engine->timeInLimiter > 0.0f) ) {
|
|
||||||
alpha = 0.0;
|
|
||||||
engine->timeInLimiter -= SimDeltaTime;
|
|
||||||
}
|
|
||||||
tdble Tq_cur = (Tq_max + EngBrkK) * alpha;
|
tdble Tq_cur = (Tq_max + EngBrkK) * alpha;
|
||||||
engine->Tq = Tq_cur;
|
engine->Tq = Tq_cur;
|
||||||
engine->Tq -= EngBrkK;
|
engine->Tq -= EngBrkK;
|
||||||
if (alpha <= 1e-6) {
|
|
||||||
|
if (alpha <= 1e-6)
|
||||||
|
{
|
||||||
engine->Tq -= engine->brakeCoeff;
|
engine->Tq -= engine->brakeCoeff;
|
||||||
}
|
}
|
||||||
|
|
||||||
tdble cons = Tq_cur * 0.75f;
|
tdble cons = Tq_cur * 0.75f;
|
||||||
if (cons > 0) {
|
if (cons > 0)
|
||||||
|
{
|
||||||
car->fuel -= (tdble) (cons * engine->rads * engine->fuelcons * 0.0000001 * SimDeltaTime);
|
car->fuel -= (tdble) (cons * engine->rads * engine->fuelcons * 0.0000001 * SimDeltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
car->fuel = (tdble) MAX(car->fuel, 0.0);
|
car->fuel = (tdble) MAX(car->fuel, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,86 +280,103 @@ SimEngineUpdateTq(tCar *car)
|
||||||
tdble
|
tdble
|
||||||
SimEngineUpdateRpm(tCar *car, tdble axleRpm)
|
SimEngineUpdateRpm(tCar *car, tdble axleRpm)
|
||||||
{
|
{
|
||||||
tTransmission *trans = &(car->transmission);
|
tTransmission *trans = &(car->transmission);
|
||||||
tClutch *clutch = &(trans->clutch);
|
tClutch *clutch = &(trans->clutch);
|
||||||
tEngine *engine = &(car->engine);
|
tEngine *engine = &(car->engine);
|
||||||
float freerads;
|
float freerads;
|
||||||
float transfer;
|
float transfer;
|
||||||
|
|
||||||
|
|
||||||
if (car->fuel <= 0.0) {
|
if (car->fuel <= 0.0)
|
||||||
engine->rads = 0;
|
{
|
||||||
clutch->state = CLUTCH_APPLIED;
|
engine->rads = 0;
|
||||||
clutch->transferValue = 0.0;
|
clutch->state = CLUTCH_APPLIED;
|
||||||
return 0.0;
|
clutch->transferValue = 0.0;
|
||||||
}
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
freerads = engine->rads;
|
freerads = engine->rads;
|
||||||
freerads += engine->Tq / engine->I * SimDeltaTime;
|
freerads += engine->Tq / engine->I * SimDeltaTime;
|
||||||
{
|
{
|
||||||
tdble dp = engine->pressure;
|
tdble dp = engine->pressure;
|
||||||
engine->pressure = engine->pressure*0.9f + 0.1f*engine->Tq;
|
engine->pressure = engine->pressure*0.9f + 0.1f*engine->Tq;
|
||||||
dp = (0.001f*fabs(engine->pressure - dp));
|
dp = (0.001f*fabs(engine->pressure - dp));
|
||||||
dp = fabs(dp);
|
dp = fabs(dp);
|
||||||
tdble rth = urandom();
|
tdble rth = urandom();
|
||||||
if (dp > rth) {
|
|
||||||
engine->exhaust_pressure += rth;
|
|
||||||
}
|
|
||||||
engine->exhaust_pressure *= 0.9f;
|
|
||||||
car->carElt->priv.smoke += 5.0f*engine->exhaust_pressure;
|
|
||||||
car->carElt->priv.smoke *= 0.99f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (dp > rth)
|
||||||
|
{
|
||||||
|
engine->exhaust_pressure += rth;
|
||||||
|
}
|
||||||
|
|
||||||
// This is a method for the joint torque that the engine experiences
|
engine->exhaust_pressure *= 0.9f;
|
||||||
// to be changed smoothly and not instantaneously.
|
car->carElt->priv.smoke += 5.0f*engine->exhaust_pressure;
|
||||||
// The closest alpha is to 1, the faster the transition is.
|
car->carElt->priv.smoke *= 0.99f;
|
||||||
transfer = 0.0;
|
}
|
||||||
float ttq = 0.0;
|
|
||||||
float I_response = trans->differential[0].feedBack.I + trans->differential[1].feedBack.I;
|
|
||||||
engine->Tq_response = 0.0;
|
|
||||||
tdble dI = fabs(trans->curI - engine->I_joint);
|
|
||||||
tdble sdI = dI;
|
|
||||||
|
|
||||||
// limit the difference to avoid model instability
|
// This is a method for the joint torque that the engine experiences
|
||||||
if (sdI>1.0) {
|
// to be changed smoothly and not instantaneously.
|
||||||
sdI = 1.0;
|
// The closest alpha is to 1, the faster the transition is.
|
||||||
}
|
transfer = 0.0;
|
||||||
|
float ttq = 0.0;
|
||||||
|
float I_response = trans->differential[0].feedBack.I + trans->differential[1].feedBack.I;
|
||||||
|
engine->Tq_response = 0.0;
|
||||||
|
tdble dI = fabs(trans->curI - engine->I_joint);
|
||||||
|
tdble sdI = dI;
|
||||||
|
|
||||||
float alpha = 0.1f; // transition coefficient
|
// limit the difference to avoid model instability
|
||||||
engine->I_joint = (tdble) (engine->I_joint*(1.0-alpha) + alpha*trans->curI);
|
if (sdI>1.0)
|
||||||
|
{
|
||||||
|
sdI = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float alpha = 0.1f; // transition coefficient
|
||||||
|
engine->I_joint = (tdble) (engine->I_joint*(1.0-alpha) + alpha*trans->curI);
|
||||||
|
|
||||||
// only use these values when the clutch is engaged or the gear
|
// only use these values when the clutch is engaged or the gear
|
||||||
// has changed.
|
// has changed.
|
||||||
if ((clutch->transferValue > 0.01) && (trans->gearbox.gear)) {
|
if ((clutch->transferValue > 0.01) && (trans->gearbox.gear))
|
||||||
|
{
|
||||||
|
transfer = clutch->transferValue * clutch->transferValue * clutch->transferValue * clutch->transferValue;
|
||||||
|
|
||||||
transfer = clutch->transferValue * clutch->transferValue * clutch->transferValue * clutch->transferValue;
|
ttq = (float) (dI* tanh(0.01*(axleRpm * trans->curOverallRatio * transfer + freerads * (1.0-transfer) -engine->rads))*100.0);
|
||||||
|
engine->rads = (tdble) ((1.0-sdI) * (axleRpm * trans->curOverallRatio * transfer + freerads * (1.0-transfer)) + sdI *(engine->rads + ((ttq)*SimDeltaTime)/(engine->I)));
|
||||||
|
if (engine->rads < 0.0)
|
||||||
|
{
|
||||||
|
engine->rads = 0;
|
||||||
|
engine->Tq = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
engine->rads = freerads;
|
||||||
|
}
|
||||||
|
|
||||||
ttq = (float) (dI* tanh(0.01*(axleRpm * trans->curOverallRatio * transfer + freerads * (1.0-transfer) -engine->rads))*100.0);
|
if (engine->rads < engine->tickover)
|
||||||
engine->rads = (tdble) ((1.0-sdI) * (axleRpm * trans->curOverallRatio * transfer + freerads * (1.0-transfer)) + sdI *(engine->rads + ((ttq)*SimDeltaTime)/(engine->I)));
|
{
|
||||||
if (engine->rads < 0.0) {
|
engine->rads = engine->tickover;
|
||||||
engine->rads = 0;
|
engine->Tq = 0.0;
|
||||||
engine->Tq = 0.0;
|
}
|
||||||
}
|
else if (engine->rads > engine->revsMax)
|
||||||
} else {
|
{
|
||||||
engine->rads = freerads;
|
engine->rads = engine->revsMax;
|
||||||
}
|
if ( (clutch->transferValue > 0.01) &&
|
||||||
if (engine->rads < engine->tickover) {
|
((trans->curOverallRatio > 0.01) || (trans->curOverallRatio < -0.01)) )
|
||||||
engine->rads = engine->tickover;
|
return engine->revsMax / trans->curOverallRatio;
|
||||||
engine->Tq = 0.0;
|
else
|
||||||
} else if (engine->rads > engine->revsMax) {
|
{
|
||||||
engine->rads = engine->revsMax;
|
return 0.0;
|
||||||
if ( (clutch->transferValue > 0.01) &&
|
}
|
||||||
((trans->curOverallRatio > 0.01) || (trans->curOverallRatio < -0.01)) )
|
}
|
||||||
return engine->revsMax / trans->curOverallRatio;
|
|
||||||
else {return 0.0;}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((trans->curOverallRatio!=0.0) && (I_response > 0)) {
|
if ((trans->curOverallRatio!=0.0) && (I_response > 0))
|
||||||
return axleRpm - sdI * ttq * trans->curOverallRatio * SimDeltaTime / ( I_response);
|
{
|
||||||
} else {
|
return axleRpm - sdI * ttq * trans->curOverallRatio * SimDeltaTime / ( I_response);
|
||||||
return 0.0;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -20,13 +20,15 @@
|
||||||
#ifndef _ENGINE_H_
|
#ifndef _ENGINE_H_
|
||||||
#define _ENGINE_H_
|
#define _ENGINE_H_
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
tdble rads;
|
tdble rads;
|
||||||
tdble a;
|
tdble a;
|
||||||
tdble b;
|
tdble b;
|
||||||
} tEngineCurveElem;
|
} tEngineCurveElem;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
tdble maxTq;
|
tdble maxTq;
|
||||||
tdble maxPw;
|
tdble maxPw;
|
||||||
tdble rpmMaxPw;
|
tdble rpmMaxPw;
|
||||||
|
@ -60,6 +62,3 @@ typedef struct
|
||||||
} tEngine;
|
} tEngine;
|
||||||
|
|
||||||
#endif /* _ENGINE_H_ */
|
#endif /* _ENGINE_H_ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,8 @@ extern float SimAirPressure;
|
||||||
extern float SimAirDensity;
|
extern float SimAirDensity;
|
||||||
|
|
||||||
/// return a number drawn uniformly from [0,1]
|
/// return a number drawn uniformly from [0,1]
|
||||||
inline float urandom() {
|
inline float urandom()
|
||||||
|
{
|
||||||
return ((((float)rand()-1)/((float)RAND_MAX)));
|
return ((((float)rand()-1)/((float)RAND_MAX)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include "sim.h"
|
#include "sim.h"
|
||||||
|
|
||||||
|
|
||||||
tCar *SimCarTable = 0;
|
tCar *SimCarTable = 0;
|
||||||
|
|
||||||
tdble SimDeltaTime;
|
tdble SimDeltaTime;
|
||||||
|
@ -316,9 +315,11 @@ SimInstantReConfig(tCar *car)
|
||||||
{
|
{
|
||||||
setup = (car->ctrl->setupChangeCmd->setup);
|
setup = (car->ctrl->setupChangeCmd->setup);
|
||||||
}
|
}
|
||||||
else return;
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
switch (car->ctrl->setupChangeCmd->type) {
|
switch (car->ctrl->setupChangeCmd->type)
|
||||||
|
{
|
||||||
case DI_BRAKE_REPARTITION:
|
case DI_BRAKE_REPARTITION:
|
||||||
SimBrakeSystemReConfig(car);
|
SimBrakeSystemReConfig(car);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -32,9 +32,6 @@ static void initDamper(tSuspension *susp)
|
||||||
damp->rebound.b2 = (damp->rebound.C1 - damp->rebound.C2) * damp->rebound.v1 + damp->rebound.b1;
|
damp->rebound.b2 = (damp->rebound.C1 - damp->rebound.C2) * damp->rebound.v1 + damp->rebound.b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get damper force
|
* get damper force
|
||||||
*/
|
*/
|
||||||
|
@ -47,22 +44,29 @@ static tdble damperForce(tSuspension *susp)
|
||||||
|
|
||||||
v = susp->v;
|
v = susp->v;
|
||||||
|
|
||||||
if (fabs(v) > 10.0f) {
|
if (fabs(v) > 10.0f)
|
||||||
|
{
|
||||||
v = (float)(SIGN(v) * 10.0);
|
v = (float)(SIGN(v) * 10.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v < 0.0f) {
|
if (v < 0.0f)
|
||||||
|
{
|
||||||
/* rebound */
|
/* rebound */
|
||||||
dampdef = &(susp->damper.rebound);
|
dampdef = &(susp->damper.rebound);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* bump */
|
/* bump */
|
||||||
dampdef = &(susp->damper.bump);
|
dampdef = &(susp->damper.bump);
|
||||||
}
|
}
|
||||||
|
|
||||||
av = fabs(v);
|
av = fabs(v);
|
||||||
if (av < dampdef->v1) {
|
if (av < dampdef->v1)
|
||||||
|
{
|
||||||
f = (dampdef->C1 * av + dampdef->b1);
|
f = (dampdef->C1 * av + dampdef->b1);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
f = (dampdef->C2 * av + dampdef->b2);
|
f = (dampdef->C2 * av + dampdef->b2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +75,6 @@ static tdble damperForce(tSuspension *susp)
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get spring force
|
* get spring force
|
||||||
*/
|
*/
|
||||||
|
@ -92,36 +93,35 @@ static tdble springForce(tSuspension *susp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SimSuspCheckIn(tSuspension *susp)
|
void SimSuspCheckIn(tSuspension *susp)
|
||||||
{
|
{
|
||||||
/*susp->state = 0;*/
|
/*susp->state = 0;*/
|
||||||
/* note: susp->state is reset in SimWheelUpdateRide in wheel.cpp */
|
/* note: susp->state is reset in SimWheelUpdateRide in wheel.cpp */
|
||||||
if (susp->x < susp->spring.packers) {
|
if (susp->x < susp->spring.packers)
|
||||||
|
{
|
||||||
susp->x = susp->spring.packers;
|
susp->x = susp->spring.packers;
|
||||||
susp->state |= SIM_SUSP_COMP;
|
susp->state |= SIM_SUSP_COMP;
|
||||||
}
|
}
|
||||||
if (susp->x >= susp->spring.xMax) {
|
|
||||||
|
if (susp->x >= susp->spring.xMax)
|
||||||
|
{
|
||||||
susp->x = susp->spring.xMax;
|
susp->x = susp->spring.xMax;
|
||||||
susp->state |= SIM_SUSP_EXT;
|
susp->state |= SIM_SUSP_EXT;
|
||||||
}
|
}
|
||||||
susp->x *= susp->spring.bellcrank;
|
susp->x *= susp->spring.bellcrank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SimSuspUpdate(tSuspension *susp)
|
void SimSuspUpdate(tSuspension *susp)
|
||||||
{
|
{
|
||||||
tdble prevforce = susp->force;
|
tdble prevforce = susp->force;
|
||||||
susp->force = (springForce(susp) + damperForce(susp) + susp->inertance * susp->a) * susp->spring.bellcrank;
|
susp->force = (springForce(susp) + damperForce(susp) + susp->inertance * susp->a) * susp->spring.bellcrank;
|
||||||
if (susp->force * prevforce < 0.0) {susp->force = 0.0;}
|
|
||||||
|
if (susp->force * prevforce < 0.0)
|
||||||
|
{
|
||||||
|
susp->force = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp, int index)
|
void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp, int index)
|
||||||
{
|
{
|
||||||
tCarSetupItem *setupSpring, *setupBellcrank, *setupInertance;
|
tCarSetupItem *setupSpring, *setupBellcrank, *setupInertance;
|
||||||
|
@ -129,7 +129,8 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
||||||
tCarSetupItem *setupFastReb, *setupSlowReb, *setupRebLvel;
|
tCarSetupItem *setupFastReb, *setupSlowReb, *setupRebLvel;
|
||||||
tCarSetupItem *setupCourse, *setupPacker;
|
tCarSetupItem *setupCourse, *setupPacker;
|
||||||
|
|
||||||
if (index < 4) {//corner spring
|
if (index < 4)
|
||||||
|
{//corner spring
|
||||||
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
||||||
setupBellcrank = &(car->carElt->setup.suspBellcrank[index]);
|
setupBellcrank = &(car->carElt->setup.suspBellcrank[index]);
|
||||||
setupInertance = &(car->carElt->setup.suspInertance[index]);
|
setupInertance = &(car->carElt->setup.suspInertance[index]);
|
||||||
|
@ -141,7 +142,9 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
||||||
setupRebLvel = &(car->carElt->setup.suspReboundLvel[index]);
|
setupRebLvel = &(car->carElt->setup.suspReboundLvel[index]);
|
||||||
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
||||||
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
||||||
} else {//heave spring
|
}
|
||||||
|
else
|
||||||
|
{//heave spring
|
||||||
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
||||||
setupBellcrank = &(car->carElt->setup.heaveBellcrank[index-4]);
|
setupBellcrank = &(car->carElt->setup.heaveBellcrank[index-4]);
|
||||||
setupInertance = &(car->carElt->setup.heaveInertance[index-4]);
|
setupInertance = &(car->carElt->setup.heaveInertance[index-4]);
|
||||||
|
@ -155,9 +158,12 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
||||||
setupPacker = NULL;
|
setupPacker = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( index < 4 ) {
|
if ( index < 4 )
|
||||||
|
{
|
||||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
||||||
} else {/* default heave = 0 */
|
}
|
||||||
|
else
|
||||||
|
{/* default heave = 0 */
|
||||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
||||||
}
|
}
|
||||||
GfParmGetNumWithLimits(hdle, section, PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
GfParmGetNumWithLimits(hdle, section, PRM_SPR, (char*)NULL, &(setupSpring->desired_value), &(setupSpring->min), &(setupSpring->max));
|
||||||
|
@ -204,7 +210,8 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
||||||
setupRebLvel->changed = true;
|
setupRebLvel->changed = true;
|
||||||
setupRebLvel->stepsize = 0.01f;
|
setupRebLvel->stepsize = 0.01f;
|
||||||
|
|
||||||
if (index<4) {
|
if (index<4)
|
||||||
|
{
|
||||||
setupCourse->desired_value = setupCourse->min = setupCourse->max = 0.5f;
|
setupCourse->desired_value = setupCourse->min = setupCourse->max = 0.5f;
|
||||||
GfParmGetNumWithLimits(hdle, section, PRM_SUSPCOURSE, (char*)NULL, &(setupCourse->desired_value), &(setupCourse->min), &(setupCourse->max));
|
GfParmGetNumWithLimits(hdle, section, PRM_SUSPCOURSE, (char*)NULL, &(setupCourse->desired_value), &(setupCourse->min), &(setupCourse->max));
|
||||||
setupCourse->changed = true;
|
setupCourse->changed = true;
|
||||||
|
@ -226,7 +233,8 @@ void SimSuspReConfig(tCar *car, tSuspension *susp, int index, tdble F0, tdble X0
|
||||||
tCarSetupItem *setupCourse, *setupPacker;
|
tCarSetupItem *setupCourse, *setupPacker;
|
||||||
bool damperchanged = false;
|
bool damperchanged = false;
|
||||||
|
|
||||||
if (index < 4) {//corner springs
|
if (index < 4)
|
||||||
|
{//corner springs
|
||||||
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
||||||
setupBellcrank = &(car->carElt->setup.suspBellcrank[index]);
|
setupBellcrank = &(car->carElt->setup.suspBellcrank[index]);
|
||||||
setupInertance = &(car->carElt->setup.suspInertance[index]);
|
setupInertance = &(car->carElt->setup.suspInertance[index]);
|
||||||
|
@ -238,7 +246,9 @@ void SimSuspReConfig(tCar *car, tSuspension *susp, int index, tdble F0, tdble X0
|
||||||
setupRebLvel = &(car->carElt->setup.suspReboundLvel[index]);
|
setupRebLvel = &(car->carElt->setup.suspReboundLvel[index]);
|
||||||
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
||||||
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
||||||
} else {//heave springs: 4 = front heave, 5 = rear heave
|
}
|
||||||
|
else
|
||||||
|
{//heave springs: 4 = front heave, 5 = rear heave
|
||||||
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
||||||
setupBellcrank = &(car->carElt->setup.heaveBellcrank[index-4]);
|
setupBellcrank = &(car->carElt->setup.heaveBellcrank[index-4]);
|
||||||
setupInertance = &(car->carElt->setup.heaveInertance[index-4]);
|
setupInertance = &(car->carElt->setup.heaveInertance[index-4]);
|
||||||
|
@ -252,82 +262,97 @@ void SimSuspReConfig(tCar *car, tSuspension *susp, int index, tdble F0, tdble X0
|
||||||
setupPacker = NULL;
|
setupPacker = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupSpring->changed) {
|
if (setupSpring->changed)
|
||||||
|
{
|
||||||
susp->spring.K = - MIN(setupSpring->max, MAX(setupSpring->min, setupSpring->desired_value));
|
susp->spring.K = - MIN(setupSpring->max, MAX(setupSpring->min, setupSpring->desired_value));
|
||||||
setupSpring->value = - susp->spring.K;
|
setupSpring->value = - susp->spring.K;
|
||||||
setupSpring->changed = false;
|
setupSpring->changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupBellcrank->changed) {
|
if (setupBellcrank->changed)
|
||||||
|
{
|
||||||
susp->spring.bellcrank = MIN(setupBellcrank->max, MAX(setupBellcrank->min, setupBellcrank->desired_value));
|
susp->spring.bellcrank = MIN(setupBellcrank->max, MAX(setupBellcrank->min, setupBellcrank->desired_value));
|
||||||
setupBellcrank->value = susp->spring.bellcrank;
|
setupBellcrank->value = susp->spring.bellcrank;
|
||||||
setupBellcrank->changed = false;
|
setupBellcrank->changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
susp->spring.x0 = susp->spring.bellcrank * X0;
|
susp->spring.x0 = susp->spring.bellcrank * X0;
|
||||||
susp->spring.F0 = F0 / susp->spring.bellcrank;
|
susp->spring.F0 = F0 / susp->spring.bellcrank;
|
||||||
|
|
||||||
if (setupInertance->changed) {
|
if (setupInertance->changed)
|
||||||
|
{
|
||||||
susp->inertance = MIN(setupInertance->max, MAX(setupInertance->min, setupInertance->desired_value));
|
susp->inertance = MIN(setupInertance->max, MAX(setupInertance->min, setupInertance->desired_value));
|
||||||
setupInertance->value = susp->inertance;
|
setupInertance->value = susp->inertance;
|
||||||
setupInertance->changed = false;
|
setupInertance->changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupSlowBump->changed) {
|
if (setupSlowBump->changed)
|
||||||
|
{
|
||||||
susp->damper.bump.C1 = MIN(setupSlowBump->max, MAX(setupSlowBump->min, setupSlowBump->desired_value));
|
susp->damper.bump.C1 = MIN(setupSlowBump->max, MAX(setupSlowBump->min, setupSlowBump->desired_value));
|
||||||
setupSlowBump->value = susp->damper.bump.C1;
|
setupSlowBump->value = susp->damper.bump.C1;
|
||||||
setupSlowBump->changed = false;
|
setupSlowBump->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupSlowReb->changed) {
|
if (setupSlowReb->changed)
|
||||||
|
{
|
||||||
susp->damper.rebound.C1 = MIN(setupSlowReb->max, MAX(setupSlowReb->min, setupSlowReb->desired_value));
|
susp->damper.rebound.C1 = MIN(setupSlowReb->max, MAX(setupSlowReb->min, setupSlowReb->desired_value));
|
||||||
setupSlowReb->value = susp->damper.rebound.C1;
|
setupSlowReb->value = susp->damper.rebound.C1;
|
||||||
setupSlowReb->changed = false;
|
setupSlowReb->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupFastBump->changed) {
|
if (setupFastBump->changed)
|
||||||
|
{
|
||||||
susp->damper.bump.C2 = MIN(setupFastBump->max, MAX(setupFastBump->min, setupFastBump->desired_value));
|
susp->damper.bump.C2 = MIN(setupFastBump->max, MAX(setupFastBump->min, setupFastBump->desired_value));
|
||||||
setupFastBump->value = susp->damper.bump.C2;
|
setupFastBump->value = susp->damper.bump.C2;
|
||||||
setupFastBump->changed = false;
|
setupFastBump->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupFastReb->changed) {
|
if (setupFastReb->changed)
|
||||||
|
{
|
||||||
susp->damper.rebound.C2 = MIN(setupFastReb->max, MAX(setupFastReb->min, setupFastReb->desired_value));
|
susp->damper.rebound.C2 = MIN(setupFastReb->max, MAX(setupFastReb->min, setupFastReb->desired_value));
|
||||||
setupFastReb->value = susp->damper.rebound.C2;
|
setupFastReb->value = susp->damper.rebound.C2;
|
||||||
setupFastReb->changed = false;
|
setupFastReb->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupBumpLvel->changed) {
|
if (setupBumpLvel->changed)
|
||||||
|
{
|
||||||
susp->damper.bump.v1 = MIN(setupBumpLvel->max, MAX(setupBumpLvel->min, setupBumpLvel->desired_value));
|
susp->damper.bump.v1 = MIN(setupBumpLvel->max, MAX(setupBumpLvel->min, setupBumpLvel->desired_value));
|
||||||
setupBumpLvel->value = susp->damper.bump.v1;
|
setupBumpLvel->value = susp->damper.bump.v1;
|
||||||
setupBumpLvel->changed = false;
|
setupBumpLvel->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupRebLvel->changed) {
|
if (setupRebLvel->changed)
|
||||||
|
{
|
||||||
susp->damper.rebound.v1 = MIN(setupRebLvel->max, MAX(setupRebLvel->min, setupRebLvel->desired_value));
|
susp->damper.rebound.v1 = MIN(setupRebLvel->max, MAX(setupRebLvel->min, setupRebLvel->desired_value));
|
||||||
setupRebLvel->value = susp->damper.rebound.v1;
|
setupRebLvel->value = susp->damper.rebound.v1;
|
||||||
setupRebLvel->changed = false;
|
setupRebLvel->changed = false;
|
||||||
damperchanged = true;
|
damperchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damperchanged) {
|
if (damperchanged)
|
||||||
|
{
|
||||||
susp->damper.bump.b1 = 0.0f;
|
susp->damper.bump.b1 = 0.0f;
|
||||||
susp->damper.rebound.b1 = 0.0f;
|
susp->damper.rebound.b1 = 0.0f;
|
||||||
|
|
||||||
initDamper(susp);
|
initDamper(susp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index<4) {
|
if (index<4)
|
||||||
if (setupCourse->changed) {
|
{
|
||||||
|
if (setupCourse->changed)
|
||||||
|
{
|
||||||
susp->spring.xMax = MIN(setupCourse->max, MAX(setupCourse->min, setupCourse->desired_value));
|
susp->spring.xMax = MIN(setupCourse->max, MAX(setupCourse->min, setupCourse->desired_value));
|
||||||
setupCourse->value = susp->spring.xMax;
|
setupCourse->value = susp->spring.xMax;
|
||||||
setupCourse->changed = false;
|
setupCourse->changed = false;
|
||||||
}
|
}
|
||||||
if (setupPacker->changed) {
|
|
||||||
|
if (setupPacker->changed)
|
||||||
|
{
|
||||||
susp->spring.packers = MIN(setupPacker->max, MAX(setupPacker->min, setupPacker->desired_value));
|
susp->spring.packers = MIN(setupPacker->max, MAX(setupPacker->min, setupPacker->desired_value));
|
||||||
setupPacker->value = susp->spring.packers;
|
setupPacker->value = susp->spring.packers;
|
||||||
setupPacker->changed = false;
|
setupPacker->changed = false;
|
||||||
|
|
Loading…
Reference in New Issue