PID模块化__以stm32直流电机速度为例
文章目录
- 前言
- 一、相关PID源码
- .c
- .h
- 二、如何使用
- 1.创建变量
- 2.初始化
- 3.运算
- 4.修改pid参数
- 总结
前言
本篇使用到的基于这个STM32CubeMX 直流电机PID速度控制、HAL库、cubemx、PID、速度控制、增量式
由于上次使用的pid没有模块化,当多出使用pid的时候就会很麻烦
所以这次使用的模块化的
一、相关PID源码
.c
/* 包含头文件 ----------------------------------------------------------------*/
#include "pid.h"/* 私有类型定义 --------------------------------------------------------------*/
/* 私有宏定义 ----------------------------------------------------------------*/
/* 私有变量 ------------------------------------------------------------------*/
/* 扩展变量 ------------------------------------------------------------------*/
/* 私有函数原形 --------------------------------------------------------------*/
/* 函数体 --------------------------------------------------------------------*/
void abs_limit(float *a, float ABS_MAX)// 对输入 a 进行限制,使其在 [-ABS_MAX, ABS_MAX] 区间内
{if (*a > ABS_MAX)*a = ABS_MAX;if (*a < -ABS_MAX)*a = -ABS_MAX;
}// 初始化 PID 参数
static void pid_param_init(pid_t* pid, // PID 控制器结构体uint32_t mode, // PID 控制器模式uint32_t maxout, // PID 控制器输出最大值uint32_t intergral_limit, // PID 控制器积分限制float kp, // PID 控制器 P 项系数float ki, // PID 控制器 I 项系数float kd) // PID 控制器 D 项系数
{pid->integral_limit = intergral_limit;pid->max_out = maxout;pid->pid_mode = mode;pid->p = kp;pid->i = ki;pid->d = kd;}
/*** @brief modify pid parameter when code running* @param[in] pid: control pid struct* @param[in] p/i/d: pid parameter* @retval none*/
static void pid_reset(pid_t *pid, float kp, float ki, float kd)// 重置 PID 控制器的参数
{pid->p = kp;pid->i = ki;pid->d = kd;pid->pout = 0;pid->iout = 0;pid->dout = 0;pid->out = 0;}/*** @brief calculate delta PID and position PID* @param[in] pid: control pid struct* @param[in] get: measure feedback value* @param[in] set: target value* @retval pid calculate output */
float pid_calc(pid_t *pid, float get, float set)// 计算 PID 控制器的输出
{pid->get = get;pid->set = set;pid->err[NOW] = set - get;if ((pid->input_max_err != 0) && (pid->err[NOW] > pid->input_max_err))pid->err[NOW] = pid->input_max_err;if ((pid->input_min_err != 0) && (pid->err[NOW] < pid->input_min_err))pid->err[NOW] = pid->input_min_err;if (pid->pid_mode == POSITION_PID) //position PID// 位置式 PID 控制器{pid->pout = pid->p * pid->err[NOW];pid->iout += pid->i * pid->err[NOW];pid->dout = pid->d * (pid->err[NOW] - pid->err[LAST]);abs_limit(&(pid->iout), pid->integral_limit);pid->out = pid->pout + pid->iout + pid->dout;abs_limit(&(pid->out), pid->max_out);}else if (pid->pid_mode == DELTA_PID) //delta PID// 增量式 PID 控制器{pid->pout = pid->p * (pid->err[NOW] - pid->err[LAST]);pid->iout = pid->i * pid->err[NOW];pid->dout = pid->d * (pid->err[NOW] - 2 * pid->err[LAST] + pid->err[LLAST]);pid->out += pid->pout + pid->iout + pid->dout;abs_limit(&(pid->out), pid->max_out);}pid->err[LLAST] = pid->err[LAST];pid->err[LAST] = pid->err[NOW];if ((pid->output_deadband != 0) && (fabs(pid->out) < pid->output_deadband))return 0;elsereturn pid->out;}
void pid_ClearIntegrals(pid_t* pid)// 清除积分项
{pid->pout = 0;pid->iout = 0;pid->dout = 0;pid->out = 0;
}
/*** @brief initialize pid parameter* @retval none*/
void PID_struct_init( // 初始化 PID 结构体pid_t* pid,uint32_t mode,uint32_t maxout,uint32_t intergral_limit,float kp,float ki,float kd)
{pid->f_param_init = pid_param_init;pid->f_pid_reset = pid_reset;pid->f_pid_calc = pid_calc;pid->f_pid_ClearIntegrals = pid_ClearIntegrals;pid->f_param_init(pid, mode, maxout, intergral_limit, kp, ki, kd);pid->f_pid_reset(pid, kp, ki, kd);
}
.h
#ifndef __PID_H__
#define __PID_H__/* 包含头文件 ----------------------------------------------------------------*/
#include "stdint.h"
#include "math.h"
/* 类型定义 ------------------------------------------------------------------*/
enum
{LLAST = 0,LAST,NOW,POSITION_PID,DELTA_PID,
};
typedef struct pid_t
{float p;float i;float d;float set;float get;float err[3];float pout;float iout;float dout;float out;float input_max_err; //input max err;float input_min_err; //input max err;float output_deadband; //output deadband;uint32_t pid_mode;uint32_t max_out;uint32_t integral_limit;void (*f_param_init)(struct pid_t *pid, uint32_t pid_mode,uint32_t max_output,uint32_t inte_limit,float p,float i,float d);void (*f_pid_reset)(struct pid_t *pid, float p, float i, float d);float (*f_pid_calc)(struct pid_t *pid, float get, float set);void (*f_pid_ClearIntegrals)(struct pid_t* pid);
} pid_t;
/* 宏定义 --------------------------------------------------------------------*/
/* 扩展变量 ------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/
void PID_struct_init(pid_t* pid,uint32_t mode,uint32_t maxout,uint32_t intergral_limit,float kp,float ki,float kd);
float pid_calc(pid_t *pid, float get, float set);
#endif // __PID_H__
二、如何使用
1.创建变量
在main.c或者其他位置创建pid的变量
pid_t a_moto_pid;
pid_t b_moto_pid;
2.初始化
注意一定要在pid计算之前初始化all_moto_pid_init,不然会导致stm32硬件错误!!!!
void all_moto_pid_init(void)
{PID_struct_init(&a_moto_pid, // PID 控制器对象DELTA_PID, // 控制器模式7500, // 输出最大值0, // 积分限制45.0f, // P 项系数25.0f, // I 项系数0.0f // D 项系数);PID_struct_init(&b_moto_pid, // PID 控制器对象DELTA_PID, // 控制器模式7500, // 输出最大值0, // 积分限制45.0f, // P 项系数25.0f, // I 项系数0.0f // D 项系数); }
3.运算
int a_moto_pid_calc(float current_value,float target_value)/*current_value当前值target_value目标值*/
{
// 使用 PID 控制器计算控制输出int control_output = a_moto_pid.f_pid_calc(&a_moto_pid, current_value, target_value); return control_output;
}
int b_moto_pid_calc(float current_value,float target_value)/*current_value当前值target_value目标值*/
{
// 使用 PID 控制器计算控制输出int control_output = b_moto_pid.f_pid_calc(&b_moto_pid, current_value, target_value); return control_output;
}
4.修改pid参数
/*
修改pid的值
*/
void angle_pid_set(float p,float i ,float d )
{angle_pid.f_pid_reset(&angle_pid, p, i, d);
}
总结
简述一下,不喜勿喷谢谢。
相关文章:
PID模块化__以stm32直流电机速度为例
文章目录 前言一、相关PID源码.c.h 二、如何使用1.创建变量2.初始化3.运算4.修改pid参数 总结 前言 本篇使用到的基于这个STM32CubeMX 直流电机PID速度控制、HAL库、cubemx、PID、速度控制、增量式 由于上次使用的pid没有模块化,当多出使用pid的时候就会很麻烦 所以…...
Java ~ Collection/Executor ~ DelayQueue【总结】
前言 文章 相关系列:《Java ~ Collection【目录】》(持续更新)相关系列:《Java ~ Executor【目录】》(持续更新)相关系列:《Java ~ Collection/Executor ~ DelayQueue【源码】》(学…...
前端高级面试题-安全相关
1 XSS 跨⽹站指令码(英语: Cross-site scripting ,通常简称为: XSS )是⼀种⽹站应⽤程式的安全漏洞攻击,是代码注⼊的⼀种。 它允许恶意使⽤者将程式码注⼊到⽹⻚上,其他使⽤者在观看⽹⻚时就会…...
【前缀和】560.和为 K 的子数组
Halo,这里是Ppeua。平时主要更新C,数据结构算法,Linux与ROS…感兴趣就关注我bua! 和为K的子数组 题目:示例:题解:解法一:解法二: 题目: 示例: 题解: 解法一: 暴力解法:我们很容易想到通过两个for循环去遍…...
【Docker】安全及日志管理
安全及日志管理 Docker 安全及日志管理一:Docker 容器与虚拟机的区别1. 隔离与共享2. 性能与损耗 二:Docker 存在的安全问题1.Docker 自身漏洞2.Docker 源码问题 三:Docker 架构缺陷与安全机制1. 容器之间的局域网攻击2. DDoS 攻击耗尽资源3.…...
基于x-scan扫描线的3D模型渲染算法
基于x-scan算法实现的z-buffer染色。c#语言,.net core framework 3.1运行。 模型是读取3D Max的obj模型。 x-scan算法实现: public List<Vertex3> xscan() {List<Vertex3> results new List<Vertex3>();SurfaceFormula formula g…...
LeetCode36.Valid-Sudoku<有效的数独>
题目: 思路: 这题并不难,它类似于N皇后问题。在N皇后问题中,行,列,对角线,写对角线,都不能出现连续的皇后。 本题类似,不过他是行,列,还有一个B…...
Linux中的pause函数
2023年7月29日,周六上午 函数原型 在Linux中,pause()函数用于使当前进程暂停执行,直到接收到一个信号。 #include <unistd.h>int pause(void);pause()函数不接受任何参数。 通常,pause()函数用于编写简单的信号处理程序&…...
CommonCollections6链分析
前面和CC1一样 优点是不限制jdk版本和cc的版本 先开一个ChainedTransformer 然后创LazyMap 我们顺便执行一下避免上面写错 能弹计算器 没问题 后面就是CC6不同的地方了 我们需要一个TiedMapEntry 因为需要一个类调用了get方法 在TiedMapEntry的getValue()方法中调用了get()…...
优化基于tcp,socket的ftp文件传输程序
原始程序: template_ftp_server_old.py: import socket import json import struct import os import time import pymysql.cursorssoc socket.socket(socket.AF_INET, socket.SOCK_STREAM) HOST 192.168.31.111 PORT 4101 soc.bind((HOST,PORT)) p…...
MySQL 数据库 【增删查改(二)】
目录 一、表的设计 1、一对一 2、一对多 3、多对多 二、新增 三、查询 1、聚合查询 (1)聚合函数: (2) group by 子句 (3)having 2、联合查询 (1)内连接 (2)外连接 (3)自链接 (4)…...
力扣 -- 978. 最长湍流子数组
一、题目 二、解题步骤 下面是用动态规划的思想解决这道题的过程,相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 三、参考代码 class Solution { public:int maxTurbulenceSize(vector<int>& nums) {int nnums.size();vector<int> f(n);…...
甘特图 Dhtmlx Gantt
介绍 在一些任务计划、日程进度等场景中我们会使用到甘特图,Dhtmlx Gantt 对于甘特图的实现支持很友好,文档API介绍全面,虽然增强版的收费,但免费版的足以够用。 官网:https://docs.dhtmlx.com/gantt/ 安装dhtml gannt…...
iOS 应用上架流程详解
iOS 应用上架流程详解 欢迎来到我的博客,今天我将为大家分享 iOS 应用上架的详细流程。在这个数字化时代,移动应用已经成为了人们生活中不可或缺的一部分,而 iOS 平台的 App Store 则是开发者们发布应用的主要渠道之一。因此,了解…...
Python入门【LEGB规则、面向对象简介、面向过程和面向对象思想、面向对象是什么? 对象的进化 、类的定义、对象完整内存结构 】(十三)
👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误…...
【消息中间件】原生PHP对接Uni H5、APP、微信小程序实时通讯消息服务
文章目录 视频演示效果前言一、分析二、全局注入MQTT连接1.引入库2.写入全局连接代码 二、PHP环境建立总结 视频演示效果 【uniapp】实现买定离手小游戏 前言 Mqtt不同环境问题太多,新手可以看下 《【MQTT】Esp32数据上传采集:最新mqtt插件(支…...
【C语言初阶】指针篇—上
目录 1. 指针是什么?2. 指针和指针类型2.1 指针-整数2.2 指针的解引用 3. 野指针3.1 野指针成因1. 指针未初始化2. 指针越界访问3. 指针指向的空间释放 3.2 如何规避野指针 1. 指针是什么? 指针是什么? 指针理解的2个要点: > 1…...
基于FasterRCNN深度学习网络的车辆检测算法matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心程序 ....................................................................... % 训练Faster R-…...
机器学习深度学习——多层感知机
👨🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——感知机 📚订阅专栏:机器学习&&深度学习 希望文章对你们有所帮助 上一节…...
Django模型将模型注释同步到数据库
1、安装django-comment-migrate库 pip install django-comment-migrate 2、将库注册到settings.py文件中 INSTALLED_APPS [...django_comment_migrate, # 表注释... ] 3、加注释 3.1、给模型(表)加注释 在模型的class Meta中编辑 verbose_name&…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
