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

STC-FOC Lite程序详解-PID单环控制

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2218

回帖

5450

积分

版主

积分
5450
发表于 2024-10-31 11:35:14 | 显示全部楼层 |阅读模式
本帖最后由 王昱顺 于 2024-10-31 11:37 编辑

      本篇文章致力于对STC-FOC Lite的原版代码进行详尽的原理解释,并且提出更改/移植/裁剪建议,方便大家对这个项目进行更加适配自己的个性化更改。
截图202410311133464196.jpg
      设计目的:取长补短,使用较低的算力实现高算力同样的控制效果。这部分功能专注于有感FOC驱动程序优化的文章,旨在通过优化控制算法,降低计算资源消耗,同时保持或提升控制性能。
      对比正常的控制方式优点:
      在计算速度方面,优化后的有感FOC驱动程序具有显著优势。全程只需要进行一次PI(比例-积分)计算,而无需像传统方法那样进行多次PID计算。这种优化大大减少了计算量,提高了计算速度,使得系统能够更快速地响应控制指令。
      在速度环调参方面,优化后的驱动程序同样表现出色。由于采用预瞄位置点开环执行的方式,因此速度控制中没有引入观测误差。这种方式不仅简化了控制流程,还降低了系统震荡的风险。尤其在参数欠调的情况下,优化后的驱动程序能够保持明显的特点(给定速度0后仍然旋转一会,这就证明参数有些欠调),并且,在参数较大的时候,很大一个范围内都不会有异常,避免了传统方法中可能出现的,调节一点就剧烈震荡现象。
      在性能方面,优化后的有感FOC驱动程序同样具有显著优势。由于其控制频率可以设置得非常高,因为位置传感器能够获得非常纯净的位置数据。这些数据没有异常抖动和误差,使得系统的控制精度和稳定性得到了极大的提升。这种高性能的控制方式对于需要精确控制的应用场景来说尤为重要。
PID介绍:
      在优化后的有感FOC驱动程序中,PID控制起到了关键作用。为了确保PID控制能够随时根据实际情况进行自适应调整,PID中引入了时间dt。这样,PID控制就能够根据系统的运行时间进行动态调整,从而保持最佳的控制效果。
      同时,为了尽量减少运算时间,驱动程序中采用了PI控制策略。PI控制是PID控制的一种简化形式,通过省略微分项来减少运算量。因为控制频率的提高,所以这种简化并没有牺牲控制性能,反而使得系统能够更快速地响应控制指令(d项通常用来补偿观测速度的不足,如果观测速度足够,d项反而是累赘)。

      下面就是一些实际的代码的详细注释和讲解:
  1. // 根据速度调整位置设定@30us
  2. float postion_add = 0;           // 小于分辨率编码器时的累加器
  3. long last_postion_add = 0; // 上次增量记忆
  4. void Timer0_Isr(void) interrupt TMR0_VECTOR
  5. {
  6.         if (Mode == Speed_Mode && Run_Flag && moto.set_speed != 0 && I_Error_Cnt < I_Error_Dat)
  7.         {
  8.                 postion_add += (float)moto.set_speed * 30.0 * (1.6384 / 6000.0); // us
  9.         }
  10. }
复制代码
      这段程序的主要功能是根据设定的速度调整位置。具体来说,它在定时器中断服务中检查是否处于速度模式、电机正在运行、设定速度不为零且堵转积分误差计数小于设定的积分误差数据。如果这些条件都满足,程序会计算位置增量并累加到一个浮点变量position_add中。这个增量是基于设定速度、时间间隔(30微秒)和一些单位转换因子计算得出的。

      这个postion_add主要功能是为了保证积分累计没有误差,防止因为整数的四舍五入造成位置生成的误差。这个变量积累了一定的位置自增值后,会在每次的SPI位置采集中断中进行判断:
  1. if (fabs(postion_add) > 1 && Mode == Speed_Mode && Run_Flag)
  2. {
  3.     moto.set_postion += (long)postion_add;
  4.     postion_add -= (long)postion_add; // 自减整数部分
  5. }
复制代码

      首先,程序将对postion_add的绝对值是否大于1进行判断,同时确认Mode变量是否设定为Speed_Mode,并确保电机在运行状态。如果全都满足,则将位置自增变量的整数部分取出,并且加到设定位置上。同时,将自身的整数部分减掉,以重新开始新一轮的累计,并且保证不丢失精度(靠刚才没有清除掉的小数部分)。
      然后,就是根据设定位置来做一个最基本的PID位置环,就可以完成高效的速度环和位置环一体运行了。这也就是所谓的单环PID。
      实际使用中,只需要根据不同的模式调用不同的PID参数和不同的PID目标值即可。
  1. // 计算位置环的pid,输出为speed的控制
  2. if (Mode == Set_ID_Mode)
  3.     moto.set_uq = (PID_Ctrl(moto.set_postion - moto.postion, &pid_setid) / 1000.0); // 调整为不同的PID
  4. if (Mode == Postion_Mode || Mode == Servo_Mode)
  5.     moto.set_uq = (PID_Ctrl(moto.set_postion - moto.postion, &pid_postion) / 1000.0); // 分频输出
  6. if (Mode == Speed_Mode)
  7.     moto.set_uq = (PID_Ctrl(moto.set_postion - moto.postion, &pid_speed) / 1000.0); // 分频输出
复制代码



回复

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:21
  • 最近打卡:2025-04-01 18:02:51

1

主题

29

回帖

119

积分

注册会员

积分
119
发表于 2024-10-31 14:49:31 | 显示全部楼层
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 17:14 , Processed in 0.104968 second(s), 57 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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