Request for comments: Transmission/Differential simuv2 updates
Christos Dimitrakakis <[email protected]>
| Newsgroups | gmane.games.torcs.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello, this is a backport of the transmission/differential code from simuv3. Just install the .cpp files in the simuv2 and do make install. You may want to use the included car with this patch, though it should work OK with most other tracks. They basically fix the following bugs: a) the way limited slip differential works (it was in fact working as an automatically locking differential before, which is OK for 4x4 offroad trucks but not for race cars!) b) the calculation of rotational inertia for the drivetrain (only the wheels' inertia was calculated so wheels could spin incredibly fast!) The effect is a somewhat 'smoother' driving response. Since we are in the process of updating all the cars, and the original cars will be removed, I thought that's a good point in time to introduce this too in simuv2. About the fixed car1-trb1. The only differences are: a) the slightly beefier rear breaks (because of the additional requirement to break the engine) b) Introduction of the ant-roll bar setting. I am *not* putting these directly on cvs. If Andrew, Bernhard, Eric don't oppose I'll do it in the next couple of days. I also have updated the rest of Berhnhard's 'no name' cars and I could fix those too. PS. The only missing feature compared to simuv3 is the momentary effect of switching gears and using the clutch, where the moment of inertia is maintained throughout the transition, while in simuv2 the engine speed is magically changed to match that of the wheels. I am not entirely happy with the way this is currently done in simuv3. I would appreciate some comments on that. ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Torcs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/torcs-devel
car1-trb1.xml
(text/xml, 17.7 KB)
<?xml version="1.0" encoding="UTF-8"?> <!-- file : car1-trb1.xml created : Thu Sep 21 20:37:54 CET 2006 copyright : (C) 2006 by Bernhard Wymann email : [email protected] version : $Id: car1-trb1.xml,v 1.1 2006/09/22 21:10:00 berniw Exp $ --> <!-- This program is free software; you can redistribute it and/or modify --> <!-- it under the terms of the GNU General Public License as published by --> <!-- the Free Software Foundation; either version 2 of the License, or --> <!-- (at your option) any later version. --> <!DOCTYPE params SYSTEM "../../../../src/libs/tgf/params.dtd"> <params name="car1-trb1" type="template"> <section name="Driver"> <!-- Position of the driver --> <attnum name="xpos" val="0.75" unit="m"/> <attnum name="ypos" val="0.00" unit="m"/> <attnum name="zpos" val="0.95" unit="m"/> </section> <section name="Sound"> <attstr name="engine sample" val="f360.wav"/> <attnum name="rpm scale" val="1.25"/> </section> <section name="Graphic Objects"> <attstr name="env" val="car1-trb1.acc"/> <attstr name="wheel texture" val="tex-wheel.rgb"/> <attstr name="shadow texture" val="shadow.rgb"/> <attstr name="tachometer texture" val="rpm8500.rgb"/> <attnum name="tachometer min value" val="0" unit="rpm"/> <attnum name="tachometer max value" val="10000" unit="rpm"/> <attstr name="speedometer texture" val="speed360.rgb"/> <attnum name="speedometer min value" val="0" unit="km/h"/> <attnum name="speedometer max value" val="360" unit="km/h"/> <section name="Ranges"> <section name="1"> <attnum name="threshold" val="0"/> <attstr name="car" val="car1-trb1.acc"/> <attstr name="wheels" val="yes"/> </section> </section> <section name="Light"> <section name="1"> <attstr name="type" val="brake2"/> <attnum name="xpos" val="-2.18"/> <attnum name="ypos" val="0.57"/> <attnum name="zpos" val="0.65"/> <attnum name="size" val="0.3"/> </section> <section name="2"> <attstr name="type" val="brake2"/> <attnum name="xpos" val="-2.18"/> <attnum name="ypos" val="-0.57"/> <attnum name="zpos" val="0.65"/> <attnum name="size" val="0.3"/> </section> </section> </section> <section name="Car"> <attstr name="category" val="Track-RWD-GrA"/> <attnum name="body length" unit="m" min="4.5" max="5.0" val="4.52"/> <attnum name="body width" unit="m" min="0.8" max="2.0" val="1.94"/> <attnum name="body height" unit="m" min="1.1" max="1.7" val="1.1"/> <!-- collision bounding box --> <attnum name="overall length" unit="m" min="4.5" max="5.0" val="4.52"/> <attnum name="overall width" unit="m" min="1.2" max="2.0" val="1.94"/> <attnum name="mass" unit="kg" val="1150.0"/> <attnum name="GC height" unit="m" val="0.25"/> <!-- weight bias --> <attnum name="front-rear weight repartition" val="0.52"/> <attnum name="front right-left weight repartition" min="0.3" max="0.7" val="0.5"/> <attnum name="rear right-left weight repartition" min="0.3" max="0.7" val="0.5"/> <!-- used for inertia, indicates the good mass centering (lower values) --> <attnum name="mass repartition coefficient" val="0.62"/> <attnum name="fuel tank" unit="l" val="100.0"/> <attnum name="initial fuel" unit="l" min="1.0" max="100.0" val="80.0"/> </section> <section name="Exhaust"> <!-- for flames --> <attnum name="power" val="1.5"/> <section name="1"> <attnum name="xpos" val="-2.33"/> <attnum name="ypos" val="-0.65"/> <attnum name="zpos" val="0.28"/> </section> <section name="2"> <attnum name="xpos" val="-2.33"/> <attnum name="ypos" val="0.65"/> <attnum name="zpos" val="0.28"/> </section> </section> <section name="Aerodynamics"> <attnum name="Cx" min="0.20" max="2.0" val="0.33"/> <attnum name="front area" unit="m2" min="1.0" max="3.0" val="1.9"/> <attnum name="front Clift" min="0.0" max="1.5" val="0.69"/> <attnum name="rear Clift" min="0.0" max="1.5" val="0.72"/> </section> <section name="Front Wing"> <attnum name="area" unit="m2" val="0.2"/> <attnum name="angle" unit="deg" min="0" max="12" val="6"/> <attnum name="xpos" unit="m" val="2.20"/> <attnum name="zpos" unit="m" val="0.04"/> </section> <section name="Rear Wing"> <attnum name="area" unit="m2" min="0" max="1.0" val="0.7"/> <attnum name="angle" unit="deg" min="0" max="18" val="14"/> <attnum name="xpos" unit="m" min="-2.5" max="-1.0" val="-2.01"/> <attnum name="zpos" unit="m" min="0.1" max="1.5" val="0.99"/> </section> <!-- Same engine for every one --> <section name="Engine"> <attnum name="revs maxi" unit="rpm" min="7921" max="10000" val="10000"/> <attnum name="revs limiter" unit="rpm" min="7000" max="9152" val="9152"/> <attnum name="tickover" unit="rpm" min="900" max="2519" val="900"/> <attnum name="fuel cons factor" min="1.1" max="1.3" val="1.1"/> <attstr name="turbo" val="true"/> <attnum name="turbo rpm" unit="rpm" val="3000"/> <attnum name="turbo factor" val="1.0"/> <attnum name="turbo lag" val="0.5"/> <section name="data points"> <section name="1"> <attnum name="rpm" unit="rpm" val="0"/> <attnum name="Tq" unit="N.m" min="0.0" max="100.0" val="100.0"/> </section> <section name="2"> <attnum name="rpm" unit="rpm" val="1000"/> <attnum name="Tq" unit="N.m" min="0.0" max="160.0" val="260.0"/> </section> <section name="3"> <attnum name="rpm" unit="rpm" val="2000"/> <attnum name="Tq" unit="N.m" min="0.0" max="190.0" val="360.0"/> </section> <section name="4"> <attnum name="rpm" unit="rpm" val="3000"/> <attnum name="Tq" unit="N.m" min="0.0" max="280.0" val="420.0"/> </section> <section name="5"> <attnum name="rpm" unit="rpm" val="4000"/> <attnum name="Tq" unit="N.m" min="0.0" max="350" val="450"/> </section> <section name="6"> <attnum name="rpm" unit="rpm" val="5000"/> <attnum name="Tq" unit="N.m" min="0.0" max="405.0" val="455.0"/> </section> <section name="7"> <attnum name="rpm" unit="rpm" val="6000"/> <attnum name="Tq" unit="N.m" min="0.0" max="443.0" val="463.0"/> </section> <section name="8"> <attnum name="rpm" unit="rpm" val="7000"/> <attnum name="Tq" unit="N.m" min="0.0" max="465.0" val="475.0"/> </section> <section name="9"> <attnum name="rpm" unit="rpm" val="8000"/> <attnum name="Tq" unit="N.m" min="0.0" max="483.0" val="483.0"/> </section> <section name="10"> <attnum name="rpm" unit="rpm" val="9000"/> <attnum name="Tq" unit="N.m" min="0.0" max="415.0" val="415.0"/> </section> <section name="11"> <attnum name="rpm" unit="rpm" val="10000"/> <attnum name="Tq" unit="N.m" min="0.0" max="360.0" val="300.0"/> </section> <section name="12"> <attnum name="rpm" unit="rpm" val="11000"/> <attnum name="Tq" unit="N.m" min="0.0" max="971.0" val="71.0"/> </section> <section name="13"> <attnum name="rpm" unit="rpm" val="12000"/> <attnum name="Tq" unit="N.m" min="0.0" max="890.0" val="890.0"/> </section> <section name="14"> <attnum name="rpm" unit="rpm" val="13000"/> <attnum name="Tq" unit="N.m" min="0.0" max="821.0" val="821.0"/> </section> <section name="15"> <attnum name="rpm" unit="rpm" val="14000"/> <attnum name="Tq" unit="N.m" min="0.0" max="762.0" val="762.0"/> </section> <section name="16"> <attnum name="rpm" unit="rpm" val="15000"/> <attnum name="Tq" unit="N.m" min="0.0" max="712.0" val="712.0"/> </section> <section name="17"> <attnum name="rpm" unit="rpm" val="16000"/> <attnum name="Tq" unit="N.m" min="0.0" max="667.0" val="667.0"/> </section> <section name="18"> <attnum name="rpm" unit="rpm" val="17000"/> <attnum name="Tq" unit="N.m" min="0.0" max="628.0" val="628.0"/> </section> <section name="19"> <attnum name="rpm" unit="rpm" val="18000"/> <attnum name="Tq" unit="N.m" min="0.0" max="593.0" val="593.0"/> </section> <section name="20"> <attnum name="rpm" unit="rpm" val="19000"/> <attnum name="Tq" unit="N.m" min="0.0" max="562.0" val="562.0"/> </section> <section name="21"> <attnum name="rpm" unit="rpm" val="20000"/> <attnum name="Tq" unit="N.m" min="0.0" max="534.0" val="534.0"/> </section> </section> </section> <section name="Clutch"> <!-- pressure plate --> <attnum name="inertia" unit="kg.m2" val="0.1150"/> </section> <section name="Gearbox"> <attnum name="shift time" unit="s" val="0.15"/> <section name="gears"> <section name="r"> <attnum name="ratio" min="-3" max="0" val="-2.0"/> <attnum name="inertia" val="0.0037"/> <attnum name="efficiency" val="0.957"/> </section> <section name="1"> <attnum name="ratio" min="0" max="5" val="3.0"/> <attnum name="inertia" val="0.003"/> <attnum name="efficiency" val="0.955"/> </section> <section name="2"> <attnum name="ratio" min="0" max="5" val="1.9"/> <attnum name="inertia" val="0.0037"/> <attnum name="efficiency" val="0.957"/> </section> <section name="3"> <attnum name="ratio" min="0" max="5" val="1.4"/> <attnum name="inertia" val="0.0048"/> <attnum name="efficiency" val="0.950"/> </section> <section name="4"> <attnum name="ratio" min="0" max="5" val="1.1"/> <attnum name="inertia" val="0.0064"/> <attnum name="efficiency" val="0.983"/> </section> <section name="5"> <attnum name="ratio" min="0" max="5" val=".9"/> <attnum name="inertia" val="0.0107"/> <attnum name="efficiency" val="0.948"/> </section> <section name="6"> <attnum name="ratio" min="0" max="5" val="0.77"/> <attnum name="inertia" val="0.0150"/> <attnum name="efficiency" val="0.940"/> </section> </section> </section> <section name="Drivetrain"> <!-- allowed values RWD, FWD, 4WD --> <attstr name="type" val="RWD"/> <!-- drive shaft inertia --> <attnum name="inertia" unit="kg.m2" val="0.0091"/> </section> <section name="Steer"> <attnum name="steer lock" unit="deg" min="1" max="21" val="21"/> <attnum name="max steer speed" unit="deg/s" min="1" max="360" val="120"/> </section> <section name="Brake System"> <attnum name="front-rear brake repartition" min="0.3" max="0.7" val="0.55"/> <attnum name="max pressure" unit="kPa" min="100" max="150000" val="29000"/> </section> <section name="Front Axle"> <attnum name="xpos" min="0.5" max="2.5" val="1.22"/> <attnum name="inertia" unit="kg.m2" val="0.0056"/> <attnum name="roll center height" unit="m" min="0" max="0.5" val="0.02"/> </section> <section name="Rear Axle"> <attnum name="xpos" min="-2.5" max="-0.5" val="-1.42"/> <attnum name="inertia" unit="kg.m2" val="0.0080"/> <attnum name="roll center height" unit="m" min="0" max="0.5" val="0.06"/> </section> <section name="Front Differential"> <!-- type of differential : SPOOL (locked), FREE, LIMITED SLIP --> <attstr name="type" in="NONE" val="NONE"/> </section> <section name="Rear Differential"> <!-- type of differential : SPOOL (locked), FREE, LIMITED SLIP --> <attstr name="type" in="SPOOL,FREE,LIMITED SLIP" val="LIMITED SLIP"/> <attnum name="inertia" unit="kg.m2" val="0.0488"/> <attnum name="ratio" min="0" max="10" val="4.5"/> <attnum name="efficiency" val="0.9625"/> </section> <section name="Front Right Wheel"> <attnum name="ypos" unit="m" val="-0.84"/> <attnum name="rim diameter" unit="in" val="18.0"/> <attnum name="tire width" unit="mm" val="255"/> <attnum name="tire height-width ratio" val=".40"/> <attnum name="inertia" unit="kg.m2" val="1.2200"/> <attnum name="ride height" unit="mm" min="100" max="300" val="100"/> <attnum name="toe" unit="deg" min="-5" max="5" val="0"/> <attnum name="stiffness" min="20.0" max="30.0" val="20.0"/> <attnum name="camber" min="-5" max="-3" unit="deg" val="-4"/> <attnum name="dynamic friction" unit="%" val="80"/> <attnum name="rolling resistance" val="0.02"/> <attnum name="mu" val="1.6"/> </section> <section name="Front Left Wheel"> <attnum name="ypos" unit="m" val="0.84"/> <attnum name="rim diameter" unit="in" val="18.0"/> <attnum name="tire width" unit="mm" val="255"/> <attnum name="tire height-width ratio" val=".40"/> <attnum name="inertia" unit="kg.m2" val="1.2200"/> <attnum name="ride height" unit="mm" min="100" max="300" val="100"/> <attnum name="toe" unit="deg" min="-5" max="5" val="0"/> <attnum name="stiffness" min="20.0" max="30.0" val="20.0"/> <attnum name="camber" min="-5" max="-3" unit="deg" val="-4"/> <attnum name="dynamic friction" unit="%" val="80"/> <attnum name="rolling resistance" val="0.02"/> <attnum name="mu" val="1.6"/> </section> <section name="Rear Right Wheel"> <attnum name="ypos" unit="m" val="-0.80"/> <attnum name="rim diameter" unit="in" val="18.0"/> <attnum name="tire width" unit="mm" val="330"/> <attnum name="tire height-width ratio" val=".30"/> <attnum name="inertia" unit="kg.m2" val="1.2200"/> <attnum name="ride height" unit="mm" min="100" max="300" val="105"/> <attnum name="toe" unit="deg" val="0"/> <attnum name="stiffness" min="20.0" max="30.0" val="20.0"/> <attnum name="camber" min="-5" max="-2" unit="deg" val="-3"/> <attnum name="dynamic friction" unit="%" val="80"/> <attnum name="rolling resistance" val="0.02"/> <attnum name="mu" val="1.6"/> </section> <section name="Rear Left Wheel"> <attnum name="ypos" unit="m" val="0.80"/> <attnum name="rim diameter" unit="in" val="18.0"/> <attnum name="tire width" unit="mm" val="330"/> <attnum name="tire height-width ratio" val=".30"/> <attnum name="inertia" unit="kg.m2" val="1.2200"/> <attnum name="ride height" unit="mm" min="100" max="300" val="105"/> <attnum name="toe" unit="deg" val="0"/> <attnum name="stiffness" min="20.0" max="30.0" val="20.0"/> <attnum name="camber" min="-5" max="-2" unit="deg" val="-3"/> <attnum name="dynamic friction" unit="%" val="80"/> <attnum name="rolling resistance" val="0.02"/> <attnum name="mu" val="1.6"/> </section> <section name="Front Anti-Roll Bar"> <attnum name="spring" unit="lbs/in" min="0" max="5000" val="2000"/> <attnum name="suspension course" unit="m" min="0" max="0.2" val="0.2"/> <attnum name="bellcrank" min="1" max="5" val="1.0"/> </section> <section name="Rear Anti-Roll Bar"> <attnum name="spring" unit="lbs/in" min="0" max="5000" val="2000"/> <attnum name="suspension course" unit="m" min="0" max="0.2" val="0.2"/> <attnum name="bellcrank" min="1" max="5" val="1.0"/> </section> <section name="Front Right Suspension"> <attnum name="spring" unit="lbs/in" min="0" max="10000" val="5500"/> <attnum name="suspension course" unit="m" min="0" max="0.2" val="0.07"/> <attnum name="bellcrank" min="0.1" max="5" val="0.8"/> <attnum name="packers" unit="mm" min="0" max="50" val="20"/> <attnum name="slow bump" unit="lbs/in/s" min="0" max="1000" val="500"/> <attnum name="slow rebound" unit="lbs/in/s" min="0" max="1000" val="300"/> <attnum name="fast bump" unit="lbs/in/s" min="0" max="1000" val="60"/> <attnum name="fast rebound" unit="lbs/in/s" min="0" max="1000" val="60"/> </section> <section name="Front Left Suspension"> <attnum name="spring" unit="lbs/in" min="0" max="10000" val="5500"/> <attnum name="suspension course" unit="m" min="0" max="0.2" val="0.07"/> <attnum name="bellcrank" min="0.1" max="5" val="0.8"/> <attnum name="packers" unit="mm" min="0" max="50" val="20"/> <attnum name="slow bump" unit="lbs/in/s" min="0" max="1000" val="500"/> <attnum name="slow rebound" unit="lbs/in/s" min="0" max="1000" val="300"/> <attnum name="fast bump" unit="lbs/in/s" min="0" max="1000" val="60"/> <attnum name="fast rebound" unit="lbs/in/s" min="0" max="1000" val="60"/> </section> <section name="Rear Right Suspension"> <attnum name="spring" unit="lbs/in" min="0" max="10000" val="5500"/> <attnum name="suspension course" unit="m" min="0" max="0.2" val="0.13"/> <attnum name="bellcrank" min="0.1" max="5" val="1.0"/> <attnum name="packers" unit="mm" min="0" max="50" val="10"/> <attnum name="slow bump" unit="lbs/in/s" min="0" max="1000" val="400"/> <attnum name="slow rebound" unit="lbs/in/s" min="0" max="1000" val="500"/> <attnum name="fast bump" unit="lbs/in/s" min="0" max="1000" val="60"/> <attnum name="fast rebound" unit="lbs/in/s" min="0" max="1000" val="60"/> </section> <section name="Rear Left Suspension"> <attnum name="spring" unit="lbs/in" min="0" max="10000" val="5500"/> <attnum name="suspension course" unit="m" min="0" max="0.2" val="0.13"/> <attnum name="bellcrank" min="0.1" max="5" val="1.0"/> <attnum name="packers" unit="mm" min="0" max="50" val="10"/> <attnum name="slow bump" unit="lbs/in/s" min="0" max="1000" val="400"/> <attnum name="slow rebound" unit="lbs/in/s" min="0" max="1000" val="500"/> <attnum name="fast bump" unit="lbs/in/s" min="0" max="1000" val="60"/> <attnum name="fast rebound" unit="lbs/in/s" min="0" max="1000" val="60"/> </section> <section name="Front Right Brake"> <attnum name="disk diameter" unit="mm" min="100" max="380" val="380"/> <attnum name="piston area" unit="cm2" val="50"/> <attnum name="mu" val="0.4"/> <attnum name="inertia" unit="kg.m2" val="0.1241"/> </section> <section name="Front Left Brake"> <attnum name="disk diameter" unit="mm" min="100" max="380" val="380"/> <attnum name="piston area" unit="cm2" val="50"/> <attnum name="mu" val="0.4"/> <attnum name="inertia" unit="kg.m2" val="0.1241"/> </section> <section name="Rear Right Brake"> <attnum name="disk diameter" unit="mm" min="100" max="380" val="330"/> <attnum name="piston area" unit="cm2" val="35"/> <attnum name="mu" val="0.4"/> <attnum name="inertia" unit="kg.m2" val="0.0714"/> </section> <section name="Rear Left Brake"> <attnum name="disk diameter" unit="mm" min="100" max="380" val="330"/> <attnum name="piston area" unit="cm2" val="35"/> <attnum name="mu" val="0.4"/> <attnum name="inertia" unit="kg.m2" val="0.0714"/> </section> </params>
transmission.cpp
(text/x-c++src, 14.2 KB)
/***************************************************************************
file : transmission.cpp
created : Sun Mar 19 00:07:19 CET 2000
copyright : (C) 2000 by Eric Espie
email : [email protected]
version : $Id: transmission.cpp,v 1.22 2005/09/15 13:50:51 olethros Exp $
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "sim.h"
static char *gearname[MAX_GEARS] = {"r", "n", "1", "2", "3", "4", "5", "6", "7", "8"};
void
SimTransmissionConfig(tCar *car)
{
void *hdle = car->params;
tCarElt *carElt = car->carElt;
tdble clutchI;
tTransmission *trans = &(car->transmission);
tClutch *clutch = &(trans->clutch);
tDifferential *differential;
char *transType;
int i, j;
tdble gRatio, fRatio, gEff, fEff;
tdble gearI;
char path[256];
clutchI = GfParmGetNum(hdle, SECT_CLUTCH, PRM_INERTIA, (char*)NULL, 0.12f);
transType = GfParmGetStr(hdle, SECT_DRIVETRAIN, PRM_TYPE, VAL_TRANS_RWD);
clutch->releaseTime = GfParmGetNum(hdle, SECT_GEARBOX, PRM_SHIFTTIME, (char*)NULL, 0.2f);
fRatio = 0;
gEff = 0;
/* Link between the differentials */
for (j = 0; j < 2; j++) {
trans->differential[TRANS_FRONT_DIFF].inAxis[j] = &(car->wheel[j].feedBack);
trans->differential[TRANS_FRONT_DIFF].outAxis[j] = &(car->wheel[j].in);
}
for (j = 0; j < 2; j++) {
trans->differential[TRANS_REAR_DIFF].inAxis[j] = &(car->wheel[2+j].feedBack);
trans->differential[TRANS_REAR_DIFF].outAxis[j] = &(car->wheel[2+j].in);
}
trans->differential[TRANS_CENTRAL_DIFF].inAxis[0] = &(trans->differential[TRANS_FRONT_DIFF].feedBack);
trans->differential[TRANS_CENTRAL_DIFF].outAxis[0] = &(trans->differential[TRANS_FRONT_DIFF].in);
trans->differential[TRANS_CENTRAL_DIFF].inAxis[1] = &(trans->differential[TRANS_REAR_DIFF].feedBack);
trans->differential[TRANS_CENTRAL_DIFF].outAxis[1] = &(trans->differential[TRANS_REAR_DIFF].in);
if (strcmp(VAL_TRANS_RWD, transType) == 0) {
SimDifferentialConfig(hdle, SECT_REARDIFFERENTIAL, &(trans->differential[TRANS_REAR_DIFF]));
trans->type = TRANS_RWD;
fRatio = trans->differential[TRANS_REAR_DIFF].ratio;
fEff = trans->differential[TRANS_REAR_DIFF].efficiency;
} else if (strcmp(VAL_TRANS_FWD, transType) == 0) {
SimDifferentialConfig(hdle, SECT_FRNTDIFFERENTIAL, &(trans->differential[TRANS_FRONT_DIFF]));
trans->type = TRANS_FWD;
fRatio = trans->differential[TRANS_FRONT_DIFF].ratio;
fEff = trans->differential[TRANS_FRONT_DIFF].efficiency;
} else if (strcmp(VAL_TRANS_4WD, transType) == 0) {
SimDifferentialConfig(hdle, SECT_FRNTDIFFERENTIAL, &(trans->differential[TRANS_FRONT_DIFF]));
SimDifferentialConfig(hdle, SECT_REARDIFFERENTIAL, &(trans->differential[TRANS_REAR_DIFF]));
SimDifferentialConfig(hdle, SECT_CENTRALDIFFERENTIAL, &(trans->differential[TRANS_CENTRAL_DIFF]));
trans->type = TRANS_4WD;
fRatio = trans->differential[TRANS_CENTRAL_DIFF].ratio;
fEff = trans->differential[TRANS_FRONT_DIFF].efficiency * trans->differential[TRANS_CENTRAL_DIFF].efficiency * trans->differential[TRANS_REAR_DIFF].efficiency;
}
trans->gearbox.gearMax = 0;
//printf ("engine I %f\n", car->engine.I);
for (i = MAX_GEARS - 1; i >= 0; i--) {
sprintf(path, "%s/%s/%s", SECT_GEARBOX, ARR_GEARS, gearname[i]);
gRatio = GfParmGetNum(hdle, path, PRM_RATIO, (char*)NULL, 0.0f);
if ((trans->gearbox.gearMax == 0) && (gRatio != 0.0f)) {
trans->gearbox.gearMax = i - 1;
}
if (gRatio == 0.0f) {
carElt->priv.gearRatio[i] = trans->overallRatio[i] = 0;
trans->freeI[i] = trans->driveI[i] = 0;
trans->gearEff[i] = 1.0f;
continue;
}
carElt->priv.gearRatio[i] = trans->overallRatio[i] = gRatio * fRatio;
gEff = GfParmGetNum(hdle, path, PRM_EFFICIENCY, (char*)NULL, 1.0f);
if (gEff > 1.0f) gEff = 1.0f;
if (gEff < 0.0f) gEff = 0.0f;
gearI = GfParmGetNum(hdle, path, PRM_INERTIA, (char*)NULL, 0.0f);
trans->driveI[i] = (car->engine.I + gearI) * (gRatio * gRatio * fRatio * fRatio);
//printf ("drivetrain %d = %f %f\n", i, trans->driveI[i], gearI);
trans->freeI[i] = gearI * (gRatio * gRatio * fRatio * fRatio);
trans->gearEff[i] = gEff;
}
if (gRatio == 0) {
/* no reverse */
trans->gearbox.gearMin = 0;
carElt->priv.gearOffset = 0;
} else {
trans->gearbox.gearMin = -1;
carElt->priv.gearOffset = 1;
}
carElt->priv.gearNb = trans->gearbox.gearMax + 1;
/* initial state */
clutch->state = CLUTCH_RELEASING;
clutch->timeToRelease = 0;
trans->gearbox.gear = 0; /* neutral */
trans->curI = trans->freeI[1];
switch(trans->type) {
case TRANS_RWD:
differential = &(trans->differential[TRANS_REAR_DIFF]);
differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[0]->Tq = 0;
differential->outAxis[1]->Tq = 0;
break;
case TRANS_FWD:
differential = &(trans->differential[TRANS_FRONT_DIFF]);
differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[0]->Tq = 0;
differential->outAxis[1]->Tq = 0;
break;
case TRANS_4WD:
differential = &(trans->differential[TRANS_FRONT_DIFF]);
differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[0]->Tq = 0;
differential->outAxis[1]->Tq = 0;
differential = &(trans->differential[TRANS_REAR_DIFF]);
differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[0]->Tq = 0;
differential->outAxis[1]->Tq = 0;
differential = &(trans->differential[TRANS_CENTRAL_DIFF]);
differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
differential->outAxis[0]->Tq = 0;
differential->outAxis[1]->Tq = 0;
break;
}
}
void
SimGearboxUpdate(tCar *car)
{
/* manages gear change */
tTransmission *trans = &(car->transmission);
tClutch *clutch = &(trans->clutch);
tGearbox *gearbox = &(trans->gearbox);
tDifferential *differential = NULL;
switch(trans->type) {
case TRANS_RWD:
differential = &(trans->differential[TRANS_REAR_DIFF]);
break;
case TRANS_FWD:
differential = &(trans->differential[TRANS_FRONT_DIFF]);
break;
case TRANS_4WD:
differential = &(trans->differential[TRANS_CENTRAL_DIFF]);
break;
}
trans->curI = trans->driveI[gearbox->gear + 1] * clutch->transferValue + trans->freeI[gearbox->gear + 1] * (1.0f - clutch->transferValue);
if (clutch->state == CLUTCH_RELEASING) {
clutch->timeToRelease -= SimDeltaTime;
if (clutch->timeToRelease <= 0.0f) {
clutch->state = CLUTCH_RELEASED;
} else {
// If user does not engage clutch, we do it automatically.
if (clutch->transferValue > 0.99f) {
clutch->transferValue = 0.0f;
trans->curI = trans->freeI[gearbox->gear + 1];
// NOTE: Shouldn't usage of accelerator when shifting be let
// to the user to decide? Especially when shifting down
// in order to accelerate more, this could be annoying.
if (car->ctrl->accelCmd > 0.1f) {
car->ctrl->accelCmd = 0.1f;
}
}
}
} else if ((car->ctrl->gear > gearbox->gear)) {
if (car->ctrl->gear <= gearbox->gearMax) {
gearbox->gear = car->ctrl->gear;
clutch->state = CLUTCH_RELEASING;
if (gearbox->gear != 0) {
clutch->timeToRelease = clutch->releaseTime;
} else {
clutch->timeToRelease = 0;
}
trans->curOverallRatio = trans->overallRatio[gearbox->gear+1];
trans->curI = trans->freeI[gearbox->gear+1];
}
} else if ((car->ctrl->gear < gearbox->gear)) {
if (car->ctrl->gear >= gearbox->gearMin) {
gearbox->gear = car->ctrl->gear;
clutch->state = CLUTCH_RELEASING;
if (gearbox->gear != 0) {
clutch->timeToRelease = clutch->releaseTime;
} else {
clutch->timeToRelease = 0;
}
trans->curOverallRatio = trans->overallRatio[gearbox->gear+1];
trans->curI = trans->freeI[gearbox->gear+1];
}
}
differential->in.I = trans->curI + differential->feedBack.I / trans->gearEff[gearbox->gear+1];
differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
if (trans->type == TRANS_4WD) {
differential = &(trans->differential[TRANS_FRONT_DIFF]);
differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
differential = &(trans->differential[TRANS_REAR_DIFF]);
differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
}
}
void
SimTransmissionUpdate(tCar *car)
{
tTransmission *trans = &(car->transmission);
tClutch *clutch = &(trans->clutch);
tDifferential *differential, *differential0, *differential1;
tdble transfer = MIN(clutch->transferValue * 3.0f, 1.0f);
switch(trans->type) {
case TRANS_RWD:
differential = &(trans->differential[TRANS_REAR_DIFF]);
differential->in.Tq = (car->engine.Tq) * trans->curOverallRatio * transfer;
SimDifferentialUpdate(car, differential, 1);
SimUpdateFreeWheels(car, 0);
/* printf("s0 %f - s1 %f (%f) inTq %f -- Tq0 %f - Tq1 %f (%f)\n", */
/* differential->outAxis[0]->spinVel, differential->outAxis[1]->spinVel, differential->outAxis[0]->spinVel - differential->outAxis[1]->spinVel, */
/* differential->in.Tq, */
/* differential->outAxis[0]->Tq, differential->outAxis[1]->Tq, differential->outAxis[0]->Tq - differential->outAxis[1]->Tq); */
break;
case TRANS_FWD:
differential = &(trans->differential[TRANS_FRONT_DIFF]);
differential->in.Tq = (car->engine.Tq) * trans->curOverallRatio * transfer;
SimDifferentialUpdate(car, differential, 1);
SimUpdateFreeWheels(car, 1);
/* printf("s0 %f - s1 %f (%f) inTq %f -- Tq0 %f - Tq1 %f (%f)\n", */
/* differential->outAxis[0]->spinVel, differential->outAxis[1]->spinVel, differential->outAxis[0]->spinVel - differential->outAxis[1]->spinVel, */
/* differential->in.Tq, */
/* differential->outAxis[0]->Tq, differential->outAxis[1]->Tq, differential->outAxis[0]->Tq - differential->outAxis[1]->Tq); */
break;
case TRANS_4WD:
differential = &(trans->differential[TRANS_CENTRAL_DIFF]);
differential0 = &(trans->differential[TRANS_FRONT_DIFF]);
differential1 = &(trans->differential[TRANS_REAR_DIFF]);
differential->in.Tq = (car->engine.Tq) * trans->curOverallRatio * transfer;
differential->inAxis[0]->spinVel = (differential0->inAxis[0]->spinVel + differential0->inAxis[1]->spinVel) / 2.0f;
differential->inAxis[1]->spinVel = (differential1->inAxis[0]->spinVel + differential1->inAxis[1]->spinVel) / 2.0f;
differential->inAxis[0]->Tq = (differential0->inAxis[0]->Tq + differential0->inAxis[1]->Tq) / differential->ratio;
differential->inAxis[1]->Tq = (differential1->inAxis[0]->Tq + differential1->inAxis[1]->Tq) / differential->ratio;
differential->inAxis[0]->brkTq = (differential0->inAxis[0]->brkTq + differential0->inAxis[1]->brkTq) / differential->ratio;
differential->inAxis[1]->brkTq = (differential1->inAxis[0]->brkTq + differential1->inAxis[1]->brkTq) / differential->ratio;
SimDifferentialUpdate(car, differential, 1);
/* printf("\nCentral : s0 %f - s1 %f (%f) inTq %f -- Tq0 %f - Tq1 %f (%f)\n", */
/* differential->outAxis[0]->spinVel, differential->outAxis[1]->spinVel, differential->outAxis[0]->spinVel - differential->outAxis[1]->spinVel, */
/* differential->in.Tq, */
/* differential->outAxis[0]->Tq, differential->outAxis[1]->Tq, differential->outAxis[0]->Tq - differential->outAxis[1]->Tq); */
differential = differential0;
SimDifferentialUpdate(car, differential, 0);
/* printf("Front : s0 %f - s1 %f (%f) inTq %f -- Tq0 %f - Tq1 %f (%f)\n", */
/* differential->outAxis[0]->spinVel, differential->outAxis[1]->spinVel, differential->outAxis[0]->spinVel - differential->outAxis[1]->spinVel, */
/* differential->in.Tq, */
/* differential->outAxis[0]->Tq, differential->outAxis[1]->Tq, differential->outAxis[0]->Tq - differential->outAxis[1]->Tq); */
differential = differential1;
SimDifferentialUpdate(car, differential, 0);
/* printf("Rear : s0 %f - s1 %f (%f) inTq %f -- Tq0 %f - Tq1 %f (%f)\n", */
/* differential->outAxis[0]->spinVel, differential->outAxis[1]->spinVel, differential->outAxis[0]->spinVel - differential->outAxis[1]->spinVel, */
/* differential->in.Tq, */
/* differential->outAxis[0]->Tq, differential->outAxis[1]->Tq, differential->outAxis[0]->Tq - differential->outAxis[1]->Tq); */
break;
}
}
differential.cpp
(text/x-c++src, 10.6 KB)
/***************************************************************************
file : differential.cpp
created : Sun Mar 19 00:06:33 CET 2000
copyright : (C) 2000 by Eric Espie
email : [email protected]
version : $Id: differential.cpp,v 1.22 2006/09/02 17:53:21 olethros Exp $
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "sim.h"
void
SimDifferentialConfig(void *hdle, char *section, tDifferential *differential)
{
char *type;
differential->I = GfParmGetNum(hdle, section, PRM_INERTIA, (char*)NULL, 0.1);
differential->efficiency = GfParmGetNum(hdle, section, PRM_EFFICIENCY, (char*)NULL, 1.0);
differential->ratio = GfParmGetNum(hdle, section, PRM_RATIO, (char*)NULL, 1.0);
differential->bias = GfParmGetNum(hdle, section, PRM_BIAS, (char*)NULL, 0.1);
differential->dTqMin = GfParmGetNum(hdle, section, PRM_MIN_TQ_BIAS, (char*)NULL, 0.05);
differential->dTqMax = GfParmGetNum(hdle, section, PRM_MAX_TQ_BIAS, (char*)NULL, 0.80) - differential->dTqMin;
differential->dSlipMax = GfParmGetNum(hdle, section, PRM_MAX_SLIP_BIAS, (char*)NULL, 0.75);
differential->lockInputTq = GfParmGetNum(hdle, section, PRM_LOCKING_TQ, (char*)NULL, 300.0);
differential->viscosity = GfParmGetNum(hdle, section, PRM_VISCOSITY_FACTOR, (char*)NULL, 2.0);
differential->viscomax = 1 - exp(-differential->viscosity);
type = GfParmGetStr(hdle, section, PRM_TYPE, VAL_DIFF_NONE);
if (strcmp(type, VAL_DIFF_LIMITED_SLIP) == 0) {
differential->type = DIFF_LIMITED_SLIP;
} else if (strcmp(type, VAL_DIFF_VISCOUS_COUPLER) == 0) {
differential->type = DIFF_VISCOUS_COUPLER;
} else if (strcmp(type, VAL_DIFF_SPOOL) == 0) {
differential->type = DIFF_SPOOL;
} else if (strcmp(type, VAL_DIFF_FREE) == 0) {
differential->type = DIFF_FREE;
} else {
differential->type = DIFF_NONE;
}
differential->feedBack.I = differential->I * differential->ratio * differential->ratio +
(differential->inAxis[0]->I + differential->inAxis[1]->I) / differential->efficiency;
}
static void
updateSpool(tCar *car, tDifferential *differential, int first)
{
tdble DrTq;
tdble ndot;
tdble spinVel;
tdble BrTq;
tdble engineReaction;
tdble I;
tdble inTq, brkTq;
DrTq = differential->in.Tq;
I = differential->outAxis[0]->I + differential->outAxis[1]->I;
inTq = differential->inAxis[0]->Tq + differential->inAxis[1]->Tq;
brkTq = differential->inAxis[0]->brkTq + differential->inAxis[1]->brkTq;
ndot = SimDeltaTime * (DrTq - inTq) / I;
spinVel = differential->inAxis[0]->spinVel + ndot;
BrTq = - SIGN(spinVel) * brkTq;
ndot = SimDeltaTime * BrTq / I;
if (((ndot * spinVel) < 0.0) && (fabs(ndot) > fabs(spinVel))) {
ndot = -spinVel;
}
if ((spinVel == 0.0) && (ndot < 0.0)) ndot = 0;
spinVel += ndot;
if (first) {
engineReaction = SimEngineUpdateRpm(car, spinVel);
if (engineReaction != 0.0) {
spinVel = engineReaction;
}
}
differential->outAxis[0]->spinVel = differential->outAxis[1]->spinVel = spinVel;
differential->outAxis[0]->Tq = (differential->outAxis[0]->spinVel - differential->inAxis[0]->spinVel) / SimDeltaTime * differential->outAxis[0]->I;
differential->outAxis[1]->Tq = (differential->outAxis[1]->spinVel - differential->inAxis[1]->spinVel) / SimDeltaTime * differential->outAxis[1]->I;
}
void
SimDifferentialUpdate(tCar *car, tDifferential *differential, int first)
{
tdble DrTq, DrTq0, DrTq1;
tdble ndot0, ndot1;
tdble spinVel0, spinVel1;
tdble inTq0, inTq1;
tdble spdRatio, spdRatioMax;
tdble deltaSpd, deltaTq;
tdble BrTq;
tdble engineReaction;
tdble meanv;
if (differential->type == DIFF_SPOOL) {
updateSpool(car, differential, first);
return;
}
DrTq = differential->in.Tq;
spinVel0 = differential->inAxis[0]->spinVel;
spinVel1 = differential->inAxis[1]->spinVel;
inTq0 = differential->inAxis[0]->Tq;
inTq1 = differential->inAxis[1]->Tq;
spdRatio = fabs(spinVel0 + spinVel1);
if (spdRatio != 0) {
spdRatio = fabs(spinVel0 - spinVel1) / spdRatio;
switch (differential->type) {
case DIFF_FREE:
// I would think that the following is what a FREE
// differential should look like, with both wheels
// independent and linked through a spider gear.
//
// The reaction from each wheel is transmitted back to the
// spider gear. If both wheels react equally, then the
// spider gear does not turn. If one of the wheel is
// immobile, so that DrTq/2=inTq0 for example, then the
// reaction does not act against the drivetrain, but since
// the spider gear can turn freely, it acts on the other wheel.
//
// This system is equivalent to a rotating gear attached
// in between two parallel surfaces, with DrTq being
// equivalent to a force acting in the center of the
// gear. If one surface is fixed, only the other surface
// moves and all the force is 'transferred' to the moving
// surface. Or, the way I like to think of it, the
// immobile surface reacts with an equal and opposite
// force[1] that cancels DrTq/2 exactly and which is
// transmitted directly with the rotating gear to the
// other, free, surface.
//
//
// A lot of explanation for 3 lines of code.. TODO: Check
// what bias would mean in such a system. Would it be
// implemented between the spider and the wheels? Or
// between the spider and the drivetrain? If the latter
// then it meanst the spider would always be turning, even
// under an even load. I think in this case it is safest
// to ignore it completely because it is frequently used
// in cars with just FWD or RWD, and very frequently in
// just the front part of 4WD cars, while the default
// differential bias setting is 0.1...
//
// [1] For an object to remain at rest, all forces acting
// on it must sum to 0.
{
float spiderTq = inTq1 - inTq0;
DrTq0 = DrTq*0.5f + spiderTq;
DrTq1 = DrTq*0.5f - spiderTq;
}
break;
case DIFF_LIMITED_SLIP:
// Limited slip differential with:
// - Gradual frictive locking
// - Open differential behaviour when not locked
//
// The spider gear transfers torque between the two axles
// When DrTq=lockInputTq, then the locking is at 66% (and
// almost 100% at double the torque). When the
// differential is locked, there is a pressure applied due
// to the different amount of spin of each wheel. This
// pressure creates a torque bias at the input, limited by
// dSlipMax.
// So the user should use lockInputTq to regulate how fast
// the differential locks and dSlipMax to regulate how much
// more torque should go to the slower moving wheel.
{
float spiderTq = inTq1 - inTq0;
float propTq = DrTq/differential->lockInputTq;
float rate = 0.0f;
if (propTq > 0.0f) {
rate = 1.0f - exp(-propTq*propTq);
}
float pressure = tanh(rate*(spinVel1-spinVel0));
float bias = differential->dSlipMax * 0.5f* pressure;
float open = 1.0f;// - rate;
DrTq0 = DrTq*(0.5f+bias) + spiderTq*open;
DrTq1 = DrTq*(0.5f-bias) - spiderTq*open;
}
break;
case DIFF_VISCOUS_COUPLER:
if (spinVel0 >= spinVel1) {
DrTq0 = DrTq * differential->dTqMin;
DrTq1 = DrTq * (1 - differential->dTqMin);
} else {
deltaTq = differential->dTqMin + (1.0 - exp(-fabs(differential->viscosity * spinVel0 - spinVel1))) /
differential->viscomax * differential->dTqMax;
DrTq0 = DrTq * deltaTq;
DrTq1 = DrTq * (1 - deltaTq);
}
break;
default: /* NONE ? */
DrTq0 = DrTq1 = 0;
break;
}
} else {
DrTq0 = DrTq / 2.0;
DrTq1 = DrTq / 2.0;
}
ndot0 = SimDeltaTime * (DrTq0 - inTq0) / differential->outAxis[0]->I;
spinVel0 += ndot0;
ndot1 = SimDeltaTime * (DrTq1 - inTq1) / differential->outAxis[1]->I;
spinVel1 += ndot1;
BrTq = - SIGN(spinVel0) * differential->inAxis[0]->brkTq;
ndot0 = SimDeltaTime * BrTq / differential->outAxis[0]->I;
if (((ndot0 * spinVel0) < 0.0) && (fabs(ndot0) > fabs(spinVel0))) {
ndot0 = -spinVel0;
}
if ((spinVel0 == 0.0) && (ndot0 < 0.0)) ndot0 = 0;
spinVel0 += ndot0;
BrTq = - SIGN(spinVel1) * differential->inAxis[1]->brkTq;
ndot1 = SimDeltaTime * BrTq / differential->outAxis[1]->I;
if (((ndot1 * spinVel1) < 0.0) && (fabs(ndot1) > fabs(spinVel1))) {
ndot1 = -spinVel1;
}
if ((spinVel1 == 0.0) && (ndot1 < 0.0)) ndot1 = 0;
spinVel1 += ndot1;
if (first) {
meanv = (spinVel0 + spinVel1) / 2.0;
engineReaction = SimEngineUpdateRpm(car, meanv);
if (meanv != 0.0) {
engineReaction = engineReaction/meanv;
if ((spinVel1*spinVel0)>0) {
if (engineReaction != 0.0) {
spinVel1 *= engineReaction;
spinVel0 *= engineReaction;
}
}
}
}
differential->outAxis[0]->spinVel = spinVel0;
differential->outAxis[1]->spinVel = spinVel1;
differential->outAxis[0]->Tq = (differential->outAxis[0]->spinVel - differential->inAxis[0]->spinVel) / SimDeltaTime * differential->outAxis[0]->I;
differential->outAxis[1]->Tq = (differential->outAxis[1]->spinVel - differential->inAxis[1]->spinVel) / SimDeltaTime * differential->outAxis[1]->I;
}