新手必看!嵌入式STM32-PID

server/2024/10/18 7:44:53/

本文目录

  • 一、知识点
    • 1. 位置式pid
      • (1)公式
      • (2)代码
    • 2. 串级PID
      • 简易代码
  • 二、调参
    • (1)纯Kp调节
    • (2)Ki调节
    • (3)Kd调节

  

一、知识点

pid_5">1. 位置式pid

(1)公式

在这里插入图片描述

(2)代码

pid.c

typedef struct PID {float  Kp;         //  Proportional Const  P系数float  Ki;           //  Integral Const      I系数float  Kd;         //  Derivative Const    D系数float  LastError;          //  Error[-1]  float  Error;              //  Error[0 ]  float  DError;            //pid->Error - pid->LastError	float  SumError;           //  Sums of Errors  float  output;float  Integralmax;      //积分项的最大值float  outputmax;        //输出项的最大值
} PID;//为了防止积分项过度累积,引入积分项的限幅是一种常见的做法。
//限制积分项的幅值可以防止积分项过度增加,从而限制了系统的累积误差。这样可以避免系统过度响应或者不稳定。
float abs_limit(float value, float ABS_MAX)   //积分限幅,设置最大值。
{if(value > ABS_MAX)value = ABS_MAX;if(value< -ABS_MAX)value = -ABS_MAX;return value;
}//函数里传入指针,修改时会修改指针里的值。
float PID_Position_Calc( PID *pid,  float  Target_val,  float Actual_val)  //位置式PID
{   pid->Error =  Target_val - Actual_val;      //与pid P系数相乘。比例误差值 当前差值=目标值-实际值pid->SumError += pid->Error;                 //与pid I系数相乘。稳态误差值 误差相加作为误差总和,给积分项pid->DError = pid->Error - pid->LastError;   //与pid D系数相乘。 微分项-消除震荡pid->output =  pid->Kp* pid->Error +   \      //这里的\是续航符,表示和下面的内容是连着的。abs_limit( pid->Ki* pid->SumError, pid->Integralmax ) +   \pid->Kd* pid->DError ;  pid->LastError = pid->Error; //更新误差//限制输出最大值,防止出现突发意外。if(pid->output > pid->outputmax )  pid->output = pid->outputmax; if(pid->output < - pid->outputmax )  pid->output = -pid->outputmax;return pid->output ;
}//PID初始化
void PIDInit(PID *pid, float Kp , float Ki , float Kd ,  float Limit_value)  
{  pid->Kp= Kp;pid->Ki= Ki;pid->Kd= Kd;pid->LastError = pid->Error =pid->SumError= pid->output =  0; pid->Integralmax = pp->outputmax  = Limit_value;
}  

2. 串级PID

利用位置式pid的方法将位置环和速度环组合在一起使用。
在这里插入图片描述

简易代码

将目标位置和实际位置传入PID中,计算出期望转速。

#include "stdio.h"PID postion_pid;
PID speed_pid;int main(void) {// 初始化系统时钟SystemClock_Config();// 初始化PID控制器PID_Init(&postion_pid, 1.0f, 0.1f, 0.01f); // PID参数根据实际情况调整PID_Init(&speed_pid, 1.0f, 0.1f, 0.01f); // PID参数根据实际情况调整// 设置目标位置float target_position = 100.0f; // 假设目标位置为100while (1) {float current_position = GetPosition();    // 获取当前位置float current_speed = GetSpeed ();        // 获取当前转速// 更新PID控制器并计算控制量,这个输出值为当前位置向目标位置变换的一个速度或力。float control_output = PID_Position_Calc(&pid, target_position, current_position); //位置环float velocity_output = PID_Position_Calc(&speed_pid, control_output , current_speed );  //速度环Set_Pwm(velocity_output); //电机转动HAL_Delay(10); // 这里延时10毫秒,可根据实际情况调整}
}// 用于模拟读取位置的函数,这里假设返回的是传感器测量到的位置
float GetPosition() {// 在这里替换为获取位置的实际代码return 0.0f; // 这里暂时返回0,表示初始位置
}
// 用于模拟读取转速的函数。
float GetSpeed () {// 在这里替换为获取位置的实际代码return 0.0f; // 这里暂时返回0,表示初始位置
}
void Set_Pwm(int pwm)  //设置速度
{TIM4->CCR1=1550-pwm;    //速度环设置--
}

