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;
    
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.