当前位置: 首页 > news >正文

第三次PID状态机

以下是 apply_params 函数的实现步骤和代码示例:


1. 定义参数结构体

在头文件中定义 PID_Params 结构体,包含需要动态调整的 PID 参数:

// ms_hal_photo_sensor.h
typedef struct {float Kp;           // 比例系数float Ki;           // 积分系数(直接使用 Ki = Kp*T/Ti)float Kd;           // 微分系数(直接使用 Kd = Kp*Td/T)float T;            // 控制周期(单位:ms)float dead_zone;    // 死区阈值float max_delta;    // 单次最大输出变化量float output_alpha; // 输出平滑系数(0.0~1.0)
} PID_Params;

2. 定义预设参数集

在代码中预设不同场景的参数集合:

// ms_hal_photo_sensor1.c
// 快速跟踪参数(高响应速度)
static const PID_Params fast_params = {.Kp = 0.8,.Ki = 0.05,.Kd = 0.1,.T = 20,.dead_zone = 10,.max_delta = 20,.output_alpha = 0.2
};// 稳态参数(低噪声抑制)
static const PID_Params slow_params = {.Kp = 0.3,.Ki = 0.01,.Kd = 0.05,.T = 50,.dead_zone = 20,.max_delta = 5,.output_alpha = 0.5
};

3. 实现 apply_params 函数

编写函数将参数应用到全局 PID 控制结构体:

// ms_hal_photo_sensor1.c
/*** @brief 应用新的PID参数集* @param params PID参数结构体指针*/
void apply_params(const PID_Params* params) {if (params == NULL) {bk_printf("[ERROR] apply_params: NULL pointer!\r\n");return;}// 原子化更新参数(根据具体平台可能需要关中断)PID_Str_Val.Kp = params->Kp;PID_Str_Val.Ki = params->Ki;PID_Str_Val.Kd = params->Kd;PID_Str_Val.T = params->T;PID_Str_Val.dead_zone = params->dead_zone;PID_Str_Val.max_delta = params->max_delta;PID_Str_Val.output_alpha = params->output_alpha;// 重置误差历史(避免参数突变导致震荡)PID_Str_Val.En = 0;PID_Str_Val.En_1 = 0;PID_Str_Val.En_2 = 0;bk_printf("PID Params Updated: Kp=%.2f Ki=%.2f Kd=%.2f T=%.0fms\r\n", params->Kp, params->Ki, params->Kd, params->T);
}

4. 状态机集成

在定时器回调或控制循环中根据系统状态切换参数:

// ms_hal_photo_sensor1.c
typedef enum {PID_STATE_STEADY,     // 稳态PID_STATE_TRACKING    // 快速跟踪
} PID_State;static PID_State current_state = PID_STATE_STEADY;void photo_timer_handler(void) {// ...原有代码...// 动态切换参数逻辑static uint32_t error_integral = 0;error_integral += fabs(PID_Str_Val.En);// 每100ms评估一次状态static uint8_t eval_counter = 0;if (++eval_counter >= 5) { eval_counter = 0;if (error_integral > 1000) {  // 累计误差大,进入跟踪模式if (current_state != PID_STATE_TRACKING) {apply_params(&fast_params);current_state = PID_STATE_TRACKING;}} else {                      // 误差小,进入稳态模式if (current_state != PID_STATE_STEADY) {apply_params(&slow_params);current_state = PID_STATE_STEADY;}}error_integral = 0;  // 重置累计误差}
}

5. 关键点说明

  1. 原子化操作
    在实时系统中,更新 PID 参数时可能需要关闭中断,确保参数赋值操作的完整性。

  2. 状态切换逻辑
    示例中通过累计误差判断系统状态,实际可根据需求使用其他指标(如误差变化率)。

  3. 参数平滑过渡
    若需更平滑的切换,可对参数进行插值过渡(如线性渐变)。

  4. 参数校验
    可在 apply_params 中添加范围检查,防止非法值:

    if (params->Kp < 0 || params->Ki < 0 || params->Kd < 0) {bk_printf("[ERROR] Invalid PID parameters!\r\n");return;
    }
    

完整调用示例

