wenyuqiang2003 2024-07-15 23:53 采纳率: 0%
浏览 17
已结题

在写pid调速的程序时,电机始终维持最大速度

我在写stm32直流有刷电机调速程序时,电机速度总是顶到最高转速。我移植的野火的程序,在pid调试助手上显示目标值与实际值相差很大,但pid并没有产生作用,始终运行在满转速状态下。

小助手输出结果如下(截取部分,pid参数为 0.5,0.5,0.5)
PID调试数据
通道 1 数据如下:
序号,实际值,目标值,差值
5,0,0,0
6,0,0,0
7,0,0,0
8,0,0,0
9,0,0,0

417,0,200,-200
418,0,200,-200
419,106,200,-94
420,294,200,94
421,302,200,102
422,128,200,-72
423,123,200,-77
424,305,200,105
425,277,200,77
426,84,200,-116
427,98,200,-102
428,288,200,88
429,308,200,108
430,126,200,-74
431,117,200,-83
432,299,200,99
433,282,200,82
434,84,200,-116
435,92,200,-108
436,285,200,85
437,308,200,108
438,140,200,-60
439,123,200,-77
440,308,200,108
441,274,200,74
442,64,200,-136
443,84,200,-116
444,280,200,80
445,324,200,124
446,156,200,-44
447,134,200,-66
448,316,200,116
449,266,200,66
450,-183529,200,-183729
451,64,200,-136
452,266,200,66
453,411,200,211
454,515,200,315
455,596,200,396
456,652,200,452
457,694,200,494
458,725,200,525
459,753,200,553
460,773,200,573
461,789,200,589
462,803,200,603
463,812,200,612
464,823,200,623
465,829,200,629
466,831,200,631
467,837,200,637
468,837,200,637
469,840,200,640
470,840,200,640
471,843,200,643
472,843,200,643

733,854,200,654
734,848,200,648
735,689,200,489
736,392,200,192
737,226,200,26
738,294,200,94
739,403,200,203
740,288,200,88
741,67,200,-133
742,89,200,-111
743,285,200,85
744,347,200,147
745,193,200,-7
746,117,200,-83
747,266,200,66
748,296,200,96
749,126,200,-74
750,106,200,-94
751,296,200,96
752,277,200,77
753,78,200,-122
754,84,200,-116
755,280,200,80
756,316,200,116
757,148,200,-52
758,131,200,-69
759,316,200,116
760,268,200,68
761,-183529,200,-183729
762,64,200,-136
763,266,200,66
764,411,200,211
765,526,200,326
766,602,200,402
767,658,200,458
768,705,200,505
769,733,200,533
770,761,200,561
771,784,200,584
772,803,200,603
773,815,200,615
774,823,200,623

代码如下

//pid实现
float PID_realize(float actual_val)
{
        /* 计算偏差:目标值减去实际值 */
    pid.err = pid.target_val - actual_val;
    
    /* 积分项更新,加上限幅 */
    pid.integral += pid.err;
    
    /* PID输出计算 */
    pid.actual_val = pid.Kp * pid.err + pid.Ki * pid.integral + pid.Kd * (pid.err - pid.err_last);
    
    /* 保存上一次的偏差,用于微分项 */
    pid.err_last = pid.err;
    
    /* 返回计算出的控制量 */
    return pid.actual_val;
}

//电机控制部分
#define c 1071.0f //电机转 一圈的编码值
#define t 0.02f    //定时器定时
void motor_pid_control(void)
{
  if (is_motor_en == 1)   
  {
    static float cont_val = 0;             
    static __IO int32_t Capture_Count = 0;    
    int32_t actual_speed = 0;                 
    Capture_Count = __HAL_TIM_GET_COUNTER(&htim2);
        __HAL_TIM_SET_COUNTER(&htim2,0);

  if(__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim2))
            Capture_Count=-65535+Capture_Count;

    actual_speed = (int32_t)(((float)(Capture_Count) / c / t)*60.0f);
  
  
    
    cont_val = PID_realize((float)actual_speed);    
    
    if (cont_val > 0)    
    {
      motor_forward();
            
    }
    else
    {
      cont_val = -cont_val;
      motor_backward();

    }
    
    cont_val = (cont_val > 500) ? 500 : cont_val;    
    motor_set_speed(cont_val);                     
    

      set_computer_value(SEND_FACT_CMD, CURVES_CH1, &actual_speed  , 1);  // ¸øͨµÀ 1 ·¢ËÍʵ¼ÊÖµ

  }
}


  • 写回答

29条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-15 23:53
    关注
    获得0.30元问题酬金

    引自免费微信小程序:皆我百晓生

    根据您提供的PID调试数据和代码,看起来您的PID算法并没有正确地控制电机的速度。让我们逐步分析可能的问题和解决方案。

    1. PID参数调整

      • 首先,确保您的PID参数(Kp、Ki、Kd)已经正确调整。这些参数对系统的响应和稳定性有很大影响。可能需要一些实验和调试来确定最佳参数。
      • 在某些情况下,默认的PID参数可能不适用于特定的电机和控制系统。尝试调整这些参数以改善系统的响应。
    2. 积分饱和问题

      • 如果积分项(pid.integral)增长得太快,它可能会导致PID输出迅速增加,从而使电机达到最大速度。考虑在积分项中添加限幅逻辑,以防止积分饱和。
    3. 微分项的影响

      • 微分项(Kd)有助于系统响应快速变化。然而,如果Kd设置得太大,它可能会使系统过于敏感,导致不稳定。尝试减小Kd的值,看看是否有所改善。
    4. 电机控制逻辑

      • motor_pid_control函数中,您使用cont_val来控制电机的方向。当cont_val为正时,电机向前转动;为负时,电机向后转动。但是,当cont_val的绝对值大于500时,您将其限制为500。这可能是导致电机始终达到最大速度的原因之一。考虑根据实际需要调整这个限制值或逻辑。
    5. 速度计算

      • 确保您的速度计算(通过Capture_Count和c的值)是正确的。尝试在不同的条件下验证这个计算,以确保它是准确的。
    6. 目标值与反馈值的单位

      • 请确保目标值和实际值的单位是一致的。有时单位不匹配会导致PID算法表现异常。
    7. 定时器定时值

      • 确保定时器的定时值(t)是准确的。如果定时器的精度或延迟存在问题,那么计算的转速可能会有误差。

    针对以上几点进行检查和调整,应该可以解决您的问题。另外,建议您使用示波器或调试工具进一步观察系统的行为,以便更准确地诊断问题所在。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 7月23日
  • 修改了问题 7月15日
  • 创建了问题 7月15日

悬赏问题

  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)
  • ¥15 服务端控制goose报文控制块的发布问题
  • ¥15 学习指导与未来导向啊
  • ¥15 求多普勒频移瞬时表达式
  • ¥15 如果要做一个老年人平板有哪些需求
  • ¥15 k8s生产配置推荐配置及部署方案
  • ¥15 matlab提取运动物体的坐标