foc学习笔记3——电流环

2023-05-16

foc学习笔记3——电流环

电流环的作用

​ 前文不断强调,进行磁场定向控制需要控制的是电流而非电压,只是因为我们没有办法直接去控制电流才暂时退而求其次地去控制电压 。虽然电压控制的效果也还不错,但由于电机不是单纯的阻性负载,所以控制电压并不能得到一个完美的效果。终极目标是控制电流,没有电流控制的foc不能叫foc,所以电流环最本质的作用是什么就不用多说了吧。

在这里插入图片描述

注:虽然框图中含有编码器,但它并不是电压控制的反馈环节,仅用来获取转子电角度,所以称其为开环控制。

在这里插入图片描述

​ 对于其他方面的作用,说一说自己的理解:

(1)让id尽可能地接近0,提高效率

​ 使用电压开环控制时,由于种种原因,id并不是一直为0,可能存在偏移或是跳动,转速越高这种情况就越厉害,而使用电流闭环可以较好地遏制这种现象。

下面两张图显示了在20V供电下,某台电机空载全速转动下的id和iq波形,其中蓝色的是id。第一张图使用电压开环控制,第二张图使用电流闭环控制。

在这里插入图片描述

在这里插入图片描述

(2)起到一个限流保护的作用

​ 当电机堵转的时候,电流等于电压除以电阻。假如电压是12V,电机内阻是0.1欧姆,那么此时流过电机的电流就是120安培。如果电机的额定电流只有10安培,那么它很有可能在1秒钟之内冒烟烧掉,同时120安培的大电流对于小型驱动板而言也是致命的。我们可以在硬件上增加过流保护的功能,当触发过流保护时直接关断三相全桥。但我们想要的是限流,尽可能地将电机流过的电流限制在给定值之下,而不是达到阈值就关断电机,因此硬件上的过流保护只是作为最后一道保护措施,真正的限流通常是由软件上的电流环来实现。将电机的电流限死在额定电流之下,这样即使电机堵转也不用担心烧毁电机或是驱动器。

(3)力矩控制

​ 电机的输出转矩和电流基本上是成正比的,因此控制了电流也就相当于控制了电机的输出转矩。(这里也再次强调一下,要让电机输出转矩是需要给它添加负载的。如果电机空载,那么它的输出转矩只需要克服摩擦力和空气阻力等,此时的输出转矩是非常小的。所以这里说的控制电机的输出转矩,其实是控制电机的最大输出转矩,也就是堵转时的转矩。)

电流环的实现

​ 由前文的控制框图可知,实现电流环需要做这么几件事情:①电机三相电流采集②克拉克变换③帕克变换④电流环PID运算。

(1)电流采样

​ 电流采样是属于硬件部分的内容,这里只做一些简单的介绍,后续如果有机会也会出几期关于硬件的文章。

​ 电流采样的方案大致有电流互感和电阻采样两种,而电阻采样又分为低端采样、母线采样和高端采样。对于电阻采样而言无论是哪一种,其原理都是一样的,根据欧姆定律可得电流等于电压除以电阻。由于电阻阻值是我们给定的,所以只要采集了电阻两端的电压就可以算出流过电阻的电流。为了尽可能的不影响电路正常工作,我们选用的采样电阻的阻值一般都会很小(毫欧级),所以电阻两端的电压往往会比较小,比如10毫欧的电阻,流过10安培的电流,其两端电压仅为100毫伏,因此我们需要运算放大器来放大这个电压信号,最后送给单片机的ADC。

​ 最终的换算公式如下:(3.3V的参考电压,12位的ADC,电流单位安培,电阻单位欧姆)
电 流 = A D C 原 始 值 / 4096 ∗ 3.3 / 采 样 电 阻 阻 值 / 运 放 放 大 倍 数 电流 = ADC原始值 / 4096 * 3.3 / 采样电阻阻值 / 运放放大倍数 =ADC/40963.3//
​ 这里也提几个关键的地方:①对于低端采样,一定要在采样电阻对应的下桥臂开启的时候采样,否则下桥臂关断的时候几乎不会有电流流过采样电阻(高端采样也类似)②对于母线采样,任何时候都有电流流过采样电阻,但这并不意味着任何时间点都可以采样,一定要避开mos管开启或关断的瞬间,否则会采集到非常严重的尖峰噪声(这个原则对于高端和低端采样也适用)。③电流采样的效果会直接影响到电流环的控制效果,因此万万不可马虎。

