• 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中无感电机启动的锁相环,都是锁相环,原理应该差不多。就是一开始有误差,最终消除误差,实际值和估算值保持一致。

    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18


    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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)


    (完)

  • 相关阅读:
    华为机试真题 C++ 实现【批量处理任务】
    【图像边缘检测】基于matlab灰度图像的积累加权边缘检测【含Matlab源码 2010期】
    任务6 学生宿舍信息管理系统
    算法刷题打卡第27天:省份数量---深度优先搜索
    leetcode:142. 环形链表 II
    【Effective Modern Cpp】条款9:优先考虑别名声明而非typedef
    Linux—系统基础一
    mysql查询排名
    队列的各个函数的实现
    MAUI+Masa Blazor APP 各大商店新手发布指南(三)vivo篇
  • 原文地址:https://blog.csdn.net/loop222/article/details/133788966