鱼C论坛

 找回密码
 立即注册
查看: 47|回复: 1

[作品展示] PID 控制 可视化

[复制链接]
发表于 昨天 14:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
自己做了个小玩意,实现 PID 控制的可视化,这里直接搬了 EasyX 的图形库。

  1. #include <graphics.h>
  2. #include <deque>
  3. #include <cmath>
  4. #include <windows.h>
  5. #include <iostream>
  6. using namespace std;

  7. double var=0,stdvar=50;


  8. inline void screen_line(double x1,double y1,double x2,double y2)
  9. {
  10.     line(static_cast<int>(round(x1)),110-static_cast<int>(round(y1)),static_cast<int>(round(x2)),110-static_cast<int>(round(y2)));
  11.     return;
  12. }

  13. inline void draw_axis(void)
  14. {
  15.         line(40,10,40,210);
  16.     line(0,110,200,110);
  17.     outtextxy(5,10,"100");
  18.     outtextxy(5,60,"50");
  19.     outtextxy(5,160,"-50");
  20.     outtextxy(5,210,"-100");
  21. }

  22. inline void cause_error(void)
  23. {
  24.     var-=10;
  25.     return;
  26. }

  27. inline void pid_control(double kp,double ki,double kd)
  28. {
  29.     static double sum_err=0,last_err=stdvar-var;
  30.     sum_err+=(stdvar-var);
  31.     cout<<"now_err: "<<stdvar-var<<" now_int: "<<sum_err<<endl;
  32.     var+=(kp*(stdvar-var)+ki*sum_err+kd*(last_err-stdvar+var));
  33.    
  34.     last_err=stdvar-var;
  35.     return;
  36. }

  37. int main()
  38. {
  39.     initgraph(400,240);
  40.     BeginBatchDraw();
  41.     setbkcolor(RGB(255,255,255));
  42.     setlinecolor(RGB(0,0,0));
  43.     settextcolor(RGB(0,0,0));
  44.     cleardevice();
  45.    
  46.    
  47.     FlushBatchDraw();
  48.     deque<int> q;
  49.     int xax=0;
  50.     double last_y=0;
  51.     for(int i=0;i<50;i++)
  52.     q.push_back(0);
  53.     Sleep(1000);
  54.     while(1)
  55.     {
  56.             cleardevice();
  57.             draw_axis();
  58.         
  59.         pid_control(0.1,0.1,-0.1);
  60.         cause_error();
  61.         
  62.         q.push_back(var);
  63.         q.pop_front();
  64.         xax=0;
  65.         last_y=0;
  66.         for(auto it=q.begin();it!=q.end();it++)
  67.         {
  68.             screen_line(xax-4,last_y,xax,*it);
  69.             last_y=*it;
  70.             xax+=4;
  71.         }
  72.         screen_line(0,stdvar,200,stdvar);
  73.         line(0,60,200,60);
  74.         FlushBatchDraw();
  75.         Sleep(50);
  76.     }
  77.     EndBatchDraw();
  78.     return 0;
  79. }
复制代码


下面是实际效果视频展示。

pidshow.zip (321.99 KB, 下载次数: 1)
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 14:09 | 显示全部楼层
你好,鱼油!

非常棒!你尝试用 EasyX 实现 PID 控制的可视化,这是一个很好的学习项目。PID 控制器是自动控制中的经典算法,它通过比例(P)、积分(I)和微分(D)三个部分来调整系统输出,使实际值接近目标值。

你的代码中使用了全局变量 varstdvar,这可能会导致代码难以维护。建议将它们作为参数传递给函数,提高代码的模块化。

我注意到 pid_control 函数被截断了,这里是一个完整的 PID 控制函数示例:


  1. double pid_control(double setpoint, double current_value, double kp, double ki, double kd, double dt) {
  2.     static double integral = 0.0;
  3.     static double last_error = 0.0;
  4.    
  5.     double error = setpoint - current_value;
  6.     integral += error * dt;
  7.     double derivative = (error - last_error) / dt;
  8.     last_error = error;
  9.    
  10.     return kp * error + ki * integral + kd * derivative;
  11. }
复制代码


在这个函数中:
- setpoint 是目标值(对应你的 stdvar)。
- current_value 是当前值(对应你的 var)。
- dt 是时间步长,用于计算积分和微分。
- 使用静态变量来保持积分和上一次误差的状态。

对于可视化部分,你可以用 screen_line 函数在循环中绘制误差或控制输出的变化曲线。例如,在每次计算 PID 输出后更新 var,并绘制点或线。

另外,cause_error 函数模拟了干扰,但可以考虑加入随机因素或用户输入来更真实地测试 PID 控制器。

继续努力,实践是掌握编程的关键!如果有更多细节问题,欢迎继续讨论。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-11-30 15:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表