-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSimpleDriver.cpp
More file actions
387 lines (331 loc) · 10.7 KB
/
SimpleDriver.cpp
File metadata and controls
387 lines (331 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
/***************************************************************************
file : SimpleDriver.cpp
copyright : (C) 2007 Daniele Loiacono
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "SimpleDriver.h"
/* Gear Changing Constants*/
const int SimpleDriver::gearUp[6]=
{
5000,6000,6000,6500,7000,0
};
const int SimpleDriver::gearDown[6]=
{
0,2500,3000,3000,3500,3500
};
/* Stuck constants*/
const int SimpleDriver::stuckTime = 25;
const float SimpleDriver::stuckAngle = .523598775; //PI/6
/* Accel and Brake Constants*/
const float SimpleDriver::maxSpeedDist=70;
const float SimpleDriver::maxSpeed=150;
const float SimpleDriver::sin5 = 0.08716;
const float SimpleDriver::cos5 = 0.99619;
/* Steering constants*/
const float SimpleDriver::steerLock=0.366519 ;
const float SimpleDriver::steerSensitivityOffset=80.0;
const float SimpleDriver::wheelSensitivityCoeff=1;
/* ABS Filter Constants */
const float SimpleDriver::wheelRadius[4]={0.3306,0.3306,0.3276,0.3276};
const float SimpleDriver::absSlip=2.0;
const float SimpleDriver::absRange=3.0;
const float SimpleDriver::absMinSpeed=3.0;
/* Clutch constants */
const float SimpleDriver::clutchMax=0.5;
const float SimpleDriver::clutchDelta=0.05;
const float SimpleDriver::clutchRange=0.82;
const float SimpleDriver::clutchDeltaTime=0.02;
const float SimpleDriver::clutchDeltaRaced=10;
const float SimpleDriver::clutchDec=0.01;
const float SimpleDriver::clutchMaxModifier=1.3;
const float SimpleDriver::clutchMaxTime=1.5;
int
SimpleDriver::getGear(CarState &cs)
{
int gear = cs.getGear();
int rpm = cs.getRpm();
// if gear is 0 (N) or -1 (R) just return 1
if (gear<1)
return 1;
// check if the RPM value of car is greater than the one suggested
// to shift up the gear from the current one
if (gear <6 && rpm >= gearUp[gear-1])
return gear + 1;
else
// check if the RPM value of car is lower than the one suggested
// to shift down the gear from the current one
if (gear > 1 && rpm <= gearDown[gear-1])
return gear - 1;
else // otherwhise keep current gear
return gear;
}
float
SimpleDriver::getSteer(CarState &cs)
{
// steering angle is compute by correcting the actual car angle w.r.t. to track
// axis [cs.getAngle()] and to adjust car position w.r.t to middle of track [cs.getTrackPos()*0.5]
float targetAngle=(cs.getAngle()-cs.getTrackPos()*0.5);
// at high speed reduce the steering command to avoid loosing the control
if (cs.getSpeedX() > steerSensitivityOffset)
return targetAngle/(steerLock*(cs.getSpeedX()-steerSensitivityOffset)*wheelSensitivityCoeff);
else
return (targetAngle)/steerLock;
}
float
SimpleDriver::getAccel(CarState &cs)
{
// checks if car is out of track
if (cs.getTrackPos() < 1 && cs.getTrackPos() > -1)
{
// reading of sensor at +5 degree w.r.t. car axis
float rxSensor=cs.getTrack(10);
// reading of sensor parallel to car axis
float cSensor=cs.getTrack(9);
// reading of sensor at -5 degree w.r.t. car axis
float sxSensor=cs.getTrack(8);
float targetSpeed;
// track is straight and enough far from a turn so goes to max speed
if (cSensor>maxSpeedDist || (cSensor>=rxSensor && cSensor >= sxSensor))
targetSpeed = maxSpeed;
else
{
// approaching a turn on right
if(rxSensor>sxSensor)
{
// computing approximately the "angle" of turn
float h = cSensor*sin5;
float b = rxSensor - cSensor*cos5;
float sinAngle = b*b/(h*h+b*b);
// estimate the target speed depending on turn and on how close it is
targetSpeed = maxSpeed*(cSensor*sinAngle/maxSpeedDist);
}
// approaching a turn on left
else
{
// computing approximately the "angle" of turn
float h = cSensor*sin5;
float b = sxSensor - cSensor*cos5;
float sinAngle = b*b/(h*h+b*b);
// estimate the target speed depending on turn and on how close it is
targetSpeed = maxSpeed*(cSensor*sinAngle/maxSpeedDist);
}
}
// accel/brake command is expontially scaled w.r.t. the difference between target speed and current one
return 2/(1+exp(cs.getSpeedX() - targetSpeed)) - 1;
}
else
return 0.3; // when out of track returns a moderate acceleration command
}
CarControl
SimpleDriver::wDrive(CarState cs, CNeuralNet* brain)
{
distRaced = cs.getDistRaced();//cs.getDistFromStart();
damage = cs.getDamage();
//this will store all the inputs for the NN
vector<double> inputs;
// reading of sensor at +5 degree w.r.t. car axis
double right = cs.getTrack(11) / 200.0;
inputs.push_back(right);
// reading of sensor parallel to car axis
double front = cs.getTrack(9) / 200.0;
inputs.push_back(front);
// reading of sensor at -5 degree w.r.t. car axis
double left = cs.getTrack(7) / 200.0;
inputs.push_back(left);
//update the brain and get feedback
vector<double> output = brain->Update(inputs, CNeuralNet::active);
//make sure there were no errors in calculating the
//output
if (output.size() < CParams::iNumOutputs)
{
return NULL;
}
//assign the outputs to the car's left & right steering as well as it's brake/acceleration
float steer = output[0];
float accel_and_brake = output[1];
// compute gear
int gear = getGear(cs);
/*
// normalize steering
if (steer < -1)
steer = -1;
if (steer > 1)
steer = 1;
*/
// set accel and brake from the joint accel/brake command
float accel,brake;
if (accel_and_brake>0)
{
accel = accel_and_brake;
brake = 0;
}
else
{
accel = 0;
// apply ABS to brake
brake = filterABS(cs,-accel_and_brake);
}
// Calculate clutching
clutching(cs,clutch);
// build a CarControl variable and return it
CarControl cc(accel,brake,gear,steer,clutch);
return cc;
/*
// check if car is currently stuck
if ( fabs(cs.getAngle()) > stuckAngle )
{
// update stuck counter
stuck++;
}
else
{
// if not stuck reset stuck counter
stuck = 0;
}
// after car is stuck for a while apply recovering policy
if (stuck > stuckTime)
{
/* set gear and sterring command assuming car is
* pointing in a direction out of track */
// to bring car parallel to track axis
/*
float steer = - cs.getAngle() / steerLock;
int gear=-1; // gear R
// if car is pointing in the correct direction revert gear and steer
if (cs.getAngle()*cs.getTrackPos()>0)
{
gear = 1;
steer = -steer;
}
// Calculate clutching
clutching(cs,clutch);
// build a CarControl variable and return it
CarControl cc (1.0,0.0,gear,steer,clutch);
return cc;
}
else // car is not stuck
{
// compute accel/brake command
float accel_and_brake = getAccel(cs);
// compute gear
int gear = getGear(cs);
// compute steering
float steer = getSteer(cs);
// normalize steering
if (steer < -1)
steer = -1;
if (steer > 1)
steer = 1;
// set accel and brake from the joint accel/brake command
float accel,brake;
if (accel_and_brake>0)
{
accel = accel_and_brake;
brake = 0;
}
else
{
accel = 0;
// apply ABS to brake
brake = filterABS(cs,-accel_and_brake);
}
// Calculate clutching
clutching(cs,clutch);
// build a CarControl variable and return it
CarControl cc(accel,brake,gear,steer,clutch);
return cc;
}
*/
}
float
SimpleDriver::filterABS(CarState &cs,float brake)
{
// convert speed to m/s
float speed = cs.getSpeedX() / 3.6;
// when spedd lower than min speed for abs do nothing
if (speed < absMinSpeed)
return brake;
// compute the speed of wheels in m/s
float slip = 0.0f;
for (int i = 0; i < 4; i++)
{
slip += cs.getWheelSpinVel(i) * wheelRadius[i];
}
// slip is the difference between actual speed of car and average speed of wheels
slip = speed - slip/4.0f;
// when slip too high applu ABS
if (slip > absSlip)
{
brake = brake - (slip - absSlip)/absRange;
}
// check brake is not negative, otherwise set it to zero
if (brake<0)
return 0;
else
return brake;
}
void
SimpleDriver::onShutdown()
{
cout << "Bye bye!" << endl;
}
void
SimpleDriver::onRestart()
{
cout << "Restarting the race!" << endl;
}
void
SimpleDriver::clutching(CarState &cs, float &clutch)
{
double maxClutch = clutchMax;
// Check if the current situation is the race start
if (cs.getCurLapTime()<clutchDeltaTime && stage==RACE && cs.getDistRaced()<clutchDeltaRaced)
clutch = maxClutch;
// Adjust the current value of the clutch
if(clutch > 0)
{
double delta = clutchDelta;
if (cs.getGear() < 2)
{
// Apply a stronger clutch output when the gear is one and the race is just started
delta /= 2;
maxClutch *= clutchMaxModifier;
if (cs.getCurLapTime() < clutchMaxTime)
clutch = maxClutch;
}
// check clutch is not bigger than maximum values
clutch = min(maxClutch,double(clutch));
// if clutch is not at max value decrease it quite quickly
if (clutch!=maxClutch)
{
clutch -= delta;
clutch = max(0.0,double(clutch));
}
// if clutch is at max value decrease it very slowly
else
clutch -= clutchDec;
}
}
void
SimpleDriver::init(float *angles)
{
// set angles as {-90,-75,-60,-45,-30,20,15,10,5,0,5,10,15,20,30,45,60,75,90}
for (int i=0; i<5; i++)
{
angles[i]=-90+i*15;
angles[18-i]=90-i*15;
}
for (int i=5; i<9; i++)
{
angles[i]=-20+(i-5)*5;
angles[18-i]=20-(i-5)*5;
}
angles[9]=0;
}