ODrive移植keil(七)—— 插值算法和偏置校准



ODrive、VESC和SimpleFOC 教程链接汇总:请点击

一、角度读取

1.1、硬件接线

在这里插入图片描述

驱动板 购买链接:https://item.taobao.com/item.htm?ft=t&id=644329838237,图锐科技
电机 购买链接:https://item.taobao.com/item.htm?ft=t&id=643573104607,图锐科技

1.2、程序演示

  • 目前支持四种编码器:ABZ、AS5047P、MT6701、MA730,本例以ABZ信号为例,

  • ENCODER_cpr 为接口对应的cpr,比如AS5047P的ABZ接口cpr=4000,SPI接口的cpr=16384,注意区分。

  • 使用这个代码,下图:
    在这里插入图片描述

  • 在MyProject.h文件中设置参数,下图:
    在这里插入图片描述

  • 编译烧写,

  • 发送指令“P”(不需要回车换行),同时用手转动电机,查看角度打印,
    在这里插入图片描述

在这里插入图片描述

  • 打印的角度为累加角度,转动过程中不清零。

1.3、代码说明

  • 角度读取在TIM1更新中断中被调用,
  • 更新中断的同时触发ADC,所以进入中断后ADC并未完成,此时读取角度,也是在等待ADC完成,
  • ODrive的代码执行时间非常紧凑,所以不支持I2C接口的编码器,当然也就不支持AS5600(I2C接口的读取速度比较慢)。

在这里插入图片描述

  • 官方代码中,读取数据使用了SPI收发DMA模式,我觉得SPI的速度已经很快,没有必要再用DMA,
  • 官方代码中,SPI读取角度都是一个16bit指令完成(比如读取AS5047P的指令是0xFFFF)。所以移植后的代码不再支持TLE5012B编码器,TLE5012B的指令包含了收发切换和延时,效率较低。
  • 官方代码支持多种SPI接口编码器,大部分型号在国内比价冷门,所以没有移植,
  • 移植后的代码很容易添加 符合这些规则的编码器。

在这里插入图片描述

二、锁相环和插值算法

读取后的角度为原始数据,再在encoder_update() 中处理,数据处理包含了两部分:锁相环和插值,
在这里插入图片描述
在这里插入图片描述

2.1、锁相环

  • 能百度到的关于锁相环的介绍,都是关于无线电通信的,本人上学的时候刚好还做过这个实验,所以我一直以为锁相环就是用于通信的。

  • 用锁相环来滤波角度超出了我的想象,我也没在网上找到任何理论依据,国内电机论坛上也从没人讲过这事(至少我没看到过)。

  • 我猜测它是用读出的角度做为目标值,估算值最终和目标值同步。当读出角度有较大波动或者干扰时,估算值能够保证一定的平滑性,起到滤波的作用。

  • 有读者在评论区讲了这个算法,并给出了官方的网址,有兴趣的同学可以看看,感谢这位读者!
    “根据odrive作者的意思,PLL估计位置和速度实质上是搭建了一个二维的状态观测器,https://discourse.odriverobotics.com/t/rotor-encoder-pll-and-velocity/224/7“

    在这里插入图片描述

  • 上图是ODrive中无感电机启动的锁相环,都是锁相环,原理应该差不多。就是一开始有误差,最终消除误差,实际值和估算值保持一致。

2.2、插值

  • 插值算法我没有看明白,我觉得应该是和偏置校准方案相关的一个处理方法,
  • 可以提前透漏下,在闭环速度控制的时候,把插值算法屏蔽了,电机转动的效果丝毫不受影响,
  • 不知道这个算法什么时候起作用,也可能是我的测试不够多,

在这里插入图片描述

2.3、角度补偿

  • 从发出读编码器指令,到获取角度再用于反Park变换,中间会有一段时间的延迟。同样的延迟时间,电机转速越高影响就越大,所以需要角度补偿。

  • 我在调试SimpleFOC的时候就遇到了这一问题,SimpleFOC代码支持的最大转速基本只能到3000RPM(7对极),我曾通过增加补偿角的方法把转速提高到8000RPM(效果并不好,电机有咔咔的噪声)。补偿角不是固定值,而且随着转速提高逐渐增大。

  • 有些公司把补偿角称之为:“进角”或者“攻角”。
    国内一般的做法是通过事先测试获取不同转速时的补偿角,分段补偿或者设定系数根据速度线性补偿。
    手动添加补偿角的方式有两个缺点:第一事先需要大量测试以得到最佳值,第二这种方法看起来不太灵活,毕竟电机转动时速度是有波动的,补偿角过于呆板。

  • ODrive中就没有补偿角,我觉得要么是它的算法精确,很好的解决延迟问题;要么就是锁相环可以起到补偿的作用。
    我尝试把锁相环部分屏蔽了,测试高转速时的效果,以确定它是否有补偿效果,但是没有屏蔽成功,这个稍后再测试。

  • 角度“ 锁相环” 在国内闻所未闻,我觉得是ODrive代码中最有价值的一项技术!

