ODrive移植keil(八)—— 闭环控制

目录

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

一、硬件接线

用编码器的SPI接口,可以跳过上电检测。ABZ接口必须每次上电校准,

驱动板 购买链接:某宝购买

电机 购买链接:某宝购买

二、官方代码操作

用官方代码操作,验证控制效果,获取配置参数,

本小节演示用v0.5.1版本固件,因为v0.5.1的教程最丰富。当然也可以用v0.5.6版本。

2.1、力矩模式

odrv0.axis0.controller.config.vel_limit 限制最大速度,当超过最大速度时力矩变小,电机速度在限速附近波动会导致电动振动。

c 复制代码
//力矩模式
odrv0.erase_configuration()
odrv0.config.dc_max_positive_current = 30
odrv0.config.dc_max_negative_current = -5.0
odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_HIGH_CURRENT
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
odrv0.axis0.encoder.config.cpr = 2**14
odrv0.axis0.controller.config.control_mode = CONTROL_MODE_TORQUE_CONTROL
odrv0.axis0.controller.config.vel_limit = 20    //超过限制速度,力矩变小
odrv0.axis0.controller.config.input_mode = INPUT_MODE_TORQUE_RAMP
odrv0.axis0.controller.config.torque_ramp_rate = 0.1
odrv0.save_configuration()     //v0.5.6保存后重启,不用再 reboot
odrv0.reboot()

odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
odrv0.axis0.error
odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

odrv0.axis0.controller.input_torque = 0.1

2.2、速度模式

c 复制代码
//速度模式
odrv0.erase_configuration()
odrv0.config.dc_max_positive_current = 30
odrv0.config.dc_max_negative_current = -5.0
odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_HIGH_CURRENT
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
odrv0.axis0.encoder.config.cpr = 2**14
odrv0.axis0.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL
odrv0.axis0.controller.config.vel_gain = 0.02
odrv0.axis0.controller.config.vel_integrator_gain = 0.2
odrv0.axis0.controller.config.vel_limit = 50   //12V电源,5008电机的最大转速大概50
odrv0.axis0.controller.config.input_mode = INPUT_MODE_VEL_RAMP
odrv0.axis0.controller.config.vel_ramp_rate = 50
odrv0.save_configuration()     //v0.5.6保存后重启,不用再 reboot
odrv0.reboot()

odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
odrv0.axis0.error
odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

odrv0.axis0.controller.input_vel = 5

2.3、位置模式

如果电机停止的位置刚好是磁阻最大,会被齿槽力拉到磁阻最小位置,然后PID算法又把它转到磁阻最大位置,如此反复拉扯。

这个问题需要在下一节抗齿槽算法来解决,

c 复制代码
//位置模式
odrv0.erase_configuration()
odrv0.config.dc_max_positive_current = 30
odrv0.config.dc_max_negative_current = -5.0
odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_HIGH_CURRENT
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
odrv0.axis0.encoder.config.cpr = 2**14
odrv0.axis0.controller.config.control_mode = CONTROL_MODE_POSITION_CONTROL
odrv0.axis0.controller.config.vel_limit = 50
odrv0.axis0.controller.config.pos_gain = 20
odrv0.axis0.controller.config.vel_gain = 0.04     //位置模式下的速度环PI参数比速度模式下的要大一点
odrv0.axis0.controller.config.vel_integrator_gain = 0.5
odrv0.axis0.controller.config.input_mode = INPUT_MODE_TRAP_TRAJ
odrv0.axis0.trap_traj.config.vel_limit = 10
odrv0.axis0.trap_traj.config.accel_limit = 10
odrv0.axis0.trap_traj.config.decel_limit = 10
odrv0.save_configuration()
odrv0.reboot()

odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
odrv0.axis0.error
odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

odrv0.axis0.controller.input_pos = 0
odrv0.axis0.controller.input_pos = 1

三、移植后的代码操作

使用本节提供的第一个代码,下图:

3.1、力矩模式

  • 在MyProject.h文件中设置参数,下图:

  • 编译烧写,

  • 发送指令"C",3秒钟后电机"嘀"一声,然后正转8个电角度,反转8个电角度,同时串口打印校准参数。

  • 再发送指令"G",电机闭环,

  • 再发送指令"S0.1",电机开始转动,如果空载电机会达到最大转速。如果限速,电机只能达到限制转速。

视频:稍后上传

3.2、速度模式

  • 在MyProject.h文件中设置参数,下图:

  • 编译烧写,

  • 发送指令"C",3秒钟后电机"嘀"一声,然后正转8个电角度,反转8个电角度,同时串口打印校准参数。

  • 再发送指令"G",电机闭环,

  • 再发送指令"T10",电机转动。读取实时速度,指令为"V"。

视频:稍后上传

3.3、位置模式

  • 在MyProject.h文件中设置参数,下图:

  • 编译烧写,

  • 发送指令"C",3秒钟后电机"嘀"一声,然后正转8个电角度,反转8个电角度,同时串口打印校准参数。

  • 再发送指令"G",电机闭环,

  • 再发送指令"K1",电机转到指定位置。读取当前位置指令为"P"。

视频:稍后上传