// 手动触发参数切换测试
void test_switch_params(void) {if (current_state == PID_STATE_STEADY) {apply_params(&fast_params);current_state = PID_STATE_TRACKING;} else {apply_params(&slow_params);current_state = PID_STATE_STEADY;}
}

通过这种设计,PID 参数可以根据系统状态动态调整,在响应速度和稳定性之间取得平衡。

相关文章:

第三次PID状态机

以下是 apply_params 函数的实现步骤和代码示例&#xff1a; 1. 定义参数结构体 在头文件中定义 PID_Params 结构体&#xff0c;包含需要动态调整的 PID 参数&#xff1a; // ms_hal_photo_sensor.h typedef struct {float Kp; // 比例系数float Ki; // …...

如何在大型项目中有效使用TypeScript进行类型定义?

嗨&#xff0c;大家好&#xff0c;我是莫循&#xff0c;Typescript是JavaScript的超集&#xff0c;现在已经广泛用于前端开发&#xff0c;那么在项目中如何用好类型定义呢&#xff1f;以下是一些可以提供参考的案例实践。 一、类型组织策略 1. 模块化类型定义 按功能/模块划分…...

C4D XP 粒子动画云端渲染指南

在 C4D 动画制作领域&#xff0c;XP 粒子特效因其复杂的动力学计算常成为渲染瓶颈。传统本地渲染不仅耗时漫长&#xff0c;还需持续占用高配置硬件。而借助专业云渲染平台&#xff0c;创作者可突破物理限制&#xff0c;高效完成 XP 粒子动画的最终输出。 以渲染 101 平台为例&a…...

mysql知识总结 基础篇

Mysql知识总结 1. 执行一条sql语句 期间发生了什么&#xff1f;1. 如何查看mysql服务被多少个客户端链接了2. 空闲链接会一直闲置嘛&#xff1f;3. mysql的链接数量有限制嘛&#xff1f;4. 我们如何知道mysql要使用哪个索引5. 什么是覆盖索引 2. MySQL 一行记录是怎么存储的&am…...

基于条码数据生成校验密码的C++实现方案

前言 在医疗试剂、工业产品等需要严格追踪管理的领域&#xff0c;条码系统常被用于标识产品信息。本文将详细介绍4种用C实现的条码密码生成算法&#xff0c;这些算法可以根据条码前11位数据生成2位校验密码&#xff08;第9、10位&#xff09;&#xff0c;用于数据校验或简单防…...

前端工具方法整理

文章目录 1.在数组中找到匹配项&#xff0c;然后创建新对象2.对象转JSON字符串3.JSON字符串转JSON对象4.有个响应式对象&#xff0c;然后想清空所有属性5.判断参数不为空6.格式化字符串7.解析数组内容用逗号拼接 1.在数组中找到匹配项&#xff0c;然后创建新对象 const modifi…...

[数据结构]图krusakl算法实现

目录 Kruskal算法 Kruskal算法 我们要在连通图中去找生成树 连通图&#xff1a;在无向图中&#xff0c;若从顶点v1到顶点v2有路径&#xff0c;则称顶点v1与顶点v2是连通的。如果图中任意一对顶点都是连通的&#xff0c;则称此图为连通图。 生成树&#xff1a;一个连通图的最小…...

18-产品经理-跟踪进度

禅道是一个可以帮助产品经理跟踪研发进度的系统。通过禅道&#xff0c;产品经理可以从多个角度了解产品的研发状态。在仪表盘中&#xff0c;可以展示所有产品或单一产品的概况&#xff0c;包括需求、计划和发布数量&#xff0c;研发需求状态&#xff0c;Bug修复率和计划发布数。…...

华为机试—挑7

题目 你需要统计 1 到 n 之间与 7 有关的数字的个数。 与 7 有关的数字包括&#xff1a; 是 7 的倍数&#xff08;如 7,14,21 等&#xff09;&#xff1b;包含数字 7&#xff08;如 17,27,37,⋯ ,70,71,72,⋯等&#xff09;。 示例 输入&#xff1a;20 输出&#xff1a;3 说…...

【区块链安全 | 第三十四篇】合约审计之重入漏洞

