齐齐哈尔建设网站,pc网站手机版开发,wordpress首页分类,建网站后如何运营文章目录 前言一、相关PID源码.c.h 二、如何使用1.创建变量2.初始化3.运算4.修改pid参数 总结 前言
本篇使用到的基于这个STM32CubeMX 直流电机PID速度控制、HAL库、cubemx、PID、速度控制、增量式 由于上次使用的pid没有模块化#xff0c;当多出使用pid的时候就会很麻烦 所以… 文章目录 前言一、相关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);
}总结
简述一下不喜勿喷谢谢。