TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
differential.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 file : differential.cpp
4 created : Sun Mar 19 00:06:33 CET 2000
5 copyright : (C) 2000-2026 by Eric Espie, Bernhard Wymann
6 email : berniw@bluewin.ch
7
8 ***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19#include "sim.h"
20
21
40static tdble
41applyBrakeToSpinVel(tdble spinVel, tdble brkTq, tdble inertia)
42{
43 tdble BrTq = - (tdble) SIGN(spinVel) * brkTq;
44 tdble ndot = SimDeltaTime * BrTq / inertia;
45
46 if (((ndot * spinVel) < 0.0f) && (fabs(ndot) > fabs(spinVel))) {
47 ndot = -spinVel;
48 }
49 if ((spinVel == 0.0f) && (ndot < 0.0f)) {
50 ndot = 0.0f;
51 }
52
53 return spinVel + ndot;
54}
55
56void SimDifferentialConfig(void *hdle, const char *section, tDifferential *differential)
57{
58 differential->I = GfParmGetNum(hdle, section, PRM_INERTIA, (char*)NULL, 0.1f);
59 differential->efficiency = GfParmGetNum(hdle, section, PRM_EFFICIENCY, (char*)NULL, 1.0f);
60 differential->ratio = GfParmGetNum(hdle, section, PRM_RATIO, (char*)NULL, 1.0f);
61 differential->dTqMin = GfParmGetNum(hdle, section, PRM_MIN_TQ_BIAS, (char*)NULL, 0.05f);
62 differential->dTqMax = GfParmGetNum(hdle, section, PRM_MAX_TQ_BIAS, (char*)NULL, 0.80f) - differential->dTqMin;
63 if (differential->dTqMax < 0.0f) differential->dTqMax = 0.0f;
64 differential->dSlipMax = GfParmGetNum(hdle, section, PRM_MAX_SLIP_BIAS, (char*)NULL, 0.03f);
65 differential->lockInputTq = GfParmGetNum(hdle, section, PRM_LOCKING_TQ, (char*)NULL, 3000.0f);
66 differential->lockBrakeInputTq = GfParmGetNum(hdle, section, PRM_LOCKINGBRAKE_TQ, (char*)NULL, differential->lockInputTq*0.33f);
67 differential->viscosity = GfParmGetNum(hdle, section, PRM_VISCOSITY_FACTOR, (char*)NULL, 1.0f);
68
69 const char* type = GfParmGetStr(hdle, section, PRM_TYPE, VAL_DIFF_NONE);
70 if (strcmp(type, VAL_DIFF_LIMITED_SLIP) == 0) {
71 differential->type = DIFF_LIMITED_SLIP;
72 } else if (strcmp(type, VAL_DIFF_VISCOUS_COUPLER) == 0) {
73 differential->type = DIFF_VISCOUS_COUPLER;
74 } else if (strcmp(type, VAL_DIFF_SPOOL) == 0) {
75 differential->type = DIFF_SPOOL;
76 } else if (strcmp(type, VAL_DIFF_FREE) == 0) {
77 differential->type = DIFF_FREE;
78 } else {
79 differential->type = DIFF_NONE;
80 }
81
82 differential->feedBack.I = differential->I * differential->ratio * differential->ratio +
83 (differential->inAxis[0]->I + differential->inAxis[1]->I) / differential->efficiency;
84}
85
86
87void SimDifferentialReConfig(tCar* car, int index)
88{
89 tDifferential *differential = &car->transmission.differential[index];
90
91 // Ratio
94 differential->ratio = v->value;
95 differential->feedBack.I = differential->I * differential->ratio * differential->ratio +
96 (differential->inAxis[0]->I + differential->inAxis[1]->I) / differential->efficiency;
97 }
98
99 // Min torque bias
100 v = &car->carElt->pitcmd.setup.diffmintqbias[index];
102 differential->dTqMin = v->value;
103 }
104
105 // Max torque bias
106 v = &car->carElt->pitcmd.setup.diffmaxtqbias[index];
108 differential->dTqMax = v->value - differential->dTqMin;
109 if (differential->dTqMax < 0.0f) {
110 differential->dTqMax = 0.0f;
111 v->value = differential->dTqMin;
112 }
113 }
114
115 // Slip bias
116 v = &car->carElt->pitcmd.setup.diffslipbias[index];
118 differential->dSlipMax = v->value;
119 }
120
121 // Locking input torque
122 v = &car->carElt->pitcmd.setup.difflockinginputtq[index];
124 differential->lockInputTq = v->value;
125 }
126
127 // Locking brake input torque
128 v = &car->carElt->pitcmd.setup.difflockinginputbraketq[index];
130 differential->lockBrakeInputTq = v->value;
131 }
132}
133
134
135static void updateSpool(tCar *car, tDifferential *differential, int first)
136{
137 tdble DrTq;
138 tdble ndot;
139 tdble spinVel;
140 tdble engineReaction;
141 tdble I;
142 tdble inTq, brkTq;
143
144 DrTq = differential->in.Tq;
145
146 I = differential->outAxis[0]->I + differential->outAxis[1]->I;
147 inTq = differential->inAxis[0]->Tq + differential->inAxis[1]->Tq;
148 brkTq = differential->inAxis[0]->brkTq + differential->inAxis[1]->brkTq;
149
150 ndot = SimDeltaTime * (DrTq - inTq) / I;
151 spinVel = differential->inAxis[0]->spinVel + ndot;
152 spinVel = applyBrakeToSpinVel(spinVel, brkTq, I);
153 if (first) {
154 engineReaction = SimEngineUpdateRpm(car, spinVel);
155 if (engineReaction != 0.0f) {
156 spinVel = engineReaction;
157 }
158 }
159 differential->outAxis[0]->spinVel = differential->outAxis[1]->spinVel = spinVel;
160
161 differential->outAxis[0]->Tq = (differential->outAxis[0]->spinVel - differential->inAxis[0]->spinVel) / SimDeltaTime * differential->outAxis[0]->I;
162 differential->outAxis[1]->Tq = (differential->outAxis[1]->spinVel - differential->inAxis[1]->spinVel) / SimDeltaTime * differential->outAxis[1]->I;
163}
164
165
166void
167SimDifferentialUpdate(tCar *car, tDifferential *differential, int first)
168{
169 tdble DrTq, DrTq0, DrTq1;
170 tdble ndot0, ndot1;
171 tdble spinVel0, spinVel1;
172 tdble inTq0, inTq1;
173 tdble spdRatioMax, commomSpinVel;
174 tdble deltaSpd, deltaTq, bias, lockTq, biassign;
175 tdble engineReaction;
176 tdble meanv;
177
178 if (differential->type == DIFF_SPOOL) {
179 updateSpool(car, differential, first);
180 return;
181 }
182
183 DrTq = differential->in.Tq;
184
185 spinVel0 = differential->inAxis[0]->spinVel;
186 spinVel1 = differential->inAxis[1]->spinVel;
187
188 inTq0 = differential->inAxis[0]->Tq;
189 inTq1 = differential->inAxis[1]->Tq;
190
191 commomSpinVel = (tdble) (fabs(spinVel0) + fabs(spinVel1));
192 if (commomSpinVel != 0) {
193 tdble spdRatio = (tdble) fabs(spinVel0 - spinVel1) / commomSpinVel;
194
195 switch (differential->type) {
196 case DIFF_FREE:
197 {
198 tdble spiderTq = inTq1 - inTq0;
199 DrTq0 = (DrTq + spiderTq)*0.5f;
200 DrTq1 = (DrTq - spiderTq)*0.5f;
201 }
202 break;
204 if (DrTq > differential->lockInputTq || DrTq < -differential->lockBrakeInputTq) {
205 updateSpool(car, differential, first);
206 return;
207 }
208
209 if (DrTq >= 0.0f) {
210 lockTq = differential->lockInputTq;
211 biassign = 1.0f;
212 } else {
213 lockTq = -differential->lockBrakeInputTq;
214 biassign = -1.0f;
215 }
216
217 spdRatioMax = differential->dSlipMax - DrTq * differential->dSlipMax / lockTq;
218 bias = 0.0f;
219 if (spdRatio > spdRatioMax) {
220 deltaSpd = (spdRatio - spdRatioMax) * commomSpinVel / 2.0f;
221 if (spinVel0 > spinVel1) {
222 spinVel0 -= deltaSpd;
223 spinVel1 += deltaSpd;
224 bias = -(spdRatio - spdRatioMax);
225 } else {
226 spinVel0 += deltaSpd;
227 spinVel1 -= deltaSpd;
228 bias = (spdRatio - spdRatioMax);
229 }
230 }
231
232 {
233 tdble spiderTq = inTq1 - inTq0;
234 DrTq0 = (DrTq*(1.0f + bias*biassign) + spiderTq)*0.5f;
235 DrTq1 = (DrTq*(1.0f - bias*biassign) - spiderTq)*0.5f;
236 }
237 break;
239 if (spinVel0 >= spinVel1) {
240 DrTq0 = DrTq * differential->dTqMin;
241 DrTq1 = DrTq * (1.0f - differential->dTqMin);
242 } else {
243 deltaTq = differential->dTqMin + (1.0f - (tdble) exp(-fabs(differential->viscosity * (spinVel0 - spinVel1)))) * differential->dTqMax;
244 DrTq0 = DrTq * deltaTq;
245 DrTq1 = DrTq * (1.0f - deltaTq);
246 }
247
248 break;
249 default: /* NONE ? */
250 DrTq0 = DrTq1 = 0.0f;
251 break;
252 }
253 } else {
254 DrTq0 = DrTq / 2.0f;
255 DrTq1 = DrTq / 2.0f;
256 }
257
258 ndot0 = SimDeltaTime * (DrTq0 - inTq0) / differential->outAxis[0]->I;
259 spinVel0 += ndot0;
260 ndot1 = SimDeltaTime * (DrTq1 - inTq1) / differential->outAxis[1]->I;
261 spinVel1 += ndot1;
262
263 spinVel0 = applyBrakeToSpinVel(spinVel0, differential->inAxis[0]->brkTq, differential->outAxis[0]->I);
264 spinVel1 = applyBrakeToSpinVel(spinVel1, differential->inAxis[1]->brkTq, differential->outAxis[1]->I);
265
266 if (first) {
267 meanv = (spinVel0 + spinVel1) / 2.0f;
268 engineReaction = SimEngineUpdateRpm(car, meanv);
269 if (meanv != 0.0f) {
270 engineReaction = engineReaction / meanv;
271 if (engineReaction != 0.0f) {
272 spinVel1 *= engineReaction;
273 spinVel0 *= engineReaction;
274 }
275 }
276 }
277
278 differential->outAxis[0]->spinVel = spinVel0;
279 differential->outAxis[1]->spinVel = spinVel1;
280
281 differential->outAxis[0]->Tq = (differential->outAxis[0]->spinVel - differential->inAxis[0]->spinVel) / SimDeltaTime * differential->outAxis[0]->I;
282 differential->outAxis[1]->Tq = (differential->outAxis[1]->spinVel - differential->inAxis[1]->spinVel) / SimDeltaTime * differential->outAxis[1]->I;
283}
284
285
#define PRM_LOCKINGBRAKE_TQ
Definition car.h:625
#define VAL_DIFF_SPOOL
Definition car.h:630
#define VAL_DIFF_FREE
Definition car.h:631
#define PRM_VISCOSITY_FACTOR
Definition car.h:626
#define VAL_DIFF_NONE
Definition car.h:629
#define PRM_LOCKING_TQ
Definition car.h:624
#define PRM_MIN_TQ_BIAS
Definition car.h:621
#define PRM_TYPE
Definition car.h:531
#define VAL_DIFF_VISCOUS_COUPLER
Definition car.h:633
#define PRM_INERTIA
Definition car.h:529
#define PRM_MAX_TQ_BIAS
Definition car.h:622
#define PRM_MAX_SLIP_BIAS
Definition car.h:623
#define PRM_EFFICIENCY
Definition car.h:530
#define VAL_DIFF_LIMITED_SLIP
Definition car.h:632
#define PRM_RATIO
Definition car.h:604
void SimDifferentialReConfig(tCar *car, int index)
void SimDifferentialConfig(void *hdle, const char *section, tDifferential *differential)
void SimDifferentialUpdate(tCar *car, tDifferential *differential, int first)
static void updateSpool(tCar *car, tDifferential *differential, int first)
static tdble applyBrakeToSpinVel(tdble spinVel, tdble brkTq, tdble inertia)
Integrate wheel/axle brake torque for one simulation step.
#define DIFF_VISCOUS_COUPLER
#define DIFF_NONE
#define DIFF_SPOOL
#define DIFF_LIMITED_SLIP
#define DIFF_FREE
tdble SimEngineUpdateRpm(tCar *car, tdble axleRpm)
Definition engine.cpp:162
float tdble
Floating point type used in TORCS.
Definition tgf.h:47
const char * GfParmGetStr(void *parmHandle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle.
Definition params.cpp:2453
tdble GfParmGetNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle.
Definition params.cpp:2534
tdble SimDeltaTime
Definition simu.cpp:35
bool SimAdjustPitCarSetupParam(tCarPitSetupValue *v)
Definition simu.cpp:500
tCarPitCmd pitcmd
private
Definition car.h:465
Section header structure.
Definition params.cpp:83
tTransmission transmission
Definition carstruct.h:51
tCarElt * carElt
Definition carstruct.h:40
tCarPitSetup setup
Definition car.h:443
tCarPitSetupValue diffmintqbias[3]
Definition car.h:426
tCarPitSetupValue diffratio[3]
Definition car.h:425
tCarPitSetupValue diffslipbias[3]
Definition car.h:428
tCarPitSetupValue difflockinginputbraketq[3]
Definition car.h:430
tCarPitSetupValue diffmaxtqbias[3]
Definition car.h:427
tCarPitSetupValue difflockinginputtq[3]
Definition car.h:429
tdble value
Definition car.h:377
tDynAxis * outAxis[2]
tDynAxis * inAxis[2]
tdble lockBrakeInputTq
tDynAxis feedBack
tdble spinVel
tdble brkTq
tDifferential differential[3]
#define SIGN(x)
Sign of the expression.
Definition tgf.h:77