文章目录 概念漏洞代码代码审计攻击代码攻击过程总结示例修复建议审计思路 概念 以太坊的智能合约可以互相调用&#xff0c;也就是说&#xff0c;一个合约可以调用另一个合约的函数。除了外部账户&#xff0c;合约本身也可以持有以太币并进行转账。当合约接收到以太币时&#…...

Java虚拟机——JVM(Java Virtual Machine)解析一

1.JVM是什么&#xff1f; 1.1 JVM概念 Java Virtual Machine (JVM) 是JDK的核心组件之一&#xff0c;它使得 Java 程序能够在任何支持 JVM 的设备或操作系统上运行&#xff0c;而无需修改源代码 JDK是什么&#xff0c;JDK和JVM是什么关系&#xff1f;1.Java IDE(Integrated …...

【JVM】question

问题 JVM线程是用户态还是内核态 java线程在jdk1.2之前&#xff0c;是基于名为“绿色线程”的用户线程实现的&#xff0c;这导致绿色线程只能同主线程共享CPU分片&#xff0c;从而无法利用多核CPU的优势。 由于绿色线程和原生线程比起来在使用时有一些限制&#xff0c; jdk1.2…...

页面编辑器CodeMirror初始化不显示行号或文本内容

延迟刷新 本来想延迟100毫秒的&#xff0c;但是会出现样式向左偏移的情况&#xff0c;于是试了试500毫秒&#xff0c;发现就没有问题了&#xff0c;可能是样式什么是需要一个加载过程吧。 useEffect(() > {editorRef.current?.setValue(value || );setTimeout(() > {edi…...

顺序表——C语言实现

目录 一、线性表 二、顺序表 1.实现动态顺序表 SeqList.h SeqList.c Test.c 问题 经验&#xff1a;free 出问题&#xff0c;2种可能性 解决问题 &#xff08;2&#xff09;尾删 &#xff08;3&#xff09;头插&#xff0c;头删 &#xff08;4&#xff09;在 pos 位…...

OpenCV 图形API(21)逐像素操作

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在OpenCV的G-API模块中&#xff0c;逐像素操作指的是对图像中的每个像素单独进行处理的操作。这些操作可以通过G-API的计算图&#xff08;Graph …...

车载联网终端4G汽车TBOX介绍定义与概述

汽车 TBOX&#xff08;Telematics Box&#xff09;是专为汽车设计的远程通信终端设备&#xff0c;属于车联网系统的关键组成部分。车联网系统一般包含主机、汽车 T - BOX、手机 APP 及后台系统。融合了车身网络和 4G 无线通信技术&#xff0c;为汽车提供丰富的 Telematics 服务…...

CentOS无法安装Vim文本编辑器问题以及解决方法

1.问题一&#xff1a;用户权限不够 解决方法一&#xff1a;切换到root用户 解决方法二&#xff1a;给本用户添加权限 2.问题二&#xff1a;镜像源问题&#xff1a;官方镜像源可能已经失效 解决方法&#xff1a; 1. 检查网络连接 2. 检查和配置 DNS 3. 更换镜像源&#…...

Kettle如何与应用集成

Kettle&#xff08;Pentaho Data Integration&#xff0c;PDI&#xff09;可以通过多种方式与应用程序集成&#xff0c;以下是7种主流方法及具体实现示例&#xff1a; 一、命令行调用&#xff08;最基础&#xff09; # 执行转换&#xff08;Transformation&#xff09; ./pan.…...

Pytorch torch.nn.utils.rnn.pad_sequence 介绍

torch.nn.utils.rnn.pad_sequence 是 PyTorch 中一个用于填充序列的实用函数&#xff0c;它主要用于处理长度不一的序列数据&#xff0c;将这些序列填充到相同的长度&#xff0c;以便能将它们组合成一个批量&#xff08;batch&#xff09;输入到神经网络中。以下是详细介绍&…...

4.7正则表达式

