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



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

一、硬件接线

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

在这里插入图片描述

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

二、官方代码操作

用官方代码操作,验证控制效果,获取配置参数,
本小节演示用v0.5.1版本固件,因为v0.5.1的教程最丰富。当然也可以用v0.5.6版本。
在这里插入图片描述

2.1、力矩模式

在这里插入图片描述

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

//力矩模式
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、速度模式

在这里插入图片描述

//速度模式
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算法又把它转到磁阻最大位置,如此反复拉扯。
这个问题需要在下一节抗齿槽算法来解决,

//位置模式
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文件中设置参数,下图:
    在这里插入图片描述
    如果有更多参数需要设置,请进入初始化阶段的几个 init()函数,下图:
    在这里插入图片描述

  • 编译烧写,

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

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

  • 再发送指令“S0.1”,电机开始转动,如果空载电机会达到最大转速。如果限速,电机只能达到限制转速。
    在这里插入图片描述

视频:https://www.bilibili.com/video/BV1XG411v7hM/?vd_source=33c70ef3713ea86e5385ac1e62223bcf

3.2、速度模式

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

  • 编译烧写,

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

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

  • 再发送指令“T10”,电机转动。读取实时速度,指令为“V”。
    在这里插入图片描述

视频:https://www.bilibili.com/video/BV1XG411v7hM/?vd_source=33c70ef3713ea86e5385ac1e62223bcf

3.3、位置模式

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

  • 编译烧写,

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

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

  • 再发送指令“K1”,电机转到指定位置。读取当前位置指令为“P”。
    在这里插入图片描述

视频:https://www.bilibili.com/video/BV1XG411v7hM/?vd_source=33c70ef3713ea86e5385ac1e62223bcf

3.4、跳过上电校准

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

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

3.4.1、手动输入参数

1、第一次设置为0,编译烧下载,下图:
在这里插入图片描述
2、发送指令“C”校准电机,获取校准参数,下图:
在这里插入图片描述
电机起始位置不同,校准的偏置角度可能不一样,填写其中任一次的校准值即可(原理在上一篇教程中讲过了)。

3、把获取的五个参数写入代码,编译下载,下图:
在这里插入图片描述

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

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的参数,重新烧写代码不会被删除,代码更新时记得发送指令删除,以免影响新代码的执行。

ABZ编码器为增量编码器,每次上电都需要校准,不能跳过。

3.5、测试云台电机

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

1、硬件接线,下图:
在这里插入图片描述

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

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

3、操作与上面的相同,不再赘述,
在这里插入图片描述

4、ODrive的位置模式+梯形轨迹,可以又快又稳的转到指定位置,

在这里插入图片描述

四、代码说明

以这个代码为例,简单捋下流程:
在这里插入图片描述

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() 函数实现,

在这里插入图片描述

代码流程就是这样,别问细节,成年人点到为止!

五、定点运算和浮点运算

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

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

  • 定点运算的标幺化太过复杂,繁琐,既要防止溢出又怕精度不够,对于新手非常不友好。
    浮点运算则简单、直观、高精度,除了单片机成本高,但是随着国产单片机的崛起,成本门槛已经不存在了。

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

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





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




(完)

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值