PID:导数低通与条件积分抗饱和
题目
初始 。每步先计算 若 且 ,或 且 ,则拒绝本次积分,否则 。用更新后的积分算 最后 。
输入
,然后 个误差。,,,,增益非负。
输出
每步 ,依次输出共 个实数。
示例
输入
25 0.1 2 0.4 0.3 0.2 1
5 5 5 5 5 5 5 5 5 5 -5 -5 -5 -5 -5 -5 -5 -5 -5 -5 0 0 0 0 0
期望输出
1 0 16.666666666666664 1 0 11.111111111111109 1 0 7.407407407407406 1 0 4.93827160493827 1 0 3.292181069958847 1 0 2.1947873799725643 1 0 1.4631915866483762 1 0 0.9754610577655841 1 0 0.6503073718437227 1 0 0.4335382478958151 -1 0 -33.04430783473612 -1 0 -22.029538556490742 -1 0 -14.686359037660495 -1 0 -9.790906025106995 -1 0 -6.527270683404663 -1 0 -4.351513788936442 -1 0 -2.9010091926242945 -1 0 -1.9340061284161962 -1 0 -1.2893374189441307 -1 0 -0.8595582792960871 1 0.0 16.093627813802605 1 0.0 10.729085209201736 1 0.0 7.152723472801157 1 0.0 4.768482315200771 0.9536964630401541 0.0 3.178988210133847
在线 C++17 练习
在浏览器编译运行,代码不上传;首次下载约 28 MB。
尚未运行
运行环境
Clang 22 / C++17 / WASI,支持本题所需标准库;不支持线程、C++ 异常或任意宿主系统访问。每例 2 秒、256 MiB 线性内存、64 KiB 输出;编译器另占浏览器内存,不适合低内存设备。初次加载最多等待 120 秒,可随时停止。
草稿保存在本浏览器。测试公开,属于本地自测而非防作弊竞赛判题;参考解答不参与运行。所有运行资产均由本站提供。
编译器来源与开源许可参考实现(完成后再展开)
对照自己的推导,检查状态更新顺序、边界条件与单位,而不只比较最终输出。
#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <vector>
#include <array>
#include <queue>
#include <tuple>
#include <limits>
using namespace std;
// Reference implementation: optional; solve the starter before opening.
int main() {
cout << setprecision(17);
int n;
double dt,kp,ki,kd,tau,L;
cin>>n>>dt>>kp>>ki>>kd>>tau>>L;
double I=0,D=0,prev=0;
while(n--) {
double e;
cin>>e;
D=tau/(tau+dt)*D+(e-prev)/(tau+dt);
double trial=I+ki*e*dt,raw=kp*e+trial+kd*D;
if(!((raw>L&&ki*e>0)||(raw<-L&&ki*e<0)))I=trial;
cout<<clamp(kp*e+I+kd*D,-L,L)<<" "<<I<<" "<<D<<"\n";
prev=e;
}
}