1.字符匹配 一般字符匹配自身. 匹配任意字符(换行符\n除外),一个点占一位\转义字符&#xff0c;使其后一个字符改变原来的意思(\.就是.)[......]字符集,对应的位置可以是字符集中的任意字符.字符集中的字符可以逐个列出,也可以给出范围如[abc]或[a-c] [^abc] 表示取反&#xf…...

CogPatInspectTool工具

CogPatInspectTool是康耐视中的一种模板比对的视觉检测工具&#xff0c;主要用于产品不良检测。其核心功能是通过将输入图像与预先训练好的模板进行对比&#xff0c;识别出两者之间的差异&#xff0c;并生成高亮差异图&#xff0c;从而判断产品是否存在缺陷。 效果图 CogPatIn…...

牛客周赛 + 洛谷刷题

秘藏 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N 200010; ll a[N], b[N]; int n, k; ll dp[2][N];//dp[i][j]是在i界中取了j之前的最大值 int main(){ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);cin >> n >&…...

【数据结构】图论存储革新:十字链表双链设计高效解决有向图入度查询难题

十字链表 导读一、邻接表的优缺点二、十字链表2.1 结点结构2.2 原理解释2.2.1 顶点表2.2.2 边结点2.2.3 十字链表 三、存储结构四、算法评价4.1 时间复杂度4.2 空间复杂度 五、优势与劣势5.1 优势5.2 劣势5.3 特点 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff…...

【JavaScript】十五、事件对象与环境对象

文章目录 1、事件对象1.1 获取事件对象1.2 常用属性1.3 案例&#xff1a;回车发布评论 2、环境对象this3、回调函数4、案例&#xff1a;tab切换5、案例&#xff1a;全选文本框&#x1f4d6; 1、事件对象 事件对象&#xff1a; 也是个对象&#xff0c;object&#xff0c;里面存…...

OJ--第N个泰波那契数列

1137. 第 N 个泰波那契数 - 力扣&#xff08;LeetCode&#xff09; 1 题干部分 2 拆解 1 状态表示&#xff1a;dp[i] 2 状态转移方程:dp[i]dp[i-1]dp[i-2]dp[i-3] 3 初始化:让dp[0]0,dp[1]dp[2]1 4 填表顺序:从dp[3]开始填从左往右填 5 返回值&#xff1a;dp[n]即为返回的…...

Python从入门到高手8.1节-元组类型详解

目录 8.1.1 理解元组类型 8.1.2 元组的类型名 8.1.3 元组的定义 8.1.4 元组的解包 8.1.5 元组是可迭代的 8.1.6 假期就这么结束了 8.1.1 理解元组类型 元组与列表有着相同的数据结构&#xff0c;区别在于&#xff0c;元组是不可变的数据类型&#xff0c;而列表是可变的数…...

使用 Qt 和 OBS 工具检测系统硬件编码器支持情况(NVENC、QSV、AMF)

在开发涉及视频处理的软件时,判断系统是否支持硬件加速编码器(如 NVIDIA NVENC、Intel QSV、AMD AMF)对于性能优化至关重要。本文将介绍如何结合 Qt 与 OBS Studio 附带的小工具程序,实现一个完整、异步且不会卡住 UI 的硬件加速检测模块。 一、背景与目标 硬件加速编码器…...

Python爬虫生成CSV文件的完整流程

引言 在当今数据驱动的时代&#xff0c;网络爬虫已成为获取互联网数据的重要工具。Python凭借其丰富的库生态系统和简洁的语法&#xff0c;成为了爬虫开发的首选语言。本文将详细介绍使用Python爬虫从网页抓取数据并生成CSV文件的完整流程&#xff0c;包括环境准备、网页请求、…...

图论:多源最短路

多源最短路 B3647 【模板】Floyd - 洛谷 #include<iostream> #include<cstring> using namespace std;const int N 110; int f[N][N]; int n, m;int main() {memset(f, 0x3f, sizeof(f));//对于重边的处理取较小值&#xff0c;所以要把全部都初始化成无穷大&…...

2024年已备案大模型发展趋势分析

2024年已备案大模型发展趋势分析 随着生成式人工智能技术的快速发展,其在各个领域的应用逐渐深入。为了规范和促进生成式人工智能服务的健康发展,国家互联网信息办公室发布了《生成式人工智能服务已备案信息》。本文将基于已备案信息,分析生成式人工智能服务的发展趋势,并…...

