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等开源技术影响的逐渐扩大,浮点运算一定会成为主流。

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

    (完)

相关推荐
LateBloomer7777 分钟前
FreeRTOS——信号量
笔记·stm32·学习·freertos
wenchm42 分钟前
细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的另一种方法
stm32·单片机·嵌入式硬件
嵌新程5 小时前
day03(单片机高级)RTOS
stm32·单片机·嵌入式硬件·freertos·rtos·u575
Lin2012305 小时前
STM32 Keil5 attribute 关键字的用法
stm32·单片机·嵌入式硬件
电工小王(全国可飞)6 小时前
STM32 RAM在Memory Map中被分为3个区域
stm32·单片机·嵌入式硬件
maxiumII6 小时前
Diving into the STM32 HAL-----DAC笔记
笔记·stm32·嵌入式硬件
时光の尘9 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
日晨难再12 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件
PegasusYu1 天前
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
stm32·教程·rtos·stm32cubeide·free-rtos·eventgroup·时间标志组
文弱书生6561 天前
输出比较简介
stm32