TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
transmission.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 file : transmission.cpp
4 created : Sun Mar 19 00:07:19 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#include <portability.h>
21
22static const char *gearname[MAX_GEARS] = {"r", "n", "1", "2", "3", "4", "5", "6", "7", "8"};
23
25{
26 void *hdle = car->params;
27 tCarElt *carElt = car->carElt;
28 //tdble clutchI;
29 tTransmission *trans = &(car->transmission);
30 tClutch *clutch = &(trans->clutch);
31 tDifferential *differential;
32 int i, j;
33 tdble gRatio, fRatio, gEff; //fEff;
34 tdble gearI;
35 const int BUFSIZE = 256;
36 char path[BUFSIZE];
37
38 //clutchI = GfParmGetNum(hdle, SECT_CLUTCH, PRM_INERTIA, (char*)NULL, 0.12f);
39 const char* transType = GfParmGetStr(hdle, SECT_DRIVETRAIN, PRM_TYPE, VAL_TRANS_RWD);
40 clutch->releaseTime = GfParmGetNum(hdle, SECT_GEARBOX, PRM_SHIFTTIME, (char*)NULL, 0.2f);
41
42 fRatio = 0;
43 gEff = 0;
44
45 /* Link between the differentials */
46 for (j = 0; j < 2; j++) {
47 trans->differential[TRANS_FRONT_DIFF].inAxis[j] = &(car->wheel[j].feedBack);
48 trans->differential[TRANS_FRONT_DIFF].outAxis[j] = &(car->wheel[j].in);
49 }
50
51 for (j = 0; j < 2; j++) {
52 trans->differential[TRANS_REAR_DIFF].inAxis[j] = &(car->wheel[2+j].feedBack);
53 trans->differential[TRANS_REAR_DIFF].outAxis[j] = &(car->wheel[2+j].in);
54 }
55
58
61
62 if (strcmp(VAL_TRANS_RWD, transType) == 0) {
64 trans->type = TRANS_RWD;
65 fRatio = trans->differential[TRANS_REAR_DIFF].ratio;
66 //fEff = trans->differential[TRANS_REAR_DIFF].efficiency;
67 } else if (strcmp(VAL_TRANS_FWD, transType) == 0) {
69 trans->type = TRANS_FWD;
70 fRatio = trans->differential[TRANS_FRONT_DIFF].ratio;
71 //fEff = trans->differential[TRANS_FRONT_DIFF].efficiency;
72 } else if (strcmp(VAL_TRANS_4WD, transType) == 0) {
76 trans->type = TRANS_4WD;
77 fRatio = trans->differential[TRANS_CENTRAL_DIFF].ratio;
78 //fEff = trans->differential[TRANS_FRONT_DIFF].efficiency * trans->differential[TRANS_CENTRAL_DIFF].efficiency * trans->differential[TRANS_REAR_DIFF].efficiency;
79 }
80
81 trans->gearbox.gearMax = 0;
82 for (i = MAX_GEARS - 1; i >= 0; i--) {
83 snprintf(path, BUFSIZE, "%s/%s/%s", SECT_GEARBOX, ARR_GEARS, gearname[i]);
84 gRatio = GfParmGetNum(hdle, path, PRM_RATIO, (char*)NULL, 0.0f);
85 if ((trans->gearbox.gearMax == 0) && (gRatio != 0.0f)) {
86 trans->gearbox.gearMax = i - 1;
87 }
88 if (gRatio == 0.0f) {
89 carElt->priv.gearRatio[i] = trans->overallRatio[i] = 0.0f;
90 trans->freeI[i] = trans->driveI[i] = 0;
91 trans->gearEff[i] = 1.0;
92 continue;
93 }
94 carElt->priv.gearRatio[i] = trans->overallRatio[i] = gRatio * fRatio;
95 gEff = GfParmGetNum(hdle, path, PRM_EFFICIENCY, (char*)NULL, 1.0f);
96 if (gEff > 1.0f) gEff = 1.0f;
97 if (gEff < 0.0f) gEff = 0.0f;
98 gearI = GfParmGetNum(hdle, path, PRM_INERTIA, (char*)NULL, 0.0f);
99 trans->driveI[i] = (car->engine.I + gearI) * (gRatio * gRatio * fRatio * fRatio);
100 trans->freeI[i] = gearI * (gRatio * gRatio * fRatio * fRatio);
101 trans->gearEff[i] = gEff;
102 }
103
104 if (gRatio == 0) {
105 /* no reverse */
106 trans->gearbox.gearMin = 0;
107 carElt->priv.gearOffset = 0;
108 } else {
109 trans->gearbox.gearMin = -1;
110 carElt->priv.gearOffset = 1;
111 }
112
113 carElt->priv.gearNb = trans->gearbox.gearMax + 1;
114
115 /* initial state */
116 clutch->state = CLUTCH_RELEASING;
117 clutch->timeToRelease = 0;
118 trans->gearbox.gear = 0; /* neutral */
119 trans->curI = trans->freeI[1];
120 switch(trans->type) {
121 case TRANS_RWD:
122 differential = &(trans->differential[TRANS_REAR_DIFF]);
123 differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
124 differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
125 differential->outAxis[0]->Tq = 0;
126 differential->outAxis[1]->Tq = 0;
127 break;
128 case TRANS_FWD:
129 differential = &(trans->differential[TRANS_FRONT_DIFF]);
130 differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
131 differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
132 differential->outAxis[0]->Tq = 0;
133 differential->outAxis[1]->Tq = 0;
134 break;
135 case TRANS_4WD:
136 differential = &(trans->differential[TRANS_FRONT_DIFF]);
137 differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
138 differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
139 differential->outAxis[0]->Tq = 0;
140 differential->outAxis[1]->Tq = 0;
141 differential = &(trans->differential[TRANS_REAR_DIFF]);
142 differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
143 differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
144 differential->outAxis[0]->Tq = 0;
145 differential->outAxis[1]->Tq = 0;
146 differential = &(trans->differential[TRANS_CENTRAL_DIFF]);
147 differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[trans->gearbox.gear+1];
148 differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[trans->gearbox.gear+1];
149 differential->outAxis[0]->Tq = 0;
150 differential->outAxis[1]->Tq = 0;
151 break;
152 }
153
154}
155
156
157static void setupGear(void* hdle, tCar *car, tCarElt *carElt, tTransmission *trans, tdble gRatio, tdble fRatio, int i)
158{
159 const int BUFSIZE = 256;
160 char path[BUFSIZE];
161
162 carElt->priv.gearRatio[i] = trans->overallRatio[i] = gRatio * fRatio;
163 snprintf(path, BUFSIZE, "%s/%s/%s", SECT_GEARBOX, ARR_GEARS, gearname[i]);
164
165 tdble gearI = GfParmGetNum(hdle, path, PRM_INERTIA, (char*)NULL, 0.0f);
166 trans->driveI[i] = (car->engine.I + gearI) * (gRatio * gRatio * fRatio * fRatio);
167 trans->freeI[i] = gearI * (gRatio * gRatio * fRatio * fRatio);
168}
169
170
172{
173 void *hdle = car->params;
174 tCarElt *carElt = car->carElt;
175 tTransmission *trans = &(car->transmission);
176 int i;
177 tdble fRatio = 0.0f;
178 const int BUFSIZE = 256;
179 char path[BUFSIZE];
180
181 if (trans->type == TRANS_RWD) {
183 fRatio = trans->differential[TRANS_REAR_DIFF].ratio;
184 } else if (trans->type == TRANS_FWD) {
186 fRatio = trans->differential[TRANS_FRONT_DIFF].ratio;
187 } else if (trans->type == TRANS_4WD) {
191 fRatio = trans->differential[TRANS_CENTRAL_DIFF].ratio;
192 }
193
194 for (i = MAX_GEARS - 1; i - 2 >= 0; i--) {
195 if (trans->overallRatio[i] > 0.0f) {
198 tdble gRatio = v->value;
199 setupGear(hdle, car, carElt, trans, gRatio, fRatio, i);
200 }
201 }
202
203 // Handle reverse gear
204 if (trans->overallRatio[0] != 0.0f) {
205 snprintf(path, BUFSIZE, "%s/%s/%s", SECT_GEARBOX, ARR_GEARS, gearname[0]);
206 tdble gRatio = GfParmGetNum(hdle, path, PRM_RATIO, (char*)NULL, 0.0f);
207 setupGear(hdle, car, carElt, trans, gRatio, fRatio, 0);
208 }
209
210 trans->gearbox.gear = 0;
211}
212
213
215{
216 /* manages gear change */
217 tTransmission *trans = &(car->transmission);
218 tClutch *clutch = &(trans->clutch);
219 tGearbox *gearbox = &(trans->gearbox);
220 tDifferential *differential = NULL;
221
222 switch(trans->type) {
223 case TRANS_RWD:
224 differential = &(trans->differential[TRANS_REAR_DIFF]);
225 break;
226 case TRANS_FWD:
227 differential = &(trans->differential[TRANS_FRONT_DIFF]);
228 break;
229 case TRANS_4WD:
230 differential = &(trans->differential[TRANS_CENTRAL_DIFF]);
231 break;
232 }
233
234 trans->curI = trans->driveI[gearbox->gear + 1] * clutch->transferValue + trans->freeI[gearbox->gear + 1] * (1.0f - clutch->transferValue);
235 if (clutch->state == CLUTCH_RELEASING) {
236 clutch->timeToRelease -= SimDeltaTime;
237 if (clutch->timeToRelease <= 0.0f) {
238 clutch->state = CLUTCH_RELEASED;
239 } else {
240 // If user does not engage clutch, we do it automatically.
241 if (clutch->transferValue > 0.99f) {
242 clutch->transferValue = 0.0f;
243 trans->curI = trans->freeI[gearbox->gear + 1];
244 if (car->ctrl->accelCmd > 0.1f) {
245 car->ctrl->accelCmd = 0.1f;
246 }
247 }
248 }
249 } else if ((car->ctrl->gear > gearbox->gear)) {
250 if (car->ctrl->gear <= gearbox->gearMax) {
251 gearbox->gear = car->ctrl->gear;
252 clutch->state = CLUTCH_RELEASING;
253 if (gearbox->gear != 0) {
254 clutch->timeToRelease = clutch->releaseTime;
255 } else {
256 clutch->timeToRelease = 0;
257 }
258 trans->curOverallRatio = trans->overallRatio[gearbox->gear+1];
259 trans->curI = trans->freeI[gearbox->gear+1];
260 differential->in.I = trans->curI + differential->feedBack.I / trans->gearEff[gearbox->gear+1];
261 differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
262 differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
263 if (trans->type == TRANS_4WD) {
264 differential = &(trans->differential[TRANS_FRONT_DIFF]);
265 differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
266 differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
267 differential = &(trans->differential[TRANS_REAR_DIFF]);
268 differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
269 differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
270 }
271 }
272 } else if ((car->ctrl->gear < gearbox->gear)) {
273 if (car->ctrl->gear >= gearbox->gearMin) {
274 gearbox->gear = car->ctrl->gear;
275 clutch->state = CLUTCH_RELEASING;
276 if (gearbox->gear != 0) {
277 clutch->timeToRelease = clutch->releaseTime;
278 } else {
279 clutch->timeToRelease = 0;
280 }
281 trans->curOverallRatio = trans->overallRatio[gearbox->gear+1];
282 trans->curI = trans->freeI[gearbox->gear+1];
283 differential->in.I = trans->curI + differential->feedBack.I / trans->gearEff[gearbox->gear+1];
284 differential->outAxis[0]->I = trans->curI / 2.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
285 differential->outAxis[1]->I = trans->curI / 2.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
286 if (trans->type == TRANS_4WD) {
287 differential = &(trans->differential[TRANS_FRONT_DIFF]);
288 differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
289 differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
290 differential = &(trans->differential[TRANS_REAR_DIFF]);
291 differential->outAxis[0]->I = trans->curI / 4.0f + differential->inAxis[0]->I / trans->gearEff[gearbox->gear+1];
292 differential->outAxis[1]->I = trans->curI / 4.0f + differential->inAxis[1]->I / trans->gearEff[gearbox->gear+1];
293 }
294 }
295 }
296}
297
298void
300{
301 tTransmission *trans = &(car->transmission);
302 tClutch *clutch = &(trans->clutch);
303 tDifferential *differential, *differential0, *differential1;
304 tdble transfer = MIN(clutch->transferValue * 3.0f, 1.0f);
305
306 switch(trans->type) {
307 case TRANS_RWD:
308 differential = &(trans->differential[TRANS_REAR_DIFF]);
309 differential->in.Tq = car->engine.Tq * trans->curOverallRatio * transfer;
310 SimDifferentialUpdate(car, differential, 1);
311 SimUpdateFreeWheels(car, 0);
312 break;
313 case TRANS_FWD:
314 differential = &(trans->differential[TRANS_FRONT_DIFF]);
315 differential->in.Tq = car->engine.Tq * trans->curOverallRatio * transfer;
316 SimDifferentialUpdate(car, differential, 1);
317 SimUpdateFreeWheels(car, 1);
318 break;
319 case TRANS_4WD:
320 differential = &(trans->differential[TRANS_CENTRAL_DIFF]);
321 differential0 = &(trans->differential[TRANS_FRONT_DIFF]);
322 differential1 = &(trans->differential[TRANS_REAR_DIFF]);
323
324 differential->in.Tq = car->engine.Tq * trans->curOverallRatio * transfer;
325 differential->inAxis[0]->spinVel = (differential0->inAxis[0]->spinVel + differential0->inAxis[1]->spinVel) / 2.0f;
326 differential->inAxis[1]->spinVel = (differential1->inAxis[0]->spinVel + differential1->inAxis[1]->spinVel) / 2.0f;
327 differential->inAxis[0]->Tq = (differential0->inAxis[0]->Tq + differential0->inAxis[1]->Tq) / differential->ratio;
328 differential->inAxis[1]->Tq = (differential1->inAxis[0]->Tq + differential1->inAxis[1]->Tq) / differential->ratio;
329 differential->inAxis[0]->brkTq = (differential0->inAxis[0]->brkTq + differential0->inAxis[1]->brkTq) / differential->ratio;
330 differential->inAxis[1]->brkTq = (differential1->inAxis[0]->brkTq + differential1->inAxis[1]->brkTq) / differential->ratio;
331
332 SimDifferentialUpdate(car, differential, 1);
333
334 differential = differential0;
335 SimDifferentialUpdate(car, differential, 0);
336
337 differential = differential1;
338 SimDifferentialUpdate(car, differential, 0);
339 break;
340 }
341}
#define SECT_CENTRALDIFFERENTIAL
Definition car.h:500
#define SECT_DRIVETRAIN
Definition car.h:506
#define VAL_TRANS_RWD
Definition car.h:635
#define MAX_GEARS
Definition car.h:278
#define VAL_TRANS_FWD
Definition car.h:636
#define VAL_TRANS_4WD
Definition car.h:637
struct CarElt tCarElt
Car structure (tCarElt).
#define PRM_TYPE
Definition car.h:531
#define SECT_FRNTDIFFERENTIAL
Definition car.h:488
#define SECT_GEARBOX
Definition car.h:507
#define PRM_INERTIA
Definition car.h:529
#define PRM_SHIFTTIME
Definition car.h:608
#define ARR_GEARS
Definition car.h:607
#define PRM_EFFICIENCY
Definition car.h:530
#define PRM_RATIO
Definition car.h:604
#define SECT_REARDIFFERENTIAL
Definition car.h:499
void SimDifferentialReConfig(tCar *car, int index)
void SimDifferentialConfig(void *hdle, const char *section, tDifferential *differential)
void SimDifferentialUpdate(tCar *car, tDifferential *differential, int first)
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
void SimUpdateFreeWheels(tCar *car, int axlenb)
Definition wheel.cpp:392
tdble SimDeltaTime
Definition simu.cpp:35
bool SimAdjustPitCarSetupParam(tCarPitSetupValue *v)
Definition simu.cpp:500
tPrivCar priv
private
Definition car.h:463
tCarPitCmd pitcmd
private
Definition car.h:465
int gear
[-1,6] for gear selection
Definition car.h:351
tdble accelCmd
Accelerator command [0.0, 1.0].
Definition car.h:348
tWheel wheel[4]
Definition carstruct.h:46
void * params
Definition carstruct.h:39
tTransmission transmission
Definition carstruct.h:51
tCarElt * carElt
Definition carstruct.h:40
tEngine engine
Definition carstruct.h:52
tCarCtrl * ctrl
Definition carstruct.h:38
tCarPitSetup setup
Definition car.h:443
tCarPitSetupValue gearsratio[MAX_GEARS - 2]
Definition car.h:419
tdble value
Definition car.h:377
tdble transferValue
tdble timeToRelease
tdble releaseTime
tDynAxis * outAxis[2]
tDynAxis * inAxis[2]
tDynAxis feedBack
tdble spinVel
tdble brkTq
tdble Tq
Definition engine.h:47
tdble I
Definition engine.h:45
int gearOffset
gearRatio[gear + gearOffset] is the ratio for gear
Definition car.h:305
int gearNb
incl reverse and neutral
Definition car.h:304
tdble gearRatio[MAX_GEARS]
including final drive
Definition car.h:303
tdble gearEff[MAX_GEARS]
tdble overallRatio[MAX_GEARS]
tdble curOverallRatio
tdble driveI[MAX_GEARS]
tdble freeI[MAX_GEARS]
tGearbox gearbox
tDifferential differential[3]
tDynAxis in
Definition wheel.h:82
tDynAxis feedBack
Definition wheel.h:83
#define MIN(x, y)
Definition tgf.h:56
void SimGearboxUpdate(tCar *car)
static const char * gearname[MAX_GEARS]
void SimTransmissionReConfig(tCar *car)
void SimTransmissionUpdate(tCar *car)
static void setupGear(void *hdle, tCar *car, tCarElt *carElt, tTransmission *trans, tdble gRatio, tdble fRatio, int i)
void SimTransmissionConfig(tCar *car)
#define TRANS_REAR_DIFF
#define TRANS_4WD
#define TRANS_FRONT_DIFF
#define CLUTCH_RELEASED
#define TRANS_RWD
#define TRANS_CENTRAL_DIFF
#define TRANS_FWD
#define CLUTCH_RELEASING