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

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

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    三、移植后的代码操作

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

    在这里插入图片描述

    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)




    (完)

  • 相关阅读:
    西瓜书研读——第三章 线性模型:多元线性回归
    OpenAI放出的ChatGPT 4的多模态语音和图像更新
    FastDeploy UIE 模型 Python 部署示例:GPU、CPU版本安装依赖
    搞定蓝牙——第一篇(蓝牙发展史与简述)
    机器学习常见降维方法及Python示例汇总【附完整代码】
    PostgreSQL数据库统计信息——统计信息系统表
    .NET静态代码织入——肉夹馍(Rougamo)发布2.2
    【最新华为OD机试E卷-支持在线评测】增强的strstr(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
    2.8 Nginx负载均衡之ip_hash
    MCU的环形FIFO
  • 原文地址:https://blog.csdn.net/loop222/article/details/133888495