ssloa 2022-05-20 19:56 采纳率: 0%
浏览 57
已结题

请教一个关于PID的知识

目前,我想写的一个pid用来控制正反转,我写了一个pid程序。他正转可以实现、但是翻转却疯转了。pid控制中正反转不应该是一致的吗。(我的电机正反转是用高低电平来控制的)
我尝试了把预期值和反馈量都变为正,结果还是和一开始的一样。请教一下,我到底是哪里出了问题QAQ

初始化

int want_speed_x[4];
int encoder_errorall_x[4];
int encoder_store_x[4];
float encoder_error_x[4];
float encoder_speed_x[4];
float last_encoder_error_x[4];

float encoder_kp0=0.045;
float encoder_ki0=0;
float encoder_kd0=0;

float encoder_kp1=0.045;
float encoder_ki1=0;
float encoder_kd1=0;

float encoder_kp2=0.045;
float encoder_ki2=0;
float encoder_kd2=0;

float encoder_kp3=0.045;
float encoder_ki3=0.0;
float encoder_kd3=0.0;

pid

int pid_x(int a)
{

              want_speed_x[0]=-500;  
              want_speed_x[1]=-500; 
              want_speed_x[2]=-500; 
              want_speed_x[3]=-500;   

    encoder_error_x[0] = want_speed_x[0] - encoder_data[0];
    encoder_errorall_x[0]+=encoder_error_x[0];
    encoder_store_x[0] += (int)(encoder_kp0*encoder_error_x[0] +encoder_ki0*encoder_errorall_x[0]+ encoder_kd0*(encoder_error_x[0] - last_encoder_error_x[0]));
    last_encoder_error_x[0] = encoder_error_x[0];
    
    encoder_error_x[1] = want_speed_x[1] - encoder_data[1];
    encoder_errorall_x[1]+=encoder_error_x[1];
    encoder_store_x[1] += (int)(encoder_kp1*encoder_error_x[1] +encoder_ki1*encoder_errorall_x[1] +encoder_kd1*(encoder_error_x[1] - last_encoder_error_x[1]));
    last_encoder_error_x[1] = encoder_error_x[1];
    
    encoder_error_x[2] = want_speed_x[2] - encoder_data[2];
    encoder_errorall_x[2]+=encoder_error_x[2];
    encoder_store_x[2] += (int)(encoder_kp2*encoder_error_x[2] +encoder_ki2*encoder_errorall_x[2]+encoder_kd2*(encoder_error_x[2] - last_encoder_error_x[2]));
    last_encoder_error_x[2] = encoder_error_x[2];
    
    encoder_error_x[3] = want_speed_x[3] - encoder_data[3];
    encoder_errorall_x[3]+=encoder_error_x[3];
    encoder_store_x[3] += (int)(encoder_kp3*encoder_error_x[3] +encoder_ki3*encoder_errorall_x[3]+ encoder_kd3*(encoder_error_x[3] - last_encoder_error_x[3]));
    last_encoder_error_x[3] = encoder_error_x[3];
       
  motor(a,encoder_store_x[0],encoder_store_x[1],encoder_store_x[2],encoder_store_x[3]); 
   PRINTF("%d,%d,%d,%d,%d,%d,%d,%d\n",encoder_data[0],encoder_data[1],encoder_data[2],encoder_data[3],encoder_store_x[0],encoder_store_x[1],encoder_store_x[2],encoder_store_x[3]);

 return 0;

}

电机控制

void motor(int move,int a,int b,int c,int d)
{
  
  
  int A;int B;int C;int D;
  A=abs(a); B=abs(b); C=abs(c); D=abs(d); 

     //move     0==前进  1==后    2==左 3==右
        
        if (move==0)
        {
         
          gpio_set(D14,1);
          gpio_set(D15,1);
          gpio_set(D0,1);
          gpio_set(D1,1);
          pwm_duty(PWM2_MODULE3_CHB_D3,A);
          pwm_duty(PWM2_MODULE3_CHA_D2,B);
          pwm_duty(PWM1_MODULE0_CHB_D13,C);
          pwm_duty(PWM1_MODULE0_CHA_D12,D);

        }

        if (move==1)
        {
          
          gpio_set(D14,0);
          gpio_set(D15,0);
          gpio_set(D0,0);
          gpio_set(D1,0);
          pwm_duty(PWM2_MODULE3_CHB_D3,A);
          pwm_duty(PWM2_MODULE3_CHA_D2,B);
          pwm_duty(PWM1_MODULE0_CHB_D13,C);
          pwm_duty(PWM1_MODULE0_CHA_D12,D);
        }

}
  • 写回答

3条回答 默认 最新

  • soar3033 2022-05-20 21:21
    关注
    获得3.00元问题酬金

    你的gpio是控制电机方向的吧 你考虑过没有 一但转速超过了目标速度你的pid结果可能需要改变方向(例如你给定的速度是负一,结果电机跑到了负二,那么新的电机给定速度方向可能会变成正的,但你的电机方向却是gpio给定的,结果就造成越差越多 越多越差 就转疯了

    评论

报告相同问题?

问题事件

  • 系统已结题 5月28日
  • 创建了问题 5月20日

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?