(2)克拉克变换和帕克变换

​ 前文已经讲过它们的反变换,这里不多废话了,两个变换加起来也就四句代码:

void Clarke_Park(struct MOTO_Type * moto, int32_t currA, int32_t currC)
{
    moto->iAlpha = (float32_t)currA;
    moto->iBeta = -(float32_t)(currA + 2 * currC) * 0.5773502692f;
    
    moto->id = moto->iAlpha * moto->cosVal + moto->iBeta * moto->sinVal;
    moto->iq = -moto->iAlpha * moto->sinVal + moto->iBeta * moto->cosVal;
}

为什么只需要两相电流而不是三相呢?因为三相电流之和等于0,知道两相可以倒推出第三相。为什么我这里用的是A相和C相的电流呢?一方面是有时候要方便板子布线,另一方面是用AB相的很多,这里介绍一下其他的,希望大家学会灵活运用。如果对具体的推导过程有兴趣的可以观看硬石专题8第6第7小节,链接已放在底部。

(3)PI运算

首先要明确一点,对于电流环而言一般是不会使用微分项D的,这个不是我说的,而是查阅了一些相关资料(包括ti的公开课,一些开源方案的源码)找到的结论。

​ 经过克拉克变换以及帕克变换,我们的三相交流电流量已经变成了两个直流的电流量,因此可以很容易的使用PID去控制它。PID相信大家都非常熟悉,而去掉了D项就更简单了:

void Curr_PI_Cal(struct PI_Type *PI_Control, float32_t target, float32_t resultMax)
{
    PI_Control->target = target;
    
    PI_Control->error = PI_Control->target - PI_Control->value;							//误差等于目标值减去测量值
    
    PI_Control->errSum += PI_Control->error * PI_Control->ki;							//积分项累加
    
    if(PI_Control->errSum > PI_Control->errSumMax)										//积分限幅
        PI_Control->errSum = PI_Control->errSumMax;
    else if(PI_Control->errSum < -PI_Control->errSumMax)
        PI_Control->errSum = -PI_Control->errSumMax;   
    
    PI_Control->result = PI_Control->kp * PI_Control->error + PI_Control->errSum;		//得到PI运算结果
    
    if(PI_Control->result > resultMax)													//最大输出限幅
        PI_Control->result = resultMax;
    else if(PI_Control->result < -resultMax)
        PI_Control->result = -resultMax;
}

这里有一个地方可能和大家以往用的不太一样:

PI_Control->result = PI_Control->kp * PI_Control->error + PI_Control->errSum;
PI_Control->result = PI_Control->kp * PI_Control->error + PI_Control->ki * PI_Control->errSum;

用下面这种的应该会多一些,但这种形式有个缺点就是它的积分限幅值是会随着 ki 的调整而变化,并且不直观,你也不知道限幅了多少。因此推荐使用上面这种形式,先将整个积分项不停地累加起来,再对其限幅。因为电流环的输入是电流id、iq,输出是电压ud、uq,而我们的ud、uq是受限于供电电压的,你不可能给你的驱动板供电12V却让它输出20V,过大的积分限幅是完全没有意义的,只会让你的电流环严重超调,而过小的限幅会让你的电机发挥不出力量,比如你的驱动板是12V供电,却只能达到6V的效果。那么多大的限幅是合适的呢,还记得前文介绍svpwm说的最大不失真电压Uref吗?
U r e f ≤ 3 3 × U d c Uref \leq \frac{\sqrt{3}}{3} \times Udc Uref33 ×Udc
积分限幅就可以通过这个公式算出来,比方说12V供电,那么积分限幅值就可以取6.93。同样的,代码最下边的 resultMax 也取这个数。

