#pid #controller #control

no-std pid-ctrl

灵活的PID控制器

1个不稳定版本

0.1.4 2023年1月4日
0.1.3 2022年8月12日
0.1.2 2022年8月12日
0.1.1 2022年8月12日
0.1.0 2022年8月12日

嵌入式开发中排名615

Download history 18/week @ 2024-03-13 8/week @ 2024-03-20 5/week @ 2024-03-27 10/week @ 2024-04-03 10/week @ 2024-04-10 20/week @ 2024-04-17 37/week @ 2024-04-24 9/week @ 2024-05-01 23/week @ 2024-05-08 10/week @ 2024-05-15 16/week @ 2024-05-22 10/week @ 2024-05-29 35/week @ 2024-06-05 54/week @ 2024-06-12 43/week @ 2024-06-19 53/week @ 2024-06-26

每月下载量187

MIT/Apache

13KB
226

概述

比例-积分-微分(PID)控制器。

灵感来源于pid-rs

具有更干净的API和删除的假设(恒定时间差分和对称限制)。

功能

  • 离散时间PID控制器
  • 定义为通用浮点类型
  • 尝试遵循rust API指南
  • #![no_std]
  • 每个p、i、d项和输出的限制
  • 使用测量误差来计算微分项(在新的设定点上没有微分冲击)
  • 将时间间隔限制在Float::epsilon()Float::infinity()之间

安装

cargo添加 pid-ctrl

示例

use pid_ctrl;
use num_traits;

fn main() {
    let mut pid = pid_ctrl::PidCtrl::new_with_pid(3.0, 2.0, 1.0);

    let setpoint = 5.0;
    let prev_measurement = 0.0;
    // calling init optional. Setpoint and prev_measurement set to 0.0 by default.
    // Recommended to avoid derivative kick on startup
    pid.init(setpoint, prev_measurement);

    let measurement = 0.0;
    let time_delta = 1.0;
    assert_eq!(
        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
        pid_ctrl::PidOut::new(15.0, 10.0, 0.0, 25.0)
    );

    // changing pid constants
    pid.kp.set_scale(4.0);
    assert_eq!(
        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
        pid_ctrl::PidOut::new(20.0, 20.0, 0.0, 40.0)
    );

    // setting symmetrical limits around zero
    pid.kp.limits.set_limit(10.0);
    assert_eq!(
        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
        pid_ctrl::PidOut::new(10.0, 30.0, 0.0, 40.0)
    );

    let time_delta = 0.5;
    assert_eq!(
        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
        pid_ctrl::PidOut::new(10.0, 35.0, 0.0, 45.0)
    );

    // setting upper limits returns error if new value conflicts with lower limit
    pid.ki.limits.try_set_upper(28.0).unwrap();  
    assert_eq!(
        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
        pid_ctrl::PidOut::new(10.0, 28.0, 0.0, 38.0)
    );

    // time_delta gets clamped to Float::epsilon() - Float::infinity()
    let measurement = 1.0;
    let time_delta = -7.0;
    pid.kd.set_scale(num_traits::Float::epsilon());
    assert_eq!(pid.step(
        pid_ctrl::PidIn::new(measurement, time_delta)), 
        pid_ctrl::PidOut::new(10.0, 28.0, -1.0, 37.0)
    );

    // configure setpoint directly
    pid.setpoint = 1.0;
    assert_eq!(pid.step(
        pid_ctrl::PidIn::new(measurement, time_delta)), 
        pid_ctrl::PidOut::new(0.0, 28.0, 0.0, 28.0)
    );
}

贡献

请随时提出问题。

希望将#![no_std]设置为可选,以便类型可以实现Display trait。

依赖关系

~94–325KB