三、偏置校准

3.1、硬件接线

使用SPI接口,SPI读出角度为绝对值,更容易找到规律,

在这里插入图片描述

驱动板 购买链接:https://item.taobao.com/item.htm?ft=t&id=644329838237,图锐科技
电机 购买链接:https://item.taobao.com/item.htm?ft=t&id=643573104607,图锐科技

3.2、官方代码操作

请先将驱动板刷机v0.5.6版本,当然也可以v0.5.1版本,结果是一样的,
ODrive操作,下图:

在这里插入图片描述

odrv0.erase_configuration()
odrv0.vbus_voltage                                             //读电源电压
odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_HIGH_CURRENT  //5008电机 + AS507P
odrv0.axis0.motor.config.pole_pairs = 7                        //电机极对数
odrv0.axis0.motor.config.calibration_current = 5               //可根据情况调整大小
odrv0.axis0.encoder.config.mode = ENCODER_MODE_SPI_ABS_AMS     //设置编码器类型
odrv0.axis0.encoder.config.abs_spi_cs_gpio_pin = 1             //选择CS引脚
odrv0.axis0.encoder.config.cpr = 2**14                         //16384
odrv0.save_configuration()
odrv0.reboot()                                                 //v0.5.6不用这一句

odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION        //检测电机的电阻和电感,3秒钟后“嘀”一声结束
odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION //检测偏置,电机约正转一圈反转一圈,回到起点,结束
odrv0.axis0.error

odrv0.axis0.motor.config.direction        //读校准的方向
odrv0.axis0.encoder.config.offset         //读校准的偏置角
odrv0.axis0.encoder.config.offset_float   //读校准的偏置角小数部分


1、只配置校准相关的参数,当然也可以完整配置,
2、测量的电机可以是Hign_Current类型,也可以是MOTOR_TYPE_GIMBAL(云台电机),
3、校准电流如果设置太大,电机可能会发热严重;设置太小,电机无力,转不动。


云台电机的配置如下:

//云台电机配置如下:
odrv0.erase_configuration()
odrv0.vbus_voltage
odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_GIMBAL         //2804电机 + AS5047P
odrv0.axis0.motor.config.pole_pairs = 7                         //电机极对数
odrv0.axis0.motor.config.calibration_current = 2                //此时为校准电压
odrv0.axis0.encoder.config.mode = ENCODER_MODE_SPI_ABS_AMS      //设置编码器类型
odrv0.axis0.encoder.config.abs_spi_cs_gpio_pin = 1              //选择CS引脚
odrv0.axis0.encoder.config.cpr = 2**14                          //16384
odrv0.save_configuration()
odrv0.reboot()                                                  //v0.5.6不用这一句

odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION      //云台电机虽然不检测电阻电感,但也要发送这个指令
odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION   //检测偏置
odrv0.axis0.error

odrv0.axis0.motor.config.direction
odrv0.axis0.encoder.config.offset
odrv0.axis0.encoder.config.offset_float

3.3、移植后的代码操作

  • 使用提供的第二个代码,下图:
    在这里插入图片描述

  • 在MyProject.h文件中设置参数,下图:
    在这里插入图片描述

  • 编译烧写,

  • 发送指令“C”(不需要回车换行),3秒钟后电机“嘀”一声,打印测量结果,同时打印整定后的电流环PI参数。

  • 再发送指令“F”(不需要回车换行,回车换行了也没错,以后不再说明),电机正转八个电角度,然后再反转八个电角度,回到起点,打印偏置校准结果,下图:
    在这里插入图片描述

3.4、偏置校准原理

偏置角就是电角度和机械角度的差值,
偏置校准,就是测出电角度为0时机械角度的值。

3.4.1、理想状态下,电机为1对极,电角度的0度刚好是编码器的0度,电角度与机械角度完全重合,此时是不用校准的,
在这里插入图片描述

3.4.2、但这没有可操作性,
首先一个磁铁根本就无法分辨出来哪个方向是0度,
其次,即使可以,这也要求极高的安装精度,误差为0,
实际生产中,磁铁随意安装在电机上,靠后期使用时校准获取偏置角,这样更适合工业化批量生产的特点,
在这里插入图片描述

