controls algo setup - #1936
Conversation
| void TireModel::estimateSlipRatio(const float wheel_angular_velocity_radps) | ||
| { | ||
| const float wheel_surface_speed_mps = wheel_angular_velocity_radps * WHEEL_RADIUS_M; | ||
| const float effective_wheel_speed_mps = std::cos(tire_outputs_.slip_angle_rad) * wheel_vel_x_mps_; |
There was a problem hiding this comment.
i imagine this is also a function of wheelSteeringAngleRad?
There was a problem hiding this comment.
slip angle is a function of wheel steering angle, it is not directly a function of wheel angle
| [[nodiscard]] float estimateDrag_N(float v_x_mps) const; | ||
|
|
||
| private: | ||
| static constexpr float FRONTAL_AREA_M2 = 0.94f; // m^2 from aero team |
There was a problem hiding this comment.
We should just put all these constants into constants.hpp
Lucien950
left a comment
There was a problem hiding this comment.
just a first pass, I think there are some high level structural understandability issues with the code we should address before correctness
| static constexpr float W_FX = 2.0f / 3.0f; // Weight on per-wheel force tracking error | ||
| static constexpr float W_MZ = 1.0f / 3.0f; // Weight on yaw moment tracking error | ||
| static constexpr int MAX_ITER = 8; // Gauss-Newton iterations per control cycle | ||
| static constexpr float SLIP_CLAMP = 0.3f; // Physical slip ratio bounds |
There was a problem hiding this comment.
is it expensive to calculate high slip?
| static constexpr int FL = 0; | ||
| static constexpr int FR = 1; | ||
| static constexpr int RL = 2; | ||
| static constexpr int RR = 3; |
There was a problem hiding this comment.
use unsigned integers
There was a problem hiding this comment.
also i prefer the wheel_set datastructure over this
| @@ -0,0 +1,22 @@ | |||
| #pragma once | |||
|
|
|||
| namespace app::tv::datatypes::datatypes | |||
There was a problem hiding this comment.
why two namespace qualifiers?
| [[nodiscard]] estimation::TireModel::StateInputs buildStateInputs( | ||
| const datatypes::datatypes::VehicleState& vs, | ||
| const float normal_load_N, | ||
| const float wheel_angular_velocity_radps) | ||
| { | ||
| return { | ||
| .wheel_angular_velocity_radps = wheel_angular_velocity_radps, | ||
| .vehicle_velocity_x_mps = vs.v_x_mps, | ||
| .vehicle_velocity_y_mps = vs.v_y_mps, | ||
| .yaw_rate_radps = vs.yaw_rate_radps, | ||
| .steering_angle_rad = vs.steer_ang_rad, | ||
| .normal_load_N = normal_load_N, | ||
| }; | ||
| } | ||
|
|
There was a problem hiding this comment.
you can just make a constructor for this
There was a problem hiding this comment.
also this is a very trivial constructor
|
|
||
| // ---- Construction ---- | ||
|
|
||
| TorqueAllocator::TorqueAllocator(estimation::TireModel::TirePressure pressure) |
There was a problem hiding this comment.
put this in the header please (optimization point)
| return std::atan2(v_y_mps, safeLongitudinalVelocity(v_x_mps)); | ||
| } | ||
|
|
||
| float vehicleDynamics::estimateYawMoment_Nm( |
There was a problem hiding this comment.
i think this is a better yaw moment estimator than in the ta? why not use this?
There was a problem hiding this comment.
oh yes I was thinking that but I didn't know how ur C++ generation was going to work so I left it here for now to make it easier
There was a problem hiding this comment.
but yes I agree for our code it should go there
| const app::tv::datatypes::datatypes::wheel_set& longitudinal_forces_N, | ||
| const app::tv::datatypes::datatypes::wheel_set& lateral_forces_N, |
There was a problem hiding this comment.
also you can just go F_y_N and F_x_N
| @@ -34,8 +34,7 @@ namespace app::tv::controllers::dyrc | |||
| * | |||
| * @return The corrective yaw moment in Nm to apply on the vehicle | |||
| */ | |||
| [[nodiscard]] inline float | |||
| computeYawMoment(const float r_actual_rad, const float steer_ang_rad, const float body_velx_mps); | |||
| [[nodiscard]] float computeYawMoment(const float r_actual_rad, const float steer_ang_rad, const float body_velx_mps); | |||
There was a problem hiding this comment.
lowkey can we calculate yawacceleration
| } | ||
|
|
||
| datatypes::datatypes::wheel_set TorqueAllocator::optimize( | ||
| const datatypes::datatypes::wheel_set& des_f_x, |
There was a problem hiding this comment.
your resired F_x is one number, and it represents the desired body F_x
There was a problem hiding this comment.
please do not specify individual wheel f_x references
There was a problem hiding this comment.
because you actually don't know how to effectively allocate, that is the whole point of the optimizer
There was a problem hiding this comment.
hmm, yeah it might be redundant rn because I optimize on Mz err but also Fx error with Mz taken into account. Note I also realized no constraint is placed on the sum of forces adding on the user quested force * 4. That is important I BELIEVE
| // Desired per-wheel longitudinal force from pedal request, projected along tire heading | ||
| const float per_wheel_tq = MAX_TORQUE_REQUEST_NM * pedal_percentage; | ||
| wheel_set des_f_x = { | ||
| .fl = per_wheel_tq * std::cos(acc_slip_angle.fl) * WHEEL_RADIUS_M , | ||
| .fr = per_wheel_tq * std::cos(acc_slip_angle.fr) * WHEEL_RADIUS_M, | ||
| .rl = per_wheel_tq * std::cos(acc_slip_angle.rl) * WHEEL_RADIUS_M, | ||
| .rr = per_wheel_tq * std::cos(acc_slip_angle.rr) * WHEEL_RADIUS_M, | ||
| }; | ||
|
|
||
| // Direct yaw rate control: corrective yaw moment | ||
| const float des_yaw_moment_nm = controllers::dyrc::computeYawMoment( | ||
| estimated_state.yaw_rate_radps, estimated_state.steer_ang_rad, estimated_state.v_x_mps); | ||
|
|
||
| // Distribute yaw moment into per-wheel force adjustment | ||
| // From Mz = (t/2) * (Fx_right - Fx_left), solve for delta Fx per side: | ||
| const float des_fx_delta = des_yaw_moment_nm / TRACK_WIDTH_m; | ||
| des_f_x.fl -= des_fx_delta; | ||
| des_f_x.fr += des_fx_delta; | ||
| des_f_x.rl -= des_fx_delta; | ||
| des_f_x.rr += des_fx_delta; |
There was a problem hiding this comment.
must change as due to optimizer interface comment
| void unpackTireOutputs( | ||
| const estimation::TireModel::Outputs& fl, | ||
| const estimation::TireModel::Outputs& fr, | ||
| const estimation::TireModel::Outputs& rl, | ||
| const estimation::TireModel::Outputs& rr) | ||
| { | ||
| acc_f_x = { .fl = fl.longitudinal_force_N, .fr = fr.longitudinal_force_N, | ||
| .rl = rl.longitudinal_force_N, .rr = rr.longitudinal_force_N }; | ||
| acc_f_y = { .fl = fl.lateral_force_N, .fr = fr.lateral_force_N, | ||
| .rl = rl.lateral_force_N, .rr = rr.lateral_force_N }; | ||
| acc_slip_ratio = { .fl = fl.slip_ratio, .fr = fr.slip_ratio, | ||
| .rl = rl.slip_ratio, .rr = rr.slip_ratio }; | ||
| acc_slip_angle = { .fl = fl.slip_angle_rad, .fr = fr.slip_angle_rad, | ||
| .rl = rl.slip_angle_rad, .rr = rr.slip_angle_rad }; | ||
| } |
There was a problem hiding this comment.
can you unpack them purely
There was a problem hiding this comment.
it makes it easier to keep track of data dependencies
| const float fl_omega, const float fr_omega, | ||
| const float rl_omega, const float rr_omega) |
There was a problem hiding this comment.
just pass the omegas in a wheels struct
There was a problem hiding this comment.
@Lucien950 Our particular H7 has really shit SIMD, the width is like 32 bits so we can only perform it with 16 bit or 8 bit values. Our main performance benefit would come from the CORDIC because you can do trig, trig inverse, and square root functions with vectors as well, but we dont have the SIMD capabilities to do add, sub, multiply with 32bit float vectors. In other versions of the H7 there is Helium SIMD which has a 128 bit width so we can conveniently do SIMD for that
There was a problem hiding this comment.
but also it may be still beneficial to vectorize this so we can easily port it to SIMD in the future
| * @return Per-wheel optimal slip ratios | ||
| */ | ||
| [[nodiscard]] datatypes::datatypes::wheel_set optimize( | ||
| const datatypes::datatypes::wheel_set& des_f_x, |
There was a problem hiding this comment.
nit: can you hit a using datatypes = datatypes::datatypes for anywhere where this is used it just makes it a bit easier to read
There was a problem hiding this comment.
its been changed to shared_datatypes.
There was a problem hiding this comment.
also arent I doing this i have an MR up for body velocity estimation and i can add yaw moment + yaw rate in the state as well
c6d491a to
880059a
Compare
|
force push :((((((( |
Aditya-Dhiman4
left a comment
There was a problem hiding this comment.
pretty sick mostly small things
| /** | ||
| * Yaw moment distribution factor Kmz (page 57) | ||
| * Accounts for load transfer effect on yaw moment generation capacity | ||
| * @return Effective moment arm (m) | ||
| */ | ||
| [[nodiscard]] constexpr float ACCELERATION_TERM_KMZ() const | ||
| { | ||
| return vd_constants::DIST_FRONT_AXLE_CG_m + (a_x_mps2 * vd_constants::DIST_HEIGHT_CG_m) / vd_constants::GRAVITY; | ||
| } | ||
| [[nodiscard]] constexpr float KMZ() const | ||
| { | ||
| const float LONG_ACCEL_TERM = ACCELERATION_TERM_KMZ(); | ||
| return ((vd_constants::CAR_WEIGHT - (vd_constants::CAR_WEIGHT / vd_constants::WHEELBASE_m) * LONG_ACCEL_TERM)) / | ||
| ((vd_constants::CAR_WEIGHT / vd_constants::WHEELBASE_m) * LONG_ACCEL_TERM); | ||
| } | ||
| /** | ||
| * Moment scaling factor F (page 58) | ||
| * Relates torque differential to yaw moment through track width and effective radius | ||
| */ | ||
| static constexpr float F = (vd_constants::TRACK_WIDTH_m / ((WHEEL_DIAMETER_IN / 2.0f) * IN_TO_M)) * GEAR_RATIO; |
There was a problem hiding this comment.
These were required for the Quintuna algo not Hexray, we should probably add a comment for future reference to prevent confusion
There was a problem hiding this comment.
actually I'm confused as to why this is required at all, i'm not so sure about what these terms are
There was a problem hiding this comment.
shayan gave these to me
There was a problem hiding this comment.
ic we can remove if u want or keep for legacy/fallback
| constexpr std::size_t AY = 1; | ||
|
|
||
| constexpr float ESTIMATOR_DT_S = 0.01f; // Matches the 100 Hz control task. | ||
| constexpr float ESTIMATOR_YAW_INERTIA = 110.0f; // TODO: Replace with measured Hexray yaw inertia. |
There was a problem hiding this comment.
Should we put this into constants.hpp?
There was a problem hiding this comment.
idk I didn't write this this all u
There was a problem hiding this comment.
dawg i did not write this i have a separate PR for this
There was a problem hiding this comment.
ok well use that then
There was a problem hiding this comment.
This is kinda hard to read lowkey grouping the functions properly would help
…d slip once coefficents are here.... testing TODO
Co-authored-by: Edwin <20777515+Lucien950@users.noreply.github.com>
…ke it a motor speed request
aaca9a1 to
3b10a21
Compare
| } }; | ||
| // bring it in | ||
| const auto [k_kappas, k_torque_max, k_torque_min] = update(state); | ||
| // std::cout << "DIH" << std::endl; |
### Changelist <!-- Give a list of the changes covered in this PR. This will help both you and the reviewer keep this PR within scope. --> ### Testing Done <!-- Outline the testing that was done to demonstrate the changes are solid. This could be unit tests, integration tests, testing on the car, etc. Include relevant code snippets, screenshots, etc as needed. --> ### Resolved Tickets <!-- Link any tickets that this PR resolves. -->
Changelist
Testing Done
Resolved Tickets