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()) {}
18 auto configModel = config[
"simple_bicycle_model"];
21 auto kinematics = configModel[
"kinematics"];
29 auto tire = configModel[
"tire"];
36 auto aero = configModel[
"aero"];
125 double& drag)
const {
126 double velocitySquared = velocityX * velocityX;
129 drag = (velocityX > 0) ? -dragMagnitude : dragMagnitude;
133 if (value > 0)
return 1;
134 if (value < 0)
return -1;
139 double normalForce)
const {
140 if (slipAngle == 0.0) {
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)))) *
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);
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;
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;
186 double rpm2rad =
TWO_PI / 60.0;
188 double motor_omega = motor_rpm * rpm2rad;
190 double available_mech_torque = 0;
192 if (std::abs(motor_rpm) >= maxMotorRPM) {
193 available_mech_torque = 0.0;
196 available_mech_torque = std::min(maxMotorTorque, maxMotorPower / std::max(1e-3, std::abs(motor_omega)));
199 double throttle_input = 0.5 * (throttleInputs.RL + throttleInputs.RR);
200 double final_motor_torque = available_mech_torque * throttle_input;
204 torques.RL = final_motor_torque * 0.5;
205 torques.RR = final_motor_torque * 0.5;
219 double voltage)
const {
220 constexpr double powerCoeff = 1.0 / 9.55;
229 double totalPower = (powerFL + powerFR + powerRL + powerRR) / calculateEfficiency(
torques);
230 return (totalPower / voltage);
237 double avgRatio = 0.5 * (innerSteeringRatio + outerSteeringRatio);
239 if (steeringInput > 0) {
240 steeringAngles.FL = innerSteeringRatio * steeringInput / avgRatio;
241 steeringAngles.FR = outerSteeringRatio * steeringInput / avgRatio;
243 steeringAngles.FL = outerSteeringRatio * steeringInput / avgRatio;
244 steeringAngles.FR = innerSteeringRatio * steeringInput / avgRatio;
265 double downforce = 0.0;
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);
288 double Fx_total = Fx_FL + Fx_FR + Fx_RL + Fx_RR;
292 double deltaW = (Fx_total *
h_cg) / l;
302 constexpr double eps = 0.00001;
313 Eigen::Vector3d rFront(
lf, 0.0, 0.0);
314 Eigen::Vector3d rRear(-
lr, 0.0, 0.0);
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));
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 {
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);
363 double& Fx_RR)
const {
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 {
391 Fx_RL + Fx_RR - std::sin(steeringFront) * Fy_Front) /
395 double axModel = axTires + drag /
m + friction.x() /
m;
399 std::cos(steeringFront) * Fy_Front + Fy_Rear) /
401 double ayModel = ayTires + friction.y() /
m;
410 double rdotFy =
lf * (Fy_Front * std::cos(steeringFront)) -
lr * (Fy_Rear);
413 double rdot = (rdotFx + rdotFy) /
Izz;
415 return Eigen::Vector3d(axModel, ayModel, rdot);
421 const Eigen::Vector3d& vRL,
422 const Eigen::Vector3d& vRR) {
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);
442 double Fz_Front, Fz_Rear;
446 double downforce, drag;
451 Eigen::Vector3d friction;
454 friction = Eigen::Vector3d::Zero();
456 Eigen::Vector3d velDir = -
velocity.normalized();
457 friction = frict * velDir;
461 double Fx_FL, Fx_FR, Fx_RL, Fx_RR;
468 double kappaFront, kappaRear;
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(),
497 acceleration = Eigen::Vector3d(dynamicStates.x(), dynamicStates.y(), 0.0);
507 Eigen::AngleAxisd yawAngle(
orientation.z(), Eigen::Vector3d::UnitZ());
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;
538 return {FL, FR, RL, RR};
ConfigElement getElement(string elementName)
void calculateNormalForces(double &Fz_Front, double &Fz_Rear) const
std::array< Eigen::Vector3d, 4 > getWheelPositions() override
Wheels getTorques() override
Eigen::Vector3d orientation
double getCurrentTS() override
void setPosition(Eigen::Vector3d position) override
void setSteeringSetpointRear(double in) override
void setThrottle(Wheels in) override
double getSteeringWheelAngle() override
double throttleActuationFL
Eigen::Vector3d getAngularAcceleration() override
Eigen::Vector3d angularAcceleration
void calculateSlipAngles(double &kappaFront, double &kappaRear) const
double throttleActuationRR
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
double throttleActuationFR
static constexpr double TORQUE_THRESHOLD
void setSteeringSetpointFront(double in) override
double throttleActuationRL
Wheels getWheelOrientations() override
static constexpr double GRAVITY
SteeringModel steeringModel
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
double powerGroundSetpoint
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
Eigen::Vector3d acceleration
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 innerSteeringRatio
double calculateSteeringWheelAngle(const Wheels &steeringAngles) const
double outerSteeringRatio
int sign(double value) const
double calculateLateralForce(double slipAngle, double normalForce) const