1+ /* *
2+ * @file Steering4.cpp
3+ * @author syhanjin
4+ * @date 2026-02-28
5+ * @brief Brief description of the file
6+ *
7+ * Detailed description (optional).
8+ *
9+ */
10+ #include " Steering4.hpp"
11+
12+ #include < cmath>
13+
14+ #define RAD2DEG (__RAD__ ) ((__RAD__) / 3 .14159265358979323846f * 180 )
15+
16+ namespace chassis
17+ {
18+ Steering4::Steering4 (Config cfg, const IChassis::Config& base_cfg) :
19+ IChassis (base_cfg), enable_calib_(cfg.enable_calibration),
20+ wheel_radius_ (1e-3f * cfg.radius), // mm to m
21+ half_distance_x (0 .5f * cfg.distance_x), half_distance_y(0 .5f * cfg.distance_y),
22+ inv_l2_ (4 .0f / (cfg.distance_x * cfg.distance_x + cfg.distance_y * cfg.distance_y)),
23+ spd2rpm_ (1 .0f / (wheel_radius_ * 3 .14159265358979323846f * 2 ) * 60 .0f ), wheel_{
24+ steering::SteeringWheel (cfg.wheel_front_right .cfg ,
25+ cfg.enable_calibration ,
26+ cfg.wheel_front_right .calib_cfg ),
27+ steering::SteeringWheel (cfg.wheel_front_left .cfg ,
28+ cfg.enable_calibration ,
29+ cfg.wheel_front_left .calib_cfg ),
30+ steering::SteeringWheel (cfg.wheel_rear_left .cfg ,
31+ cfg.enable_calibration ,
32+ cfg.wheel_rear_left .calib_cfg ),
33+ steering::SteeringWheel (cfg.wheel_rear_right .cfg ,
34+ cfg.enable_calibration ,
35+ cfg.wheel_rear_right .calib_cfg ),
36+ }
37+ {
38+ }
39+
40+ void Steering4::applyVelocity (const Velocity& velocity)
41+ {
42+ if (enable_calib_ && !calibrated_)
43+ // 需要校准但未校准,无法设置速度
44+ return ;
45+ for (size_t i = 0 ; i < static_cast <size_t >(WheelType::Max); ++i)
46+ {
47+ const auto [xi, yi] = getWheelPosition (static_cast <WheelType>(i));
48+ const float vxi = velocity.vx - velocity.wz * yi;
49+ const float vyi = velocity.vy + velocity.wz * xi;
50+ const float speed_rpm = spd2rpm_ * std::hypot (vxi, vyi);
51+ if (fabsf (speed_rpm) < 1e-6f )
52+ {
53+ // 速度为零,无须转向
54+ wheel_[i].setTargetVelocity ({
55+ .angle = wheel_[i].getSteerAngle (),
56+ .speed = 0 ,
57+ });
58+ }
59+ else
60+ {
61+ const float angle = RAD2DEG (atan2f (vyi, vxi));
62+ wheel_[i].setTargetVelocity ({ angle, speed_rpm });
63+ }
64+ }
65+ }
66+ void Steering4::velocityControllerUpdate ()
67+ {
68+ if (enable_calib_ && !calibrated_)
69+ {
70+ // check calibration state
71+ bool calibrated = true ;
72+ for (auto & w : wheel_)
73+ calibrated &= w.isCalibrated ();
74+ calibrated_ = calibrated;
75+ }
76+ else
77+ {
78+ // 更新反馈速度
79+ float vx = 0 , vy = 0 , wz = 0 ;
80+ for (size_t i = 0 ; i < static_cast <size_t >(WheelType::Max); ++i)
81+ {
82+ const auto [xi, yi] = getWheelPosition (static_cast <WheelType>(i));
83+ const float steer_angle = wheel_[i].getSteerAngle ();
84+ const float driver_speed = wheel_[i].getDriveSpeed () / spd2rpm_;
85+ const float steer_angle_rad = DEG2RAD (steer_angle);
86+ const float sin_theta = sinf (steer_angle_rad);
87+ const float cos_theta = cosf (steer_angle_rad);
88+ vx += driver_speed * cos_theta;
89+ vy += driver_speed * sin_theta;
90+ wz += -yi * cos_theta + xi * sin_theta;
91+ }
92+ velocity_.vx = 0 .25f * vx;
93+ velocity_.vy = 0 .25f * vy;
94+ velocity_.wz = inv_l2_ * wz;
95+ }
96+
97+ for (auto & w : wheel_)
98+ wheel_->update ();
99+ }
100+
101+ Steering4::WheelPosition Steering4::getWheelPosition (WheelType wheel) const
102+ {
103+ constexpr WheelPosition WHEEL_POS[static_cast <size_t >(WheelType::Max)] = {
104+ { 1 , -1 }, { 1 , 1 }, { -1 , 1 }, { -1 , -1 }
105+ };
106+ const auto [kx, ky] = WHEEL_POS[static_cast <size_t >(wheel)];
107+ return {
108+ kx * half_distance_x,
109+ ky * half_distance_y,
110+ };
111+ }
112+ } // namespace chassis
0 commit comments