TORCS  1.3.9
The Open Racing Car Simulator
aero.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : aero.cpp
4  created : Sun Mar 19 00:04:50 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 
20 
21 #include "sim.h"
22 
23 void SimAeroConfig(tCar *car)
24 {
25  void *hdle = car->params;
26  tdble Cx, FrntArea;
27 
28  Cx = GfParmGetNum(hdle, SECT_AERODYNAMICS, PRM_CX, (char*)NULL, 0.4f);
29  FrntArea = GfParmGetNum(hdle, SECT_AERODYNAMICS, PRM_FRNTAREA, (char*)NULL, 2.5f);
30  car->aero.Clift[0] = GfParmGetNum(hdle, SECT_AERODYNAMICS, PRM_FCL, (char*)NULL, 0.0f);
31  car->aero.Clift[1] = GfParmGetNum(hdle, SECT_AERODYNAMICS, PRM_RCL, (char*)NULL, 0.0f);
32  car->aero.SCx2 = 0.645f * Cx * FrntArea;
33  car->aero.Cd += car->aero.SCx2;
34 }
35 
36 
38 {
39  tdble hm;
40  int i;
41  tCar *otherCar;
42  tdble x, y;
43  tdble yaw, otherYaw, airSpeed, tmpas, spdang, tmpsdpang, dyaw;
44  tdble dragK = 1.0;
45 
46  x = car->DynGCg.pos.x;
47  y = car->DynGCg.pos.y;
48  yaw = car->DynGCg.pos.az;
49  airSpeed = car->DynGC.vel.x;
50  spdang = (tdble) atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);
51 
52  if (airSpeed > 10.0f) {
53  for (i = 0; i < s->_ncars; i++) {
54  if (i == car->carElt->index) {
55  // skip myself
56  continue;
57  }
58 
59  otherCar = &(SimCarTable[i]);
60  otherYaw = otherCar->DynGCg.pos.az;
61  tmpsdpang = spdang - (tdble) atan2(y - otherCar->DynGCg.pos.y, x - otherCar->DynGCg.pos.x);
62  NORM_PI_PI(tmpsdpang);
63  dyaw = yaw - otherYaw;
64  NORM_PI_PI(dyaw);
65 
66  if ((otherCar->DynGC.vel.x > 10.0f) && (fabs(dyaw) < 0.1396f)) {
67  if (fabs(tmpsdpang) > 2.9671f) { /* 10 degrees */
68  // behind another car
69  tmpas = 1.0f - (tdble) exp(- 2.0f * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) /
70  (otherCar->aero.Cd * otherCar->DynGC.vel.x));
71  if (tmpas < dragK) {
72  dragK = tmpas;
73  }
74  } else if (fabs(tmpsdpang) < 0.1396f) { /* 8 degrees */
75  // before another car, lower drag by maximum 15% (this is just another guess)
76  tmpas = 1.0f - 0.15f * (tdble) exp(- 8.0f * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) / (car->aero.Cd * car->DynGC.vel.x));
77  if (tmpas < dragK) {
78  dragK = tmpas;
79  }
80  }
81  }
82  }
83  }
84 
85  car->airSpeed2 = airSpeed * airSpeed;
86  tdble v2 = car->airSpeed2;
87 
88  // simulate ground effect drop off caused by non-frontal airflow (diffusor stops working etc.)
89  tdble cosa = 1.0f;
90  if (car->speed > 1.0f) {
91  cosa = car->DynGC.vel.x/car->speed;
92  }
93 
94  if (cosa < 0.0f) {
95  cosa = 0.0f;
96  }
97 
98  car->aero.drag = - (tdble) SIGN(car->DynGC.vel.x) * car->aero.SCx2 * v2 * (1.0f + (tdble)car->dammage / 10000.0f) * dragK * dragK;
99 
100  hm = 1.5f * (car->wheel[0].rideHeight + car->wheel[1].rideHeight + car->wheel[2].rideHeight + car->wheel[3].rideHeight);
101  hm = hm*hm;
102  hm = hm*hm;
103  hm = 2.0f * (tdble) exp(-3.0f*hm);
104  car->aero.lift[0] = - car->aero.Clift[0] * v2 * hm * cosa;
105  car->aero.lift[1] = - car->aero.Clift[1] * v2 * hm * cosa;
106 }
107 
108 static const char *WingSect[2] = {SECT_FRNTWING, SECT_REARWING};
109 
110 void SimWingConfig(tCar *car, int index)
111 {
112  void *hdle = car->params;
113  tWing *wing = &(car->wing[index]);
114  tdble area;
115 
116  area = GfParmGetNum(hdle, WingSect[index], PRM_WINGAREA, (char*)NULL, 0);
117  wing->angle = GfParmGetNum(hdle, WingSect[index], PRM_WINGANGLE, (char*)NULL, 0);
118  wing->staticPos.x = GfParmGetNum(hdle, WingSect[index], PRM_XPOS, (char*)NULL, 0);
119  wing->staticPos.z = GfParmGetNum(hdle, WingSect[index], PRM_ZPOS, (char*)NULL, 0);
120  wing->staticPos.x -= car->statGC.x;
121 
122  wing->Kx = -1.23f * area;
123  wing->Kz = 4.0f * wing->Kx;
124 
125  if (index == 1) {
126  car->aero.Cd -= wing->Kx* (tdble) sin(wing->angle);
127  }
128 }
129 
130 
131 void SimWingReConfig(tCar *car, int index)
132 {
133  tCarPitSetupValue* v = &car->carElt->pitcmd.setup.wingangle[index];
134  if (SimAdjustPitCarSetupParam(v)) {
135  tWing *wing = &(car->wing[index]);
136  tdble oldCd = wing->Kx* (tdble) sin(wing->angle);
137  wing->angle = v->value;
138 
139  if (index == 1) {
140  car->aero.Cd += oldCd;
141  car->aero.Cd -= wing->Kx* (tdble) sin(wing->angle);
142  }
143  }
144 }
145 
146 
147 void SimWingUpdate(tCar *car, int index, tSituation* s)
148 {
149  tWing *wing = &(car->wing[index]);
150  tdble vt2 = car->airSpeed2;
151  // compute angle of attack
152  tdble aoa = (tdble) atan2(car->DynGC.vel.z, car->DynGC.vel.x);
153  aoa += wing->angle;
154  // the sinus of the angle of attack
155  tdble sinaoa = (tdble) sin(aoa);
156 
157  if (car->DynGC.vel.x > 0.0f) {
158  wing->forces.x = wing->Kx * vt2 * (1.0f + (tdble)car->dammage / 10000.0f) * sinaoa;
159  wing->forces.z = wing->Kz * vt2 * sinaoa;
160  } else {
161  wing->forces.x = wing->forces.z = 0.0f;
162  }
163 }
tdble angle
Definition: aero.h:42
tdble SCx2
Definition: aero.h:30
t3Dd forces
Definition: aero.h:39
void * params
Definition: carstruct.h:39
tdble Kz
Definition: aero.h:41
tDynPt DynGC
Definition: carstruct.h:64
cars situation used to inform the GUI and the drivers
Definition: raceman.h:85
tdble y
y coordinate
Definition: tgf.h:132
#define PRM_CX
Definition: car.h:578
#define SECT_REARWING
Definition: car.h:486
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
Definition: aero.h:36
tdble Clift[2]
Definition: aero.h:31
#define SECT_FRNTWING
Definition: car.h:475
#define PRM_FCL
Definition: car.h:579
t3Dd staticPos
Definition: aero.h:45
#define DIST(x1, y1, x2, y2)
Distance between two points.
Definition: tgf.h:97
tCar * SimCarTable
Definition: simu.cpp:34
#define PRM_WINGANGLE
Definition: car.h:583
tAero aero
Definition: carstruct.h:49
static const char * WingSect[2]
Definition: aero.cpp:108
void SimAeroUpdate(tCar *car, tSituation *s)
Definition: aero.cpp:37
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
void SimWingConfig(tCar *car, int index)
Definition: aero.cpp:110
tdble Kx
Definition: aero.h:40
#define PRM_RCL
Definition: car.h:580
tdble value
Definition: car.h:375
#define PRM_ZPOS
Definition: car.h:566
tdble speed
Definition: carstruct.h:88
tdble x
x coordinate
Definition: tgf.h:131
tCarElt * carElt
Definition: carstruct.h:40
tCarPitSetup setup
Definition: car.h:441
tdble lift[2]
Definition: aero.h:27
#define SECT_AERODYNAMICS
Definition: car.h:499
tdble z
z coordinate
Definition: tgf.h:118
tDynPt DynGCg
Definition: carstruct.h:65
int index
car index
Definition: car.h:457
tCarPitSetupValue wingangle[2]
Definition: car.h:420
#define PRM_XPOS
Definition: car.h:564
void SimAeroConfig(tCar *car)
Definition: aero.cpp:23
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 PRM_FRNTAREA
Definition: car.h:581
tdble airSpeed2
Definition: carstruct.h:69
static Vector y[4]
Definition: Convex.cpp:56
tdble Cd
Definition: aero.h:32
tdble rideHeight
Definition: wheel.h:35
tdble drag
Definition: aero.h:26
tdble az
angle along z axis
Definition: tgf.h:136
tPosd vel
velocity
Definition: tgf.h:145
void SimWingReConfig(tCar *car, int index)
Definition: aero.cpp:131
#define PRM_WINGAREA
Definition: car.h:582
tWheel wheel[4]
Definition: carstruct.h:46
int dammage
Definition: carstruct.h:83
t3Dd statGC
Definition: carstruct.h:59
#define NORM_PI_PI(x)
Angle normalization between -PI and PI.
Definition: tgf.h:88
void SimWingUpdate(tCar *car, int index, tSituation *s)
Definition: aero.cpp:147
tWing wing[2]
Definition: carstruct.h:50
tPosd pos
position
Definition: tgf.h:144
tdble x
x coordinate
Definition: tgf.h:116
tdble z
z coordinate
Definition: tgf.h:133