二、调参

讲述Kp、Ki、Kd的作用。

(1)纯Kp调节

假设有一个高为10m的水桶需要灌满水,这里我们假设Kp=0.2(每次灌水量为剩余灌水量的0.2倍)。
第一次灌水:10×0.2, 剩余8(10-10×0.2)。
第二次灌水: 8×0.2, 剩余6.4(8-8×0.2)。
第三次灌水:6.4×0.2 ,剩余5.12。

  这里我们发现当我们设置Kp后,一直会慢慢接近目标值,但是当Kp设置过小时,消耗的时间也就会更多。这里我们可以适当的调大Kp,使得更快的接近目标值。但是当Kp大于某个定值时,就会出现抖动,如下,假设Kp=1.5。
则第一次灌水:10×1.5,剩余 -5。
第二次灌水:-5×1.5,剩余2.5(-5 - (-5×1.5))。
第三次灌水:2.5×1.5,剩余 -1.25。

所以,要根据实际适当调整p值,不要使得Kp过大,而出现抖动。

(2)Ki调节

(3)Kd调节


http://www.ppmy.cn/server/5233.html

相关文章

Appium的使用:混合APP切换上下文

网上别的文章说要把移动端的webview设置成调试模式,才能看到下图信息。 但我这里是直接在Android Studio新建了一个空白活动,然后放的webview控件,写的webview代码,直接部署到模拟器上,在确定adb可以连接到模拟器后,在桌面浏览器输入chrome://inspect/#devices后就可以看…

JUC面试——⭐⭐Java中的四种引用类型/Threadlocal

四种引用类型 Java 中对象的引用分为四种级别&#xff0c;这四种级别由高到低依次为&#xff1a;强引用、软引用、弱引用和虚引用。 基础知识 强引用&#xff1a;普通使用的引用 强引用是造成 Java 内存泄漏的主要原因之一 软引用&#xff1a; GC内存不够时回收 适用于&…

后端开发简介

后端开发是软件开发领域的一个重要组成部分&#xff0c;主要负责构建和维护应用程序的服务器端逻辑、数据处理、系统架构和基础设施。后端开发人员通常专注于处理那些用户看不到但对应用程序功能至关重要的部分&#xff0c;确保数据的安全存储、高效检索、业务逻辑的正确执行以…

java面向对象的继承Shape

* - Shape基类 拥有draw()和erase()两个方法 * - 基于Shape类创建Circle子类 * - 基于Shape类创建Square子类 * - 创建Shape类创建Triangle子类 * - 创建随机形状发生的类(不是子类) * - 定义公共类(测试类),创建Shape类的数组对象长度为10&#xff0c;并为对象数组赋值其内容C…

ARM_day8:基于iic总线的通信

一、IIC总线的基本概念&#xff1a; iic总线是一种带应答的同步的、串行、半双工的通信方式&#xff0c;支持一个主机对应多个从机。它有一根SCL&#xff08;时钟线&#xff09;和一根SDA&#xff08;数据线&#xff09;组成&#xff0c;由于只有一根数据线&#xff0c;所以它是…

Elasticsearch(1)

目录 115.elasticsearch是什么?基于Lucene的,那么为什么不直接使用Lucene呢? 116.ELK技术栈的常见应用场景? 117.ES索引模板是什么? 118.ES中索引的生命周期管理?

SnapGene Mac激活版 分子生物学软件

SnapGene Mac是一款功能全面、操作便捷的综合性分子生物学软件&#xff0c;专为Mac用户打造。它集成了DNA序列编辑、分析、可视化和团队协作等多种功能&#xff0c;为科研人员提供了一个高效、可靠的分子生物学研究工具。 SnapGene Mac激活版下载 在SnapGene Mac中&#xff0c;…

hcip实验5:ospf综合实验

实验拓扑&#xff1a; 实验目的&#xff1a; 1、R4为ISP&#xff0c;其上只配置IP地址&#xff1b;R4与其他所直连设备间均使用公有IP&#xff1b; 2、R3-R5、R6、R7为MGRE环境&#xff0c;R3为中心站点&#xff1b; 3、整个OSPF环境IP基于172.16.0.0/16划分&#xff1b;除了R…