TORCS  1.3.9
The Open Racing Car Simulator
wheel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : wheel.cpp
4  created : Sun Mar 19 00:09:06 CET 2000
5  copyright : (C) 2000-2024 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 <stdio.h>
20 #include "sim.h"
21 
25 
26 void SimWheelConfig(tCar *car, int index)
27 {
28  void *hdle = car->params;
29  tCarElt *carElt = car->carElt;
30  tWheel *wheel = &(car->wheel[index]);
31  tdble rimdiam, tireratio, pressure;
32  tdble x0, Ca, RFactor, EFactor, patchLen;
33 
34  pressure = GfParmGetNum(hdle, WheelSect[index], PRM_PRESSURE, (char*)NULL, 275600);
35  rimdiam = GfParmGetNum(hdle, WheelSect[index], PRM_RIMDIAM, (char*)NULL, 0.33f);
36  wheel->tirewidth = GfParmGetNum(hdle, WheelSect[index], PRM_TIREWIDTH, (char*)NULL, 0.145f);
37  tireratio = GfParmGetNum(hdle, WheelSect[index], PRM_TIRERATIO, (char*)NULL, 0.75f);
38  wheel->mu = GfParmGetNum(hdle, WheelSect[index], PRM_MU, (char*)NULL, 1.0f);
39  wheel->I = GfParmGetNum(hdle, WheelSect[index], PRM_INERTIA, (char*)NULL, 1.5f);
40  wheel->I += wheel->brake.I; // add brake inertia
41  wheel->staticPos.y = GfParmGetNum(hdle, WheelSect[index], PRM_YPOS, (char*)NULL, 0.0f);
42  x0 = GfParmGetNum(hdle, WheelSect[index], PRM_RIDEHEIGHT, (char*)NULL, 0.20f);
43  wheel->staticPos.az = GfParmGetNum(hdle, WheelSect[index], PRM_TOE, (char*)NULL, 0.0f);
44  wheel->staticPos.ax = GfParmGetNum(hdle, WheelSect[index], PRM_CAMBER, (char*)NULL, 0.0f);
45  wheel->staticPos.ay = GfParmGetNum(hdle, WheelSect[index], PRM_CASTER, (char*)NULL, 0.0f);
46  Ca = GfParmGetNum(hdle, WheelSect[index], PRM_CA, (char*)NULL, 30.0f);
47  RFactor = GfParmGetNum(hdle, WheelSect[index], PRM_RFACTOR, (char*)NULL, 0.8f);
48  EFactor = GfParmGetNum(hdle, WheelSect[index], PRM_EFACTOR, (char*)NULL, 0.7f);
49  wheel->lfMax = GfParmGetNum(hdle, WheelSect[index], PRM_LOADFMAX, (char*)NULL, 1.6f);
50  wheel->lfMin = GfParmGetNum(hdle, WheelSect[index], PRM_LOADFMIN, (char*)NULL, 0.8f);
51  wheel->opLoad = GfParmGetNum(hdle, WheelSect[index], PRM_OPLOAD, (char*)NULL, wheel->weight0 * 1.2f);
52  wheel->mass = GfParmGetNum(hdle, WheelSect[index], PRM_MASS, (char*)NULL, 20.0f);
53 
54  wheel->lfMin = MIN(0.8f, wheel->lfMin);
55  wheel->lfMax = MAX(1.6f, wheel->lfMax);
56 
57  // Absolute pressure of cold tire.
58  wheel->pressure = pressure;
59  wheel->currentPressure = pressure;
60 
61  RFactor = MIN(1.0f, RFactor);
62  RFactor = MAX(0.1f, RFactor);
63  EFactor = MIN(1.0f, EFactor);
64 
65  patchLen = wheel->weight0 / (wheel->tirewidth * pressure);
66 
67  wheel->staticPos.z = -car->statGC.z;
68 
69  wheel->radius = rimdiam / 2.0f + wheel->tirewidth * tireratio;
70  wheel->tireSpringRate = wheel->weight0 / (wheel->radius * (1.0f - cos(asin(patchLen / (2.0f * wheel->radius)))));
71  wheel->relPos.x = wheel->staticPos.x = car->axle[index/2].xpos;
72  wheel->relPos.y = wheel->staticPos.y;
73  wheel->relPos.z = wheel->radius - wheel->susp.spring.x0;
74  wheel->relPos.ax = wheel->relPos.ay = wheel->relPos.az = 0.0f;
75  wheel->steer = 0.0f;
76 
77  /* components */
78  SimSuspConfig(hdle, SuspSect[index], &(wheel->susp), wheel->weight0, x0);
79  SimBrakeConfig(hdle, BrkSect[index], &(wheel->brake));
80 
81  carElt->_rimRadius(index) = rimdiam / 2.0f;
82  carElt->_tireHeight(index) = wheel->tirewidth * tireratio;
83  carElt->_tireWidth(index) = wheel->tirewidth;
84  carElt->_brakeDiskRadius(index) = wheel->brake.radius;
85  carElt->_wheelRadius(index) = wheel->radius;
86 
87  wheel->mfC = 2.0f - asin(RFactor) * 2.0f / PI;
88  wheel->mfB = Ca / wheel->mfC;
89  wheel->mfE = EFactor;
90 
91  wheel->lfK = log((1.0f - wheel->lfMin) / (wheel->lfMax - wheel->lfMin));
92 
93  wheel->feedBack.I += wheel->I;
94  wheel->feedBack.spinVel = 0.0f;
95  wheel->feedBack.Tq = 0.0f;
96  wheel->feedBack.brkTq = 0.0f;
97  wheel->rel_vel = 0.0f;
98 
99  // Additional parameters for the tire wear model
100  wheel->treadThinkness = GfParmGetNum(hdle, WheelSect[index], PRM_TREADTHICKNESS, (char*)NULL, 0.005f); // default 5 [mm]
101  tdble rimmass = GfParmGetNum(hdle, WheelSect[index], PRM_RIMMASS, (char*)NULL, 7.0f); // default 7 [kg]
102  wheel->hysteresisFactor = GfParmGetNum(hdle, WheelSect[index], PRM_HYSTERESIS, (char*)NULL, 1.0f); // default 1.0 [-]
103  wheel->wearFactor = GfParmGetNum(hdle, WheelSect[index], PRM_WEAR, (char*)NULL, 1.0f); // default 1.0 [-]
104  wheel->idealTemperature = GfParmGetNum(hdle, WheelSect[index], PRM_IDEALTEMP, (char*)NULL, 95.0f + 273.15f); // default 95°C
105 
106  carElt->info.wheel[index].idealTemperature = wheel->idealTemperature;
107 
108  const tdble rubberDensity = 930.0f; // Density of Rubber (NR) in [kg/m^3].
109  wheel->treadMass = (2.0f*wheel->radius - wheel->treadThinkness)*PI*wheel->tirewidth*wheel->treadThinkness*rubberDensity;
110  wheel->baseMass = wheel->mass - wheel->treadMass - rimmass;
111  if (wheel->baseMass < 0.0f) {
112  wheel->baseMass = 3.0f;
113  GfError("Wheel mass minus tire tread mass minus rim mass is smaller than 0.0kg, setting it to 3.0 kg");
114  }
115 
116  // Surface area for convection model
117  tdble innerRadius = rimdiam / 2.0f;
118  tdble tireSideArea = PI*(wheel->radius*wheel->radius - innerRadius*innerRadius);
119  wheel->tireConvectionSurface = 2.0f*(PI*wheel->tirewidth*wheel->radius + tireSideArea);
120 
121  // Mass of gas in the tire m=P*V/(R*T)
122  tdble temperature = 273.15f + 20.0f; // Kelvin
123  tdble volume = tireSideArea*wheel->tirewidth; // meter*meter*meter
124  tdble nitrogenR = 296.8f; // Joule/(kg*Kelvin), N2
125 
126  wheel->tireGasMass = (wheel->pressure * volume) / (nitrogenR * temperature); // kg
127 
128  wheel->initialTemperature = temperature;
129  wheel->currentTemperature = temperature;
130 
131  wheel->currentWear = 0.0f;
132  wheel->currentGraining = 0.0f;
133  wheel->currentGripFactor = 1.0f;
134 }
135 
136 
137 void SimWheelReConfig(tCar *car, int index)
138 {
139  tWheel *wheel = &(car->wheel[index]);
140 
141  // Camber
142  tCarPitSetupValue* v = &car->carElt->pitcmd.setup.wheelcamber[index];
143  if (SimAdjustPitCarSetupParam(v)) {
144  wheel->staticPos.ax = v->value;
145  }
146 
147  // Toe
148  v = &car->carElt->pitcmd.setup.wheeltoe[index];
149  if (SimAdjustPitCarSetupParam(v)) {
150  wheel->staticPos.az = v->value;
151  }
152 
153  // Caster
154  v = &car->carElt->pitcmd.setup.wheelcaster[index];
155  if (SimAdjustPitCarSetupParam(v)) {
156  wheel->staticPos.ay = v->value;
157  }
158 
159  // Ride height/suspension
160  v = &car->carElt->pitcmd.setup.wheelrideheight[index];
162  SimSuspReConfig(car, index, &(wheel->susp), wheel->weight0, v->value);
163 }
164 
165 
166 void SimWheelUpdateRide(tCar *car, int index)
167 {
168  tWheel *wheel = &(car->wheel[index]);
169  tdble Zroad;
170 
171  // compute suspension travel
172  RtTrackGlobal2Local(car->trkPos.seg, wheel->pos.x, wheel->pos.y, &(wheel->trkPos), TR_LPOS_SEGMENT);
173  RtTrackSurfaceNormalL(&(wheel->trkPos), &(wheel->surfaceNormal));
174  wheel->zRoad = Zroad = RtTrackHeightL(&(wheel->trkPos));
175 
176  // Wheel susp.x is not the wheel movement, look at SimSuspCheckIn, it becomes there scaled with
177  // susp->spring.bellcrank, so we invert this here.
178  tdble prexwheel = wheel->susp.x / wheel->susp.spring.bellcrank;
179 
180  tdble new_susp_x = prexwheel - wheel->rel_vel * SimDeltaTime;
181  tdble max_extend = (wheel->pos.z - Zroad)*wheel->surfaceNormal.z;
182  wheel->rideHeight = max_extend;
183 
184  wheel->state &= ~SIM_WH_ONAIR;
185  if (max_extend < new_susp_x) {
186  new_susp_x = max_extend;
187  wheel->rel_vel = 0.0f;
188  } else if (new_susp_x < wheel->susp.spring.packers) {
189  new_susp_x = wheel->susp.spring.packers;
190  wheel->rel_vel = 0.0f;
191  }
192 
193  if (new_susp_x < max_extend) {
194  wheel->state |= SIM_WH_ONAIR;
195  }
196 
197  tdble prex = wheel->susp.x;
198  wheel->susp.x = new_susp_x;
199 
200  // verify the suspension travel, beware, wheel->susp.x will be scaled by SimSuspCheckIn
201  SimSuspCheckIn(&(wheel->susp));
202  wheel->susp.v = (prex - wheel->susp.x) / SimDeltaTime;
203 
204  // update wheel brake
205  SimBrakeUpdate(car, wheel, &(wheel->brake));
206 }
207 
208 
209 
210 
211 void SimWheelUpdateForce(tCar *car, int index)
212 {
213  tWheel *wheel = &(car->wheel[index]);
214  tdble axleFz = wheel->axleFz;
215  tdble vt, v, v2, wrl; // wheel related velocity
216  tdble Fn, Ft;
217  tdble waz;
218  tdble CosA, SinA;
219  tdble s, sa, sx, sy; // slip vector
220  tdble stmp, F, Bx;
221  tdble mu;
222  wheel->state = 0;
223 
224  // VERTICAL STUFF CONSIDERING SMALL PITCH AND ROLL ANGLES
225  // update suspension force
226  SimSuspUpdate(&(wheel->susp));
227 
228  // check suspension state
229  wheel->state |= wheel->susp.state;
230  if ((wheel->state & SIM_SUSP_EXT) && wheel->rel_vel <= 0.0f) {
231  wheel->forces.z = wheel->rel_vel/SimDeltaTime*wheel->mass;
232  wheel->rel_vel = 0.0;
233  } else {
234  wheel->forces.z = axleFz + wheel->susp.force;
235  wheel->rel_vel -= SimDeltaTime * wheel->forces.z / wheel->mass;
236  }
237 
238  // update wheel coord, center relative to GC
239  wheel->relPos.z = - wheel->susp.x / wheel->susp.spring.bellcrank + wheel->radius;
240 
241  // Wheel contact with the ground can just push the car upwards, but not drag it towards the ground.
242  // Because forces.z includes the inertia of the wheel, the wheel force can act on the car body
243  // without interacting with the ground.
244  tdble zforce = wheel->forces.z;
245  if ((zforce < 0.0f) || (wheel->state & SIM_WH_ONAIR)) {
246  zforce = 0.0f;
247  }
248 
249  // HORIZONTAL FORCES
250  waz = wheel->steer + wheel->staticPos.az;
251  CosA = cos(waz);
252  SinA = sin(waz);
253 
254  // tangent velocity.
255  vt = wheel->bodyVel.x * CosA + wheel->bodyVel.y * SinA;
256  v2 = wheel->bodyVel.x * wheel->bodyVel.x + wheel->bodyVel.y * wheel->bodyVel.y;
257  v = sqrt(v2);
258 
259  // slip angle
260  if (v < 0.000001f) {
261  sa = 0.0f;
262  } else {
263  sa = atan2(wheel->bodyVel.y, wheel->bodyVel.x) - waz;
264  }
265  NORM_PI_PI(sa);
266 
267  wrl = wheel->spinVel * wheel->radius;
268  if ((wheel->state & SIM_WH_ONAIR) != 0) {
269  sx = sy = 0.0f;
270  } else if (v < 0.000001f) {
271  sx = wrl;
272  sy = 0.0f;
273  } else {
274  sx = (vt - wrl) / fabs(vt);
275  sy = sin(sa);
276  }
277 
278  Ft = 0.0f;
279  Fn = 0.0f;
280  s = sqrt(sx*sx+sy*sy);
281 
282  {
283  // calculate _skid and _reaction for sound.
284  if (v < 2.0f) {
285  car->carElt->_skid[index] = 0.0f;
286  } else {
287  car->carElt->_skid[index] = MIN(1.0f, (s*zforce*0.0002f));
288  }
289  }
290 
291  tdble casterCamber = sin(wheel->staticPos.ay)*wheel->steer;
292  tdble camberDelta;
293  if (index % 2) {
294  wheel->relPos.ax = -wheel->staticPos.ax - casterCamber;
295  camberDelta = -casterCamber;
296  } else {
297  wheel->relPos.ax = wheel->staticPos.ax - casterCamber;
298  camberDelta = casterCamber;
299  }
300 
301  stmp = MIN(s, 1.5f);
302 
303  // MAGIC FORMULA
304  Bx = wheel->mfB * stmp;
305  F = sin(wheel->mfC * atan(Bx * (1.0f - wheel->mfE) + wheel->mfE * atan(Bx))) * (1.0f + stmp * simSkidFactor[car->carElt->_skillLevel]);
306 
307  // load sensitivity
308  mu = wheel->mu * (wheel->lfMin + (wheel->lfMax - wheel->lfMin) * exp(wheel->lfK * zforce / wheel->opLoad));
309 
310  // Surface property blending if tire overlaps. The tire overlaps if its center is closer than half the width from the edge.
311  tTrackSeg *otherSurface = NULL;
312  tdble halfTireWidth = wheel->tirewidth/2.0f;
313  tdble otherSurfaceContribution = 0.0f; // Contribution of the other surface, [0..1], effectively [0..0.5]
314 
315  if (wheel->trkPos.toLeft < halfTireWidth) {
316  otherSurface = RtTrackGetSideNeighbourSeg(car->trkPos.seg, wheel->trkPos.seg, TR_SIDE_LFT);
317  otherSurfaceContribution = 1.0f/2.0f - wheel->trkPos.toLeft/wheel->tirewidth;
318  } else if (wheel->trkPos.toRight < halfTireWidth) {
319  otherSurface = RtTrackGetSideNeighbourSeg(car->trkPos.seg, wheel->trkPos.seg, TR_SIDE_RGT);
320  otherSurfaceContribution = 1.0f/2.0f - wheel->trkPos.toRight/wheel->tirewidth;
321  }
322 
323  tdble surfaceFriction = wheel->trkPos.seg->surface->kFriction;
324  tdble rollRes = wheel->trkPos.seg->surface->kRollRes;
325 
326  if (otherSurface != NULL && otherSurfaceContribution > 0.0f) {
327  surfaceFriction = surfaceFriction*(1.0f - otherSurfaceContribution) + otherSurface->surface->kFriction*otherSurfaceContribution;
328  rollRes = rollRes*(1.0f - otherSurfaceContribution) + otherSurface->surface->kRollRes*otherSurfaceContribution;
329  car->carElt->priv.otherSurfaceContribution[index] = otherSurfaceContribution;
330  car->carElt->priv.otherSurfaceSeg[index] = otherSurface;
331  } else {
332  car->carElt->priv.otherSurfaceContribution[index] = 0.0f;
333  car->carElt->priv.otherSurfaceSeg[index] = NULL;
334  }
335 
336  F *= zforce * mu * surfaceFriction * (1.0f + 0.05f * sin((-wheel->staticPos.ax + camberDelta) * 18.0f)); /* coeff */
337  F *= wheel->currentGripFactor;
338 
339  wheel->rollRes = zforce * rollRes;
340  car->carElt->priv.wheel[index].rollRes = wheel->rollRes;
341 
342  if (s > 0.000001f) {
343  // wheel axis based
344  Ft -= F * sx / s;
345  Fn -= F * sy / s;
346  }
347 
348  RELAXATION2(Fn, wheel->preFn, 50.0f);
349  RELAXATION2(Ft, wheel->preFt, 50.0f);
350 
351  wheel->relPos.az = waz;
352 
353  wheel->forces.x = Ft * CosA - Fn * SinA;
354  wheel->forces.y = Ft * SinA + Fn * CosA;
355  wheel->spinTq = Ft * wheel->radius;
356  wheel->sa = sa;
357  wheel->sx = sx;
358 
359  wheel->tireZForce = zforce;
360  wheel->tireSlip = stmp;
361 
362  wheel->feedBack.spinVel = wheel->spinVel;
363  wheel->feedBack.Tq = wheel->spinTq;
364  wheel->feedBack.brkTq = wheel->brake.Tq;
365 
366  car->carElt->_wheelSlipSide(index) = sy*v;
367  car->carElt->_wheelSlipAccel(index) = sx*v;
368  car->carElt->_reaction[index] = zforce;
369 }
370 
371 
372 void
374 {
375  int i;
376  tWheel *wheel;
377 
378  for (i = 0; i < 4; i++) {
379  wheel = &(car->wheel[i]);
380  wheel->spinVel = wheel->in.spinVel;
381 
382  RELAXATION2(wheel->spinVel, wheel->prespinVel, 50.0f);
383 
384  wheel->relPos.ay += wheel->spinVel * SimDeltaTime;
385  NORM_PI_PI(wheel->relPos.ay);
386  car->carElt->_wheelSpinVel(i) = wheel->spinVel;
387  }
388 }
389 
390 
391 void
392 SimUpdateFreeWheels(tCar *car, int axlenb)
393 {
394  int i;
395  tWheel *wheel;
396  tdble BrTq; // brake torque
397  tdble ndot; // rotation acceleration
398  tdble I;
399 
400  for (i = axlenb * 2; i < axlenb * 2 + 2; i++) {
401  wheel = &(car->wheel[i]);
402 
403  I = wheel->I + car->axle[axlenb].I / 2.0f;
404 
405  ndot = SimDeltaTime * wheel->spinTq / I;
406  wheel->spinVel -= ndot;
407 
408  BrTq = - SIGN(wheel->spinVel) * wheel->brake.Tq;
409  ndot = SimDeltaTime * BrTq / I;
410 
411  if (fabs(ndot) > fabs(wheel->spinVel)) {
412  ndot = -wheel->spinVel;
413  }
414 
415  wheel->spinVel += ndot;
416  wheel->in.spinVel = wheel->spinVel;
417  }
418 }
419 
420 
421 void SimWheelUpdateTire(tCar *car, int index) {
422  if (!(rulesTireFactor > 0.0f) || car->carElt->info.skillLevel != 3) {
423  return;
424  }
425 
426  tWheel *wheel = &(car->wheel[index]);
427 
428  tdble normalForce = wheel->tireZForce;
429  tdble slip = wheel->tireSlip;
430 
431  tdble wheelSpeed = fabs(wheel->spinVel*wheel->radius);
432  tdble deltaTemperature = wheel->currentTemperature - car->localTemperature;
433 
434  // Calculate factor for energy which is turned into heat, according papers this seems to be pretty constant
435  // for a specific construction and constant slip (empiric value with model validation, called hysteresis).
436  // A value of 0.1 is available in papers, so for 10% slip I head for 0.1, where 0.05 come from rolling and
437  // the other 0.05 from slip. Additionaly the hysteresis goes down with wear.
438  tdble elasticity = (wheel->pressure - car->localPressure)/(wheel->currentPressure - car->localPressure);
439  tdble hysteresis = (0.05f*(sqrt(1.0f - wheel->currentWear))*elasticity + 0.5f*slip)*wheel->hysteresisFactor;
440 
441  // Calculate energy input for the tire
442  tdble energyGain = normalForce*wheelSpeed*SimDeltaTime*hysteresis;
443 
444  // Calculate energy loss of the tire (convection, convection model approximation from papers,
445  // 5.9f + airspeed*3.7f [W/(meter*meter*Kelvin)]). Because the model is linear it is reasonable to apply
446  // it to the whole tire at once (no subdivision in elements).
447  tdble energyLoss = (5.9f + wheelSpeed*3.7f)*deltaTemperature*wheel->tireConvectionSurface*SimDeltaTime;
448 
449  tdble deltaEnergy = energyGain - energyLoss;
450 
451  // Calculate heat capacity. Basically the heat capacity of the gas in the tire accounts for a "normal" TORCS tire
452  // around 2 percent of the whole tire heat capacity, so one could neglect this. I put it into the model because it:
453  // - is more than 1 percent
454  // - you could think of some tire build where this ratio is significantly higher (e.g. 4 percent)
455  //
456  // Because the tire is a sufficiently rigid volume we assume for the isochoric process (constant volume, variable
457  // pressure and temperature).
458  //
459  // Material properties: The heat capacity of nitorgen N2 is "almost" constant over our temperature ranges:
460  // 29.1 (at 25°C) vs 29.3 (at 100°C) [J/(mol*Kelvin)]. So this is assumed constant, error less than 1 percent.
461  // But this does not apply for Rubber (NR):
462  // 1.982 (at 20°C) [J/(g*Kelvin)] vs 2.121 (at 100°C), so this is more than 6 percent.
463  tdble tireCelsius = wheel->currentTemperature - 273.15f;
464  tdble cpRubber = 2009.0f - 1.962f*tireCelsius + 3.077f*tireCelsius*tireCelsius/100.0f;
465 
466  // Calculate the actual rubber mass. This is some base mass (constant) plus the mass of the tread (dynamic,
467  // wears down).
468  tdble actualRubberMass = wheel->treadMass*(1.0f - wheel->currentWear) + wheel->baseMass;
469 
470  // Calculate actual heat capacity
471  const tdble cvNitrogen = 1041.0f - 296.8f; // cv = cp - R, [J/(kg*Kelvin)]
472  tdble heatCapacity = cpRubber * actualRubberMass + cvNitrogen * wheel->tireGasMass;
473 
474  // Energy transfer into the tire
475  wheel->currentTemperature += deltaEnergy/heatCapacity;
476  wheel->currentPressure = wheel->currentTemperature/wheel->initialTemperature*wheel->pressure;
477 
478  // Wear
479  double deltaWear = (wheel->currentPressure - car->localPressure)*slip*wheelSpeed*SimDeltaTime*normalForce*wheel->wearFactor*0.00000000000009;
480 
481  wheel->currentWear += deltaWear*rulesTireFactor;
482  if (wheel->currentWear > 1.0f) wheel->currentWear = 1.0f;
483 
484  // Graining
485  tdble grainTemperature = (wheel->idealTemperature - wheel->initialTemperature)*3.0f/4.0f + wheel->initialTemperature;
486  tdble deltaGraining = (grainTemperature - wheel->currentTemperature)*deltaWear;
487  if (deltaGraining > 0.0f) {
488  deltaGraining *= wheel->currentWear;
489  }
490 
491  wheel->currentGraining += deltaGraining;
492  if (wheel->currentGraining > 1.0f) {
493  wheel->currentGraining = 1.0f;
494  } else if(wheel->currentGraining < 0.0f) {
495  wheel->currentGraining = 0.0f;
496  }
497 
498  tdble di = (wheel->currentTemperature - wheel->idealTemperature)/(wheel->idealTemperature - wheel->initialTemperature);
499  wheel->currentGripFactor = ((1.0f-(MIN((di*di), 1.0f)))/4.0f + 3.0f/4.0f)*(1.0f - wheel->currentGraining/10.0f);
500 }
501 
502 
503 void
504 SimWheelResetWear(tCar *car, int index)
505 {
506  tWheel *wheel = &(car->wheel[index]);
507 
508  wheel->currentPressure = wheel->pressure;
509  wheel->currentTemperature = car->localTemperature;
510  wheel->currentWear = 0.0f;
511  wheel->currentGraining = 0.0f;
512  wheel->currentGripFactor = 1.0f;
513 }
tdble RtTrackHeightL(tTrkLocPos *p)
Returns the absolute height in meters of the road at the Local position p.
Definition: rttrack.cpp:314
#define GfError
Definition: tgf.h:351
#define PRM_TREADTHICKNESS
Definition: car.h:546
void * params
Definition: carstruct.h:39
tdble opLoad
Definition: wheel.h:73
tdble initialTemperature
Definition: wheel.h:91
tdble sx
Definition: wheel.h:53
tdble currentTemperature
Definition: wheel.h:98
tdble tireZForce
Definition: wheel.h:104
tdble packers
Definition: susp.h:43
tdble wearFactor
Definition: wheel.h:93
#define PRM_LOADFMIN
Definition: car.h:544
tDynAxis in
Definition: wheel.h:80
#define PRM_TOE
Definition: car.h:536
#define PRM_CA
Definition: car.h:539
tdble xpos
Definition: axle.h:29
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
Definition: track.h:432
tInitCar info
public
Definition: car.h:458
tdble prespinVel
Definition: wheel.h:44
tdble y
y coordinate
Definition: tgf.h:132
void SimWheelConfig(tCar *car, int index)
Definition: wheel.cpp:26
tdble steer
Definition: wheel.h:54
void SimWheelUpdateTire(tCar *car, int index)
Definition: wheel.cpp:421
tdble mfB
Definition: wheel.h:68
tdble hysteresisFactor
Definition: wheel.h:92
tdble otherSurfaceContribution[4]
Definition: car.h:317
#define SIM_WH_ONAIR
Definition: wheel.h:47
static const char * SuspSect[4]
Definition: wheel.cpp:23
Car structure (tCarElt).
Definition: car.h:455
#define PRM_EFACTOR
Definition: car.h:541
tdble force
Definition: susp.h:55
tdble treadMass
Definition: wheel.h:86
bool SimAdjustPitCarSetupParam(tCarPitSetupValue *v)
Definition: simu.cpp:491
tdble mfC
Definition: wheel.h:67
tAxle axle[2]
Definition: carstruct.h:45
#define SECT_FRNTLFTWHEEL
Definition: car.h:479
tCarPitCmd pitcmd
private
Definition: car.h:463
#define SIGN(x)
Sign of the expression.
Definition: tgf.h:78
Definition: carstruct.h:35
tdble rollRes
Definition: wheel.h:34
tdble x0
Definition: susp.h:40
#define PRM_HYSTERESIS
Definition: car.h:548
void SimBrakeUpdate(tCar *car, tWheel *wheel, tBrake *brake)
Definition: brake.cpp:35
tdble SimDeltaTime
Definition: simu.cpp:35
#define SECT_FRNTLFTSUSP
Definition: car.h:481
void SimSuspConfig(void *hdle, const char *section, tSuspension *susp, tdble F0, tdble X0)
Definition: susp.cpp:140
tdble x
Definition: susp.h:52
#define SECT_REARRGTWHEEL
Definition: car.h:489
void SimSuspUpdate(tSuspension *susp)
Definition: susp.cpp:122
tdble lfMax
Definition: wheel.h:70
#define SECT_FRNTLFTBRAKE
Definition: car.h:483
tdble lfK
Definition: wheel.h:72
tdble mu
Definition: wheel.h:64
tdble tireSlip
Definition: wheel.h:103
tdble tireConvectionSurface
Definition: wheel.h:90
#define PRM_TIREWIDTH
Definition: car.h:533
tdble spinTq
Definition: wheel.h:42
const double PI
PI.
Definition: tgf.h:69
#define SECT_FRNTRGTSUSP
Definition: car.h:480
#define PRM_PRESSURE
Definition: car.h:542
#define TR_SIDE_LFT
Definition: track.h:403
void SimSuspReConfig(tCar *car, int index, tSuspension *susp, tdble F0, tdble X0)
Definition: susp.cpp:161
tPosd relPos
Definition: wheel.h:51
tBrake brake
Definition: wheel.h:30
tdble ay
angle along y axis
Definition: tgf.h:135
#define SECT_FRNTRGTWHEEL
Definition: car.h:478
tSuspension susp
Definition: wheel.h:29
#define SECT_REARLFTWHEEL
Definition: car.h:490
#define SECT_REARLFTBRAKE
Definition: car.h:494
#define PRM_RIDEHEIGHT
Definition: car.h:535
tdble currentGripFactor
Definition: wheel.h:101
#define PRM_IDEALTEMP
Definition: car.h:549
void SimWheelUpdateRotation(tCar *car)
Definition: wheel.cpp:373
void RtTrackGlobal2Local(tTrackSeg *segment, tdble X, tdble Y, tTrkLocPos *p, int type)
Convert a Global (segment, X, Y) position into a Local one (segment, toRight, toStart)The segment in ...
Definition: rttrack.cpp:156
tdble mfE
Definition: wheel.h:69
static const char * WheelSect[4]
Definition: wheel.cpp:22
tdble idealTemperature
Definition: wheel.h:94
tdble radius
Definition: wheel.h:63
static const char * BrkSect[4]
Definition: wheel.cpp:24
tdble lfMin
Definition: wheel.h:71
#define PRM_WEAR
Definition: car.h:550
tTrkLocPos trkPos
Definition: wheel.h:49
Definition: wheel.h:25
tdble rulesTireFactor
Definition: simu.cpp:41
tWheelSpec wheel[4]
Wheels specifications.
Definition: car.h:89
tSpring spring
Definition: susp.h:49
tdble bellcrank
Definition: susp.h:42
tdble rollRes
rolling resistance, useful for sound
Definition: car.h:255
tTrackSeg * otherSurfaceSeg[4]
Definition: car.h:318
#define PRM_CAMBER
Definition: car.h:537
tdble zRoad
Definition: wheel.h:36
tdble spinVel
Definition: differential.h:25
tdble pressure
Definition: wheel.h:76
tdble idealTemperature
Definition: car.h:56
tdble toLeft
Distance (- to left, + to right) relative to left side of segment.
Definition: track.h:434
double currentWear
Definition: wheel.h:99
tdble tireSpringRate
Definition: wheel.h:62
#define PRM_MU
Definition: car.h:531
#define PRM_MASS
Definition: car.h:517
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
tTrkLocPos trkPos
Definition: carstruct.h:68
Definition: Endpoint.h:36
#define SIM_SUSP_EXT
Definition: susp.h:58
tdble value
Definition: car.h:375
tPosd staticPos
Definition: wheel.h:57
t3Dd pos
Definition: wheel.h:37
#define SECT_REARRGTSUSP
Definition: car.h:491
tdble x
x coordinate
Definition: tgf.h:131
tCarPitSetupValue wheelrideheight[4]
Definition: car.h:390
tWheelState wheel[4]
Definition: car.h:290
tCarElt * carElt
Definition: carstruct.h:40
tCarPitSetup setup
Definition: car.h:441
#define PRM_OPLOAD
Definition: car.h:545
tdble axleFz
Definition: wheel.h:48
tdble I
Definition: axle.h:38
tdble I
Definition: wheel.h:65
#define SECT_REARLFTSUSP
Definition: car.h:492
tdble currentGraining
Definition: wheel.h:100
tdble Tq
Definition: brake.h:25
tdble y
y coordinate
Definition: tgf.h:117
tdble baseMass
Definition: wheel.h:87
tPrivCar priv
private
Definition: car.h:461
tdble mass
Definition: wheel.h:74
int state
Definition: susp.h:56
#define SECT_REARRGTBRAKE
Definition: car.h:493
t3Dd surfaceNormal
Definition: wheel.h:50
tdble z
z coordinate
Definition: tgf.h:118
#define PRM_LOADFMAX
Definition: car.h:543
tdble rel_vel
Definition: wheel.h:77
tTrackSeg * RtTrackGetSideNeighbourSeg(tTrackSeg *main, tTrackSeg *current, int tr_side)
Get the neighbour segment of the given current segment.
Definition: rttrack.cpp:383
tdble spinVel
Definition: wheel.h:43
#define PRM_TIRERATIO
Definition: car.h:534
tdble weight0
Definition: wheel.h:61
tCarPitSetupValue wheelcamber[4]
Definition: car.h:388
tdble simSkidFactor[]
Definition: categories.cpp:32
tdble v
Definition: susp.h:53
#define PRM_RFACTOR
Definition: car.h:540
#define RELAXATION2(target, prev, rate)
Definition: robottools.h:30
#define PRM_RIMMASS
Definition: car.h:547
tdble I
Definition: brake.h:27
#define SECT_FRNTRGTBRAKE
Definition: car.h:482
tdble brkTq
Definition: differential.h:27
#define TR_SIDE_RGT
Definition: track.h:404
void SimSuspCheckIn(tSuspension *susp)
Definition: susp.cpp:101
#define PRM_RIMDIAM
Definition: car.h:532
tdble kRollRes
Rolling resistance.
Definition: track.h:249
tTrackSeg * seg
Track segment.
Definition: track.h:420
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
tdble localTemperature
Definition: carstruct.h:90
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
Definition: track.h:276
tdble treadThinkness
Definition: wheel.h:88
tdble rideHeight
Definition: wheel.h:35
tdble radius
Definition: brake.h:28
tdble Tq
Definition: differential.h:26
tdble preFn
Definition: wheel.h:83
#define PRM_YPOS
Definition: car.h:565
tdble az
angle along z axis
Definition: tgf.h:136
tdble preFt
Definition: wheel.h:83
void SimWheelReConfig(tCar *car, int index)
Definition: wheel.cpp:137
#define PRM_CASTER
Definition: car.h:538
void SimUpdateFreeWheels(tCar *car, int axlenb)
Definition: wheel.cpp:392
tTrackSurface * surface
Segment surface.
Definition: track.h:394
tWheel wheel[4]
Definition: carstruct.h:46
#define TR_LPOS_SEGMENT
Relative to the segment which the point is located, including border and sides, mostly used for conta...
Definition: track.h:428
Definition: Endpoint.h:36
t3Dd statGC
Definition: carstruct.h:59
tdble ax
angle along x axis
Definition: tgf.h:134
tDynAxis feedBack
Definition: wheel.h:81
tdble localPressure
Definition: carstruct.h:91
#define NORM_PI_PI(x)
Angle normalization between -PI and PI.
Definition: tgf.h:88
tdble tirewidth
Definition: wheel.h:78
void SimWheelUpdateRide(tCar *car, int index)
Definition: wheel.cpp:166
void SimWheelUpdateForce(tCar *car, int index)
Definition: wheel.cpp:211
#define PRM_INERTIA
Definition: car.h:525
int skillLevel
Driver&#39;s skill level (0=rookie -> 3=pro)
Definition: car.h:81
tCarPitSetupValue wheelcaster[4]
Definition: car.h:391
tdble I
Definition: differential.h:28
void RtTrackSurfaceNormalL(tTrkLocPos *p, t3Dd *norm)
Used to get the normal vector of the road (pointing upward).
Definition: rttrack.cpp:540
tdble sa
Definition: wheel.h:52
tdble kFriction
Coefficient of friction.
Definition: track.h:247
tdble x
x coordinate
Definition: tgf.h:116
t3Dd forces
Definition: wheel.h:33
tCarPitSetupValue wheeltoe[4]
Definition: car.h:389
t3Dd bodyVel
Definition: wheel.h:38
int state
Definition: wheel.h:45
tdble currentPressure
Definition: wheel.h:97
void SimBrakeConfig(void *hdle, const char *section, tBrake *brake)
Definition: brake.cpp:21
void SimWheelResetWear(tCar *car, int index)
Definition: wheel.cpp:504
tdble z
z coordinate
Definition: tgf.h:133
tdble tireGasMass
Definition: wheel.h:89