​ 这里也温馨提示一下,Uref是通过ud和uq两个矢量合成的,所以要让Uref小于限幅值,并非仅让ud、uq分别小于限幅值就够了。

电流环的调试

同样先明确几点:①对于普通的无刷电机,id给定值为零②调试时先调D轴的PI参数,如果效果满意,就把D轴的PI参数原封不动的赋给Q轴。

(1)参数整定方法

​ 电流环的PI参数是可以算出来的,只要知道了电机的电阻和电感,就能得到这台电机的电流环PI参数。具体的推导过程可以参考下面链接的第一个视频,这里只说结论。

对于串联型的PI控制器:
K p = L × b a n d w i d t h × 2 π Kp = L\times bandwidth\times2\pi Kp=L×bandwidth×2π

K i = R ÷ L Ki = R \div L Ki=R÷L

对于并联型的PI控制器:
K p = L × b a n d w i d t h × 2 π Kp = L\times bandwidth\times2\pi Kp=L×bandwidth×2π

K i = R × b a n d w i d t h × 2 π Ki = R\times bandwidth\times2\pi Ki=R×bandwidth×2π

解释:

  1. 这里的 L 和 R 的单位是 H 和 Ω
  2. 如果你不清楚串联型和并联型PI控制器的区别,那么你用的百分之99就是并联型的PI控制器。前面的代码就是并联型的。
  3. 这里的带宽是自己给定的,带宽越小系统越稳定,响应越慢;带宽越大系统越不稳定,但响应越快
  4. 根据ti的资料,带宽取电流采样频率的 1/20 ;根据视频中那位大佬的回复,电流环带宽从100Hz到1000Hz的都有。
  5. 有些资料把 2π 放进带宽里面,而有些则是分开计算,这就产生了一个误区,两种计算方法会使PI参数相差6.28倍。个人两种方法都尝试过,不乘6.28的PI参数的阶跃响应波形更平滑,而乘以6.28的波形会略有超调,但电机并未产生震荡且能够正常工作。这里我更加偏向要乘6.28的说法,各位看着办。

(2)调试实例

​ 使用5208云台电机,通过万用表等仪器测得电阻为 11.4Ω,电感由于没有专业仪器,只好参考相似型号电机,估测为 3mH 左右(由于电机是闲鱼买的,没有详细参数,后面可以通过细调Kp参数来解决)。使用并联型PI,带宽这里取300Hz,可得:
K p = 0.003 × 300 × 2 π = 5.625 Kp = 0.003\times 300\times2\pi=5.625 Kp=0.003×300×2π=5.625

K i = 11.4 × 300 × 2 π = 21477.6 Ki = 11.4\times 300\times2\pi=21477.6 Ki=11.4×300×2π=21477.6

但由于我使用ADC的原始值作为反馈信号,因此PI参数也要相应的改变一下。由前面的公式计算得到: 电流 = ADC原始值 / 500,因此PI参数也要除以500。还有一点也要注意,算出来的Ki参数是不包含积分时间的,因此要补上,我这里的积分时间是 1 / 8000 秒。所以最终的PI参数为:
K p = 5.625 ÷ 500 = 0.01125 Kp = 5.625\div500=0.01125 Kp=5.625÷500=0.01125

K i = 21477.6 ÷ 500 ÷ 8000 = 0.00537 Ki=21477.6 \div 500 \div 8000 = 0.00537 Ki=21477.6÷500÷8000=0.00537

​ 下面把调好的参数下载到单片机里,看一下D轴电流的阶跃响应如何(这里暂时先不给Q轴赋值)

在这里插入图片描述

这里给定的目标值是200,也就是0.4A,可以看到响应波形是很漂亮的,除了上升和下降的终点处有一些毛刺。

​ 下面将D轴的PI参数原封不动的赋给Q轴试试:

在这里插入图片描述

这里D轴给定值为0,Q轴给定值仅为50(0.1A),但由于电机空载电流达不到0.1A,因此Q轴电流环积分项迅速饱和,此时电机正全速旋转。

