TORCS  1.3.9
The Open Racing Car Simulator
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 
40 static tdble
41 applyBrakeToSpinVel(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 
56 void 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 
87 void SimDifferentialReConfig(tCar* car, int index)
88 {
89  tDifferential *differential = &car->transmission.differential[index];
90 
91  // Ratio
92  tCarPitSetupValue* v = &car->carElt->pitcmd.setup.diffratio[index];
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];
101  if (SimAdjustPitCarSetupParam(v)) {
102  differential->dTqMin = v->value;
103  }
104 
105  // Max torque bias
106  v = &car->carElt->pitcmd.setup.diffmaxtqbias[index];
107  if (SimAdjustPitCarSetupParam(v)) {
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];
117  if (SimAdjustPitCarSetupParam(v)) {
118  differential->dSlipMax = v->value;
119  }
120 
121  // Locking input torque
122  v = &car->carElt->pitcmd.setup.difflockinginputtq[index];
123  if (SimAdjustPitCarSetupParam(v)) {
124  differential->lockInputTq = v->value;
125  }
126 
127  // Locking brake input torque
128  v = &car->carElt->pitcmd.setup.difflockinginputbraketq[index];
129  if (SimAdjustPitCarSetupParam(v)) {
130  differential->lockBrakeInputTq = v->value;
131  }
132 }
133 
134 
135 static 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 
166 void
167 SimDifferentialUpdate(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;
203  case DIFF_LIMITED_SLIP:
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 DIFF_FREE
Definition: differential.h:37
#define PRM_TYPE
Definition: car.h:527
void SimDifferentialReConfig(tCar *car, int index)
#define PRM_LOCKING_TQ
Definition: car.h:620
static tdble applyBrakeToSpinVel(tdble spinVel, tdble brkTq, tdble inertia)
Integrate wheel/axle brake torque for one simulation step.
tCarPitSetupValue diffmaxtqbias[3]
Definition: car.h:425
bool SimAdjustPitCarSetupParam(tCarPitSetupValue *v)
Definition: simu.cpp:491
tCarPitCmd pitcmd
private
Definition: car.h:463
#define SIGN(x)
Sign of the expression.
Definition: tgf.h:78
Definition: carstruct.h:35
#define PRM_MIN_TQ_BIAS
Definition: car.h:617
void SimDifferentialUpdate(tCar *car, tDifferential *differential, int first)
tdble SimDeltaTime
Definition: simu.cpp:35
#define VAL_DIFF_LIMITED_SLIP
Definition: car.h:628
Section header structure.
Definition: params.cpp:83
#define PRM_MAX_SLIP_BIAS
Definition: car.h:619
tDifferential differential[3]
Definition: transmission.h:68
tDynAxis * outAxis[2]
Definition: differential.h:54
tCarPitSetupValue diffratio[3]
Definition: car.h:423
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:2311
#define VAL_DIFF_SPOOL
Definition: car.h:626
static void updateSpool(tCar *car, tDifferential *differential, int first)
#define VAL_DIFF_NONE
Definition: car.h:625
tCarPitSetupValue difflockinginputtq[3]
Definition: car.h:427
#define VAL_DIFF_VISCOUS_COUPLER
Definition: car.h:629
tdble spinVel
Definition: differential.h:25
tdble efficiency
Definition: differential.h:42
tdble SimEngineUpdateRpm(tCar *car, tdble axleRpm)
Definition: engine.cpp:162
tDynAxis * inAxis[2]
Definition: differential.h:53
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
tdble value
Definition: car.h:375
tCarElt * carElt
Definition: carstruct.h:40
tCarPitSetup setup
Definition: car.h:441
#define DIFF_VISCOUS_COUPLER
Definition: differential.h:39
#define DIFF_LIMITED_SLIP
Definition: differential.h:38
#define PRM_RATIO
Definition: car.h:600
#define PRM_MAX_TQ_BIAS
Definition: car.h:618
void SimDifferentialConfig(void *hdle, const char *section, tDifferential *differential)
tdble brkTq
Definition: differential.h:27
tCarPitSetupValue diffmintqbias[3]
Definition: car.h:424
tdble lockBrakeInputTq
Definition: differential.h:47
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:2392
#define DIFF_SPOOL
Definition: differential.h:36
tdble Tq
Definition: differential.h:26
tTransmission transmission
Definition: carstruct.h:51
#define DIFF_NONE
Definition: differential.h:35
tDynAxis in
Definition: differential.h:51
tdble lockInputTq
Definition: differential.h:46
#define VAL_DIFF_FREE
Definition: car.h:627
#define PRM_EFFICIENCY
Definition: car.h:526
#define PRM_INERTIA
Definition: car.h:525
#define PRM_VISCOSITY_FACTOR
Definition: car.h:622
tdble I
Definition: differential.h:28
tCarPitSetupValue diffslipbias[3]
Definition: car.h:426
tDynAxis feedBack
Definition: differential.h:52
#define PRM_LOCKINGBRAKE_TQ
Definition: car.h:621
tCarPitSetupValue difflockinginputbraketq[3]
Definition: car.h:428