1mod constants;
2mod utils;
3
4const V_CAR: f64 = 26.8;
5const W_E: f64 = 3600.0 * 2.0 * std::f64::consts::PI / 60.0;
6const RHO_AIR: f64 = 1.225;
7const R_TRACK: f64 = 9.0;
8const P_BRAKE: f64 = 10_000_000.0;
9const C_DC: f64 = 0.04;
10const GRAVITY: f64 = 9.81;
11const Y_SUSPENSION: f64 = 0.05;
12const DYDT_SUSPENSION: f64 = 0.025;
13
14const EVEN_WEIGHTS: [f64; 11] = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
16const WEIGHTS1: [i32; 11] = [14, 1, 20, 30, 10, 1, 1, 10, 10, 2, 1]; const WEIGHTS2: [i32; 11] = [25, 1, 15, 20, 15, 1, 1, 15, 5, 1, 1]; const WEIGHTS3: [i32; 11] = [14, 1, 20, 15, 25, 1, 1, 10, 10, 2, 1]; #[derive(Default)]
21pub struct Car {
22 rear_wing_height: f64,
23 rear_wing_length: f64,
24 rear_wing_angle_of_attack: f64,
25 front_wing_height: f64,
26 front_wing_length: f64,
27 front_wing_width: f64,
28 front_wing_angle_of_attack: f64,
29 side_wings_height: f64,
30 side_wings_length: f64,
31 side_wings_width: f64,
32 side_wings_angle_of_attack: f64,
33 rear_tire_pressure: f64,
34 front_tire_pressure: f64,
35 cabin_height: f64,
36 cabin_length: f64,
37 cabin_width: f64,
38 cabin_thickness: f64,
39 impact_attenuator_height: f64,
40 impact_attenuator_width: f64,
41 rear_wing_density: f64,
42 front_wing_density: f64,
43 side_wing_density: f64,
44 cabin_density: f64,
45 impact_attenuator_density: f64,
46 impact_attenuator_modulus: f64,
47 rear_tire_radius: f64,
48 rear_tire_mass: f64,
49 front_tire_radius: f64,
50 front_tire_mass: f64,
51 engine_power: f64,
52 engine_length: f64,
53 engine_height: f64,
54 engine_torque: f64,
55 engine_mass: f64,
56 brake_radius: f64,
57 brake_density: f64,
58 brake_length: f64,
59 brake_height: f64,
60 brake_width: f64,
61 brake_thickness: f64,
62 rear_suspension_spring_constant: f64,
63 rear_suspension_damping_coefficient: f64,
64 rear_suspension_mass: f64,
65 front_suspension_spring_constant: f64,
66 front_suspension_damping_coefficient: f64,
67 front_suspension_mass: f64,
68 rear_wing_width: f64,
69 rear_wing_y_position: f64,
70 front_wing_y_position: f64,
71 side_wing_y_position: f64,
72 engine_y_position: f64,
73 cabin_y_position: f64,
74 impact_attenuator_length: f64,
75 impact_attenuator_y_position: f64,
76 rear_suspension_y_position: f64,
77 front_suspension_y_position: f64,
78}
79
80impl Car {
81 pub fn new() -> Self {
82 let tires = constants::get_tires();
84 let brakes = constants::get_brakes();
85 let motors = constants::get_motors();
86 let materials = constants::get_materials();
87 let suspensions = constants::get_suspensions();
88
89 let rear_tire_index = utils::multinomial_draw(vec![1.0; tires.len()]);
91 let front_tire_index = utils::multinomial_draw(vec![1.0; tires.len()]);
92 let brake_index = utils::multinomial_draw(vec![1.0; brakes.len()]);
93 let motor_index = utils::multinomial_draw(vec![1.0; motors.len()]);
94 let suspension_index = utils::multinomial_draw(vec![1.0; suspensions.len()]);
95 let rear_wing_material_index = utils::multinomial_draw(vec![1.0; materials.len()]);
96 let front_wing_material_index = utils::multinomial_draw(vec![1.0; materials.len()]);
97 let side_wing_material_index = utils::multinomial_draw(vec![1.0; materials.len()]);
98 let cabin_material_index = utils::multinomial_draw(vec![1.0; materials.len()]);
99 let impact_attenuator_material_index = utils::multinomial_draw(vec![1.0; materials.len()]);
100
101 let impact_attenuator_height = utils::random_uniform(
103 constants::CONST_BOUNDS[17][0],
104 constants::CONST_BOUNDS[17][1],
105 );
106 let front_wing_length =
107 utils::random_uniform(constants::CONST_BOUNDS[4][0], constants::CONST_BOUNDS[4][1]);
108 let cabin_height = utils::random_uniform(
109 constants::CONST_BOUNDS[13][0],
110 constants::CONST_BOUNDS[13][1],
111 );
112 let rear_wing_height =
113 utils::random_uniform(constants::CONST_BOUNDS[0][0], constants::CONST_BOUNDS[0][1]);
114 let front_wing_height =
115 utils::random_uniform(constants::CONST_BOUNDS[3][0], constants::CONST_BOUNDS[3][1]);
116 let side_wings_height =
117 utils::random_uniform(constants::CONST_BOUNDS[7][0], constants::CONST_BOUNDS[7][1]);
118
119 Car {
120 rear_wing_height,
122 rear_wing_length: utils::random_uniform(
123 constants::CONST_BOUNDS[1][0],
124 constants::CONST_BOUNDS[1][1],
125 ),
126 rear_wing_angle_of_attack: utils::random_uniform(
127 constants::CONST_BOUNDS[2][0],
128 constants::CONST_BOUNDS[2][1],
129 ),
130 front_wing_height,
131 front_wing_length,
132 front_wing_width: utils::random_uniform(
133 constants::CONST_BOUNDS[5][0],
134 constants::CONST_BOUNDS[5][1],
135 ),
136 front_wing_angle_of_attack: utils::random_uniform(
137 constants::CONST_BOUNDS[6][0],
138 constants::CONST_BOUNDS[6][1],
139 ),
140 side_wings_height,
141 side_wings_length: utils::random_uniform(
142 constants::CONST_BOUNDS[8][0],
143 constants::CONST_BOUNDS[8][1],
144 ),
145 side_wings_width: utils::random_uniform(
146 constants::CONST_BOUNDS[9][0],
147 constants::CONST_BOUNDS[9][1],
148 ),
149 side_wings_angle_of_attack: utils::random_uniform(
150 constants::CONST_BOUNDS[10][0],
151 constants::CONST_BOUNDS[10][1],
152 ),
153 rear_tire_pressure: utils::random_uniform(
154 constants::CONST_BOUNDS[11][0],
155 constants::CONST_BOUNDS[11][1],
156 ),
157 front_tire_pressure: utils::random_uniform(
158 constants::CONST_BOUNDS[12][0],
159 constants::CONST_BOUNDS[12][1],
160 ),
161 cabin_height,
162 cabin_length: utils::random_uniform(
163 constants::CONST_BOUNDS[14][0],
164 constants::CONST_BOUNDS[14][1],
165 ),
166 cabin_width: utils::random_uniform(
167 constants::CONST_BOUNDS[15][0],
168 constants::CONST_BOUNDS[15][1],
169 ),
170 cabin_thickness: utils::random_uniform(
171 constants::CONST_BOUNDS[16][0],
172 constants::CONST_BOUNDS[16][1],
173 ),
174 impact_attenuator_height,
175 impact_attenuator_width: utils::random_uniform(
176 constants::CONST_BOUNDS[18][0],
177 constants::CONST_BOUNDS[18][1],
178 ),
179
180 rear_wing_density: materials[&rear_wing_material_index]["density"],
182 front_wing_density: materials[&front_wing_material_index]["density"],
183 side_wing_density: materials[&side_wing_material_index]["density"],
184 cabin_density: materials[&cabin_material_index]["density"],
185 impact_attenuator_density: materials[&impact_attenuator_material_index]["density"],
186 impact_attenuator_modulus: materials[&impact_attenuator_material_index]["modulus"],
187 rear_tire_radius: tires[&rear_tire_index]["radius"],
188 rear_tire_mass: tires[&rear_tire_index]["mass"],
189 front_tire_radius: tires[&front_tire_index]["radius"],
190 front_tire_mass: tires[&front_tire_index]["mass"],
191 engine_power: motors[&motor_index]["power"],
192 engine_length: motors[&motor_index]["length"],
193 engine_height: motors[&motor_index]["height"],
194 engine_torque: motors[&motor_index]["torque"],
195 engine_mass: motors[&motor_index]["mass"],
196 brake_radius: brakes[&brake_index]["radius"],
197 brake_density: brakes[&brake_index]["density"],
198 brake_length: brakes[&brake_index]["length"],
199 brake_height: brakes[&brake_index]["height"],
200 brake_width: brakes[&brake_index]["width"],
201 brake_thickness: brakes[&brake_index]["thickness"],
202 rear_suspension_spring_constant: suspensions[&suspension_index]["spring_constant"],
203 rear_suspension_damping_coefficient: suspensions[&suspension_index]
204 ["damping_coefficient"],
205 rear_suspension_mass: suspensions[&suspension_index]["mass"],
206 front_suspension_spring_constant: suspensions[&suspension_index]["spring_constant"],
207 front_suspension_damping_coefficient: suspensions[&suspension_index]
208 ["damping_coefficient"],
209 front_suspension_mass: suspensions[&suspension_index]["mass"],
210
211 rear_wing_width: utils::random_uniform(
213 0.3,
214 9.0 - 2.0 * tires[&rear_tire_index]["radius"],
215 ),
216 rear_wing_y_position: utils::random_uniform(
217 0.5 + rear_wing_height / 2.0,
218 1.2 - rear_wing_height / 2.0,
219 ),
220 front_wing_y_position: utils::random_uniform(
221 0.03 + front_wing_height,
222 0.25 - rear_wing_height / 2.0,
223 ),
224 side_wing_y_position: utils::random_uniform(
225 0.03 + side_wings_height / 2.0,
226 0.25 - side_wings_height / 2.0,
227 ),
228 engine_y_position: utils::random_uniform(
229 0.03 + motors[&motor_index]["height"] / 2.0,
230 0.5 - motors[&motor_index]["height"] / 2.0,
231 ),
232 cabin_y_position: utils::random_uniform(
233 0.03 + cabin_height / 2.0,
234 1.2 - cabin_height / 2.0,
235 ),
236 impact_attenuator_length: utils::random_uniform(0.2, 0.7 - front_wing_length),
237 impact_attenuator_y_position: utils::random_uniform(
238 0.03 + impact_attenuator_height / 2.0,
239 1.2 - impact_attenuator_height / 2.0,
240 ),
241 rear_suspension_y_position: utils::random_uniform(
242 tires[&rear_tire_index]["radius"],
243 2.0 * tires[&rear_tire_index]["radius"],
244 ),
245 front_suspension_y_position: utils::random_uniform(
246 tires[&front_tire_index]["radius"],
247 2.0 * tires[&front_tire_index]["radius"],
248 ),
249 }
250 }
251
252 pub fn new_from_parameters(p: &Vec<f64>) -> Self {
253 let tires = constants::get_tires();
255 let brakes = constants::get_brakes();
256 let motors = constants::get_motors();
257 let materials = constants::get_materials();
258 let suspensions = constants::get_suspensions();
259
260 let rear_wing_material_index = p[19] as usize;
262 let front_wing_material_index = p[20] as usize;
263 let side_wing_material_index = p[21] as usize;
264 let cabin_material_index = p[22] as usize;
265 let impact_attenuator_material_index = p[23] as usize;
266 let rear_tire_index = p[24] as usize;
267 let front_tire_index = p[25] as usize;
268 let brake_index = p[26] as usize;
269 let motor_index = p[27] as usize;
270 let suspension_index = p[28] as usize;
271
272 Car {
273 rear_wing_height: p[0],
274 rear_wing_length: p[1],
275 rear_wing_angle_of_attack: p[2],
276 front_wing_height: p[3],
277 front_wing_length: p[4],
278 front_wing_width: p[5],
279 front_wing_angle_of_attack: p[6],
280 side_wings_height: p[7],
281 side_wings_length: p[8],
282 side_wings_width: p[9],
283 side_wings_angle_of_attack: p[10],
284 rear_tire_pressure: p[11],
285 front_tire_pressure: p[12],
286 cabin_height: p[13],
287 cabin_length: p[14],
288 cabin_width: p[15],
289 cabin_thickness: p[16],
290 impact_attenuator_height: p[17],
291 impact_attenuator_width: p[18],
292 rear_wing_density: materials[&rear_wing_material_index]["density"],
293 front_wing_density: materials[&front_wing_material_index]["density"],
294 side_wing_density: materials[&side_wing_material_index]["density"],
295 cabin_density: materials[&cabin_material_index]["density"],
296 impact_attenuator_density: materials[&impact_attenuator_material_index]["density"],
297 impact_attenuator_modulus: materials[&impact_attenuator_material_index]["modulus"],
298 rear_tire_radius: tires[&rear_tire_index]["radius"],
299 rear_tire_mass: tires[&rear_tire_index]["mass"],
300 front_tire_radius: tires[&front_tire_index]["radius"],
301 front_tire_mass: tires[&front_tire_index]["mass"],
302 engine_power: motors[&motor_index]["power"],
303 engine_length: motors[&motor_index]["length"],
304 engine_height: motors[&motor_index]["height"],
305 engine_torque: motors[&motor_index]["torque"],
306 engine_mass: motors[&motor_index]["mass"],
307 brake_radius: brakes[&brake_index]["radius"],
308 brake_density: brakes[&brake_index]["density"],
309 brake_length: brakes[&brake_index]["length"],
310 brake_height: brakes[&brake_index]["height"],
311 brake_width: brakes[&brake_index]["width"],
312 brake_thickness: brakes[&brake_index]["thickness"],
313 rear_suspension_spring_constant: suspensions[&suspension_index]["spring_constant"],
314 rear_suspension_damping_coefficient: suspensions[&suspension_index]
315 ["damping_coefficient"],
316 rear_suspension_mass: suspensions[&suspension_index]["mass"],
317 front_suspension_spring_constant: suspensions[&suspension_index]["spring_constant"],
318 front_suspension_damping_coefficient: suspensions[&suspension_index]
319 ["damping_coefficient"],
320 front_suspension_mass: suspensions[&suspension_index]["mass"],
321 rear_wing_width: p[29],
322 rear_wing_y_position: p[30],
323 front_wing_y_position: p[31],
324 side_wing_y_position: p[32],
325 engine_y_position: p[33],
326 cabin_y_position: p[34],
327 impact_attenuator_length: p[35],
328 impact_attenuator_y_position: p[36],
329 rear_suspension_y_position: p[37],
330 front_suspension_y_position: p[38],
331 }
332 }
333
334 pub fn objective(&self, weights: [f64; 11]) -> f64 {
335 weights[0] * self.mass()
336 + weights[1] * self.center_of_gravity()
337 + weights[2] * self.drag_force()
338 + weights[3] * self.downward_force()
339 + weights[4] * self.acceleration()
340 + weights[5] * self.crash_force()
341 + weights[6] * self.impact_attenuator_volume()
342 + weights[7] * self.corner_velocity()
343 + weights[8] * self.brakeing_distance()
344 + weights[9] * self.suspension_acceleration()
345 + weights[10] * self.pitch_moment()
346 }
347
348 pub fn objectives(&self) -> [f64; 11] {
349 [
350 self.mass(),
351 self.center_of_gravity(),
352 self.drag_force(),
353 self.downward_force(),
354 self.acceleration(),
355 self.crash_force(),
356 self.impact_attenuator_volume(),
357 self.corner_velocity(),
358 self.brakeing_distance(),
359 self.suspension_acceleration(),
360 self.pitch_moment(),
361 ]
362 }
363
364 pub fn check_bounds(&self) -> Vec<f64> {
365 todo!()
366 }
367
368 pub fn check_nonlinear_constraints(&self) -> Vec<f64> {
369 todo!()
370 }
371
372 pub fn check_linear_constraints(&self) -> Vec<f64> {
373 todo!()
374 }
375
376 pub fn center_of_gravity(&self) -> f64 {
377 let total_mass = self.mass();
378 let t1 = (self.mass_rear_wing() * self.rear_wing_y_position
379 + self.mass_front_wing() * self.front_wing_y_position
380 + self.engine_mass * self.engine_y_position
381 + self.mass_cabin() * self.cabin_y_position
382 + self.mass_impact_attenuator() * self.impact_attenuator_y_position)
383 / total_mass;
384 let t2 = 2.0
385 * (self.mass_side_wings() * self.side_wing_y_position
386 + self.rear_tire_mass * self.rear_tire_radius
387 + self.front_tire_mass * self.front_tire_radius
388 + self.mass_brake() * self.front_tire_radius
389 + self.rear_suspension_mass * self.rear_suspension_y_position
390 + self.front_suspension_mass * self.front_suspension_y_position)
391 / total_mass;
392 return t1 + t2;
393 }
394
395 pub fn drag_force(&self) -> f64 {
396 todo!()
397 }
398
399 pub fn downward_force(&self) -> f64 {
400 todo!()
401 }
402
403 pub fn acceleration(&self) -> f64 {
404 todo!()
405 }
406 pub fn crash_force(&self) -> f64 {
407 todo!()
408 }
409 pub fn impact_attenuator_volume(&self) -> f64 {
410 todo!()
411 }
412 pub fn corner_velocity(&self) -> f64 {
413 todo!()
414 }
415 pub fn brakeing_distance(&self) -> f64 {
416 todo!()
417 }
418 pub fn suspension_acceleration(&self) -> f64 {
419 todo!()
420 }
421 pub fn pitch_moment(&self) -> f64 {
422 todo!()
423 }
424
425 pub fn mass(&self) -> f64 {
426 self.mass_rear_wing()
427 + self.mass_front_wing()
428 + 2.0 * self.mass_side_wings()
429 + 2.0 * self.rear_tire_mass
430 + 2.0 * self.front_tire_mass
431 + self.engine_mass
432 + self.mass_cabin()
433 + self.mass_impact_attenuator()
434 + 4.0 * self.mass_brake()
435 + 2.0 * self.rear_suspension_mass
436 + 2.0 * self.front_suspension_mass
437 }
438
439 fn mass_rear_wing(&self) -> f64 {
440 self.rear_wing_length
441 * self.rear_wing_width
442 * self.rear_wing_height
443 * self.rear_wing_density
444 }
445
446 fn mass_front_wing(&self) -> f64 {
447 self.front_wing_length
448 * self.front_wing_width
449 * self.front_wing_height
450 * self.front_wing_density
451 }
452
453 fn mass_side_wings(&self) -> f64 {
454 self.side_wings_length
455 * self.side_wings_width
456 * self.side_wings_height
457 * self.side_wing_density
458 }
459 fn mass_impact_attenuator(&self) -> f64 {
460 self.impact_attenuator_length
461 * self.impact_attenuator_width
462 * self.impact_attenuator_height
463 * self.impact_attenuator_density
464 }
465 fn mass_cabin(&self) -> f64 {
466 2.0 * (self.cabin_height * self.cabin_length * self.cabin_thickness
467 + self.cabin_height * self.cabin_width * self.cabin_thickness
468 + self.cabin_length * self.cabin_height * self.cabin_thickness)
469 * self.cabin_density
470 }
471 fn mass_brake(&self) -> f64 {
472 self.brake_length * self.brake_width * self.brake_height * self.brake_density
473 }
474}
475
476impl argmin::prelude::ArgminOp for Car {
477 type Param = Vec<f64>;
478 type Output = f64;
479 type Hessian = ();
480 type Jacobian = ();
481 type Float = f64;
482
483 fn apply(&self, param: &Self::Param) -> Result<Self::Output, argmin::prelude::Error> {
484 Ok(Car::new_from_parameters(param).objective(EVEN_WEIGHTS))
485 }
486}
487
488impl std::fmt::Display for Car {
489 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
490 todo!()
491 }
492}
493
494#[cfg(test)]
495mod tests {
496 use super::*;
497
498 #[test]
499 fn internal() {
500 let cost = Car::new();
501 println!("{:?}", cost.objective(EVEN_WEIGHTS));
502 }
513}