spring功能汇总

1.创建一个dao接口&#xff0c;实现类&#xff1b;service接口&#xff0c;实现类并且service里用new创建对象方式调用dao的方法 2.使用spring分别获取dao和service对象(IOC) 注意 2中的service里面获取dao的对象方式不用new的(DI) 运行测试&#xff1a; 使用1的方式创建servic…...

Transformer - Feed Forward前馈网络

一、数学原理 1. 前馈神经网络公式 2. Dropout公式 二、代码实现 import math import torchimport torch.nn as nnclass FeedForward(nn.Module):def __init__(self, d_model, dff, dropout):super().__init__()self.W1 nn.Linear(d_model, dff)self.W2 nn.Linear(dff, d_mo…...

Compose Multiplatform+Kotlin Multiplatfrom 第五弹跨平台 截图

截图功能 Compose MultiplatformKotlin Multiplatfrom下实现桌面端的截图功能&#xff0c;起码搞了两星期&#xff0c;最后终于做出来了&#xff0c;操作都很流畅&#xff0c;截取的文件大小也正常&#xff0c;可参考支持讨论&#xff01; 功能效果 代码实现 //在jvmMain下创…...

算法题(119):高精度减法

审题&#xff1a; 本题高精度减法主要是要区分正负号&#xff0c;然后进行模拟 思路&#xff1a; 方法一&#xff1a;模拟法 首先本题需要我们利用字符串进行大数相减 第一步&#xff1a;区分s1和s2谁更大 先从数的位数进行判断&#xff0c;然后再从高到低的位数进行判断 第二步…...

使用成员函数指针数组简化C++类中的操作

使用成员函数指针数组简化C类中的操作 在C编程中&#xff0c;我们常常会遇到需要对一组相似的操作进行处理的情况。例如&#xff0c;在一个游戏引擎中&#xff0c;你可能希望角色能够执行一系列的动作&#xff0c;如行走、跳跃或攻击等。为了简化这些操作的管理和调用&#xf…...

WebGL数学手记:矩阵基础

一、矩阵的定义 矩阵&#xff0c;数学术语。在数学中&#xff0c;矩阵&#xff08;Matrix&#xff09;是一个按照长方阵列排列的复数或实数集合。 1.英文发音&#xff08;Matrix&#xff09; Matrix的发音类似于中文的[美吹克斯]&#xff0c;知道它的发音。方便后期看教程时…...

Python爬取数据(二)

一.example2包下的 1.re模块的compile函数使用 import repatternre.compile(r\d) print(pattern) 2.match的方法使用 import re patternre.compile(r\d) # m1pattern.match(one123twothree345four) #参数2&#xff1a;指定起始位置(包含),参数3&#xff1a;终止位置(包含),…...

我的NISP二级之路-01

目录 一.SSE-CMM系统安全工程-能力成熟度模型(Systems Security Engineering - Capability Maturity Model) 二.ISMS 即信息安全管理体系(Information Security Management System),是一种基于风险管理的、系统化的管理体系 三.Kerberos协议 1. 用户登录与 AS 请求 2…...

自制简易 Shell:像搭建积木小屋一样打造命令交互小天地

目录 准备工作&#xff1a;搭建小屋的材料 打造小屋的 “身份牌” 接收指令&#xff1a;小屋的 “对讲机” 拆解指令&#xff1a;把大任务拆成小积木 执行指令&#xff1a;小屋的 “行动队” 特殊指令&#xff1a;小屋的 “特色功能” 小屋的日常运转 完整代码 啥是 …...

WEB安全--内网渗透--利用Net-NTLMv2 Hash

一、前言 在前两篇文章中分析了NTLM协议中Net-NTLMv2 Hash的生成、如何捕获Net-NTLMv2 Hash&#xff0c;现在就来探讨一下在内网环境中&#xff0c;如何利用Net-NTLMv2 Hash进行渗透。 二、Net-NTLM Hash的破解 工具&#xff1a;hashcat 原理&#xff1a;利用其内部的字典对…...

MySQL 数据库操作指南:从数据库创建到数据操作

关键词&#xff1a;MySQL&#xff1b;数据库操作&#xff1b;DDL&#xff1b;DML 一、引言 MySQL 作为广泛应用的关系型数据库管理系统&#xff0c;对于开发人员和数据库管理员而言&#xff0c;熟练掌握其操作至关重要。本文章通过一系列 SQL 示例&#xff0c;详细阐述 MySQL…...

从传递函数到PID控制器

在过程控制中&#xff0c;按偏差的比例&#xff08;P&#xff0c;Proportional&#xff09;、积分&#xff08;I&#xff0c;Integral&#xff09;和微分&#xff08;D&#xff0c;Differential&#xff09;进行控制的PID控制器&#xff08;亦称PID调节器&#xff09;是应用最为…...

抓wifi无线空口包之Ubuntu抓包(二)

一、设置网卡信道和频段&#xff0c;并抓包 1、使用iwconfig查看自己机器的无线网卡名称 wangwang-ThinkCentre-M930t-N000:~$ iwconfig lo no wireless extensions. eno1 no wireless extensions. enxc8a3624ab329 no wireless extensions. wlx90de80d1b5b1 IE…...

使用protobuf编译提示无法打开包括文件: ‘absl/log/absl_log.h’: No such file or directory

问题原因 Protobuf 依赖 Abseil&#xff1a; Protobuf 3.20 版本开始依赖 Abseil&#xff0c;但你的系统未正确安装或配置 Abseil。 头文件路径未包含&#xff1a; 编译器找不到 absl/log/absl_log.h&#xff0c;可能是因为 Abseil 未正确安装或未在项目中设置包含路径。 …...

深入浅出Java 锁 | 源码剖析 | 万字解析

目录 硬件内存结构&Java内存模型 硬件内存结构 Java内存模型&#xff08;JMM&#xff09; JMM中三大特性&#xff1a;原子性、有序性、可见性 Java中有哪些锁&#xff1f; Java中锁可以分成悲观锁和乐观锁的实现。 乐观锁和悲观锁的区别&#xff0c;乐观锁一定好嘛&…...

java流程控制12:流程控制练习

流程控制练习 打印三角型 package com.zheng.struct;public class TestDemo {public static void main(String[] args) {//打印三角形 5行for(int i1;i<5;i){for(int j5;j>i;j--){System.out.print(" ");}for(int j1;j<i;j){System.out.print("*&quo…...

JAVA:ByteBuddy 动态字节码操作库的技术指南

1、简述 ByteBuddy 是一个功能强大的 Java 字节码操作库&#xff0c;可以帮助开发者在运行时动态生成和修改类&#xff0c;而无需直接接触复杂的 ASM API。它被广泛应用于框架开发、AOP&#xff08;面向切面编程&#xff09;、代理类生成、性能监控等领域。 2、ByteBuddy 的优…...

C语言学习记录(13)自定义类型:结构体

一、结构体变量的声明、创建和初始化 1.结构体变量的声明 结构体变量我们学操作符的时候就顺带讲了一点了&#xff0c;因为当时讲了结构体成员变量访问操作符.。 结构体变量不像int、float这种内置类型的&#xff0c;一旦创建&#xff0c;系统就知道这是干啥的&#xff0c;结…...

rtthread 软件SPI驱动, 支持mode0~3,MSB,LSB

rtthread的软件模拟SPI用的上层PIN驱动写&#xff0c;由于经过层层封装&#xff0c;时钟频率并不会太高&#xff0c;200MHz的MCU跑不到1MHz的时钟频率。所以最好是在底层就模拟好&#xff0c;给上层用。 头文件 struct io_poSOFT {gpio_type *port;uint16_t pin; }; typedef …...

C++自学笔记——动态创建对象

动态创建对象 1. 什么是动态创建对象&#xff1f; 在学习之前的知识点时&#xff0c;我们知道有静态存储期和自动存储期。 静态存储期的对象在程序的整个生命周期内都存在&#xff0c;全局变量和static修饰的局部变量都属于这一类。自动存储期的对象&#xff0c;这些对象在函…...