TORCS  1.3.9
The Open Racing Car Simulator
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 
22 static 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 
157 static 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 
298 void
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 }
int gear
[-1,6] for gear selection
Definition: car.h:349
void * params
Definition: carstruct.h:39
#define VAL_TRANS_FWD
Definition: car.h:632
void SimGearboxUpdate(tCar *car)
void SimTransmissionUpdate(tCar *car)
tDynAxis in
Definition: wheel.h:80
tCarPitSetupValue gearsratio[MAX_GEARS - 2]
Definition: car.h:417
tdble gearRatio[MAX_GEARS]
including final drive
Definition: car.h:301
#define PRM_TYPE
Definition: car.h:527
void SimDifferentialReConfig(tCar *car, int index)
Car structure (tCarElt).
Definition: car.h:455
#define SECT_DRIVETRAIN
Definition: car.h:502
int gearOffset
gearRatio[gear + gearOffset] is the ratio for gear
Definition: car.h:303
tdble I
Definition: engine.h:45
bool SimAdjustPitCarSetupParam(tCarPitSetupValue *v)
Definition: simu.cpp:491
tCarPitCmd pitcmd
private
Definition: car.h:463
Definition: carstruct.h:35
tCarCtrl * ctrl
Definition: carstruct.h:38
tdble driveI[MAX_GEARS]
Definition: transmission.h:59
void SimDifferentialUpdate(tCar *car, tDifferential *differential, int first)
tdble SimDeltaTime
Definition: simu.cpp:35
tdble timeToRelease
Definition: transmission.h:45
tDifferential differential[3]
Definition: transmission.h:68
tdble overallRatio[MAX_GEARS]
Definition: transmission.h:58
tDynAxis * outAxis[2]
Definition: differential.h:54
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_TRANS_RWD
Definition: car.h:631
#define TRANS_FWD
Definition: transmission.h:56
tdble spinVel
Definition: differential.h:25
#define TRANS_CENTRAL_DIFF
Definition: transmission.h:67
tDynAxis * inAxis[2]
Definition: differential.h:53
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
#define VAL_TRANS_4WD
Definition: car.h:633
tdble value
Definition: car.h:375
tdble Tq
Definition: engine.h:47
tCarElt * carElt
Definition: carstruct.h:40
#define SECT_FRNTDIFFERENTIAL
Definition: car.h:484
tCarPitSetup setup
Definition: car.h:441
tdble transferValue
Definition: transmission.h:47
#define CLUTCH_RELEASING
Definition: transmission.h:41
static void setupGear(void *hdle, tCar *car, tCarElt *carElt, tTransmission *trans, tdble gRatio, tdble fRatio, int i)
tPrivCar priv
private
Definition: car.h:461
#define PRM_RATIO
Definition: car.h:600
#define SECT_CENTRALDIFFERENTIAL
Definition: car.h:496
int gearMax
Definition: transmission.h:33
void SimDifferentialConfig(void *hdle, const char *section, tDifferential *differential)
tdble brkTq
Definition: differential.h:27
#define TRANS_FRONT_DIFF
Definition: transmission.h:65
void SimTransmissionReConfig(tCar *car)
tdble accelCmd
Accelerator command [0.0, 1.0].
Definition: car.h:346
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
static const char * gearname[MAX_GEARS]
int gearNb
incl reverse and neutral
Definition: car.h:302
void SimTransmissionConfig(tCar *car)
#define CLUTCH_RELEASED
Definition: transmission.h:40
tdble gearEff[MAX_GEARS]
Definition: transmission.h:61
#define PRM_SHIFTTIME
Definition: car.h:604
#define TRANS_RWD
Definition: transmission.h:55
tdble Tq
Definition: differential.h:26
tClutch clutch
Definition: transmission.h:53
tTransmission transmission
Definition: carstruct.h:51
tdble freeI[MAX_GEARS]
Definition: transmission.h:60
tWheel wheel[4]
Definition: carstruct.h:46
tdble releaseTime
Definition: transmission.h:46
tEngine engine
Definition: carstruct.h:52
#define TRANS_4WD
Definition: transmission.h:57
Definition: Endpoint.h:36
int state
Definition: transmission.h:38
#define SECT_REARDIFFERENTIAL
Definition: car.h:495
int gearMin
Definition: transmission.h:32
#define SECT_GEARBOX
Definition: car.h:503
tDynAxis in
Definition: differential.h:51
tDynAxis feedBack
Definition: wheel.h:81
#define TRANS_REAR_DIFF
Definition: transmission.h:66
void SimUpdateFreeWheels(tCar *car, int axlenb)
Definition: wheel.cpp:392
#define ARR_GEARS
Definition: car.h:603
#define PRM_EFFICIENCY
Definition: car.h:526
#define PRM_INERTIA
Definition: car.h:525
tdble I
Definition: differential.h:28
tGearbox gearbox
Definition: transmission.h:52
tDynAxis feedBack
Definition: differential.h:52
#define MAX_GEARS
Definition: car.h:276
tdble curOverallRatio
Definition: transmission.h:62