目录
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)
(完)