VOFA+ :PID速度环调参

VOFA+ :PID速度环调参

一、PID

PID是一种常见的反馈控制系统,广泛应用于工业控制、自动化和机器人等领域。PID控制器基于当前系统的误差(偏差)、积分(偏差的累积)和微分(偏差的变化率)来调整控制输出,以使系统的实际输出尽可能接近期望值或设定点。

这里是PID的三个组成部分:

  1. 比例(Proportional, P):该部分产生一个输出,与当前误差成比例。增加比例增益(P增益)会增加系统对误差的敏感度,但可能导致系统过冲或振荡。
  2. 积分(Integral, I):该部分根据时间对误差的积累来产生一个输出。它可以用来消除静态误差,即使系统有漂移或存在持续偏差。
  3. 微分(Derivative, D):该部分根据误差变化率来产生一个输出。它可以减少系统的超调,并改善系统的动态响应,但过大的D增益可能导致系统过于敏感,产生噪声或抖动。

PID控制器的输出是这三个部分的加权和,通常用以下公式表示:
O u t p u t = K p ∗ e r r o r + K i ∗ ∫ e r r o r d t + K d ∗ d ( e r r o r ) / d t Output = Kp * error + Ki * ∫error dt + Kd * d(error)/dt Output=Kperror+Kierrordt+Kdd(error)/dt
其中, K p 、 K I 、 K D K_p、K_I、K_D KpKIKD分别是比例、积分和微分的增益(参数),error表示期望值与实际值之间的偏差。

PID控制器的参数调整通常是一个挑战,需要根据具体的应用和系统特性进行调整。常见的方法包括手动调节、试错法、自动调节算法等。

img

这里对PID原理的介绍可以参考:一文读懂PID控制算法(抛弃公式,从原理上真正理解PID控制)

二、代码部分

PID有位置式和增量式的PID:

1.位置式PID

#define INTEGRAL_MAX 1000
#define OUTPUTVAL_MAX 1000
typedef struct
{
    float targetVal;//目标值
    float error;//误差
    float lastError;//上次误差
    float P;
    float I;
    float D;
    float integral;//积分项
    float outPutVal;//输出
}PID;

uint16_t getPlacePIDVal(float nowVal,PID *pid)
{
   
    pid->error = pid->targetVal - nowVal;
    //积分限幅
    if (fabs(pid->integral) < INTEGRAL_MAX) 
    {
    pid->integral += pid->error;
    }
    pid->outPutVal += (pid->P * pid->error + pid->I * pid->integral + pid->D * (pid->error - pid->oldError));
    //输出限幅
    pid->outPutVal = (pid->outPutVal > OUTPUTVAL_MAX) ? OUTPUTVAL_MAX : pid->outPutVal;
    pid->oldError = pid->error;
    return pid->outPutVal;
}

2.增量式PI

#define OUTPUTVAL_MAX 1000
typedef struct
{
    float targetVal;//目标值
    float error;//误差
    float lastError;//上次误差
    float P;
    float I;
    float outPutVal;//输出
}PID;

uint16_t getIncrementPIDVal(float nowVal,PID *pid)
{
    pid->error = pid->targetVal - nowVal;
    pid->outPutVal += (float)(pid->P * (pid->error - pid->oldError)  + pid->I * pid->error);
    //输出限制
    pid->outPutVal = (pid->outPutVal > OUTPUTVAL_MAX) ? OUTPUTVAL_MAX : pid->outPutVal;
    pid->oldError = pid->error;
    return pid->outPutVal;
}


这里速度环我选择使用增量式PI来控制

三、VOFA+

下载地址

简单地来说,VOFA+是一个超级串口助手,除了可以实现一般串口助手的串口数据收发,它还可以实现数据绘图(包括直方图、FFT图),控件编辑,图像显示等功能。使用VOFA+,可以给我们平常的PID调参等调试带来方便,还可以自己制作符合自己要求的上位机,为嵌入式开发带来方便。

怎么使用呢?可以简单的的阅读一下官网的手册

手册

这里我们选择使用FireWater模式

image-20240127220205625

控制布局如上

因为我们PID的参数一般是浮点型,需要用四个字节来表示,我参考了很多文章发现大家都是换算得到的,这里我推荐使用c语言的库函数sscanf()在串口所收集到的数组里面读取,这里参考一下我的命令格式

image-20240127220128848

代码如下:

#include "cs_vofa.h"
#define CMD_MAX 10
char cmd[CMD_MAX];
float parameter;

void messageSetPID(char * str)
{
    if(sscanf(str,"%4s%f",cmd,&parameter) != 2) return;
    if(cmd[0] == 'R')
    {
        if(cmd[1] != '_' || cmd[3] != '=') return;
        if(cmd[2] == 'P')
        {
            R_PID.P = parameter;
        }
        else if(cmd[2] == 'I')
        {
            R_PID.I= parameter;
        }
        else if(cmd[2] == 'D')
        {
            R_PID.D= parameter;
        }
        else if(cmd[2] == 'T')
        {
            R_PID.targetVal = parameter;
        }
    }
    else if(cmd[0] == 'L')
    {
       if(cmd[1] != '_' || cmd[3] != '=') return;
        if(cmd[2] == 'P')
        {
            L_PID.P = parameter;
        }
        else if(cmd[2] == 'I')
        {
            L_PID.I= parameter;
        }
        else if(cmd[2] == 'D')
        {
            L_PID.D= parameter;
        } 
        else if(cmd[2] == 'T')
        {
            L_PID.targetVal = parameter;
        }
    }
}

上面是处理VOFA所的命令

那么怎么把下位置的数据发给VOFA,VOFA做出波形图呢?

这边其实很简单,我们采用FireWater模式

image-20240127220103809

所以我们只需要把对应的速度以上面格式发送就行。

四、效果

image-20240126205509787
资源下载:百度网盘

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值