Skip to main content

Module controller

Module controller 

Source
Expand description

Controller trait - 控制器通用接口

定义了所有控制器必须实现的接口。

§设计理念

  • Tick 模式: 用户控制循环,控制器只负责计算
  • 时间感知: 显式传入 dt,便于单元测试
  • 类型安全: 使用强类型单位(Rad, NewtonMeter
  • 错误处理: 关联类型 Error 允许自定义错误

§时间跳变处理

当检测到异常的 dt 时(如系统卡顿、线程调度延迟), on_time_jump() 方法会被调用。

⚠️ 重要: 对于时间敏感的控制器(如 PID),必须覆盖此方法:

  • 必须重置: 微分项(D term),防止计算出巨大的导数
  • 不要清零: 积分项(I term),否则机械臂会瞬间失去抗重力能力

§示例

use piper_client::control::Controller;
use piper_client::types::{JointArray, Rad, NewtonMeter};
use std::time::Duration;

struct MyController {
    target: JointArray<Rad>,
    last_error: JointArray<f64>,
}

impl Controller for MyController {
    type Error = std::io::Error;

    fn tick(
        &mut self,
        current: &JointArray<Rad>,
        dt: Duration,
    ) -> Result<JointArray<NewtonMeter>, Self::Error> {
        // 计算控制输出
        let error = self.target.map_with(*current, |t, c| t - c);
        let output = error.map(|e| NewtonMeter(e.0 * 10.0)); // 简单 P 控制
        self.last_error = error.map(|e| e.0);
        Ok(output)
    }

    fn on_time_jump(&mut self, _dt: Duration) -> Result<(), Self::Error> {
        // ✅ 重置微分项相关状态
        self.last_error = JointArray::from([0.0; 6]);
        // ❌ 不要清零积分项!
        Ok(())
    }
}

Traits§

Controller
控制器通用接口