​ 我们将D轴设定值设为0,Q轴设定值设为200,然后用手反复堵转电机看一看响应波形:

在这里插入图片描述

当电机堵转时,Q轴电流被限制在200(0.4A)附近;当松开电机时,电机迅速地恢复全速转动,且Q轴电流仅为空载电流。并且当Q轴的设定值越大,堵转时电机的输出转矩越大。

​ 至此,电流环的调试基本完成,大家可以参考这三张图来判断电流环的调试是否正确。第三张图的Q轴电流存在超调是因为之前全速转动的时候积分项已完全饱和,突然的堵转使积分项来不及释放干净而导致过冲,解决的办法是使用抗饱和的PI控制器,如动态积分限幅等。但如果是要求不高的场合,正确的静态积分限幅已经足够了。

解释:

  1. 先调D轴是因为如果调Q轴会使电机转起来,而电机空载下的电流非常小,如果达不到我们的给定值,积分器会迅速饱和,使电机全速转动。
  2. 串联型的PI控制器和并联型的本质上是一样的,只是Ki参数会不同。并联型的Ki相当于串联型的Kp*Ki,因此对于串联型的来说,调节Kp会使积分项的增益也随之改变。但是串联型的好处就在于使用Ki实现零极点对消,然后通过调节Kp来调整带宽。并联型的如果要调整带宽,则PI参数需要一起调。

参考资料:

  1. 视频:【电机控制】《PID调节器》第一部分:电流环设计
  2. 视频:TI公开培训(中文字幕) 电机控制,PI控制器,PID控制器和现场定向控制
  3. 视频:硬石相关章节
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

