尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

深入理解单车平衡串级pid

深入理解单车平衡串级pid 1.框架图单车的平衡框架是由3串级pid构成2.环的概念最简单判断就是看输入速度环输入速度控制速度的大小转向环:决定车要往那边偏输入-----左转/右转角度环让车身真的达到目标角度输入---目标角度向左3度/向右3度角速度环控制舵机快速稳住车身输入往左/右的速度快一点3.外环与内环判断内环与外环关键看响应速度但内环与外环有着因果关系比如拿位置环与速度环举例我们想让车从A点转到B点当我们的电机听不懂我们要通过位置环输出一个速度给速度环告诉单片机输出多大的pwm给电机从而使电机转起来让车从A点走到B点4.单车的3环关系pid控制关系讲解关系图解问题1为什么我输出的是角度但经过pid以后它变成角速度了根据【文档内容】中pid_compute函数的实现逻辑以及您在平衡车控制中的使用方式pid_compute函数本身并不知道也不关心输入/输出的物理意义。它只是一个数学计算器。​ 您之所以看到“输入角度输出角速度”是由于您在控制系统架构设计和PID参数整定上赋予了它这样的角色和物理转换关系。下面为您详细拆解这个过程的原理1.pid_compute函数本身只做数学运算从【文档内容】可见pid_compute函数的内部逻辑是纯粹的数学计算计算误差error target - measure。无论target和measure是角度、角速度、位置还是温度对它来说都只是一个数值。套用公式根据是位置式还是增量式PID使用系数kp、ki、kd对当前误差和历史误差进行加权求和得出一个输出值output。输出限幅将output限制在预设的范围内out_limit。结论该函数不进行任何物理单位的转换。它只是根据目标值和测量值的差值误差按照一个固定的数学规则PID公式计算出一个控制量。2. “角度进角速度出”是串级控制架构的体现在您的平衡车代码control_loop_bicycle()中相关语句是target_gyro pid_compute(pid_balance, final_target_roll, current_roll);这条语句的关键在于您是将pid_balance这个角度环控制器的输出赋值给了名为target_gyro目标角速度​ 的变量。这正是串级PID控制的核心思想外环角度环pid_balance。输入角度误差final_target_roll - current_roll。职责思考“为了把当前角度纠正到目标角度我需要车身产生多大的角速度旋转快慢”输出一个数值您将这个数值解释并定义为期望的角速度target_gyro。内环角速度环pid_balance_gyro在下一行代码中被使用。输入角速度误差target_gyro - current_gyro。这里的target_gyro就是外环的输出。职责思考“为了达到外环要求的角速度我需要给舵机/电机多大的控制力PWM占空比或角度”输出直接驱动执行器舵机的控制信号balance_out。物理过程的隐喻假设车向左倾倒了current_roll偏左。角度环​ (pid_balance) 计算“倾斜了5度要把它拉回来我需要让车身以每秒30度的速度向右旋转。” 于是它输出target_gyro 30。角速度环​ (pid_balance_gyro) 计算“陀螺仪显示当前向右转速只有10度/秒离30还差20。我需要让舵机再打大一点。” 于是它输出一个更大的balance_out给舵机。舵机动作车身开始更快地向右旋转角度逐渐被纠正。3. 物理单位的转换是如何实现的通过PID参数的整定调试来实现。当您调试pid_balance的kp、ki、kd参数时您实际上是在建立一条“翻译规则”kp的作用决定了“每1度的角度误差应该对应多少度/秒的期望角速度”。例如kp5可能意味着“1度误差对应5度/秒的角速度指令”。out_limit的作用限定了期望角速度的最大最小值例如±250度/秒这直接赋予了输出值target_gyro以角速度的物理单位和量级。简单来说pid_compute(pid_balance, ...)输出的那个数字它本来没有单位。是您通过调试参数让这个数字的大小和变化规律恰好对应了一个合理的、具有“度/秒”单位的角速度指令值然后您把这个值当作角速度传给内环。总结与类比您可以这样理解pid_compute函数像一个通用的调解员。你给它两个有矛盾的数目标值和实际值它根据一套规则PID参数算出一个“调解方案”输出值。它不关心矛盾的是“角度”还是“速度”。您的系统设计您安排了两个调解员接力工作。第一个调解员 (pid_balance) 专门调解角度矛盾它的输出方案被规定为给第二个调解员的“工作目标”。第二个调解员 (pid_balance_gyro) 专门调解角速度矛盾它努力使实际角速度达到第一个调解员提出的目标。参数调试就是训练第一个调解员让它提出的“角速度目标”既有效能快速纠正角度又合理不会太大导致系统震荡。因此target_gyro pid_compute(pid_balance, ...);这行代码是您串级控制思想在程序中的具体实现。它之所以成立不是因为PID函数会魔法而是因为您通过精心的系统架构设计和参数整定赋予了这行代码特定的物理意义。可以理解为pid就是我们自己设置的一套转换规则他可以通过调参来实现不同物理量之间的转换他本身不具有任何物理意义对它来讲输入输出都只是一个数值要通过我们不断的去调它的参数让两个值之间的物理量进行转换。问题2万一pid的输入和输出不是简单的比值关系呢这是一个非常深刻且关键的问题。您指出了经典 PID 控制理论中的一个核心前提。是的PID 控制器无论是位置式还是增量式其基础数学公式本质上建立在一个隐含的假设上系统的输入误差与所需的输出控制量之间可以通过一个线性组合比例、积分、微分的加权和来建立有效的关系。当这个假设不成立即被控对象的动态特性是非线性、强耦合或时变的简单的线性 PID 就会表现出局限。文档中的pid_compute函数作为通用算法并未处理这种情况。基于我所掌握的控制系统知识工程上主要通过以下几种策略应对1. 核心前提“黑箱”与局部线性化PID 之所以广泛应用是因为它将复杂的被控对象视为一个“黑箱”并假设在其工作点附近对象的动态可以用线性关系来近似。调参 (Kp, Ki, Kd) 的过程就是在为这个“局部线性模型”寻找合适的系数。2. 当系统非线性时在 PID 框架内的应对策略即使系统整体非线性工程师也常通过以下方式在 PID 框架内进行改良增益调度根据系统不同的工作状态切换多组 PID 参数。示例在您的平衡车中当车体倾角很大如 30 度时可能需要一组更“激进”的参数来快速回正而当倾角很小 5 度时则需要另一组更“柔和”的参数来精细保持平衡防止抖动。这需要预设一个根据current_roll查表或计算参数的机制。前馈补偿在 PID 输出上叠加一个基于模型或经验的预估控制量以抵消已知的非线性或扰动。示例如果知道让电机加速到某一转速需要特定的 PWM 占空比非线性关系可以直接将这个预估占空比作为前馈量加到速度环 PID 的输出上。PID 则主要负责补偿前馈模型的不准确和未知扰动。非线性变换对 PID 的输入或输出进行非线性映射如平方、死区补偿、饱和函数使其在与被控对象交互前“线性化”。示例对误差e取平方e²后再送入比例项使得小误差时控制力弱大误差时控制力急剧增强。或者在误差很小时设置一个“死区”避免执行器频繁微动。3. 超越 PID更复杂的控制器当系统非线性非常严重上述方法难以奏效时就需要更高级的控制策略模糊 PID用模糊规则如“如果误差为正大且误差变化率为负中则输出为负大”来动态调整 PID 参数适用于难以建立精确数学模型但专家经验丰富的系统。模型预测控制基于一个可以是非线性的系统模型预测未来一段时间内的系统行为并在线优化一系列控制输入。这是处理多变量、强约束非线性系统的强大方法。滑模控制设计一个特殊的控制律强制系统状态轨迹“滑向”一个预设的滑模面并对参数变化和扰动具有强鲁棒性。自适应控制在线实时地辨识系统参数并动态调整控制器参数适用于系统参数时变的场合。回到您的平衡车项目在您的串级 PID 设计中角度环 - 角速度环这个关系在小角度范围内sinθ ≈ θ可以近似为线性。Kp实质上决定了“单位角度误差对应多大期望角速度”的比率。因此在这里使用线性 PID 是合理且有效的。角速度环 - 舵机/PWM这个环节可能包含非线性如舵机死区、减速齿轮间隙、车体转动惯量的非线性。您的pid_balance_gyro的Kp参数实际上是在“表征”这个非线性关系的局部线性近似。调试过程就是在为当前工作点找到这个最佳近似。速度环 - 电机这可能是一个非线性更明显的环节涉及电机静摩擦力、电机转矩与电流/占空比的非线性关系、轮地摩擦等。这也是为什么速度环通常需要Ki积分来克服静摩擦死区引起的稳态误差。结论您的担心完全正确。PID 的“简单比值关系”是其强大易用性的来源也是其在面对复杂非线性系统时的根本局限。在实际工程中我们首先尝试用PID 增益调度/前馈​ 等组合方法来处理常见的非线性问题。只有当系统过于复杂时才会考虑更高级的控制算法。对于平衡车这类系统经过精心调试的串级 PID 通常已经能提供卓越的性能这证明了在其主要工作区域内线性近似是足够有效的。您在调参时遇到的瓶颈有时正是需要引入上述某种非线性处理策略的信号。在单车环中我们先把他们全部先当成线性
返回列表