鱼C论坛

 找回密码
 立即注册
查看: 749|回复: 2

[已解决]为什么这个 输出值不变

[复制链接]
发表于 2020-10-18 12:29:50 | 显示全部楼层 |阅读模式

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

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

x
  1. #include <stdio.h>
  2. #include <Windows.h>
  3. typedef struct
  4. {
  5.     float                kp;         //P
  6.     float                ki;         //I
  7.     float                kd;         //D
  8.     float                imax;       //积分限幅

  9.     float                out_p;  //KP输出
  10.     float                out_i;  //KI输出
  11.     float                out_d;  //KD输出
  12.     float                out;    //pid输出

  13.     float                integrator; //< 积分值
  14.     float                last_error; //< 上次误差
  15.     float                last_derivative;//< 上次误差与上上次误差之差
  16.     float                     last_t;     //< 上次时间
  17. }pid_param_t;




  18. float constrain_float(float amt, float low, float high)
  19. {
  20.         return ((amt)<(low)?(low):((amt)>(high)?(high):(amt)));
  21. }




  22. /*!
  23.   * @brief    pid参数初始化函数
  24.   *
  25.   * @param    无
  26.   *
  27.   * @return   无
  28.   *
  29.   * @note     无
  30.   *
  31.   * @see      无
  32.   *
  33.   * @date     2020/6/8
  34.   */
  35. void PidInit(pid_param_t * pid)
  36. {
  37.         pid->kp        = 0;
  38.         pid->ki        = 0;
  39.         pid->kd        = 0;
  40.         pid->imax      = 0;
  41.         pid->out_p     = 0;
  42.         pid->out_i     = 0;
  43.         pid->out_d     = 0;
  44.         pid->out       = 0;
  45.         pid->integrator= 0;
  46.         pid->last_error= 0;
  47.         pid->last_derivative   = 0;
  48.         pid->last_t    = 0;
  49. }


  50. /*!
  51.   * @brief    pid位置式控制器输出
  52.   *
  53.   * @param    pid     pid参数
  54.   * @param    error   pid输入误差
  55.   *
  56.   * @return   PID输出结果
  57.   *
  58.   * @note     无
  59.   *
  60.   * @see      无
  61.   *
  62.   * @date     2020/6/8
  63.   */
  64. float PidLocCtrl(pid_param_t * pid, float error)
  65. {
  66.         /* 累积误差 */
  67.         pid->integrator += error;

  68.         /* 误差限幅 */
  69.         constrain_float(pid->integrator, -pid->imax, pid->imax);

  70.         pid->last_error = error;
  71.         pid->out_p = pid->kp * error;
  72.         pid->out_i = pid->ki * pid->integrator;
  73.         pid->out_d = pid->kd * (error - pid->last_error);



  74.         pid->out = pid->out_p + pid->out_i + pid->out_d;

  75.         return pid->out;
  76. }




  77. int main ()
  78. {
  79.         pid_param_t pid1;
  80.         int T=100;  
  81.         PidInit(&pid1);
  82.         pid1.kp = 0.2;
  83.         pid1.ki = 0.1;
  84.        
  85.         PidLocCtrl(&pid1, 100);
  86.         while(pid1.out != 100)
  87.          {
  88.                  printf("pid1.out  %f\n",pid1.out);
  89.                 Sleep(T);//延时ms        
  90.          }
  91.        
  92. }
复制代码
为什么 这段代码的输出值 恒不变
  1. struct _pid{
  2.     float SetSpeed;           //定义设定值
  3.     float ActualSpeed;        //定义实际值
  4.     float err;               //定义偏差值
  5.     float err_last;           //定义上一个偏差值
  6.     float Kp,Ki,Kd;           //定义比例、积分、微分系数
  7.     float voltage;         //定义电压值(控制执行器的变量)
  8.     float integral;           //定义积分值
  9. }pid;
  10. void PID_init(){
  11.     printf("PID_init begin \n");
  12.     pid.SetSpeed=0.0;
  13.     pid.ActualSpeed=40.0;
  14.     pid.err=0.0;
  15.     pid.err_last=0.0;
  16.     pid.voltage=0.0;
  17.     pid.integral=0.0;
  18.     pid.Kp=0.2;
  19.     pid.Ki=0.1;
  20.     pid.Kd=0;
  21.     printf("PID_init end \n");
  22. }


  23. float PID_realize(float speed){
  24.     pid.SetSpeed=speed;
  25.     pid.err=pid.SetSpeed-pid.ActualSpeed;
  26.     pid.integral+=pid.err;
  27.     pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
  28.     pid.err_last=pid.err;
  29.     pid.ActualSpeed=pid.voltage*1.0;
  30.     return pid.voltage;
  31. }

  32. int main(){
  33.     PID_init();
  34.     int count=0;
  35.     while(count<100)
  36.     {
  37.         float speed=PID_realize(200.0);
  38.         printf("%f\n",speed);
  39.         
  40.         count++;
  41.     }
  42. return 0;
  43. }
复制代码
而这段输出值会变啊
最佳答案
2020-10-18 14:39:37
虽然不知道你要干嘛,但是,你上面的代码,while循环里面只有sleep()跟printf(),肯定不会有数值改变。你应该把需要的函数放到while里面。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-10-18 14:39:37 | 显示全部楼层    本楼为最佳答案   
虽然不知道你要干嘛,但是,你上面的代码,while循环里面只有sleep()跟printf(),肯定不会有数值改变。你应该把需要的函数放到while里面。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-18 15:25:29 | 显示全部楼层
这个题目我在某个论坛已经回复过了,怎么又拿到这里来了?

while(pid1.out != 100)
{
      printf("pid1.out  %f\n",pid1.out);
      Sleep(T);//延时ms        
}

pid1.out != 100 没有改变,因而进入死循环,输出30.000

while(count<100)
{
        float speed=PID_realize(200.0);
        printf("%f\n",speed);
        
        count++;
}

这里因为每循环一次,调用一次PID_realize(float speed)函数,同时count 就加1,所以,count < 100,在count自加到100时,退出循环,输出当然就会变啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-27 10:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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