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:
iobyte 2024-02-12 21:36:21 +00:00
parent 8579c811a6
commit 6dc546b74d
14 changed files with 659 additions and 394 deletions

View File

@ -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;
} }

View File

@ -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;

View File

@ -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

View File

@ -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_ */

View File

@ -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)));
} }

View File

@ -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;

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;

View File

@ -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

View File

@ -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_ */

View File

@ -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)));
} }

View File

@ -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;

View File

@ -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;