Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
VehicleModelBicycle.cpp
Go to the documentation of this file.
2
3
4#include <cmath>
5#include <algorithm>
6
8#include "transform.hpp"
9
11 : position(Eigen::Vector3d::Zero()),
12 orientation(Eigen::Vector3d::Zero()),
13 velocity(Eigen::Vector3d::Zero()),
14 angularVelocity(Eigen::Vector3d::Zero()),
15 acceleration(Eigen::Vector3d::Zero()) {}
16
18 auto configModel = config["simple_bicycle_model"];
19
20 // Read kinematics parameters
21 auto kinematics = configModel["kinematics"];
22 kinematics.getElement<double>(&lf, "lf");
23 kinematics.getElement<double>(&lr, "lr");
24 kinematics.getElement<double>(&sf, "sf");
25 kinematics.getElement<double>(&sr, "sr");
26 kinematics.getElement<double>(&h_cg, "h_cg");
27
28 // Read tire model parameters
29 auto tire = configModel["tire"];
30 tire.getElement<double>(&tireModel.Blat, "Blat");
31 tire.getElement<double>(&tireModel.Clat, "Clat");
32 tire.getElement<double>(&tireModel.Dlat, "Dlat");
33 tire.getElement<double>(&tireModel.Elat, "Elat");
34
35 // Read aerodynamic parameters
36 auto aero = configModel["aero"];
37 aero.getElement<double>(&aeroModel.cla, "cla");
38 aero.getElement<double>(&aeroModel.cda, "cda");
39 aero.getElement<double>(&aeroModel.aeroArea, "aeroArea");
40
41 // Read general vehicle parameters
42 configModel.getElement<double>(&m, "m");
43 configModel.getElement<double>(&Izz, "Izz");
44 configModel.getElement<double>(&powertrainModel.wheelRadius, "wheelRadius");
45 configModel.getElement<double>(&powertrainModel.gearRatio, "gearRatio");
46 configModel.getElement<double>(&steeringModel.innerSteeringRatio, "innerSteeringRatio");
47 configModel.getElement<double>(&steeringModel.outerSteeringRatio, "outerSteeringRatio");
48 configModel.getElement<double>(&powertrainModel.nominalVoltageTS, "nominalVoltageTS");
49 configModel.getElement<double>(&powertrainModel.powerGroundForce, "powerGroundForce");
50 configModel.getElement<double>(&powertrainModel.maxMotorPower, "maxMotorPower");
51 configModel.getElement<double>(&powertrainModel.maxMotorRPM, "maxMotorRPM");
52 configModel.getElement<double>(&powertrainModel.maxMotorTorque, "maxMotorTorque");
53 return true;
54}
55
56Eigen::Vector3d VehicleModelBicycle::getPosition() { return position; }
57
59
60Eigen::Vector3d VehicleModelBicycle::getVelocity() { return velocity; }
61
63
65
67
69
73
75
79
81
83
85
87
89
91
93
97
99 // Rear steering not implemented
100}
101
103 throttleActuationFL = std::clamp(in.FL, -1.0, 1.0);
104 throttleActuationFR = std::clamp(in.FR, -1.0, 1.0);
105 throttleActuationRL = std::clamp(in.RL, -1.0, 1.0);
106 throttleActuationRR = std::clamp(in.RR, -1.0, 1.0);
107}
108
110 powerGroundSetpoint = std::clamp(in, 0.0, 1.0);
111}
112
113void VehicleModelBicycle::setPosition(Eigen::Vector3d newPosition) { position = newPosition; }
114
115void VehicleModelBicycle::setOrientation(Eigen::Vector3d newOrientation) {
116 orientation = newOrientation;
117}
118
119double VehicleModelBicycle::processSlipAngleLat(double alpha_input, double Fz) {
120 return tireModel.calculateLateralForce(alpha_input, Fz);
121}
122
123// tested
124void VehicleModelBicycle::AerodynamicsModel::calculateForces(double velocityX, double& downforce,
125 double& drag) const {
126 double velocitySquared = velocityX * velocityX;
127 downforce = 0.5 * AIR_DENSITY * aeroArea * cla * velocitySquared;
128 double dragMagnitude = 0.5 * AIR_DENSITY * aeroArea * cda * velocitySquared;
129 drag = (velocityX > 0) ? -dragMagnitude : dragMagnitude;
130}
131
133 if (value > 0) return 1;
134 if (value < 0) return -1;
135 return 1; // Default to 1 for zero
136}
137
139 double normalForce) const {
140 if (slipAngle == 0.0) {
141 return 0.0; // No slip angle, no lateral force
142 }
143 double dpi = (p_input - NOMPRES) / NOMPRES;
144 double Fz_0_prime = LFZO * FNOM;
145 double Kya = PKY1 * Fz_0_prime * (1 + PPY1 * dpi) * (1 - PKY3 * abs(y_input)) *
146 sin(PKY4 * atan((normalForce / Fz_0_prime) /
147 ((PKY2 + PKY5 * y_input * y_input) * (1 + PPY2 * dpi)))) *
148 zeta_3 * LKY;
149 double dfz = (normalForce - Fz_0_prime) / Fz_0_prime;
150 double Kyg0 = normalForce * (PKY6 + PKY7 * dfz) * (1 + PPY5 * dpi) * LKYC;
151 double Vs_y = tan(slipAngle) * abs(V_cx);
152 double Vs_x = -slip_ratio * abs(V_cx);
153 double Vs = sqrt(Vs_x * Vs_x + Vs_y * Vs_y);
154 double V0 = LONGVL;
155 double LMUY_star = LMUY / (1.0 + LMUV * (Vs / V0));
156 double SVyg = normalForce * (PVY3 + PVY4 * dfz) * y_input * LKYC * LMUY_star * zeta_2;
157 double SHy = (PHY1 + PHY2 * dfz) +
158 ((Kyg0 * y_input - SVyg) / (Kya + eps_k * sign(Kya))) * zeta_0 + zeta_4 - 1.0;
159 double alpha_y = slipAngle + SHy;
160 double Ey = (PEY1 + PEY2 * dfz) *
161 (1 + PEY5 * y_input * y_input - (PEY3 + PEY4 * y_input) * sign(alpha_y)) * LEY;
162 double Cy = PCY1 * LCY;
163 double mu_y = (PDY1 + PDY2 * dfz) * (1.0 + PPY3 * dpi + PPY4 * dpi * dpi) *
164 (1.0 - PDY3 * y_input * y_input) * LMUY_star;
165 double Dy = mu_y * normalForce * zeta_2;
166 double By = Kya / (Cy * Dy + eps_y * sign(Dy));
167 double DVyk = mu_y * normalForce * (RVY1 + RVY2 * dfz + RVY3 * y_input) *
168 cos(atan(RVY4 * slipAngle)) * zeta_2;
169 double SVyk = DVyk * sin(RVY5 * atan(RVY6 * slip_ratio)) * LVYKA;
170 double Eyk = REY1 + REY2 * dfz;
171 double SHyk = RHY1 + RHY2 * dfz;
172 double ks = slip_ratio + SHyk;
173 double Byk = (RBY1 + RBY4 * y_input * y_input) * cos(atan(RBY2 * (slipAngle - RBY3))) * LYKA;
174 double Cyk = RCY1;
175 double Gyk_0 = cos(Cyk * atan(Byk * SHyk - Eyk * (Byk * SHyk - atan(Byk * SHyk))));
176 double Gyk = (cos(Cyk * atan(Byk * ks - Eyk * (Byk * ks - atan(Byk * ks)))) / Gyk_0);
177 double SVy = normalForce * (PVY1 + PVY2 * dfz) * LVY * LMUY_star * zeta_2 + SVyg;
178 double Fy_0 = Dy * sin(Cy * atan(By * alpha_y - Ey * (By * alpha_y - atan(By * alpha_y)))) + SVy;
179 double Fy = Gyk * Fy_0 + SVyk;
180
181 return Fy;
182}
183
184//tested
185void VehicleModelBicycle::PowertrainModel::calculateWheelTorques(const Wheels& throttleInputs, const Wheels& wheelspeeds, Wheels& torques) const {
186 double rpm2rad = TWO_PI / 60.0;
187 double motor_rpm = 0.5 * (wheelspeeds.RL + wheelspeeds.RR) * gearRatio;
188 double motor_omega = motor_rpm * rpm2rad;
189
190 double available_mech_torque = 0;
191
192 if (std::abs(motor_rpm) >= maxMotorRPM) {
193 available_mech_torque = 0.0;
194 } else {
195 // Dynamic torque limit, max torque up to max power
196 available_mech_torque = std::min(maxMotorTorque, maxMotorPower / std::max(1e-3, std::abs(motor_omega)));
197 }
198
199 double throttle_input = 0.5 * (throttleInputs.RL + throttleInputs.RR);
200 double final_motor_torque = available_mech_torque * throttle_input;
201
202 torques.FL = 0.0;
203 torques.FR = 0.0;
204 torques.RL = final_motor_torque * 0.5;
205 torques.RR = final_motor_torque * 0.5;
206}
207
208//tested
210 // Simple efficiency model based on rear wheel torques
211 // TODO: macros instead of harcoded values
212
213 return 0.002333 * (abs(torques.RL) + abs(torques.RR)) + 0.594;
214}
215
216//tested
218 const Wheels& wheelspeeds,
219 double voltage) const {
220 constexpr double powerCoeff = 1.0 / 9.55;
221
222 // Calculate power for each wheel
223 double powerFL = torques.FL * wheelspeeds.FL * powerCoeff;
224 double powerFR = torques.FR * wheelspeeds.FR * powerCoeff;
225 double powerRL = torques.RL * wheelspeeds.RL * powerCoeff;
226 double powerRR = torques.RR * wheelspeeds.RR * powerCoeff;
227
228 // Calculate total power and return current
229 double totalPower = (powerFL + powerFR + powerRL + powerRR) / calculateEfficiency(torques);
230 return (totalPower / voltage);
231}
232
233// tested
235 Wheels& steeringAngles) const {
236 // Apply Ackermann steering geometry
237 double avgRatio = 0.5 * (innerSteeringRatio + outerSteeringRatio);
238
239 if (steeringInput > 0) {
240 steeringAngles.FL = innerSteeringRatio * steeringInput / avgRatio;
241 steeringAngles.FR = outerSteeringRatio * steeringInput / avgRatio;
242 } else {
243 steeringAngles.FL = outerSteeringRatio * steeringInput / avgRatio;
244 steeringAngles.FR = innerSteeringRatio * steeringInput / avgRatio;
245 }
246
247 // Rear wheels have zero steering angle
248 steeringAngles.RL = 0.0;
249 steeringAngles.RR = 0.0;
250}
251
252//tested
254 const Wheels& steeringAngles) const {
255 // Calculate steering wheel angle based on the front left steering angle and appropriate ratio
256 return (steeringAngles.FL > 0) ? steeringAngles.FL / innerSteeringRatio
257 : steeringAngles.FL / outerSteeringRatio;
258}
259
260//tested
261void VehicleModelBicycle::calculateNormalForces(double& Fz_Front, double& Fz_Rear) const {
262 double l = lr + lf;
263
264 // Calculate downforce from aerodynamics
265 double downforce = 0.0;
266 double drag = 0.0;
267 aeroModel.calculateForces(velocity.x(), downforce, drag);
268
269 // Add ground effect if requested
271
272 // Calculate normal forces on axles with weight distribution and aero effects
273 Fz_Front = std::max(0.0, (m * GRAVITY + downforce) * 0.5 * lr / l);
274 Fz_Rear = std::max(0.0, (m * GRAVITY + downforce) * 0.5 * lf / l);
275}
276
277
278/*
279Currently this function depends on the longitudinal forces applied on the wheels and therefore can only be called after calling calculateLongitudinalForces.
280This can be changed but it would imply calling the calculation of longitudinal forces twice.
281
282Also note that this only accounts for longitudinal weight transfer, because we are using a bycicle model , lateral weight transfer cannot be applied as we only have one wheel in each axle.
283
284To apply lateral weight transfer it would be necessary to account for each of the 4 wheels seperately.
285*/
286void VehicleModelBicycle::calculateWeightTransfer(double& Fz_Front, double& Fz_Rear , double& Fx_FL , double& Fx_FR , double& Fx_RL , double& Fx_RR) const {
287 // Calculate total longitudinal force (traction + braking)
288 double Fx_total = Fx_FL + Fx_FR + Fx_RL + Fx_RR;
289
290
291 double l = lf + lr; // wheelbase
292 double deltaW = (Fx_total * h_cg) / l;
293
294 // Positive Fx_total (acceleration): weight shifts to rear
295 // Negative Fx_total (braking): weight shifts to front
296 Fz_Front -= deltaW;
297 Fz_Rear += deltaW;
298}
299
300
301void VehicleModelBicycle::calculateSlipAngles(double& kappaFront, double& kappaRear) const {
302 constexpr double eps = 0.00001; // Prevent division by zero
303
309 bool stillstand = (velocity.norm() < VELOCITY_THRESHOLD) &&
311
312 // Calculate wheel positions relative to CoG
313 Eigen::Vector3d rFront(lf, 0.0, 0.0);
314 Eigen::Vector3d rRear(-lr, 0.0, 0.0);
315
316 // Calculate wheel velocities
317 Eigen::Vector3d vFront = velocity + angularVelocity.cross(rFront);
318 Eigen::Vector3d vRear = velocity + angularVelocity.cross(rRear);
319
320 // Calculate average front steering angle
321 double steeringFront = 0.5 * (steeringAngles.FL + steeringAngles.FR);
322
323 // Calculate slip angles for front and rear
324 kappaFront = std::atan2(vFront.y(), std::max(std::abs(vFront.x()), eps)) - steeringFront;
325 kappaRear = std::atan2(vRear.y(), std::max(std::abs(vRear.x()), eps));
326
327 if (stillstand) {
328 kappaFront = 0.0;
329 kappaRear = 0.0;
330 }
331}
332
333
334//tested
335// New helper function to calculate wheel positions and velocities
336void VehicleModelBicycle::calculateWheelGeometry(double& steeringFront, Eigen::Vector3d& rFL,
337 Eigen::Vector3d& rFR, Eigen::Vector3d& rRL,
338 Eigen::Vector3d& rRR, Eigen::Vector3d& rFront,
339 Eigen::Vector3d& rRear, Eigen::Vector3d& vFL,
340 Eigen::Vector3d& vFR, Eigen::Vector3d& vRL,
341 Eigen::Vector3d& vRR) const {
342 // Calculate average front steering angle
343 steeringFront = 0.5 * (steeringAngles.FL + steeringAngles.FR);
344
345 // Calculate wheel positions relative to CoG
346 rFL = Eigen::Vector3d(lf, 0.5 * sf, 0.0);
347 rFR = Eigen::Vector3d(lf, -0.5 * sf, 0.0);
348 rRL = Eigen::Vector3d(-lr, 0.5 * sr, 0.0);
349 rRR = Eigen::Vector3d(-lr, -0.5 * sr, 0.0);
350 rFront = Eigen::Vector3d(lf, 0.0, 0.0);
351 rRear = Eigen::Vector3d(-lr, 0.0, 0.0);
352
353 // Calculate wheel velocities
354 vFL = velocity + angularVelocity.cross(rFL);
355 vFR = velocity + angularVelocity.cross(rFR);
356 vRL = velocity + angularVelocity.cross(rRL);
357 vRR = velocity + angularVelocity.cross(rRR);
358}
359
360//tested
361// New helper function to calculate longitudinal forces
362void VehicleModelBicycle::calculateLongitudinalForces(double& Fx_FL, double& Fx_FR, double& Fx_RL,
363 double& Fx_RR) const {
364 // Calculate powertrain efficiency
365 double powertrainEfficiency = powertrainModel.calculateEfficiency(torques);
366
367 // Calculate longitudinal forces on wheels
368 Fx_FL = 0; // Front wheel drive not enabled
369 Fx_FR = 0; // Front wheel drive not enabled
370 Fx_RL =
371 (powertrainModel.gearRatio * torques.RL / powertrainModel.wheelRadius) * powertrainEfficiency;
372 Fx_RR =
373 (powertrainModel.gearRatio * torques.RR / powertrainModel.wheelRadius) * powertrainEfficiency;
374
375 // Apply forces only when torque is significant or vehicle is moving
376 Fx_FL *= (abs(torques.FL) > TORQUE_THRESHOLD || velocity.x() > VELOCITY_MIN_THRESHOLD) ? 1.0 : 0.0;
377 Fx_FR *= (abs(torques.FR) > TORQUE_THRESHOLD || velocity.x() > VELOCITY_MIN_THRESHOLD) ? 1.0 : 0.0;
378 Fx_RL *= (abs(torques.RL) > TORQUE_THRESHOLD || velocity.x() > VELOCITY_MIN_THRESHOLD) ? 1.0 : 0.0;
379 Fx_RR *= (abs(torques.RR) > TORQUE_THRESHOLD || velocity.x() > VELOCITY_MIN_THRESHOLD) ? 1.0 : 0.0;
380}
381
382// New helper function to calculate accelerations
383//tested
384Eigen::Vector3d VehicleModelBicycle::calculateAccelerations(double steeringFront, double Fx_FL,
385 double Fx_FR, double Fx_RL,
386 double Fx_RR, double Fy_Front,
387 double Fy_Rear, double drag,
388 const Eigen::Vector3d& friction) const {
389 // Calculate longitudinal acceleration from tire forces
390 double axTires = (std::cos(steeringAngles.FL) * Fx_FL + std::cos(steeringAngles.FR) * Fx_FR +
391 Fx_RL + Fx_RR - std::sin(steeringFront) * Fy_Front) /
392 m;
393
394 // Apply aerodynamic drag and friction to get total acceleration
395 double axModel = axTires + drag / m + friction.x() / m;
396
397 // Calculate lateral acceleration from tire forces
398 double ayTires = (std::sin(steeringAngles.FL) * Fx_FL + std::sin(steeringAngles.FR) * Fx_FR +
399 std::cos(steeringFront) * Fy_Front + Fy_Rear) /
400 m;
401 double ayModel = ayTires + friction.y() / m;
402
403 // Calculate yaw moment contributions
404 double rdotFx
405 = 0.5 * this->sf * (-Fx_FL * std::cos(this->steeringAngles.FL) + Fx_FR * std::cos(this->steeringAngles.FR))
406 + this->lf * (Fx_FL * std::sin(this->steeringAngles.FL) + Fx_FR * std::sin(this->steeringAngles.FR))
407 + 0.5 * this->sr * (Fx_RR * std::cos(this->steeringAngles.RR) - Fx_RL * std::cos(this->steeringAngles.RL))
408 - this->lr * (Fx_RL * std::sin(this->steeringAngles.RL) + Fx_RR * std::sin(this->steeringAngles.RR));
409
410 double rdotFy = lf * (Fy_Front * std::cos(steeringFront)) - lr * (Fy_Rear);
411
412 // Calculate yaw acceleration
413 double rdot = (rdotFx + rdotFy) / Izz;
414
415 return Eigen::Vector3d(axModel, ayModel, rdot);
416}
417
418//tested
419// New helper function to update wheel speeds
420void VehicleModelBicycle::updateWheelSpeeds(const Eigen::Vector3d& vFL, const Eigen::Vector3d& vFR,
421 const Eigen::Vector3d& vRL,
422 const Eigen::Vector3d& vRR) {
423 // Conversion factor from RPM to m/s
424 double rpm2ms = powertrainModel.wheelRadius * TWO_PI / 60;
425
426 // Update wheel speeds
427 wheelspeeds.FL = vFL.x() / rpm2ms;
428 wheelspeeds.FR = vFR.x() / rpm2ms;
429 wheelspeeds.RL = vRL.x() / rpm2ms;
430 wheelspeeds.RR = vRR.x() / rpm2ms;
431}
432
433// Refactored getDynamicStates using the new helper functions
434Eigen::Vector3d VehicleModelBicycle::getDynamicStates(double dt) {
435 // Calculate wheel positions and velocities
436 double steeringFront;
437 Eigen::Vector3d rFL, rFR, rRL, rRR, rFront, rRear;
438 Eigen::Vector3d vFL, vFR, vRL, vRR;
439 calculateWheelGeometry(steeringFront, rFL, rFR, rRL, rRR, rFront, rRear, vFL, vFR, vRL, vRR);
440
441 // Calculate normal forces on axles
442 double Fz_Front, Fz_Rear;
443 calculateNormalForces(Fz_Front, Fz_Rear);
444
445 // Calculate aero drag
446 double downforce, drag;
447 aeroModel.calculateForces(velocity.x(), downforce, drag);
448
449 // Calculate rolling resistance (applied opposite to velocity direction)
450 double frict = (Fz_Front + Fz_Rear) * ROLLING_RESISTANCE_COEFF;
451 Eigen::Vector3d friction;
452
453 if (velocity.norm() < 0.01) {
454 friction = Eigen::Vector3d::Zero();
455 } else {
456 Eigen::Vector3d velDir = -velocity.normalized();
457 friction = frict * velDir;
458 }
459
460 // Calculate longitudinal forces
461 double Fx_FL, Fx_FR, Fx_RL, Fx_RR;
462 calculateLongitudinalForces(Fx_FL, Fx_FR, Fx_RL, Fx_RR);
463
464 // Calculate weight transfer based on longitudinal forces -> this works because fz front and rear were calculate above
465 calculateWeightTransfer(Fz_Front, Fz_Rear, Fx_FL, Fx_FR, Fx_RL, Fx_RR);
466
467 // Calculate slip angles
468 double kappaFront, kappaRear;
469 calculateSlipAngles(kappaFront, kappaRear);
470
471 // Calculate lateral forces using tire model
472 double Fy_Front = processSlipAngleLat(kappaFront, Fz_Front / 2) * 2;
473 double Fy_Rear = processSlipAngleLat(kappaRear, Fz_Rear / 2) * 2;
474
475 // Update wheel speeds
476 updateWheelSpeeds(vFL, vFR, vRL, vRR);
477
478 RCLCPP_DEBUG(rclcpp::get_logger("a"),
479 "Vx: %f, Vy: %f, W: %f, KappaF: %f, KappaR: %f, Fy_Front: %f, Fy_Rear: %f, drag: %f, friction: %f", velocity.x(),
480 velocity.y(), angularVelocity.z(), kappaFront, kappaRear, Fy_Front, Fy_Rear, drag, friction.x());
481
482 // Calculate accelerations
483 return calculateAccelerations(steeringFront, Fx_FL, Fx_FR, Fx_RL, Fx_RR, Fy_Front, Fy_Rear, drag,
484 friction);
485}
486
488
489 // Convert throttle to wheel torques (using PowertrainModel)
492
493 // Calculate dynamic states
494 Eigen::Vector3d dynamicStates = getDynamicStates(dt);
495
496 // Update acceleration from dynamic states
497 acceleration = Eigen::Vector3d(dynamicStates.x(), dynamicStates.y(), 0.0);
498
499 // Update angular velocity and acceleration
500 angularVelocity.z() += dynamicStates.z() * dt;
501 angularAcceleration.z() = dynamicStates.z();
502
503 // Update velocity with acceleration and angular velocity effects
505
506 // Update position based on velocity and orientation
507 Eigen::AngleAxisd yawAngle(orientation.z(), Eigen::Vector3d::UnitZ());
508 position += (yawAngle.matrix() * velocity) * dt;
509
510 // Update orientation based on angular velocity
511 orientation.z() += dt * angularVelocity.z();
512
513 // Update wheel orientations
514 const double wheelRotationFactor = TWO_PI / (60.0 * powertrainModel.gearRatio);
515
517 std::fmod(wheelOrientations.FL + wheelspeeds.FL * dt * wheelRotationFactor, TWO_PI);
519 std::fmod(wheelOrientations.FR + wheelspeeds.FR * dt * wheelRotationFactor, TWO_PI);
521 std::fmod(wheelOrientations.RL + wheelspeeds.RL * dt * wheelRotationFactor, TWO_PI);
523 std::fmod(wheelOrientations.RR + wheelspeeds.RR * dt * wheelRotationFactor, TWO_PI);
524}
525
526//tested
527std::array<Eigen::Vector3d, 4> VehicleModelBicycle::getWheelPositions() {
528 // Transform wheel positions from vehicle coordinates to world coordinates
529 //auto rotMat = eulerAnglesToRotMat(orientation).transpose();
530 // ^ removed because it was causing a bug
531 auto rotMat = eulerAnglesToRotMat(orientation);
532
533 Eigen::Vector3d FL = rotMat * Eigen::Vector3d(lf, sf * 0.5, 0.0) + position;
534 Eigen::Vector3d FR = rotMat * Eigen::Vector3d(lf, -sf * 0.5, 0.0) + position;
535 Eigen::Vector3d RL = rotMat * Eigen::Vector3d(-lr, sr * 0.5, 0.0) + position;
536 Eigen::Vector3d RR = rotMat * Eigen::Vector3d(-lr, -sr * 0.5, 0.0) + position;
537
538 return {FL, FR, RL, RR};
539}
ConfigElement getElement(string elementName)
void calculateNormalForces(double &Fz_Front, double &Fz_Rear) const
std::array< Eigen::Vector3d, 4 > getWheelPositions() override
Wheels getTorques() override
double getCurrentTS() override
void setPosition(Eigen::Vector3d position) override
void setSteeringSetpointRear(double in) override
void setThrottle(Wheels in) override
double getSteeringWheelAngle() override
Eigen::Vector3d getAngularAcceleration() override
Eigen::Vector3d angularAcceleration
void calculateSlipAngles(double &kappaFront, double &kappaRear) const
void setRpmSetpoints(Wheels in) override
static constexpr double AIR_DENSITY
void setOrientation(Eigen::Vector3d orientation) override
void setTorques(Wheels in) override
Eigen::Vector3d getVelocity() override
Eigen::Vector3d getDynamicStates(double dt)
double processSlipAngleLat(double alpha_input, double Fz)
void calculateWeightTransfer(double &Fz_Front, double &Fz_Rear, double &Fx_FL, double &Fx_FR, double &Fx_RL, double &Fx_RR) const
Wheels getSteeringAngles() override
void setMinTorques(Wheels in) override
Wheels getWheelspeeds() override
static constexpr double TORQUE_THRESHOLD
void setSteeringSetpointFront(double in) override
Wheels getWheelOrientations() override
static constexpr double GRAVITY
void setPowerGroundSetpoint(double in) override
static constexpr double VELOCITY_MIN_THRESHOLD
bool readConfig(ConfigElement &config) override
static constexpr double VELOCITY_THRESHOLD
PowertrainModel powertrainModel
AerodynamicsModel aeroModel
static constexpr double TWO_PI
Eigen::Vector3d getPosition() override
static constexpr double ANGULAR_VELOCITY_THRESHOLD
void calculateLongitudinalForces(double &Fx_FL, double &Fx_FR, double &Fx_RL, double &Fx_RR) const
Eigen::Vector3d calculateAccelerations(double steeringFront, double Fx_FL, double Fx_FR, double Fx_RL, double Fx_RR, double Fy_Front, double Fy_Rear, double drag, const Eigen::Vector3d &friction) const
void setMaxTorques(Wheels in) override
void forwardIntegrate(double dt) override
void updateWheelSpeeds(const Eigen::Vector3d &vFL, const Eigen::Vector3d &vFR, const Eigen::Vector3d &vRL, const Eigen::Vector3d &vRR)
void calculateWheelGeometry(double &steeringFront, Eigen::Vector3d &rFL, Eigen::Vector3d &rFR, Eigen::Vector3d &rRL, Eigen::Vector3d &rRR, Eigen::Vector3d &rFront, Eigen::Vector3d &rRear, Eigen::Vector3d &vFL, Eigen::Vector3d &vFR, Eigen::Vector3d &vRL, Eigen::Vector3d &vRR) const
Eigen::Vector3d angularVelocity
static constexpr double ROLLING_RESISTANCE_COEFF
Eigen::Vector3d getOrientation() override
double getVoltageTS() override
Eigen::Vector3d getAcceleration() override
Eigen::Vector3d getAngularVelocity() override
void calculateForces(double velocityX, double &downforce, double &drag) const
void calculateWheelTorques(const Wheels &throttleInputs, const Wheels &wheelspeeds, Wheels &torques) const
double calculateCurrent(const Wheels &torques, const Wheels &wheelspeeds, double voltage) const
double calculateEfficiency(const Wheels &torques) const
void calculateSteeringAngles(double steeringInput, Wheels &steeringAngles) const
double calculateSteeringWheelAngle(const Wheels &steeringAngles) const
double calculateLateralForce(double slipAngle, double normalForce) const
Eigen::Matrix3d eulerAnglesToRotMat(Eigen::Vector3d &angles)
Definition transform.cpp:14