3.4.3、SimpleFOC的偏置校准对比

  • 想要理解ODrive的偏置校准,建议先理解SimpleFOC的偏置校准。
    请看这篇教程:SimpleFOC移植STM32(四)—— 闭环控制,零点校准部分。

  • SimpleFOC的偏置校准是用简单的方法实现简单的功能,
    ODrive的偏置校准是用复杂的方法实现简单的功能,当然ODrive的适应性可能会更好。

在这里插入图片描述

  • SimpleFOC中,设置电角度为0,读取此时的机械角度,再把读到的角度限制在[ 0, 2Pi/PP ]范围内,得到的就是偏置角。因为被限制了范围,所以同一个电机无论上电位置如何,计算结果都是相同的。

  • ODrive中,可以理解为设置电角度为0,读取到的角度就是偏置角,不限制范围,所以偏置角的个数和电机极对数对应。比如电机是7对极,那么这个电机就最多有7个不同的偏置角。下面我们解释为什么有7个。

3.5、代码说明

3.5.1、校准代码,下图:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

代码中有注释,我们只说难点,
encvaluesum,每1ms累加一次角度,最后再除以累加次数,这是求平均值的算法,得到的是中点的角度,
校准时转过了16Pi的距离,中点位置就是8Pi,所以phase_offset是8Pi电角度时对应的机械角。
之所以要正反转8对极,就是为了尽可能的平均误差,保证校准的可靠性。

3.5.2、查看校准结果

在这里插入图片描述
7对极的电机,每对极对应的cpr = 16384/7=2340.57,它的偏置值有7个,上面检测的其中一个偏置角=4071,可以推测出其它6个偏置角为:6411、-610,-2951,-5291,-7632,1731。ODrive的角度取值范围是 [-Pi, Pi],对应[-8192, 8192]。
每次校准前转动约一个电角度,检测值如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
与计算值完全相同,
按照simpleFOC的算法,这7个值其实本应该是一个值。
提前透漏习下,在下一节的闭环控制中,保存其中任一个偏置角,上电跳过检测,都可以让电机稳定转动。
ODrive官方代码上电无法跳过检测,这个我们下一节再解释。

SPI接口读出的是绝对值,所以同一个电机,偏置值是固定的,可以保存下来,以后上电跳过检测;
ABZ是增量编码器,每次上电都从0开始,所以偏置值不确定,需要每次上电都先检测,这点在SimpleFOC中已经说明过。





欢迎加入技术交流群:923734429 (入群申请写:CSDN)


(完)

### 将SimpleFOC库移植Keil MDK开发环境 #### 准备工作 为了成功将SimpleFOC库移植Keil MDK环境中,需先准备好必要的软件硬件资源。确保已安装适合版本的Keil MDK IDE[^2],并确认所使用的MCU型号(如GD32F205VE)及其对应的固件库版本(例如GD32F20x_Firmware_Library_V2.4.0)。此外,还需准备一个兼容的调试工具,比如JLink V688a。 #### 获取SimpleFOC库文件 访问SimpleFOC官方GitHub仓库或其他可靠来源获取最新的库文件。下载完成后解压至本地目录以便后续操作。 #### 创建新项目 启动Keil MDK,在菜单栏选择`Project -> New µVision Project...`来创建一个新的工程。按照提示指定保存路径以及目标设备型号(GD32F205VET6)[^1]。 #### 添加SimpleFOC源码 进入项目的管理界面(`Project`),右键点击`Source Group 1`-> `Add Existing Files to Group 'Source Group 1'...` ,浏览定位到之前下载好的SimpleFOC库中的`.c/.cpp`等实现文件夹位置,选中所有需要加入编译过程的相关文件后点击OK按钮完成添加动作。 对于某些特定功能模块可能还需要额外引入头文件(.h),同样通过上述方式将其放置于合适的位置下;同时注意调整好各个组之间的依赖关系以保证链接阶段不出错。 #### 配置编译选项 针对不同系列单片机架构特点适当修改预处理器宏定义(-D)、优化级别(O)等相关参数设置。具体做法是在左侧树形结构图里双击Target名称打开配置窗口,切换至"C/C++"标签页内进行相应设定。另外也要记得更新包含路径(Include Paths),使之能够正确解析外部引用的头文件。 #### 测试验证 一切就绪之后尝试构建整个工程项目(Build Target),如果没有任何警告或错误信息则说明初步移植已经顺利完成。接下来可以编写简单的测试案例调用SimpleFOC API接口函数来进行基本的功能检验。 ```c #include "simplefoc.h" int main(void){ // 初始化机控制对象实例化... while (1){ // 实现闭环速度/位置调节算法逻辑循环体... } } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值