3.4、跳过上电校准

  • 官方ODrive每次上电都要校准一下才能进入闭环,否则会报错(只有无感模式可以直接进入闭环),据说在代码中配置也可以跳过校准,我没找到配置的方法。

  • SimpleFOC中,把校准参数写入代码可以跳过检测,我按照SimpleFOC的方法做了类似设计:

3.4.1、手动输入参数

1、第一次设置为0,编译烧下载,下图:

2、发送指令"C"校准电机,获取校准参数,下图:

电机起始位置不同,校准的偏置角度可能不一样,填写其中任一次的校准值即可(原理在上一篇教程中讲过了)。

3、把获取的五个参数写入代码,编译下载,下图:

4、重新上电,可以不用再校准,直接发送指令"G"进入闭环。

5、ABZ编码器为增量编码器,需要每次上电都检测,不能跳过。

3.4.2、flash保存参数

手动输入参数比较麻烦,功能升级,增加了flash保存功能,并且可以开机进入闭环,请看第二个代码,

1、上电后发送指令"C"校准电机,

2、发送指令"A1"配置已经校准,相当于官方指令:odrv0.axis0.motor.config.pre_calibrated = True,

3、如果需要开机进入闭环,发送指令"B1",相当于官方指令:odrv0.axis0.config.startup_closed_loop_control = True,

4、发送指令"F"保存参数到flash,

5、发送指令"R"重启。

6、初始化时设置好目标值,闭环后可直接运行到设定值。

保存在flash的参数,重新烧写代码不会被删除,代码更新时记得发送指令删除,以免影响新代码的执行。

3.5、测试云台电机

ODrive也可以控制云台电机,参数更容易调试,因为有梯形轨迹算法,所以位置模式的效果也比SimpleFOC好,

1、硬件接线,下图:

驱动板 购买链接:某宝购买

电机 购买链接:某宝购买

2、在MyProject.h文件中设置参数,下图:

3、操作与上面的相同,不再赘述,

视频:稍后上传

四、代码说明

以这个代码为例,简单捋下流程:

1、while(1) 的工作量很小,下图

2、定时器更新中断是核心,下图:

3、大部分功能处理在 上图的control_loop_cb() 函数中,

4、在axis.c文件中进入闭环,下图:

5、在controller.c文件中根据输出模式,处理位置、速度和力矩变量,

然后是位置环PID和速度环PID运算,下图:

所有的输入模式,运算后最终生成这个输出,下图:

6、在motor,c中生成 Id/Iq,下图:

7、接下来就是你们喜欢的FOC变换,主要由 pwm_update_cb() 函数实现,

代码流程就是这样,别问我细节,我不可能自毁形象告诉你我不会!

五、定点运算和浮点运算

  • 定点运算,通过放大程序运行中的变量的方式,把浮点数转化为定点数,提高了计算效率,使得低性能的单片机也可以实现高性能的算法。

  • 去年(2022年)初的时候我还曾计划过把SimpleFOC的代码转换为定点运算,好在没空做。

  • 定点运算早就存在,但是ST采用定点运算配合它的电机库,极大的推广了这一技术,我觉得目前市面上只要是定点运算的电机驱动器,应该都会受到ST的影响,或者直接就师承ST。

  • 定点运算的标幺化太过复杂,繁琐,既要防止溢出又怕精度不够,对于新手非常不友好。

    浮点运算则简单、直观、高精度,除了单片机成本高,但是随着国产单片机的崛起,成本门槛已经不存在了。

  • 并且随着ODrive和VESC等开源技术影响的逐渐扩大,浮点运算一定会成为主流。

  • 看到一些国产单片机厂家在推定点运算的驱动器,我觉得这些厂家应该是没把握住技术发展方向,要么就是技术不够成熟。请大家根据自己的能力和需要选择技术路线。

    (完)

相关推荐
嵌入式杂谈2 小时前
STM32中断编程指南:NVIC和中断优先级
stm32·单片机·嵌入式硬件
zxfly20135 小时前
STM32的DMA技术介绍
stm32·单片机·嵌入式硬件
CV金科10 小时前
蓝桥杯—STM32G431RBT6(IIC通信--EEPROM(AT24C02)存储器进行通信)
stm32·单片机·嵌入式硬件·算法·蓝桥杯
嵌入式详谈12 小时前
基于STM32的智能风扇控制系统设计
stm32·单片机·嵌入式硬件
小小怪大梦想12 小时前
RTC实时时钟
stm32·单片机·嵌入式硬件
SZPU领跑17 小时前
第十二届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)(第一套)
stm32·单片机·算法·职场和发展·蓝桥杯
Tlog嵌入式20 小时前
蓝桥杯【物联网】零基础到国奖之路:十六. 扩展模块之矩阵按键
arm开发·stm32·单片机·mcu·物联网·蓝桥杯·iot
黄小美32121 小时前
STM32(五)GPIO输入硬件电路及C语言知识复习
stm32·单片机·嵌入式硬件
py.鸽鸽21 小时前
STM32
stm32·单片机·嵌入式硬件
朴人21 小时前
【从零开始实现stm32无刷电机FOC】【实践】【7.1/7 硬件设计】
stm32·单片机·嵌入式硬件