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&…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
