50 if (!std::isfinite(dt) || dt <= 0 || dt > std::chrono::duration<fp32>(info_.control_time * 5).count()) {
55 if (yaw_motor_->
faulted() || (pitch_motor_ && pitch_motor_->
faulted()))
56 drive_fault_latched_ =
true;
57 const auto angle = imu_->
angle();
58 const auto gyro = imu_->
gyro();
59 const auto motor_angle = yaw_motor_->
angle();
60 const fp32 raw_relative = motor_angle - info_.yaw_zero;
61 const bool finite_feedback = std::isfinite(angle.yaw) && std::isfinite(angle.pitch) &&
62 std::isfinite(angle.roll) && std::isfinite(raw_relative) &&
63 std::isfinite(gyro.x) && std::isfinite(gyro.y) && std::isfinite(gyro.z);
65 online_ = finite_feedback && std::isfinite(projected_yaw_rate) &&
66 !drive_fault_latched_ && !imu_->
offline() && !yaw_motor_->
offline() &&
67 (!pitch_motor_ || !pitch_motor_->
offline());
71 measured_yaw_ = angle.yaw;
72 measured_pitch_ = angle.pitch;
74 yaw_rate_ = projected_yaw_rate;
78 targets_initialized_ = initialized_ =
false;
81 if (!targets_initialized_ || !enabled_) {
83 targets_initialized_ = online_;
85 const bool calibration_blocked = recentering_ && info_.recenter_on_enable &&
86 !info_.yaw_zero_calibrated;
87 if (!enabled_ || !online_ || calibration_blocked) {
91 if (info_.yaw_current_control)
co_await yaw_motor_->
set_current(0.0f);
97 if (info_.pitch_current_control)
co_await pitch_motor_->
set_current(0.0f);
104 if (!info_.yaw_current_control) yaw_motor_->
set_enabled(
true);
105 if (pitch_motor_ && !info_.pitch_current_control) pitch_motor_->
set_enabled(
true);
107 if (recentering_ && info_.recenter_on_enable) {
108 yaw_relative_pid_.
update(0.0f, relative_yaw_, dt);
109 yaw_speed = info_.yaw_recenter_direction * yaw_relative_pid_.
state();
110 pitch_target_ = info_.init_pitch;
111 initialized_ = settle_.update(enabled_, online_, relative_yaw_,
113 info_.init_tolerance, std::chrono::duration<fp32>(info_.init_settle_time).count(), dt);
114 yaw_target_ = measured_yaw_;
116 yaw_angle_pid_.
update(yaw_target_, measured_yaw_, dt);
117 yaw_speed = info_.yaw_angle_direction * yaw_angle_pid_.
state();
122 if (info_.yaw_current_control) {
123 yaw_rate_pid_.
update(yaw_speed, yaw_rate_, dt);
124 co_await yaw_motor_->
set_current(info_.yaw_direction * yaw_rate_pid_.
state());
125 }
else co_await yaw_motor_->
set_angle_speed(info_.yaw_direction * yaw_speed);
127 pitch_angle_pid_.
update(pitch_target_, measured_pitch_, dt);
128 if (info_.pitch_current_control) {
129 pitch_rate_pid_.
update(pitch_angle_pid_.
state(), gyro.y, dt);
130 co_await pitch_motor_->
set_current(info_.pitch_direction * pitch_rate_pid_.
state());
131 }
else co_await pitch_motor_->
set_angle_speed(info_.pitch_direction * pitch_angle_pid_.
state());
awaitable< void > update(fp32 dt)
void set_enabled(bool v) override
启用或禁用云台输出。
void set_recentering(bool v) override
fp32 pitch() const override
获取当前 pitch 姿态,单位 rad。
fp32 yaw() const override
获取当前 yaw 姿态,单位 rad。