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 current_lift = 2.0f * (car->aero.Clift[0] + car->aero.Clift[1]);
|
||||
|
||||
if (current_lift > max_lift)
|
||||
{
|
||||
if (car->features & FEAT_LIMITEDGROUNDEFFECT)
|
||||
|
@ -152,36 +153,49 @@ SimAeroUpdate(tCar *car, tSituation *s)
|
|||
airSpeed = car->DynGC.vel.x;
|
||||
spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);
|
||||
|
||||
if (airSpeed > 10.0) {
|
||||
for (i = 0; i < s->_ncars; i++) {
|
||||
if (i == car->carElt->index) {
|
||||
if (airSpeed > 10.0)
|
||||
{
|
||||
for (i = 0; i < s->_ncars; i++)
|
||||
{
|
||||
if (i == car->carElt->index)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
otherCar = &(SimCarTable[i]);
|
||||
otherYaw = otherCar->DynGCg.pos.az;
|
||||
tmpsdpang = spdang - atan2(y - otherCar->DynGCg.pos.y, x - otherCar->DynGCg.pos.x);
|
||||
FLOAT_NORM_PI_PI(tmpsdpang);
|
||||
dyaw = yaw - otherYaw;
|
||||
FLOAT_NORM_PI_PI(dyaw);
|
||||
|
||||
if ((otherCar->DynGC.vel.x > 10.0) &&
|
||||
(fabs(dyaw) < 0.1396)) {
|
||||
if (fabs(tmpsdpang) > 2.9671) { /* 10 degrees */
|
||||
(fabs(dyaw) < 0.1396))
|
||||
{
|
||||
if (fabs(tmpsdpang) > 2.9671)
|
||||
{ /* 10 degrees */
|
||||
/* behind another car */
|
||||
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)));
|
||||
if (tmpas < dragK) {
|
||||
if (tmpas < dragK)
|
||||
{
|
||||
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] */
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
car->airSpeed2 = airSpeed * airSpeed;
|
||||
tdble v2 = car->airSpeed2;
|
||||
|
||||
|
@ -339,8 +353,11 @@ SimWingConfig(tCar *car, int index)
|
|||
}
|
||||
else if (wing->WingType == 2)
|
||||
{
|
||||
if (wing->AR > 0.001) wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
|
||||
else wing->Kz1 = (tdble)(2 * PI);
|
||||
if (wing->AR > 0.001)
|
||||
wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
|
||||
else
|
||||
wing->Kz1 = (tdble)(2 * PI);
|
||||
|
||||
wing->Kx = (tdble) (0.5 * rho * area);
|
||||
wing->Kz2 = 1.05f;
|
||||
wing->Kz3 = 0.05f;
|
||||
|
@ -357,18 +374,24 @@ SimWingReConfig(tCar *car, int index)
|
|||
tWing *wing = &(car->wing[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));
|
||||
angle->value = wing->angle;
|
||||
|
||||
if (wing->WingType == 0) {
|
||||
if (index==1) {
|
||||
if (wing->WingType == 0)
|
||||
{
|
||||
if (index==1)
|
||||
{
|
||||
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]);
|
||||
car->aero.Cd = (tdble)(car->aero.CdBody - wing->Kx*sin(wing->angle - wing->AoAatZRad) - otherwing->Kx*sin(otherwing->angle - otherwing->AoAatZRad));
|
||||
}
|
||||
|
||||
angle->changed = false;
|
||||
}
|
||||
}
|
||||
|
@ -379,12 +402,14 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
tWing *wing = &(car->wing[index]);
|
||||
|
||||
/* return with 0 if no wing present */
|
||||
if (wing->WingType == -1) {
|
||||
if (wing->WingType == -1)
|
||||
{
|
||||
wing->forces.x = wing->forces.z = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (index == 1) {
|
||||
if (index == 1)
|
||||
{
|
||||
// Check wing angle controller
|
||||
if (car->ctrl->wingControlMode == 2)
|
||||
// Update wing angle
|
||||
|
@ -424,8 +449,11 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
}
|
||||
else if (aoa > 0)
|
||||
{
|
||||
if (aoa < wing->AoStall) 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->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)
|
||||
{x = (tdble)0.0;}
|
||||
else
|
||||
|
@ -433,12 +461,16 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
x = aoa - wing->AoStall + 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);
|
||||
}
|
||||
else if (aoa > -PI_2)
|
||||
{
|
||||
if (aoa > -wing->AoStall) 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->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)
|
||||
{x = (tdble)0.0;}
|
||||
else
|
||||
|
@ -446,12 +478,16 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
x = aoa + wing->AoStall - 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aoa < wing->AoStall - PI) 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 - PI)
|
||||
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)
|
||||
{x = (tdble)0.0;}
|
||||
else
|
||||
|
@ -459,6 +495,7 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
x = (tdble) (aoa - wing->AoStall + wing->Stallw + PI);
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -467,7 +504,8 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
{
|
||||
if (wing->forces.x > 0.0)
|
||||
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 */
|
||||
|
@ -513,4 +551,3 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
else
|
||||
wing->forces.x = wing->forces.z = 0.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
|
@ -61,6 +59,7 @@ SimCarConfig(tCar *car)
|
|||
car->TCL_SlipScale = 1.0f;
|
||||
car->ABS_SlipScale = 0.1f;
|
||||
car->ABS_BrakeScale = 1.0f;
|
||||
|
||||
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_AEROTOCG, VAL_NO);
|
||||
if (strcmp(enabling, VAL_YES) == 0)
|
||||
{
|
||||
|
@ -98,27 +97,32 @@ SimCarConfig(tCar *car)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -189,7 +193,9 @@ SimCarConfig(tCar *car)
|
|||
/* configure components */
|
||||
tCarSetupItem *setupSpring;
|
||||
tdble K[4], Kfheave, Krheave;
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
setupSpring = &(car->carElt->setup.suspSpring[i]);
|
||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
||||
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;
|
||||
K[i] = setupSpring->desired_value;
|
||||
}
|
||||
|
||||
setupSpring = &(car->carElt->setup.heaveSpring[0]);
|
||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
||||
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_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);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
SimWheelConfig(car, i);
|
||||
}
|
||||
|
||||
|
@ -237,7 +246,9 @@ SimCarConfig(tCar *car)
|
|||
SimSteerConfig(car);
|
||||
SimBrakeSystemConfig(car);
|
||||
SimAeroConfig(car);
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
SimWingConfig(car, i);
|
||||
}
|
||||
|
||||
|
@ -251,11 +262,13 @@ SimCarConfig(tCar *car)
|
|||
carElt->_dimension = car->dimension;
|
||||
carElt->_statGC = car->statGC;
|
||||
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;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
car->wheel[i].staticPos.x -= car->statGC.x;
|
||||
car->wheel[i].staticPos.y -= car->statGC.y;
|
||||
}
|
||||
|
@ -286,8 +299,10 @@ SimCarConfig(tCar *car)
|
|||
car->corner[REAR_LFT].pos.z = 0;
|
||||
|
||||
/* set wing positions */
|
||||
if (car->features & FEAT_AEROTOCG) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (car->features & FEAT_AEROTOCG)
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
car->wing[i].staticPos.x -= car->statGC.x;
|
||||
car->wing[i].staticPos.y -= car->statGC.y;
|
||||
car->wing[i].staticPos.z -= car->statGC.z;
|
||||
|
@ -305,7 +320,9 @@ SimCarConfig(tCar *car)
|
|||
priv->dashboardInstant[i].type = DI_NONE;
|
||||
priv->dashboardInstant[i].setup = NULL;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
if (setup->brakeRepartition.min != setup->brakeRepartition.max)
|
||||
{
|
||||
priv->dashboardInstant[i].type = DI_BRAKE_REPARTITION;
|
||||
|
|
|
@ -29,12 +29,12 @@ SimEngineConfig(tCar *car)
|
|||
char idx[64];
|
||||
tEngineCurveElem *data;
|
||||
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
||||
struct tEdesc {
|
||||
struct tEdesc
|
||||
{
|
||||
tdble rpm;
|
||||
tdble tq;
|
||||
} *edesc;
|
||||
|
||||
|
||||
setupRevLimit->desired_value = setupRevLimit->min = setupRevLimit->max = 800;
|
||||
GfParmGetNumWithLimits(hdle, SECT_ENGINE, PRM_REVSLIM, (char*)NULL, &(setupRevLimit->desired_value), &(setupRevLimit->min), &(setupRevLimit->max));
|
||||
setupRevLimit->changed = true;
|
||||
|
@ -59,7 +59,7 @@ SimEngineConfig(tCar *car)
|
|||
{
|
||||
car->engine.TCL = 1.0f;
|
||||
car->engine.EnableTCL = GfParmGetNum(hdle, SECT_ENGINE, PRM_TCLINSIMU, (char*)NULL, 0.0f) > 0;
|
||||
/*
|
||||
/*
|
||||
if (car->engine.EnableTCL)
|
||||
fprintf(stderr,"TCL: Enabled\n");
|
||||
else
|
||||
|
@ -72,12 +72,15 @@ SimEngineConfig(tCar *car)
|
|||
car->engine.curve.nbPts = GfParmGetEltNb(hdle, idx);
|
||||
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);
|
||||
edesc[i].rpm = GfParmGetNum(hdle, idx, PRM_RPM, (char*)NULL, car->engine.revsMax);
|
||||
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].tq = edesc[i - 1].tq;
|
||||
}
|
||||
|
@ -85,19 +88,25 @@ SimEngineConfig(tCar *car)
|
|||
maxTq = 0;
|
||||
car->engine.curve.maxPw = 0;
|
||||
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->rads = edesc[i+1].rpm;
|
||||
|
||||
if ((data->rads>=car->engine.tickover)
|
||||
&& (edesc[i+1].tq > maxTq)
|
||||
&& (data->rads < car->engine.revsLimiter)) {
|
||||
&& (data->rads < car->engine.revsLimiter))
|
||||
{
|
||||
maxTq = edesc[i+1].tq;
|
||||
rpmMaxTq = data->rads;
|
||||
}
|
||||
|
||||
if ((data->rads>=car->engine.tickover)
|
||||
&& (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.maxPw = data->rads * edesc[i+1].tq;
|
||||
car->engine.curve.rpmMaxPw = data->rads;
|
||||
|
@ -119,21 +128,30 @@ SimEngineConfig(tCar *car)
|
|||
|
||||
/* check engine brake */
|
||||
if ( car->engine.brakeCoeff < 0.0 )
|
||||
{car->engine.brakeCoeff = 0.0;}
|
||||
{
|
||||
car->engine.brakeCoeff = 0.0;
|
||||
}
|
||||
car->engine.brakeCoeff *= maxTq;
|
||||
/*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;
|
||||
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;
|
||||
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;
|
||||
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 */
|
||||
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->carElt->_enginerpmRedLine = car->engine.revsLimiter;
|
||||
setupRevLimit->value = car->engine.revsLimiter;
|
||||
|
@ -160,14 +179,16 @@ SimEngineUpdateTq(tCar *car)
|
|||
tTransmission *trans = &(car->transmission);
|
||||
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->Tq = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// set clutch on when engine revs too low
|
||||
if (engine->rads < engine->tickover) {
|
||||
if (engine->rads < engine->tickover)
|
||||
{
|
||||
clutch->state = CLUTCH_APPLIED;
|
||||
clutch->transferValue = 0.0f;
|
||||
// engine->rads = engine->tickover;
|
||||
|
@ -177,52 +198,67 @@ SimEngineUpdateTq(tCar *car)
|
|||
tdble EngBrkK = engine->brakeLinCoeff * engine->rads;
|
||||
|
||||
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->rads = engine->tickover;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
tdble Tq_max = 0.0;
|
||||
for (i = 0; i < car->engine.curve.nbPts; i++) {
|
||||
if (engine->rads < curve->data[i].rads) {
|
||||
for (i = 0; i < car->engine.curve.nbPts; i++)
|
||||
{
|
||||
if (engine->rads < curve->data[i].rads)
|
||||
{
|
||||
Tq_max = engine->rads * curve->data[i].a + curve->data[i].b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tdble alpha = car->ctrl->accelCmd;
|
||||
if (engine->rads > engine->revsLimiter) {
|
||||
|
||||
if (engine->rads > engine->revsLimiter)
|
||||
{
|
||||
alpha = 0.0;
|
||||
if (car->features & FEAT_REVLIMIT) {
|
||||
engine->timeInLimiter = 0.1f;
|
||||
}
|
||||
if (car->features & FEAT_REVLIMIT)
|
||||
{
|
||||
engine->timeInLimiter = 0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
// Option TCL ...
|
||||
if (car->features & FEAT_TCLINSIMU)
|
||||
{
|
||||
if (engine->EnableTCL)
|
||||
Tq_max *= (tdble) MAX(0.0,MIN(1.0,engine->TCL));
|
||||
/*
|
||||
// Option TCL ...
|
||||
if (car->features & FEAT_TCLINSIMU)
|
||||
{
|
||||
if (engine->EnableTCL)
|
||||
Tq_max *= (tdble) MAX(0.0,MIN(1.0, engine->TCL));
|
||||
/*
|
||||
if (engine->EnableTCL)
|
||||
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;
|
||||
engine->Tq = Tq_cur;
|
||||
engine->Tq -= EngBrkK;
|
||||
if (alpha <= 1e-6) {
|
||||
|
||||
if (alpha <= 1e-6)
|
||||
{
|
||||
engine->Tq -= engine->brakeCoeff;
|
||||
}
|
||||
|
||||
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) MAX(car->fuel, 0.0);
|
||||
}
|
||||
}
|
||||
|
@ -244,86 +280,103 @@ SimEngineUpdateTq(tCar *car)
|
|||
tdble
|
||||
SimEngineUpdateRpm(tCar *car, tdble axleRpm)
|
||||
{
|
||||
tTransmission *trans = &(car->transmission);
|
||||
tClutch *clutch = &(trans->clutch);
|
||||
tEngine *engine = &(car->engine);
|
||||
float freerads;
|
||||
float transfer;
|
||||
tTransmission *trans = &(car->transmission);
|
||||
tClutch *clutch = &(trans->clutch);
|
||||
tEngine *engine = &(car->engine);
|
||||
float freerads;
|
||||
float transfer;
|
||||
|
||||
|
||||
if (car->fuel <= 0.0) {
|
||||
engine->rads = 0;
|
||||
clutch->state = CLUTCH_APPLIED;
|
||||
clutch->transferValue = 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
if (car->fuel <= 0.0)
|
||||
{
|
||||
engine->rads = 0;
|
||||
clutch->state = CLUTCH_APPLIED;
|
||||
clutch->transferValue = 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
freerads = engine->rads;
|
||||
freerads += engine->Tq / engine->I * SimDeltaTime;
|
||||
{
|
||||
tdble dp = engine->pressure;
|
||||
engine->pressure = engine->pressure*0.9f + 0.1f*engine->Tq;
|
||||
dp = (0.001f*fabs(engine->pressure - dp));
|
||||
dp = fabs(dp);
|
||||
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;
|
||||
}
|
||||
freerads = engine->rads;
|
||||
freerads += engine->Tq / engine->I * SimDeltaTime;
|
||||
{
|
||||
tdble dp = engine->pressure;
|
||||
engine->pressure = engine->pressure*0.9f + 0.1f*engine->Tq;
|
||||
dp = (0.001f*fabs(engine->pressure - dp));
|
||||
dp = fabs(dp);
|
||||
tdble rth = urandom();
|
||||
|
||||
if (dp > rth)
|
||||
{
|
||||
engine->exhaust_pressure += rth;
|
||||
}
|
||||
|
||||
// This is a method for the joint torque that the engine experiences
|
||||
// to be changed smoothly and not instantaneously.
|
||||
// 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;
|
||||
engine->exhaust_pressure *= 0.9f;
|
||||
car->carElt->priv.smoke += 5.0f*engine->exhaust_pressure;
|
||||
car->carElt->priv.smoke *= 0.99f;
|
||||
}
|
||||
|
||||
// limit the difference to avoid model instability
|
||||
if (sdI>1.0) {
|
||||
sdI = 1.0;
|
||||
}
|
||||
// This is a method for the joint torque that the engine experiences
|
||||
// to be changed smoothly and not instantaneously.
|
||||
// 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
|
||||
engine->I_joint = (tdble) (engine->I_joint*(1.0-alpha) + alpha*trans->curI);
|
||||
// limit the difference to avoid model instability
|
||||
if (sdI>1.0)
|
||||
{
|
||||
sdI = 1.0;
|
||||
}
|
||||
|
||||
// only use these values when the clutch is engaged or the gear
|
||||
// has changed.
|
||||
if ((clutch->transferValue > 0.01) && (trans->gearbox.gear)) {
|
||||
float alpha = 0.1f; // transition coefficient
|
||||
engine->I_joint = (tdble) (engine->I_joint*(1.0-alpha) + alpha*trans->curI);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
if (engine->rads < engine->tickover) {
|
||||
engine->rads = engine->tickover;
|
||||
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;}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if ((trans->curOverallRatio!=0.0) && (I_response > 0)) {
|
||||
return axleRpm - sdI * ttq * trans->curOverallRatio * SimDeltaTime / ( I_response);
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
if (engine->rads < engine->tickover)
|
||||
{
|
||||
engine->rads = engine->tickover;
|
||||
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
|
||||
|
|
|
@ -20,13 +20,15 @@
|
|||
#ifndef _ENGINE_H_
|
||||
#define _ENGINE_H_
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
tdble rads;
|
||||
tdble a;
|
||||
tdble b;
|
||||
} tEngineCurveElem;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
tdble maxTq;
|
||||
tdble maxPw;
|
||||
tdble rpmMaxPw;
|
||||
|
@ -60,6 +62,3 @@ typedef struct
|
|||
} tEngine;
|
||||
|
||||
#endif /* _ENGINE_H_ */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -136,7 +136,8 @@ extern float SimAirPressure;
|
|||
extern float SimAirDensity;
|
||||
|
||||
/// return a number drawn uniformly from [0,1]
|
||||
inline float urandom() {
|
||||
inline float urandom()
|
||||
{
|
||||
return ((((float)rand()-1)/((float)RAND_MAX)));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "sim.h"
|
||||
|
||||
|
||||
tCar *SimCarTable = 0;
|
||||
|
||||
tdble SimDeltaTime;
|
||||
|
@ -320,9 +319,11 @@ SimInstantReConfig(tCar *car)
|
|||
{
|
||||
setup = (car->ctrl->setupChangeCmd->setup);
|
||||
}
|
||||
else return;
|
||||
else
|
||||
return;
|
||||
|
||||
switch (car->ctrl->setupChangeCmd->type) {
|
||||
switch (car->ctrl->setupChangeCmd->type)
|
||||
{
|
||||
case DI_BRAKE_REPARTITION:
|
||||
SimBrakeSystemReConfig(car);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* get damper force
|
||||
*/
|
||||
|
@ -47,22 +44,29 @@ static tdble damperForce(tSuspension *susp)
|
|||
|
||||
v = susp->v;
|
||||
|
||||
if (fabs(v) > 10.0f) {
|
||||
if (fabs(v) > 10.0f)
|
||||
{
|
||||
v = (float)(SIGN(v) * 10.0);
|
||||
}
|
||||
|
||||
if (v < 0.0f) {
|
||||
if (v < 0.0f)
|
||||
{
|
||||
/* rebound */
|
||||
dampdef = &(susp->damper.rebound);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bump */
|
||||
dampdef = &(susp->damper.bump);
|
||||
}
|
||||
|
||||
av = fabs(v);
|
||||
if (av < dampdef->v1) {
|
||||
if (av < dampdef->v1)
|
||||
{
|
||||
f = (dampdef->C1 * av + dampdef->b1);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
f = (dampdef->C2 * av + dampdef->b2);
|
||||
}
|
||||
|
||||
|
@ -71,9 +75,6 @@ static tdble damperForce(tSuspension *susp)
|
|||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* get spring force
|
||||
*/
|
||||
|
@ -92,36 +93,35 @@ static tdble springForce(tSuspension *susp)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SimSuspCheckIn(tSuspension *susp)
|
||||
{
|
||||
/*susp->state = 0;*/
|
||||
/* 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->state |= SIM_SUSP_COMP;
|
||||
}
|
||||
if (susp->x >= susp->spring.xMax) {
|
||||
|
||||
if (susp->x >= susp->spring.xMax)
|
||||
{
|
||||
susp->x = susp->spring.xMax;
|
||||
susp->state |= SIM_SUSP_EXT;
|
||||
}
|
||||
susp->x *= susp->spring.bellcrank;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SimSuspUpdate(tSuspension *susp)
|
||||
{
|
||||
tdble prevforce = susp->force;
|
||||
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)
|
||||
{
|
||||
tCarSetupItem *setupSpring, *setupBellcrank, *setupInertance;
|
||||
|
@ -129,7 +129,8 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
|||
tCarSetupItem *setupFastReb, *setupSlowReb, *setupRebLvel;
|
||||
tCarSetupItem *setupCourse, *setupPacker;
|
||||
|
||||
if (index < 4) {//corner spring
|
||||
if (index < 4)
|
||||
{//corner spring
|
||||
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
||||
setupBellcrank = &(car->carElt->setup.suspBellcrank[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]);
|
||||
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
||||
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
||||
} else {//heave spring
|
||||
}
|
||||
else
|
||||
{//heave spring
|
||||
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
||||
setupBellcrank = &(car->carElt->setup.heaveBellcrank[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;
|
||||
}
|
||||
|
||||
if ( index < 4 ) {
|
||||
if ( index < 4 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
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->stepsize = 0.01f;
|
||||
|
||||
if (index<4) {
|
||||
if (index<4)
|
||||
{
|
||||
setupCourse->desired_value = setupCourse->min = setupCourse->max = 0.5f;
|
||||
GfParmGetNumWithLimits(hdle, section, PRM_SUSPCOURSE, (char*)NULL, &(setupCourse->desired_value), &(setupCourse->min), &(setupCourse->max));
|
||||
setupCourse->changed = true;
|
||||
|
@ -226,7 +233,8 @@ void SimSuspReConfig(tCar *car, tSuspension *susp, int index, tdble F0, tdble X0
|
|||
tCarSetupItem *setupCourse, *setupPacker;
|
||||
bool damperchanged = false;
|
||||
|
||||
if (index < 4) {//corner springs
|
||||
if (index < 4)
|
||||
{//corner springs
|
||||
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
||||
setupBellcrank = &(car->carElt->setup.suspBellcrank[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]);
|
||||
setupCourse = &(car->carElt->setup.suspCourse[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]);
|
||||
setupBellcrank = &(car->carElt->setup.heaveBellcrank[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;
|
||||
}
|
||||
|
||||
if (setupSpring->changed) {
|
||||
if (setupSpring->changed)
|
||||
{
|
||||
susp->spring.K = - MIN(setupSpring->max, MAX(setupSpring->min, setupSpring->desired_value));
|
||||
setupSpring->value = - susp->spring.K;
|
||||
setupSpring->changed = false;
|
||||
}
|
||||
|
||||
if (setupBellcrank->changed) {
|
||||
if (setupBellcrank->changed)
|
||||
{
|
||||
susp->spring.bellcrank = MIN(setupBellcrank->max, MAX(setupBellcrank->min, setupBellcrank->desired_value));
|
||||
setupBellcrank->value = susp->spring.bellcrank;
|
||||
setupBellcrank->changed = false;
|
||||
}
|
||||
|
||||
susp->spring.x0 = susp->spring.bellcrank * X0;
|
||||
susp->spring.F0 = F0 / susp->spring.bellcrank;
|
||||
|
||||
if (setupInertance->changed) {
|
||||
if (setupInertance->changed)
|
||||
{
|
||||
susp->inertance = MIN(setupInertance->max, MAX(setupInertance->min, setupInertance->desired_value));
|
||||
setupInertance->value = susp->inertance;
|
||||
setupInertance->changed = false;
|
||||
}
|
||||
|
||||
if (setupSlowBump->changed) {
|
||||
if (setupSlowBump->changed)
|
||||
{
|
||||
susp->damper.bump.C1 = MIN(setupSlowBump->max, MAX(setupSlowBump->min, setupSlowBump->desired_value));
|
||||
setupSlowBump->value = susp->damper.bump.C1;
|
||||
setupSlowBump->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupSlowReb->changed) {
|
||||
if (setupSlowReb->changed)
|
||||
{
|
||||
susp->damper.rebound.C1 = MIN(setupSlowReb->max, MAX(setupSlowReb->min, setupSlowReb->desired_value));
|
||||
setupSlowReb->value = susp->damper.rebound.C1;
|
||||
setupSlowReb->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupFastBump->changed) {
|
||||
if (setupFastBump->changed)
|
||||
{
|
||||
susp->damper.bump.C2 = MIN(setupFastBump->max, MAX(setupFastBump->min, setupFastBump->desired_value));
|
||||
setupFastBump->value = susp->damper.bump.C2;
|
||||
setupFastBump->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupFastReb->changed) {
|
||||
if (setupFastReb->changed)
|
||||
{
|
||||
susp->damper.rebound.C2 = MIN(setupFastReb->max, MAX(setupFastReb->min, setupFastReb->desired_value));
|
||||
setupFastReb->value = susp->damper.rebound.C2;
|
||||
setupFastReb->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupBumpLvel->changed) {
|
||||
if (setupBumpLvel->changed)
|
||||
{
|
||||
susp->damper.bump.v1 = MIN(setupBumpLvel->max, MAX(setupBumpLvel->min, setupBumpLvel->desired_value));
|
||||
setupBumpLvel->value = susp->damper.bump.v1;
|
||||
setupBumpLvel->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupRebLvel->changed) {
|
||||
if (setupRebLvel->changed)
|
||||
{
|
||||
susp->damper.rebound.v1 = MIN(setupRebLvel->max, MAX(setupRebLvel->min, setupRebLvel->desired_value));
|
||||
setupRebLvel->value = susp->damper.rebound.v1;
|
||||
setupRebLvel->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (damperchanged) {
|
||||
if (damperchanged)
|
||||
{
|
||||
susp->damper.bump.b1 = 0.0f;
|
||||
susp->damper.rebound.b1 = 0.0f;
|
||||
|
||||
initDamper(susp);
|
||||
}
|
||||
|
||||
if (index<4) {
|
||||
if (setupCourse->changed) {
|
||||
if (index<4)
|
||||
{
|
||||
if (setupCourse->changed)
|
||||
{
|
||||
susp->spring.xMax = MIN(setupCourse->max, MAX(setupCourse->min, setupCourse->desired_value));
|
||||
setupCourse->value = susp->spring.xMax;
|
||||
setupCourse->changed = false;
|
||||
}
|
||||
if (setupPacker->changed) {
|
||||
|
||||
if (setupPacker->changed)
|
||||
{
|
||||
susp->spring.packers = MIN(setupPacker->max, MAX(setupPacker->min, setupPacker->desired_value));
|
||||
setupPacker->value = susp->spring.packers;
|
||||
setupPacker->changed = false;
|
||||
|
|
|
@ -94,6 +94,7 @@ SimAeroConfig(tCar *car)
|
|||
|
||||
float max_lift = MaximumLiftGivenDrag (0.5f * rho * Cx * FrntArea, FrntArea);
|
||||
float current_lift = 2.0f * (car->aero.Clift[0] + car->aero.Clift[1]);
|
||||
|
||||
if (current_lift > max_lift)
|
||||
{
|
||||
if (car->features & FEAT_LIMITEDGROUNDEFFECT)
|
||||
|
@ -152,36 +153,49 @@ SimAeroUpdate(tCar *car, tSituation *s)
|
|||
airSpeed = car->DynGC.vel.x;
|
||||
spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);
|
||||
|
||||
if (airSpeed > 10.0) {
|
||||
for (i = 0; i < s->_ncars; i++) {
|
||||
if (i == car->carElt->index) {
|
||||
if (airSpeed > 10.0)
|
||||
{
|
||||
for (i = 0; i < s->_ncars; i++)
|
||||
{
|
||||
if (i == car->carElt->index)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
otherCar = &(SimCarTable[i]);
|
||||
otherYaw = otherCar->DynGCg.pos.az;
|
||||
tmpsdpang = spdang - atan2(y - otherCar->DynGCg.pos.y, x - otherCar->DynGCg.pos.x);
|
||||
FLOAT_NORM_PI_PI(tmpsdpang);
|
||||
dyaw = yaw - otherYaw;
|
||||
FLOAT_NORM_PI_PI(dyaw);
|
||||
|
||||
if ((otherCar->DynGC.vel.x > 10.0) &&
|
||||
(fabs(dyaw) < 0.1396)) {
|
||||
if (fabs(tmpsdpang) > 2.9671) { /* 10 degrees */
|
||||
(fabs(dyaw) < 0.1396))
|
||||
{
|
||||
if (fabs(tmpsdpang) > 2.9671)
|
||||
{ /* 10 degrees */
|
||||
/* behind another car */
|
||||
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)));
|
||||
if (tmpas < dragK) {
|
||||
if (tmpas < dragK)
|
||||
{
|
||||
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] */
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
car->airSpeed2 = airSpeed * airSpeed;
|
||||
tdble v2 = car->airSpeed2;
|
||||
|
||||
|
@ -339,8 +353,11 @@ SimWingConfig(tCar *car, int index)
|
|||
}
|
||||
else if (wing->WingType == 2)
|
||||
{
|
||||
if (wing->AR > 0.001) wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
|
||||
else wing->Kz1 = (tdble)(2 * PI);
|
||||
if (wing->AR > 0.001)
|
||||
wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
|
||||
else
|
||||
wing->Kz1 = (tdble)(2 * PI);
|
||||
|
||||
wing->Kx = (tdble) (0.5 * rho * area);
|
||||
wing->Kz2 = 1.05f;
|
||||
wing->Kz3 = 0.05f;
|
||||
|
@ -357,18 +374,24 @@ SimWingReConfig(tCar *car, int index)
|
|||
tWing *wing = &(car->wing[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));
|
||||
angle->value = wing->angle;
|
||||
|
||||
if (wing->WingType == 0) {
|
||||
if (index==1) {
|
||||
if (wing->WingType == 0)
|
||||
{
|
||||
if (index==1)
|
||||
{
|
||||
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]);
|
||||
car->aero.Cd = (tdble)(car->aero.CdBody - wing->Kx*sin(wing->angle - wing->AoAatZRad) - otherwing->Kx*sin(otherwing->angle - otherwing->AoAatZRad));
|
||||
}
|
||||
|
||||
angle->changed = false;
|
||||
}
|
||||
}
|
||||
|
@ -379,12 +402,14 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
tWing *wing = &(car->wing[index]);
|
||||
|
||||
/* return with 0 if no wing present */
|
||||
if (wing->WingType == -1) {
|
||||
if (wing->WingType == -1)
|
||||
{
|
||||
wing->forces.x = wing->forces.z = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (index == 1) {
|
||||
if (index == 1)
|
||||
{
|
||||
// Check wing angle controller
|
||||
if (car->ctrl->wingControlMode == 2)
|
||||
// Update wing angle
|
||||
|
@ -424,8 +449,11 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
}
|
||||
else if (aoa > 0)
|
||||
{
|
||||
if (aoa < wing->AoStall) 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->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)
|
||||
{x = (tdble)0.0;}
|
||||
else
|
||||
|
@ -433,12 +461,16 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
x = aoa - wing->AoStall + 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);
|
||||
}
|
||||
else if (aoa > -PI_2)
|
||||
{
|
||||
if (aoa > -wing->AoStall) 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->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)
|
||||
{x = (tdble)0.0;}
|
||||
else
|
||||
|
@ -446,12 +478,16 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
x = aoa + wing->AoStall - 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aoa < wing->AoStall - PI) 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 - PI)
|
||||
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)
|
||||
{x = (tdble)0.0;}
|
||||
else
|
||||
|
@ -459,6 +495,7 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
x = (tdble) (aoa - wing->AoStall + wing->Stallw + PI);
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -467,7 +504,8 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
{
|
||||
if (wing->forces.x > 0.0)
|
||||
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 */
|
||||
|
@ -513,4 +551,3 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
|
|||
else
|
||||
wing->forces.x = wing->forces.z = 0.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
|
@ -99,27 +97,32 @@ SimCarConfig(tCar *car)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -190,7 +193,9 @@ SimCarConfig(tCar *car)
|
|||
/* configure components */
|
||||
tCarSetupItem *setupSpring;
|
||||
tdble K[4], Kfheave, Krheave;
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
setupSpring = &(car->carElt->setup.suspSpring[i]);
|
||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 175000.0f;
|
||||
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;
|
||||
K[i] = setupSpring->desired_value;
|
||||
}
|
||||
|
||||
setupSpring = &(car->carElt->setup.heaveSpring[0]);
|
||||
setupSpring->desired_value = setupSpring->min = setupSpring-> max = 0.0f;
|
||||
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_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);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
SimWheelConfig(car, i);
|
||||
}
|
||||
|
||||
|
@ -238,7 +246,9 @@ SimCarConfig(tCar *car)
|
|||
SimSteerConfig(car);
|
||||
SimBrakeSystemConfig(car);
|
||||
SimAeroConfig(car);
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
SimWingConfig(car, i);
|
||||
}
|
||||
|
||||
|
@ -252,11 +262,13 @@ SimCarConfig(tCar *car)
|
|||
carElt->_dimension = car->dimension;
|
||||
carElt->_statGC = car->statGC;
|
||||
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;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
car->wheel[i].staticPos.x -= car->statGC.x;
|
||||
car->wheel[i].staticPos.y -= car->statGC.y;
|
||||
}
|
||||
|
@ -287,8 +299,10 @@ SimCarConfig(tCar *car)
|
|||
car->corner[REAR_LFT].pos.z = 0;
|
||||
|
||||
/* set wing positions */
|
||||
if (car->features & FEAT_AEROTOCG) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (car->features & FEAT_AEROTOCG)
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
car->wing[i].staticPos.x -= car->statGC.x;
|
||||
car->wing[i].staticPos.y -= car->statGC.y;
|
||||
car->wing[i].staticPos.z -= car->statGC.z;
|
||||
|
@ -306,7 +320,9 @@ SimCarConfig(tCar *car)
|
|||
priv->dashboardInstant[i].type = DI_NONE;
|
||||
priv->dashboardInstant[i].setup = NULL;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
if (setup->brakeRepartition.min != setup->brakeRepartition.max)
|
||||
{
|
||||
priv->dashboardInstant[i].type = DI_BRAKE_REPARTITION;
|
||||
|
|
|
@ -29,12 +29,12 @@ SimEngineConfig(tCar *car)
|
|||
char idx[64];
|
||||
tEngineCurveElem *data;
|
||||
tCarSetupItem *setupRevLimit = &(car->carElt->setup.revsLimiter);
|
||||
struct tEdesc {
|
||||
struct tEdesc
|
||||
{
|
||||
tdble rpm;
|
||||
tdble tq;
|
||||
} *edesc;
|
||||
|
||||
|
||||
setupRevLimit->desired_value = setupRevLimit->min = setupRevLimit->max = 800;
|
||||
GfParmGetNumWithLimits(hdle, SECT_ENGINE, PRM_REVSLIM, (char*)NULL, &(setupRevLimit->desired_value), &(setupRevLimit->min), &(setupRevLimit->max));
|
||||
setupRevLimit->changed = true;
|
||||
|
@ -59,7 +59,7 @@ SimEngineConfig(tCar *car)
|
|||
{
|
||||
car->engine.TCL = 1.0f;
|
||||
car->engine.EnableTCL = GfParmGetNum(hdle, SECT_ENGINE, PRM_TCLINSIMU, (char*)NULL, 0.0f) > 0;
|
||||
/*
|
||||
/*
|
||||
if (car->engine.EnableTCL)
|
||||
fprintf(stderr,"TCL: Enabled\n");
|
||||
else
|
||||
|
@ -72,12 +72,15 @@ SimEngineConfig(tCar *car)
|
|||
car->engine.curve.nbPts = GfParmGetEltNb(hdle, idx);
|
||||
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);
|
||||
edesc[i].rpm = GfParmGetNum(hdle, idx, PRM_RPM, (char*)NULL, car->engine.revsMax);
|
||||
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].tq = edesc[i - 1].tq;
|
||||
}
|
||||
|
@ -85,19 +88,25 @@ SimEngineConfig(tCar *car)
|
|||
maxTq = 0;
|
||||
car->engine.curve.maxPw = 0;
|
||||
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->rads = edesc[i+1].rpm;
|
||||
|
||||
if ((data->rads>=car->engine.tickover)
|
||||
&& (edesc[i+1].tq > maxTq)
|
||||
&& (data->rads < car->engine.revsLimiter)) {
|
||||
&& (data->rads < car->engine.revsLimiter))
|
||||
{
|
||||
maxTq = edesc[i+1].tq;
|
||||
rpmMaxTq = data->rads;
|
||||
}
|
||||
|
||||
if ((data->rads>=car->engine.tickover)
|
||||
&& (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.maxPw = data->rads * edesc[i+1].tq;
|
||||
car->engine.curve.rpmMaxPw = data->rads;
|
||||
|
@ -119,21 +128,30 @@ SimEngineConfig(tCar *car)
|
|||
|
||||
/* check engine brake */
|
||||
if ( car->engine.brakeCoeff < 0.0 )
|
||||
{car->engine.brakeCoeff = 0.0;}
|
||||
{
|
||||
car->engine.brakeCoeff = 0.0;
|
||||
}
|
||||
car->engine.brakeCoeff *= maxTq;
|
||||
/*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;
|
||||
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;
|
||||
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;
|
||||
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 */
|
||||
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->carElt->_enginerpmRedLine = car->engine.revsLimiter;
|
||||
setupRevLimit->value = car->engine.revsLimiter;
|
||||
|
@ -160,14 +179,16 @@ SimEngineUpdateTq(tCar *car)
|
|||
tTransmission *trans = &(car->transmission);
|
||||
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->Tq = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// set clutch on when engine revs too low
|
||||
if (engine->rads < engine->tickover) {
|
||||
if (engine->rads < engine->tickover)
|
||||
{
|
||||
clutch->state = CLUTCH_APPLIED;
|
||||
clutch->transferValue = 0.0f;
|
||||
// engine->rads = engine->tickover;
|
||||
|
@ -177,52 +198,67 @@ SimEngineUpdateTq(tCar *car)
|
|||
tdble EngBrkK = engine->brakeLinCoeff * engine->rads;
|
||||
|
||||
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->rads = engine->tickover;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
tdble Tq_max = 0.0;
|
||||
for (i = 0; i < car->engine.curve.nbPts; i++) {
|
||||
if (engine->rads < curve->data[i].rads) {
|
||||
for (i = 0; i < car->engine.curve.nbPts; i++)
|
||||
{
|
||||
if (engine->rads < curve->data[i].rads)
|
||||
{
|
||||
Tq_max = engine->rads * curve->data[i].a + curve->data[i].b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tdble alpha = car->ctrl->accelCmd;
|
||||
if (engine->rads > engine->revsLimiter) {
|
||||
|
||||
if (engine->rads > engine->revsLimiter)
|
||||
{
|
||||
alpha = 0.0;
|
||||
if (car->features & FEAT_REVLIMIT) {
|
||||
engine->timeInLimiter = 0.1f;
|
||||
}
|
||||
if (car->features & FEAT_REVLIMIT)
|
||||
{
|
||||
engine->timeInLimiter = 0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
// Option TCL ...
|
||||
if (car->features & FEAT_TCLINSIMU)
|
||||
{
|
||||
if (engine->EnableTCL)
|
||||
Tq_max *= (tdble) MAX(0.0,MIN(1.0,engine->TCL));
|
||||
/*
|
||||
// Option TCL ...
|
||||
if (car->features & FEAT_TCLINSIMU)
|
||||
{
|
||||
if (engine->EnableTCL)
|
||||
Tq_max *= (tdble) MAX(0.0,MIN(1.0, engine->TCL));
|
||||
/*
|
||||
if (engine->EnableTCL)
|
||||
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;
|
||||
engine->Tq = Tq_cur;
|
||||
engine->Tq -= EngBrkK;
|
||||
if (alpha <= 1e-6) {
|
||||
|
||||
if (alpha <= 1e-6)
|
||||
{
|
||||
engine->Tq -= engine->brakeCoeff;
|
||||
}
|
||||
|
||||
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) MAX(car->fuel, 0.0);
|
||||
}
|
||||
}
|
||||
|
@ -244,86 +280,103 @@ SimEngineUpdateTq(tCar *car)
|
|||
tdble
|
||||
SimEngineUpdateRpm(tCar *car, tdble axleRpm)
|
||||
{
|
||||
tTransmission *trans = &(car->transmission);
|
||||
tClutch *clutch = &(trans->clutch);
|
||||
tEngine *engine = &(car->engine);
|
||||
float freerads;
|
||||
float transfer;
|
||||
tTransmission *trans = &(car->transmission);
|
||||
tClutch *clutch = &(trans->clutch);
|
||||
tEngine *engine = &(car->engine);
|
||||
float freerads;
|
||||
float transfer;
|
||||
|
||||
|
||||
if (car->fuel <= 0.0) {
|
||||
engine->rads = 0;
|
||||
clutch->state = CLUTCH_APPLIED;
|
||||
clutch->transferValue = 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
if (car->fuel <= 0.0)
|
||||
{
|
||||
engine->rads = 0;
|
||||
clutch->state = CLUTCH_APPLIED;
|
||||
clutch->transferValue = 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
freerads = engine->rads;
|
||||
freerads += engine->Tq / engine->I * SimDeltaTime;
|
||||
{
|
||||
tdble dp = engine->pressure;
|
||||
engine->pressure = engine->pressure*0.9f + 0.1f*engine->Tq;
|
||||
dp = (0.001f*fabs(engine->pressure - dp));
|
||||
dp = fabs(dp);
|
||||
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;
|
||||
}
|
||||
freerads = engine->rads;
|
||||
freerads += engine->Tq / engine->I * SimDeltaTime;
|
||||
{
|
||||
tdble dp = engine->pressure;
|
||||
engine->pressure = engine->pressure*0.9f + 0.1f*engine->Tq;
|
||||
dp = (0.001f*fabs(engine->pressure - dp));
|
||||
dp = fabs(dp);
|
||||
tdble rth = urandom();
|
||||
|
||||
if (dp > rth)
|
||||
{
|
||||
engine->exhaust_pressure += rth;
|
||||
}
|
||||
|
||||
// This is a method for the joint torque that the engine experiences
|
||||
// to be changed smoothly and not instantaneously.
|
||||
// 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;
|
||||
engine->exhaust_pressure *= 0.9f;
|
||||
car->carElt->priv.smoke += 5.0f*engine->exhaust_pressure;
|
||||
car->carElt->priv.smoke *= 0.99f;
|
||||
}
|
||||
|
||||
// limit the difference to avoid model instability
|
||||
if (sdI>1.0) {
|
||||
sdI = 1.0;
|
||||
}
|
||||
// This is a method for the joint torque that the engine experiences
|
||||
// to be changed smoothly and not instantaneously.
|
||||
// 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
|
||||
engine->I_joint = (tdble) (engine->I_joint*(1.0-alpha) + alpha*trans->curI);
|
||||
// limit the difference to avoid model instability
|
||||
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
|
||||
// has changed.
|
||||
if ((clutch->transferValue > 0.01) && (trans->gearbox.gear)) {
|
||||
// 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;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
if (engine->rads < engine->tickover) {
|
||||
engine->rads = engine->tickover;
|
||||
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 (engine->rads < engine->tickover)
|
||||
{
|
||||
engine->rads = engine->tickover;
|
||||
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;
|
||||
}
|
||||
if ((trans->curOverallRatio!=0.0) && (I_response > 0))
|
||||
{
|
||||
return axleRpm - sdI * ttq * trans->curOverallRatio * SimDeltaTime / ( I_response);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -20,13 +20,15 @@
|
|||
#ifndef _ENGINE_H_
|
||||
#define _ENGINE_H_
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
tdble rads;
|
||||
tdble a;
|
||||
tdble b;
|
||||
} tEngineCurveElem;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
tdble maxTq;
|
||||
tdble maxPw;
|
||||
tdble rpmMaxPw;
|
||||
|
@ -60,6 +62,3 @@ typedef struct
|
|||
} tEngine;
|
||||
|
||||
#endif /* _ENGINE_H_ */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -136,7 +136,8 @@ extern float SimAirPressure;
|
|||
extern float SimAirDensity;
|
||||
|
||||
/// return a number drawn uniformly from [0,1]
|
||||
inline float urandom() {
|
||||
inline float urandom()
|
||||
{
|
||||
return ((((float)rand()-1)/((float)RAND_MAX)));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "sim.h"
|
||||
|
||||
|
||||
tCar *SimCarTable = 0;
|
||||
|
||||
tdble SimDeltaTime;
|
||||
|
@ -316,9 +315,11 @@ SimInstantReConfig(tCar *car)
|
|||
{
|
||||
setup = (car->ctrl->setupChangeCmd->setup);
|
||||
}
|
||||
else return;
|
||||
else
|
||||
return;
|
||||
|
||||
switch (car->ctrl->setupChangeCmd->type) {
|
||||
switch (car->ctrl->setupChangeCmd->type)
|
||||
{
|
||||
case DI_BRAKE_REPARTITION:
|
||||
SimBrakeSystemReConfig(car);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* get damper force
|
||||
*/
|
||||
|
@ -47,22 +44,29 @@ static tdble damperForce(tSuspension *susp)
|
|||
|
||||
v = susp->v;
|
||||
|
||||
if (fabs(v) > 10.0f) {
|
||||
if (fabs(v) > 10.0f)
|
||||
{
|
||||
v = (float)(SIGN(v) * 10.0);
|
||||
}
|
||||
|
||||
if (v < 0.0f) {
|
||||
if (v < 0.0f)
|
||||
{
|
||||
/* rebound */
|
||||
dampdef = &(susp->damper.rebound);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bump */
|
||||
dampdef = &(susp->damper.bump);
|
||||
}
|
||||
|
||||
av = fabs(v);
|
||||
if (av < dampdef->v1) {
|
||||
if (av < dampdef->v1)
|
||||
{
|
||||
f = (dampdef->C1 * av + dampdef->b1);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
f = (dampdef->C2 * av + dampdef->b2);
|
||||
}
|
||||
|
||||
|
@ -71,9 +75,6 @@ static tdble damperForce(tSuspension *susp)
|
|||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* get spring force
|
||||
*/
|
||||
|
@ -92,36 +93,35 @@ static tdble springForce(tSuspension *susp)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SimSuspCheckIn(tSuspension *susp)
|
||||
{
|
||||
/*susp->state = 0;*/
|
||||
/* 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->state |= SIM_SUSP_COMP;
|
||||
}
|
||||
if (susp->x >= susp->spring.xMax) {
|
||||
|
||||
if (susp->x >= susp->spring.xMax)
|
||||
{
|
||||
susp->x = susp->spring.xMax;
|
||||
susp->state |= SIM_SUSP_EXT;
|
||||
}
|
||||
susp->x *= susp->spring.bellcrank;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SimSuspUpdate(tSuspension *susp)
|
||||
{
|
||||
tdble prevforce = susp->force;
|
||||
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)
|
||||
{
|
||||
tCarSetupItem *setupSpring, *setupBellcrank, *setupInertance;
|
||||
|
@ -129,7 +129,8 @@ void SimSuspConfig(tCar *car, void *hdle, const char *section, tSuspension *susp
|
|||
tCarSetupItem *setupFastReb, *setupSlowReb, *setupRebLvel;
|
||||
tCarSetupItem *setupCourse, *setupPacker;
|
||||
|
||||
if (index < 4) {//corner spring
|
||||
if (index < 4)
|
||||
{//corner spring
|
||||
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
||||
setupBellcrank = &(car->carElt->setup.suspBellcrank[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]);
|
||||
setupCourse = &(car->carElt->setup.suspCourse[index]);
|
||||
setupPacker = &(car->carElt->setup.suspPacker[index]);
|
||||
} else {//heave spring
|
||||
}
|
||||
else
|
||||
{//heave spring
|
||||
setupSpring = &(car->carElt->setup.heaveSpring[index-4]);
|
||||
setupBellcrank = &(car->carElt->setup.heaveBellcrank[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;
|
||||
}
|
||||
|
||||
if ( index < 4 ) {
|
||||
if ( index < 4 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
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->stepsize = 0.01f;
|
||||
|
||||
if (index<4) {
|
||||
if (index<4)
|
||||
{
|
||||
setupCourse->desired_value = setupCourse->min = setupCourse->max = 0.5f;
|
||||
GfParmGetNumWithLimits(hdle, section, PRM_SUSPCOURSE, (char*)NULL, &(setupCourse->desired_value), &(setupCourse->min), &(setupCourse->max));
|
||||
setupCourse->changed = true;
|
||||
|
@ -226,7 +233,8 @@ void SimSuspReConfig(tCar *car, tSuspension *susp, int index, tdble F0, tdble X0
|
|||
tCarSetupItem *setupCourse, *setupPacker;
|
||||
bool damperchanged = false;
|
||||
|
||||
if (index < 4) {//corner springs
|
||||
if (index < 4)
|
||||
{//corner springs
|
||||
setupSpring = &(car->carElt->setup.suspSpring[index]);
|
||||
setupBellcrank = &(car->carElt->setup.suspBellcrank[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]);
|
||||
setupCourse = &(car->carElt->setup.suspCourse[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]);
|
||||
setupBellcrank = &(car->carElt->setup.heaveBellcrank[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;
|
||||
}
|
||||
|
||||
if (setupSpring->changed) {
|
||||
if (setupSpring->changed)
|
||||
{
|
||||
susp->spring.K = - MIN(setupSpring->max, MAX(setupSpring->min, setupSpring->desired_value));
|
||||
setupSpring->value = - susp->spring.K;
|
||||
setupSpring->changed = false;
|
||||
}
|
||||
|
||||
if (setupBellcrank->changed) {
|
||||
if (setupBellcrank->changed)
|
||||
{
|
||||
susp->spring.bellcrank = MIN(setupBellcrank->max, MAX(setupBellcrank->min, setupBellcrank->desired_value));
|
||||
setupBellcrank->value = susp->spring.bellcrank;
|
||||
setupBellcrank->changed = false;
|
||||
}
|
||||
|
||||
susp->spring.x0 = susp->spring.bellcrank * X0;
|
||||
susp->spring.F0 = F0 / susp->spring.bellcrank;
|
||||
|
||||
if (setupInertance->changed) {
|
||||
if (setupInertance->changed)
|
||||
{
|
||||
susp->inertance = MIN(setupInertance->max, MAX(setupInertance->min, setupInertance->desired_value));
|
||||
setupInertance->value = susp->inertance;
|
||||
setupInertance->changed = false;
|
||||
}
|
||||
|
||||
if (setupSlowBump->changed) {
|
||||
if (setupSlowBump->changed)
|
||||
{
|
||||
susp->damper.bump.C1 = MIN(setupSlowBump->max, MAX(setupSlowBump->min, setupSlowBump->desired_value));
|
||||
setupSlowBump->value = susp->damper.bump.C1;
|
||||
setupSlowBump->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupSlowReb->changed) {
|
||||
if (setupSlowReb->changed)
|
||||
{
|
||||
susp->damper.rebound.C1 = MIN(setupSlowReb->max, MAX(setupSlowReb->min, setupSlowReb->desired_value));
|
||||
setupSlowReb->value = susp->damper.rebound.C1;
|
||||
setupSlowReb->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupFastBump->changed) {
|
||||
if (setupFastBump->changed)
|
||||
{
|
||||
susp->damper.bump.C2 = MIN(setupFastBump->max, MAX(setupFastBump->min, setupFastBump->desired_value));
|
||||
setupFastBump->value = susp->damper.bump.C2;
|
||||
setupFastBump->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupFastReb->changed) {
|
||||
if (setupFastReb->changed)
|
||||
{
|
||||
susp->damper.rebound.C2 = MIN(setupFastReb->max, MAX(setupFastReb->min, setupFastReb->desired_value));
|
||||
setupFastReb->value = susp->damper.rebound.C2;
|
||||
setupFastReb->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupBumpLvel->changed) {
|
||||
if (setupBumpLvel->changed)
|
||||
{
|
||||
susp->damper.bump.v1 = MIN(setupBumpLvel->max, MAX(setupBumpLvel->min, setupBumpLvel->desired_value));
|
||||
setupBumpLvel->value = susp->damper.bump.v1;
|
||||
setupBumpLvel->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (setupRebLvel->changed) {
|
||||
if (setupRebLvel->changed)
|
||||
{
|
||||
susp->damper.rebound.v1 = MIN(setupRebLvel->max, MAX(setupRebLvel->min, setupRebLvel->desired_value));
|
||||
setupRebLvel->value = susp->damper.rebound.v1;
|
||||
setupRebLvel->changed = false;
|
||||
damperchanged = true;
|
||||
}
|
||||
|
||||
if (damperchanged) {
|
||||
if (damperchanged)
|
||||
{
|
||||
susp->damper.bump.b1 = 0.0f;
|
||||
susp->damper.rebound.b1 = 0.0f;
|
||||
|
||||
initDamper(susp);
|
||||
}
|
||||
|
||||
if (index<4) {
|
||||
if (setupCourse->changed) {
|
||||
if (index<4)
|
||||
{
|
||||
if (setupCourse->changed)
|
||||
{
|
||||
susp->spring.xMax = MIN(setupCourse->max, MAX(setupCourse->min, setupCourse->desired_value));
|
||||
setupCourse->value = susp->spring.xMax;
|
||||
setupCourse->changed = false;
|
||||
}
|
||||
if (setupPacker->changed) {
|
||||
|
||||
if (setupPacker->changed)
|
||||
{
|
||||
susp->spring.packers = MIN(setupPacker->max, MAX(setupPacker->min, setupPacker->desired_value));
|
||||
setupPacker->value = susp->spring.packers;
|
||||
setupPacker->changed = false;
|
||||
|
|
Loading…
Reference in New Issue