foc学习笔记3——电流环 的相关文章

  • 神奇!明明是 socket,被我玩成了 http!

    颓废青年 xff0c 快出来挨打 xff01 点击上方 Java极客技术 xff0c 选择 设为星标 后台回复 java xff0c 获取Java知识体系 面试必看资料 资料会持续更新 xff0c 已更新第四次 xff01 文章精品专栏 记
  • python画图程序

    usr bin python coding utf 8 import wx import wx lib buttons as buttons import wx adv as adv import wx lib colourselect a
  • 升级到tensorflow2.0,我整个人都不好了

    版本升级到 tensorflow 2 0 的悲惨经历 没事别升级 Tensorflow 2 0发布已经有一段时间了 xff0c 各种基于新API的教程看上去的确简单易用 xff0c 一个简单的mnist手写识别只需要下面不到20行代码就OK
  • 修改conda环境和缓存默认路径

    默认情况下 xff0c conda 创建的新环境 以及过往安装的模块缓存都存储在用户目录下 xff0c 这一点不会在 conda xff08 user specific xff09 配置文件 HOME condarc 中体现出来 xff0c
  • 融合人体姿态估计和目标检测的学生课堂行为识别

    融合人体姿态估计和目标检测的学生课堂行为识别 参考网 摘要 xff1a 在課堂教学中 xff0c 人工智能技术可以帮助实现学生行为分析自动化 xff0c 让教师能够高效且直观地掌握学生学习行为投入的情况 xff0c 为后续优化教学设计与实施
  • Python实例详解pdfplumber读取PDF写入Excel

    一 Python操作PDF 13大库对比 PDF xff08 Portable Document Format xff09 是一种便携文档格式 xff0c 便于跨操作系统传播文档 PDF文档遵循标准格式 xff0c 因此存在很多可以操作PD
  • 如何使用ChatGPT API训练自定义知识库AI聊天机器人

    原文 xff1a 如何使用ChatGPT API训练自定义知识库AI聊天机器人 闪电博 在我们之前的文章中 xff0c 我们演示了如何用ChatGPT API建立一个AI聊天机器人 xff0c 并指定一个角色来进行个性化处理 但如果你想在自
  • 哈工大团队开源医学智能问诊大模型 | 华佗: 基于中文医学知识的LLaMa指令微调模型

    原文 xff1a CVHub 门头沟学院AI视觉实验室御用公众号 学术 科研 就业 185篇原创内容 公众号 Title HuaTuo Tuning LLaMA Model with Chinese Medical Knowledge PD
  • 开源数字人Fay

    原文 xff1a 别再因AI焦虑 xff0c 这波年轻人已经用 中国版ChatGPT 创业成功了 数字人 AI 创业 新浪新闻 开源 xff1a GitHub TheRamU Fay Fay是一个完整的开源项目 xff0c 包含Fay控制器
  • 推荐 3 个令你惊艳的 GitHub 项目

    原文 xff1a 推荐 3 个令你惊艳的 GitHub 项目 昨日 GitHub Trending 上榜的开源项目 xff0c 基于 AI 技术提高你的生产力 借助 AI 你能搭建自己的数字人 搭建自己的法律助手 文档分析助手 本期推荐开源
  • AI 数字人制作(方案一):输入一张图片和一段文字即可生成数字人

    方案一 xff1a 原文 xff1a AI 数字人制作 xff08 方案一 xff09 哔哩哔哩 bilibili AI 文字和图片生成数字人 输入一张图片和一段文字即可生成数字人 用三个开源项目整合成可以商用的数字人项目 文本生成语音开源
  • 大量数据情况下单线程插入和多线程insert数据库的性能测试

    大量数据情况下单线程插入和多线程insert数据库的性能测试 之前一直没有遇到过大批量数据入库的场景 xff0c 所以一直没有思考过在大量数据的情况下单线程插入和多线程插入的性能情况 今天在看一个项目源代码的时候发现使用了多线程insert
  • 查看tensorflow 安装目录

    使用命令 xff1a pip show f tensorflow 图和张量源码 xff1a C Program Files Anaconda3 Lib site packages tensorflow python framework op
  • FP-growth算法,fpgrowth算法详解

    FP growth算法 xff0c fpgrowth算法详解 使用FP growth算法来高效发现频繁项集 前言 你用过搜索引擎挥发现这样一个功能 xff1a 输入一个单词或者单词的一部分 xff0c 搜索引擎酒会自动补全查询词项 xff0
  • 如何将一个矩阵化为行阶梯形矩阵

    2016 03 29 尾巴 线性代数 有同学反映上一课过于冷冰冰 xff0c 都是一些不带证明的公式 如果线性代数所有公式都要证明的话 xff0c 线性代数的难度会上好几个量级 xff0c 有的公式的证明是特别特别难的 还有一个 xff0c
  • Activity启动模式与任务栈(Task)全面深入记录(上)

    转载请注明出处 xff08 谢谢 xff09 xff1a http blog csdn net javazejian article details 52071885 任务栈简单入门 最近又把两本进阶书看了一遍 xff0c 但总感觉好记性不
  • VSCode自定义代码片段3——url大全

    url大全 url 39 3 如何自定义用户代码片段 xff1a VSCode 61 左下角设置 61 用户代码片段 61 新建全局代码片段文件 61 自定义片段名称 61 编辑用户片段 61 ctrl 43 S 保存 url大全 34 P
  • mac中如何使用vsode愉快地运行C、C++程序

    闲来无事 xff0c 想在mac中写写C C 43 43 程序 xff0c 打开应用商店 xff0c 准备下个xcode玩玩 xff0c 结果小30G的空间占用直接劝退 因为一直使用vscode开发 xff0c 便萌生了使用插件来运行C C
  • CMake入门3之 静态链接库和动态链接库

    目录 目标 xff1a 环境 创建静态和动态链接库 文件准备 构建 安装静态链接库 使用静态链接库和动态库 使用动态库 使用静态库 目标 xff1a 构建静态链接库和动态链接库 xff0c 安装到系统 xff0c 写一个程序使用安装的静态链
  • 行人检测数据集

    MIT数据库 该数据库为较早公开的行人数据库 xff0c 共924张行人图片 xff08 ppm格式 xff0c 宽高为64 128 xff09 xff0c 肩到脚的距离约80象素 该数据库只含正面和背面两个视角 xff0c 无负样本 xf

随机推荐