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

news2024/12/29 13:36:18

目录

  • 一、硬件接线
  • 二、官方代码操作
    • 2.1、力矩模式
    • 2.2、速度模式
    • 2.3、位置模式
  • 三、移植后的代码操作
    • 3.1、力矩模式
    • 3.2、速度模式
    • 3.3、位置模式
    • 3.4、跳过上电校准
      • 3.4.1、手动输入参数
      • 3.4.2、flash保存参数
    • 3.5、测试云台电机
  • 四、代码说明
  • 五、定点运算和浮点运算


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

一、硬件接线

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

在这里插入图片描述

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

二、官方代码操作

用官方代码操作,验证控制效果,获取配置参数,
本小节演示用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文件中设置参数,下图:
    在这里插入图片描述

  • 编译烧写,

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

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


    (完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1110305.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全感知智能配电房:让电力运行可控、高效

在当今数字化、智能化的时代,全感知智能配电房的出现无疑为电力行业带来了革命性的变革。这种新型配电房不仅提高了电力供应的效率,还大大降低了运营成本,为我们的日常生活和工作提供了更稳定、更可靠的电力保障。 力安科技全感知智能配电…

Teleport

从官网中获取到的代码如下 App.vue <template><div class"outer"><h3>Tooltips with Vue 3 Teleport</h3><div><MyModal /></div></div> </template> <script setup> import MyModal from "./My…

pinia踩坑之旅——在组件外使用pinia

pinia踩坑之旅——在组件外使用pinia 缘由 最近在使用 pinia 开发项目时产生了一个 bug&#xff0c;说在定义 pinia 前使用了 pinia。 报错如下&#xff1a; 代码展示 先来看一个我的代码&#xff08;这里我新开了一个项目用于演示&#xff09;&#xff0c;如果懒得看代码的…

【Python基础】数值类型

int(整形) 在 Python 中定义变量是 不需要指定类型&#xff08;在其他很多高级语言中都需要&#xff09; 整形&#xff0c;也被称之为整数。整数就是数学中的数字。 整形在Python中不受长度限制大小范围 使用 type 函数可以查看一个变量的类型 In[1]: 1 Out[1]: 1In[2]: t…

Win10修改编辑hosts文件无法保存的处理方法

1.首先打开hosts文件所在位置&#xff0c;我们输入C:WindowsSystem32Driversetc后回车就可以打开了&#xff0c;右键hosts文件&#xff0c;选择属性。 2.点击hosts属性对话框里的“高级”。 3.在hosts的高级安全设置界面点击更改权限&#xff0c;在新弹出的对话框里点击添加按…

TStor CSP文件存储在大模型训练中的实践

业务背景 大模型作为人工智能领域的重要发展趋势&#xff0c;正在逐渐改变人们的生活和工作方式。随着近年来大模型领域技术的突破&#xff0c;各类语言模型、图像模型、视频模型快速演进&#xff0c;国内外市场也不断涌现出优秀的大模型研究及商业化平台&#xff0c;预期通过…

竞赛 深度学习人体语义分割在弹幕防遮挡上的实现 - python

文章目录 1 前言1 课题背景2 技术原理和方法2.1基本原理2.2 技术选型和方法 3 实例分割4 实现效果5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习人体语义分割在弹幕防遮挡上的应用 该项目较为新颖&#xff0c;适合作为竞…

GoogleNet论文精读

论文名&#xff1a;Going depper with convolutions论文下载地址&#xff1a;https://github.com/jixiuy/paper引言第一段&#xff1a;背景成绩1*1的卷积在channel上升维和降维&#xff0c;channel融合&#xff0c;计算方法上等价于FNNGAP&#xff08;全局平均池化&#xff09;…

协同云办公原来可以这么简单!只需掌握这5个技巧

随着云计算技术的发展&#xff0c;协同云办公已经成为越来越多企业和团队的必备工具。但是&#xff0c;对于很多人来说&#xff0c;如何高效地进行协同云办公却仍是一个挑战。本文将介绍五个简单的技巧&#xff0c;让你轻松掌握协同云办公的秘诀&#xff0c;让你的工作更高效、…

《潮玩产业发展报告(2023)》发布 泡泡玛特进军海外潮玩市场

近期&#xff0c;新华网联合中国社会科学院财经战略研究院发布了《超越潮流&#xff1a;千亿级潮玩产业彰显人文经济价值——潮玩产业发展报告&#xff08;2023&#xff09;》&#xff08;下称《报告》&#xff09;。针对潮玩产业快速发展&#xff0c;课题组组长、中国社会科学…

25台兰博基尼跑车赛道巡游!泡泡玛特MOLLY攒的局就是这么拉风

入秋以来气温逐渐转冷&#xff0c;但泡泡玛特的市场活动却持续升温&#xff1a;国内首个潮玩行业沉浸式IP主题乐园泡泡玛特城市乐园正式开园&#xff1b;2023PTS上海国际潮流玩具展&#xff1b;入驻美国第二大商场、布里斯班再拓新店等海外布局步伐不停……将广大消费者的身心带…

C++数据结构X篇_18_二叉树的创建(根据遍历结果创建二叉树;#号法创建树)

本篇将会介绍二叉树的创建&#xff0c;重点学习#号法创建树的方法。 文章目录 1. 根据遍历结果创建二叉树&#xff08;只需记住结论即可&#xff09;1.1 首先有一个问题&#xff0c;根据中序遍历的结果能确定一棵树吗&#xff1f;1.2 那如何才能确定一棵树&#xff1f;&#x…

Python 框架学习 Django篇 (四) 数据库增删改查(CURD)

在上一章结尾我们了解到如采用前后端开发分离的架构模式开发&#xff0c;后端几乎不负责任何展现界面的工作&#xff0c;只负责对数据进行管理 &#xff0c;对数据的管理主要体现在&#xff1a; &#xff08;增加、修改、删除、列出 &#xff09;具体的接口参考大佬的文档BYSM…

插入排序改进 将交换变成赋值语句 优点适用于近乎有序的序列

效果非常的明显 下面给出代码截图 再给出原代码 #include<iostream> #include<string> #include "Student.h" #include "sorttesthelper.h" using namespace std;template<typename T >void selectionSort( T arr[], int n){for(int i…

MATLAB——Decision Tress决策树程序

给个关注呦&#xff01;欢迎关注微♥公众号“电击小子程高兴的MATLAB小屋”&#xff0c;海量资源等你来呦&#xff01; 光储直流微电网MATLAB/Simulink仿真 光伏PV三相并网逆变器 %% I. 清空环境变量 clear all clc warning off %% II. 导入数据 第一列是序号 第二…

让你至少拿2份offer的软件测试面试题来了(100题带标准答案)

一、自我介绍 二、灵活问题 1、大概说说之前公司的测试流程 2、测试报告有哪些内容? 3、如何保证用例的覆盖度&#xff1f; 4、什么是测试用例&#xff0c;什么是测试脚本&#xff1f;两者的关系 5、Bug的级别&#xff0c;按照什么划分 6、你认为是bug&#xff0c;开发认…

微信小程序开发的OA会议之会议,投票,个人中心的页面搭建及模板,还有自定义组件的学习

目录 一、自定义组件 1. 创建 2. 定义 3. 编写 4. 使用 二、会议 1. 数据 2. 显示 3. 样式 三、个人中心 1. 页面 2. 样式 四、投票 1. 引用 2. 数据 3. 页面 4. 样式 每篇收获 一、自定义组件 开发者可以将页面内的功能模块抽象成自定义组件&#xff0c;以…

国外访问学者面签技巧

当涉及国外访问学者的面签时&#xff0c;提前准备和掌握一些技巧可以大大增加成功的机会。本文知识人网小编将为您介绍一些关键的面签技巧&#xff0c;帮助您在国外访问学者面签中表现出色。 1.详细准备材料&#xff1a;在面签前&#xff0c;确保您已经准备好所有所需的文件和材…

乙酰基四肽-3/Acetyl Tetrapeptide-3——刺激毛囊,长出新头发,有效防止秃头

社会对头发很着迷。从圣经人物参孙&#xff08;他从头发中获得力量&#xff0c;并说如果剃光头他就会失去力量&#xff09;&#xff0c;到社交媒体上无休无止地谈论名人的标志性风格&#xff0c;头发是一个永恒的话题。 为什么痴迷&#xff1f;好吧&#xff0c;我们的头发是外…

分布式事务及CAP和BASE顶底

一、分布式事务 单体应用肯定就不存在分布式事务了&#xff0c;只有在分布式微服务系统中&#xff0c;各个服务之间通过RPC调用后&#xff0c;每个微服务有自己和数据库的连接&#xff0c;各个微服务的回滚不影响其他的微服务事务&#xff0c;这几必须使用分布式事务来解决分布…