TORCS  1.3.9
The Open Racing Car Simulator
susp.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : susp.cpp
4  created : Sun Mar 19 00:08:41 CET 2000
5  copyright : (C) 2000-2016 by Eric Espie, Bernhard Wymann
6  email : torcs@free.fr
7  version : $Id$
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
20 #include <stdio.h>
21 #include "sim.h"
22 
23 /*
24  * b2 and b3 calculus
25  */
26 static void initDamper(tSuspension *susp)
27 {
28  tDamper *damp;
29 
30  damp = &(susp->damper);
31  damp->bump.b2 = (damp->bump.C1 - damp->bump.C2) * damp->bump.v1;
32  damp->rebound.b2 = (damp->rebound.C1 - damp->rebound.C2) * damp->rebound.v1;
33 }
34 
35 
36 
37 
38 /*
39  * get damper force
40  */
42 {
43  tDamperDef *dampdef;
44  tdble f;
45  tdble av;
46  tdble v;
47 
48  // limit for damper velocity
49  const tdble SUSP_DAMPER_MAX_VELOCITY = 10.0f; // [m/s]
50 
51  v = susp->v;
52 
53  if (fabs(v) > SUSP_DAMPER_MAX_VELOCITY) {
54  v = (tdble) SIGN(v) * SUSP_DAMPER_MAX_VELOCITY;
55  }
56 
57  if (v < 0.0f) {
58  /* rebound */
59  dampdef = &(susp->damper.rebound);
60  } else {
61  /* bump */
62  dampdef = &(susp->damper.bump);
63  }
64 
65  av = (tdble) fabs(v);
66  if (av < dampdef->v1) {
67  f = (dampdef->C1 * av);
68  } else {
69  f = (dampdef->C2 * av + dampdef->b2);
70  }
71 
72  f *= (tdble) SIGN(v);
73 
74  return f;
75 }
76 
77 
78 
79 
80 /*
81  * get spring force
82  */
84 {
85  tSpring *spring = &(susp->spring);
86  tdble f;
87 
88  /* K is < 0 */
89  f = spring->K * (susp->x - spring->x0) + spring->F0;
90  if (f < 0.0f) {
91  // Compression spring, so the force can never change the sign.
92  f = 0.0f;
93  }
94 
95  return f;
96 }
97 
98 
99 
100 
102 {
103  susp->state = 0;
104  if (susp->x < susp->spring.packers) {
105  // Packers are not scaled with susp->spring.bellcrank, because they are a hard
106  // rubber element or plate spring packs directly mounted on the piston of the
107  // damper.
108  susp->x = susp->spring.packers;
109  susp->state = SIM_SUSP_COMP;
110  }
111 
112  susp->x *= susp->spring.bellcrank;
113  if (susp->x > susp->spring.xMax) {
114  susp->x = susp->spring.xMax;
115  susp->state = SIM_SUSP_EXT;
116  }
117 }
118 
119 
120 
121 
123 {
124  tdble internalForce = springForce(susp) + damperForce(susp);
125  if (internalForce <= 0.0f) {
126  // The damping can at its best cancel out the spring force. Requred because
127  // of numerical integration artefacts with (if the velocity is 0 there is no
128  // damping, so the spring accelarates the system for one time step; if the
129  // damping is set very high this can result in a counterforce larger than the
130  // spring force in the next timestep)
131  susp->force = 0.0f;
132  } else {
133  susp->force = internalForce * susp->spring.bellcrank;
134  }
135 }
136 
137 
138 
139 
140 void SimSuspConfig(void *hdle, const char *section, tSuspension *susp, tdble F0, tdble X0)
141 {
142  susp->spring.K = GfParmGetNum(hdle, section, PRM_SPR, (char*)NULL, 175000.0f);
143  susp->spring.xMax = GfParmGetNum(hdle, section, PRM_SUSPCOURSE, (char*)NULL, 0.5f);
144  susp->spring.bellcrank = GfParmGetNum(hdle, section, PRM_BELLCRANK, (char*)NULL, 1.0f);
145  susp->spring.packers = GfParmGetNum(hdle, section, PRM_PACKERS, (char*)NULL, 0.0f);
146  susp->damper.bump.C1 = GfParmGetNum(hdle, section, PRM_SLOWBUMP, (char*)NULL, 0.0f);
147  susp->damper.rebound.C1 = GfParmGetNum(hdle, section, PRM_SLOWREBOUND, (char*)NULL, 0.0f);
148  susp->damper.bump.C2 = GfParmGetNum(hdle, section, PRM_FASTBUMP, (char*)NULL, susp->damper.bump.C1);
149  susp->damper.rebound.C2 = GfParmGetNum(hdle, section, PRM_FASTREBOUND, (char*)NULL, susp->damper.rebound.C1);
150  susp->damper.bump.v1 = GfParmGetNum(hdle, section, PRM_BUMPTHRESHOLD, (char*)NULL, 0.5f);
151  susp->damper.rebound.v1 = GfParmGetNum(hdle, section, PRM_REBOUNDTHRESHOLD, (char*)NULL, 0.5f);
152 
153  susp->spring.x0 = susp->spring.bellcrank * X0;
154  susp->spring.F0 = F0 / susp->spring.bellcrank;
155  susp->spring.K = - susp->spring.K;
156 
157  initDamper(susp);
158 }
159 
160 
161 void SimSuspReConfig(tCar* car, int index, tSuspension *susp, tdble F0, tdble X0)
162 {
163  // Spring
164  tCarPitSetupValue* v = &car->carElt->pitcmd.setup.suspspring[index];
165  if (SimAdjustPitCarSetupParam(v)) {
166  susp->spring.K = - v->value;
167  }
168 
169  // Packers
170  v = &car->carElt->pitcmd.setup.susppackers[index];
171  if (SimAdjustPitCarSetupParam(v)) {
172  susp->spring.packers = v->value;
173  }
174 
175  // Slow bump
176  v = &car->carElt->pitcmd.setup.suspslowbump[index];
177  if (SimAdjustPitCarSetupParam(v)) {
178  susp->damper.bump.C1 = v->value;
179  }
180 
181  // Slow rebound
182  v = &car->carElt->pitcmd.setup.suspslowrebound[index];
183  if (SimAdjustPitCarSetupParam(v)) {
184  susp->damper.rebound.C1 = v->value;
185  }
186 
187  // Fast bump
188  v = &car->carElt->pitcmd.setup.suspfastbump[index];
189  if (SimAdjustPitCarSetupParam(v)) {
190  susp->damper.bump.C2 = v->value;
191  }
192 
193  // Fast rebound
194  v = &car->carElt->pitcmd.setup.suspfastrebound[index];
195  if (SimAdjustPitCarSetupParam(v)) {
196  susp->damper.rebound.C2 = v->value;
197  }
198 
199  // Bump threshold
200  v = &car->carElt->pitcmd.setup.suspbumpthreshold[index];
201  if (SimAdjustPitCarSetupParam(v)) {
202  susp->damper.bump.v1 = v->value;
203  }
204 
205  // Rebound threshold
206  v = &car->carElt->pitcmd.setup.suspreboundthreshold[index];
207  if (SimAdjustPitCarSetupParam(v)) {
208  susp->damper.rebound.v1 = v->value;
209  }
210 
211  susp->spring.x0 = susp->spring.bellcrank * X0;
212  susp->spring.F0 = F0 / susp->spring.bellcrank;
213 
214  initDamper(susp);
215 }
216 
217 
218 void SimSuspThirdReConfig(tCar* car, int index, tSuspension *susp, tdble F0, tdble X0)
219 {
220  // Spring
221  tCarPitSetupValue* v = &car->carElt->pitcmd.setup.thirdspring[index];
222  if (SimAdjustPitCarSetupParam(v)) {
223  susp->spring.K = - v->value;
224  }
225 
226  // Bump
227  v = &car->carElt->pitcmd.setup.thirdbump[index];
228  if (SimAdjustPitCarSetupParam(v)) {
229  susp->damper.bump.C1 = v->value;
230  susp->damper.bump.C2 = v->value;
231  }
232 
233  // Rebound
234  v = &car->carElt->pitcmd.setup.thirdrebound[index];
235  if (SimAdjustPitCarSetupParam(v)) {
236  susp->damper.rebound.C1 = v->value;
237  susp->damper.rebound.C2 = v->value;
238  }
239 
240  susp->spring.xMax = X0;
241 
242  susp->spring.x0 = susp->spring.bellcrank * X0;
243  susp->spring.F0 = F0 / susp->spring.bellcrank;
244 
245  initDamper(susp);
246 }
tdble C2
Definition: susp.h:27
tdble K
Definition: susp.h:38
tdble xMax
Definition: susp.h:41
tdble packers
Definition: susp.h:43
void SimSuspCheckIn(tSuspension *susp)
Definition: susp.cpp:101
tdble F0
Definition: susp.h:39
tCarPitSetupValue suspslowrebound[4]
Definition: car.h:401
#define PRM_SUSPCOURSE
Definition: car.h:554
tdble force
Definition: susp.h:55
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
tCarPitSetupValue suspslowbump[4]
Definition: car.h:400
Definition: carstruct.h:35
tdble x0
Definition: susp.h:40
Section header structure.
Definition: params.cpp:83
tdble x
Definition: susp.h:52
#define SIM_SUSP_COMP
Definition: susp.h:57
static tdble damperForce(tSuspension *susp)
Definition: susp.cpp:41
tdble b2
Definition: susp.h:27
Definition: susp.h:36
#define PRM_PACKERS
Definition: car.h:556
tCarPitSetupValue suspbumpthreshold[4]
Definition: car.h:404
#define PRM_BUMPTHRESHOLD
Definition: car.h:561
tSpring spring
Definition: susp.h:49
tdble bellcrank
Definition: susp.h:42
#define PRM_SLOWBUMP
Definition: car.h:557
tCarPitSetupValue thirdspring[2]
Definition: car.h:411
#define PRM_FASTREBOUND
Definition: car.h:560
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
Definition: susp.h:30
#define SIM_SUSP_EXT
Definition: susp.h:58
tdble value
Definition: car.h:375
tCarPitSetupValue susppackers[4]
Definition: car.h:399
#define PRM_BELLCRANK
Definition: car.h:555
tCarElt * carElt
Definition: carstruct.h:40
tCarPitSetup setup
Definition: car.h:441
tdble C1
Definition: susp.h:26
tCarPitSetupValue thirdrebound[2]
Definition: car.h:413
tdble v1
Definition: susp.h:26
tCarPitSetupValue thirdbump[2]
Definition: car.h:412
#define PRM_SLOWREBOUND
Definition: car.h:558
int state
Definition: susp.h:56
tCarPitSetupValue suspfastbump[4]
Definition: car.h:402
void SimSuspUpdate(tSuspension *susp)
Definition: susp.cpp:122
tdble v
Definition: susp.h:53
#define PRM_REBOUNDTHRESHOLD
Definition: car.h:562
void SimSuspConfig(void *hdle, const char *section, tSuspension *susp, tdble F0, tdble X0)
Definition: susp.cpp:140
static tdble springForce(tSuspension *susp)
Definition: susp.cpp:83
tCarPitSetupValue suspreboundthreshold[4]
Definition: car.h:405
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
tDamperDef bump
Definition: susp.h:32
#define PRM_SPR
Definition: car.h:553
void SimSuspReConfig(tCar *car, int index, tSuspension *susp, tdble F0, tdble X0)
Definition: susp.cpp:161
void SimSuspThirdReConfig(tCar *car, int index, tSuspension *susp, tdble F0, tdble X0)
Definition: susp.cpp:218
tCarPitSetupValue suspfastrebound[4]
Definition: car.h:403
tCarPitSetupValue suspspring[4]
Definition: car.h:398
#define PRM_FASTBUMP
Definition: car.h:559
tDamperDef rebound
Definition: susp.h:33
tDamper damper
Definition: susp.h:50
static void initDamper(tSuspension *susp)
Definition: susp.cpp:26