精华内容
下载资源
问答
  • 串级PID

    2020-02-10 19:48:27
    串级pid简介 串级pid内外两环并联调节,这样的好处的是增加系统的稳定性,抗干扰。同时调节系统缓慢过度,注意外环都是本身误差,内环是速度,如位置控制外环是位置,内环是速度,是因为位置改变的实现是靠三个方向...

    串级pid简介
    串级pid内外两环并联调节,这样的好处的是增加系统的稳定性,抗干扰。同时调节系统缓慢过度,注意外环都是本身误差,内环是速度,如位置控制外环是位置,内环是速度,是因为位置改变的实现是靠三个方向的速度积分出来的。同样姿态控制中,外环是角度差,内环是加速度,是因为角度的实现是靠角速度过渡来的,他们都是这样的一个过渡过程。实际中如果你追求响应的快捷,你也可以直接控制内环,或者直接控制姿态。
    串级PID两个PID控制算法,只不过把他们串起来了(更精确的说是套起来)。那这么做有什么用?答案是,它增强了系统的抗干扰性(也就是增强稳定性),因为有两个控制器控制飞行器,它会比单个控制器控制更多的变量,使得飞行器的适应能力更强。画出串级PID的原理框图
    在这里插入图片描述
    在整定串级PID时的经验则是:先整定内环PID,再整定外环P。因为内环靠近输出,效果直接。
    现在用伺服电机为例,一起理解一下PID串级控制。
    伺服电机一般为三个环控制,所谓三环就是3个闭环负反馈PID调节系统。
    最内的PID环就是电流环,此环完全在伺服驱动器内部进行,通过霍尔装置检测驱动器给电机的各相的输出电流,负反馈给电流的设定进行PID调节,从而达到输出电流尽量接近等于设定电流,电流环就是控制电机转矩的,所以在转矩模式下驱动器的运算最小,动态响应最快。所以对电流控制即可实现电机转矩控制,此时PID为单回路PID控制。输入信号为目标电流,输出转矩,反馈信号为实时电流。

    第2环是速度环,通过检测的电机编码器的信号来进行负反馈PID调节,它的环内PID输出直接就是电流环的设定,所以速度环控制时就包含了速度环和电流环,换句话说任何模式都必须使用电流环,电流环是控制的根本,在速度和位置控制的同时系统实际也在进行电流(转矩)的控制以达到对速度和位置的相应控制。

    输入信号为目标速度 -->(电流闭环)–>反馈实时速度
    注意: FUN_PID(目标速度 - 反馈实时速度) 作为目标电流 ,传递给内环的电流闭环

    第3环是位置环,它是最外环,可以在驱动器和电机编码器间构建也可以在外部控制器和电机编码器或最终负载间构建,要根据实际情况来定。由于位置控制环内部输出就是速度环的设定,位置控制模式下系统进行了所有3个环的运算,此时的系统运算量最大,动态响应速度也最慢。 目标位置 --> (速度闭环) --> 反馈实时位置

    注意: FUN_PID(目标位置 - 反馈实时位置) 作为目标速度 ,传递给内环的速度闭环

    对于电流和速度,需要给定最大和最小速度,最大和最小电流,实际使用时还有做进一步优化和调整。

    摘录自:https://blog.csdn.net/Terrys0518/article/details/80770447
    https://blog.csdn.net/Gen_Ye/article/details/52534609

    展开全文
  • matlab串级PID仿真模型-串级PID.rar 可直接运行
  • 答应为实验室的同学做一次简单的关于串级PID的介绍,主要从感性认识串级PID的结构与作用切入,因此笔者尽量避免引入公式及其推导,因为这些推导在各类控制类书籍与相关论文中均有介绍,我就不再班门弄斧了。...

    答应为实验室的同学做一次简单的关于串级PID的介绍,主要从感性认识串级PID的结构与作用切入,因此笔者尽量避免引入公式及其推导,因为这些推导在各类控制类书籍与相关论文中均有介绍,我就不再班门弄斧了。

    本文假设读者已有单级PID控制的基础,对于PID的原理不做描述。


     

    假设我们需要解决这样一个问题:

    控制小车从当走到红色标签位置,设小车实时位置为x0(t)

     

    如果我们使用单级PID,运动框图应该如下图所示:

    误差e来自小车当前位置与目标位置的差值,即 e = x1 - x0;

    误差e经过PID算法得到输出小车给定速度v;

    小车给定速度v经过建立的电机小车模型传递函数(实际上是一个积分器,对速度积分即可得到位移),得到小车的当前位置x0;

    选取一组合适的PID参数,我们就可以很好的实现这个任务。根据不同的要求,我们可以找到不同的PID参数以实现快速收敛控制,或者无超调控制。

    但是现在考虑这样一个情况:

    小车所在的路面与水平面存在一个非零的夹角θ:

    现在如果我们还拿之前的PID参数去解决这个问题,我们可能就会发现小车的运行情况没有之前那么理想了,可能会出现但不限于收敛速度变慢无超调控制的PID参数出现超调小车在目的地附近振荡等情况。

    这是为什么呢,我们仔细看一下之前框图里的执行环节Motors-Car,把它打开看一下:

    我们发现,真正的积分器环节是Car,而积分器环节Car的真正输入是v';

    v恒等于v'吗?换言之,我叫小车电机以v的速度运行,他会立刻响应并保持在这一速度吗?答案显然是否定的:

    v'与v不完全一致,这就是原有的单级PID控制算法出现问题的原因,我们实际供给电机的是电压,一定的电压对应一定的转速v,然而电机转速v不是关于电压的单值函数电机转速v受到很多条件的影响,鉴于电机模型复杂且对于不同种类的电机模型也不尽相似,我们只讨论其中的另一个主要变量:负载转矩。当小车启动制动,走上坡道都会造成负载转矩的变化,从而进一步影响电机转速v

    如何解决?我们可以对电机Motors环节做一个转速闭环:

    这样就可以改善这个问题(注意是改善,不是解决!)

    有了这个闭环,就可以让电机的实际转速v'快速的跟踪给定速度v,至于有多快,还是要看电机模型和PID参数,但是一定比之前开环控制的效果要好。

    我们将这个改良的执行环节 Improved Motors-Car 替换原先单级PID运动框图中的执行环节Motors-Car,就可以得到这样一个串级PID的结构框图了:

    如此操作,在倾斜的坡道上,原来的参数也能较好的适应了。我们来看这个结构框图,里面有两个反馈箭头,也就形成了两个闭环,一个环在内,一个环在外。

    其中转速闭环称为串级PID的内环位置闭环称为串级PID的外环,现在去想象一下小车实际运行的情况,是不是能比较好的理解课本上 内环先稳定,外环后稳定的原因了?

     

     

     


    笔者希望这篇博文能够起到抛砖引玉的作用,让各位读者在之后系统学习串级PID的推导时更好的理解串级PID的思想。如果您觉得这篇博文有帮助,请您点下右上角的点赞,谢谢!

    展开全文
  • 串级PID仿真

    2017-05-13 21:59:10
    串级PID控制器Matlab仿真
  • PID介绍 PID调参 串级PID

    千次阅读 多人点赞 2019-06-19 13:44:38
    鉴于串级PID在pixhawk系统中的重要性,无论是误差的补偿,如姿态解算;还是控制的实现,如姿态控制,位置控制,靠的都是串级的pid,这里我们先对串级pid做一个介绍,后面会再接着分析,姿态的控制以及位置的解算和...

     鉴于串级PID在pixhawk系统中的重要性,无论是误差的补偿,如姿态解算;还是控制的实现,如姿态控制,位置控制,靠的都是串级的pid,这里我们先对串级pid做一个介绍,后面会再接着分析,姿态的控制以及位置的解算和控制。他们的分析都还将从原理框图和源码注释上说明,就是把自己平时的一点整理与大家交流一下,也希望大神能带我飞。

        这一部分说三部分内容:

         1、pid的介绍
         2、pid调参
         3、串级pid

         4、pid与滤波的关系,这也是一个很有意思的问题,一个是从控制角度理解,一个是从滤波角度理解。这一个我只是一点理解,就在这里先说一点。pid中,i相当于低通滤波器,极限情况下理解:直流信号肯定会持续积分,反而高频的噪声正负叠加被屏蔽了,所以i是低通滤波器。而D是高通滤波器,同样极限情况下理解:直流信号微分为0,高频的噪声微分却有了值,所以D是高通滤波器,和我们平时说到的D太大容易放大噪声造成震动等效。

         1、pid的介绍


        在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,简单的不是原始的,简单的也不是落后的,简单到了美的程度。现在虽然已经演变出很多智能的算法,如蚁群,神经网络等,感兴趣可以看一下刘金琨老师的《先进pid控制》,但是在实际应用中还是以串级pid为主,因为它可靠。

        先看看PID算法的一般形式:

       PID的流程简单到了不能再简单的程度,通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。这里我们规定(在t时刻):

       1.输入量为rin(t);

       2.输出量为rout(t);

       3.偏差量为err(t)=rin(t)-rout(t);

       pid的控制规律为

       1.说明一下反馈控制的原理,通过上面的框图不难看出,PID控制其实是对偏差的控制过程;

       2.如果偏差为0,则比例环节不起作用,只有存在偏差时,比例环节才起作用。

       3.积分环节主要是用来消除静差,所谓静差,就是系统稳定后输出值和设定值之间的差值,积分环节实际上就是偏差累计的过程,把累计的误差加到原有系统上以抵消系统造成的静差。

       4.而微分信号则反应了偏差信号的变化规律,或者说是变化趋势,根据偏差信号的变化趋势来进行超前调节,从而增加了系统的快速性。

        下面将对PID连续系统离散化,从而方便在处理器上实现。下面把连续状态的公式再贴一下:

        假设采样间隔为T,则在第K T时刻:

        偏差err(K)=rin(K)-rout(K);

        积分环节用加和的形式表示,即err(K)+err(K+1)+……;

        微分环节用斜率的形式表示,即[err(K)-err(K-1)]/T;

        从而形成如下PID离散表示形式:

        则u(K)可表示成为:

       至于说Kp、Ki、Kd三个参数的具体表达式,我想可以轻松的推出了,这里节省时间,不再详细表示了。

    其实到这里为止,PID的基本离散表示形式已经出来了。目前的这种表述形式属于位置型PID,另外一种表述方式为增量式PID,由U上述表达式可以轻易得到:

        那么:

        这就是离散化PID的增量式表示方式,由公式可以看出,增量式的表达结果和最近三次的偏差有关,这样就大大提高了系统的稳定性。需要注意的是最终的输出结果应该为

           u(K)+增量调节值;

         PID的离散化过程基本思路就是这样,下面是将离散化的公式转换成为C语言,从而实现微控制器的控制作用。

    那么如何用c语言进行表达?下面将对pid一种常见的形式进行c语言的描述,注意他们的演变过程,在pixhawk中也用到这其中的一些注意事项,如积分分离。

         位置型PID的C语言实现:


    第一步:定义PID变量结构体,代码如下:

    struct _pid{
        float SetSpeed;            //定义设定值
        float ActualSpeed;        //定义实际值
        float err;                //定义偏差值
        float err_last;            //定义上一个偏差值
        float Kp,Ki,Kd;            //定义比例、积分、微分系数
        float voltage;          //定义电压值(控制执行器的变量)
        float integral;            //定义积分值
    }pid;

       控制算法中所需要用到的参数在一个结构体中统一定义,方便后面的使用。

    第二部:初始化变量,代码如下:

    void PID_init(){
        printf("PID_init begin \n");
        pid.SetSpeed=0.0;
        pid.ActualSpeed=0.0;
        pid.err=0.0;
        pid.err_last=0.0;
        pid.voltage=0.0;
        pid.integral=0.0;
        pid.Kp=0.2;
        pid.Ki=0.015;
        pid.Kd=0.2;
        printf("PID_init end \n");
    }

        统一初始化变量,尤其是Kp,Ki,Kd三个参数,调试过程当中,对于要求的控制效果,可以通过调节这三个量直接进行调节。

    第三步:编写控制算法,代码如下:

    float PID_realize(float speed){
        pid.SetSpeed=speed;
        pid.err=pid.SetSpeed-pid.ActualSpeed;
        pid.integral+=pid.err;//位置式pid是对积分的持续累加,容易造成积分饱和,是系统过调
        pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
        pid.err_last=pid.err;
        pid.ActualSpeed=pid.voltage*1.0;
        return pid.ActualSpeed;
    }

    注意:这里用了最基本的算法实现形式,没有考虑死区问题,没有设定上下限,只是对公式的一种直接的实现,后面的介绍当中还会逐渐的对此改进。

       到此为止,PID的基本实现部分就初步完成了。下面是测试代码:

    int main(){
        printf("System begin \n");
        PID_init();
        int count=0;
        while(count<1000)
        {
            float speed=PID_realize(200.0);
            printf("%f\n",speed);
            count++;
        }
    return 0;
    }

    增量型PID的C语言实现:


    实现过程仍然是分为定义变量、初始化变量、实现控制算法函数、算法测试四个部分,

    #include<stdio.h>
    #include<stdlib.h>

    struct _pid{
        float SetSpeed;            //定义设定值
        float ActualSpeed;        //定义实际值
        float err;                //定义偏差值
        float err_next;            //定义上一个偏差值
        float err_last;            //定义最上前的偏差值
        float Kp,Ki,Kd;            //定义比例、积分、微分系数
    }pid;

    void PID_init(){
        pid.SetSpeed=0.0;
        pid.ActualSpeed=0.0;
        pid.err=0.0;
        pid.err_last=0.0;
        pid.err_next=0.0;
        pid.Kp=0.2;
        pid.Ki=0.015;
        pid.Kd=0.2;
    }

    float PID_realize(float speed){
        pid.SetSpeed=speed;
        pid.err=pid.SetSpeed-pid.ActualSpeed;
        float incrementSpeed=pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last);//只和前后三次的误差值有关,也方便计算
        pid.ActualSpeed+=incrementSpeed;
        pid.err_last=pid.err_next;
        pid.err_next=pid.err;
        return pid.ActualSpeed;
    }

    int main(){
        PID_init();
        int count=0;
        while(count<1000)
        {
            float speed=PID_realize(200.0);
            printf("%f\n",speed);
            count++;
        }
        return 0;
    }


    积分分离的PID控制算法C语言实现:


        在普通PID控制中,引入积分环节的目的,主要是为了消除静差,提高控制精度。但是在启动、结束或大幅度增减设定时,短时间内系统输出有很大的偏差,会造成PID运算的积分积累,导致控制量超过执行机构可能允许的最大动作范围对应极限控制量,从而引起较大的超调,甚至是震荡,这是绝对不允许的。

       为了克服这一问题,引入了积分分离的概念,其基本思路是当被控量与设定值偏差较大时,取消积分作用; 当被控量接近给定值时,引入积分控制,以消除静差,提高精度。其具体实现代码如下:

        pid.Kp=0.2;
        pid.Ki=0.04;
        pid.Kd=0.2;  //初始化过程

    if(abs(pid.err)>200)
        {
        index=0;
        }else{
        index=1;
        pid.integral+=pid.err;
        }
        pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);    

    //算法具体实现过程可参考上面的

    抗积分饱和的PID控制算法C语言实现:

        所谓的积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,若控制器输出U(k)继续增大,执行器开度不可能再增大,此时计算机输出控制量超出了正常运行范围而进入饱和区。一旦系统出现反向偏差,u(k)逐渐从饱和区退出。进入饱和区越深则退出饱和区时间越长。在这段时间里,执行机构仍然停留在极限位置而不随偏差反向而立即做出相应的改变,这时系统就像失控一样,造成控制性能恶化,这种现象称为积分饱和现象或积分失控现象。

        防止积分饱和的方法之一就是抗积分饱和法,该方法的思路是在计算u(k)时,首先判断上一时刻的控制量u(k-1)是否已经超出了极限范围: 如果u(k-1)>umax,则只累加负偏差; 如果u(k-1)<umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。直接贴出代码,不懂的看看前面几节的介绍。

    float PID_realize(float speed){
        int index;
        pid.SetSpeed=speed;
        pid.err=pid.SetSpeed-pid.ActualSpeed;

       if(pid.ActualSpeed>pid.umax)  //灰色底色表示抗积分饱和的实现
        {

           if(abs(pid.err)>200)      //蓝色标注为积分分离过程
            {
                index=0;
            }else{
                index=1;
                if(pid.err<0)
                {//如果超上限要嘛加负值要嘛就不加了,免得进入饱和区
                  pid.integral+=pid.err;          

                        }
            }
        }else if(pid.ActualSpeed<pid.umin){
            if(abs(pid.err)>200)      //积分分离过程
            {
                index=0;
            }else{
                index=1;
                if(pid.err>0)
                {//如果超下限要嘛加正值要嘛就不加了免得进入饱和区
                pid.integral+=pid.err;
                }
            }
        }else{
            if(abs(pid.err)>200)                    //积分分离过程
            {
                index=0;
            }else{
                index=1;
                pid.integral+=pid.err;
            }
        }

        pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);


        pid.err_last=pid.err;
        pid.ActualSpeed=pid.voltage*1.0;
        return pid.ActualSpeed;
    }


    变积分的PID控制算法C语言实现:


       变积分PID可以看成是积分分离的PID算法的更一般的形式。在普通的PID控制算法中,由于积分系数ki是常数,所以在整个控制过程中,积分增量是不变的。但是,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强。积分系数取大了会产生超调,甚至积分饱和,取小了又不能短时间内消除静差。因此,根据系统的偏差大小改变积分速度是有必要的。

       变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对应:偏差越大,积分越慢; 偏差越小,积分越快。

       这里给积分系数前加上一个比例值index:

       当abs(err)<180时,index=1;

       当180<abs(err)<200时,index=(200-abs(err))/20;

       当abs(err)>200时,index=0;

       最终的比例环节的比例系数值为ki*index;

     float PID_realize(float speed){
        float index;
        pid.SetSpeed=speed;
        pid.err=pid.SetSpeed-pid.ActualSpeed;

        if(abs(pid.err)>200)           //变积分过程
        {
        index=0.0;
        }else if(abs(pid.err)<180){
        index=1.0;
        pid.integral+=pid.err;
        }else{
        index=(200-abs(pid.err))/20;
        pid.integral+=pid.err;
        }
        pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);

        pid.err_last=pid.err;
        pid.ActualSpeed=pid.voltage*1.0;
        return pid.ActualSpeed;
    }


        最后给出大家专家系统中控制经验,自己理解吧。

        反应系统性能的两个参数是系统误差e和误差变化律ec

        首先我们规定一个误差的极限值,假设为Mmax;规定一个误差的比较大的值,假设为Mmid;规定一个误差的较小值,假设为Mmin;

         e*ec>0  误差在朝向误差绝对值增大的方向变化(可以理解成速度和加速度)

                 若此时 abs(e)>Mmid :误差较大 强控制 

                 若此时 abs(e)<Mmid :误差绝对值本身并不是很大 一般的控制作用

         e*ec<0  误差在朝向误差绝对值减小的方向变化

                 若此时 e*err(k-1)>0或者e=0 :误差的绝对值向减小的方向变化,或者已经达到平衡状态,

                        此时保持控制器输出不变即可。 

                 若此时e*err(k-1)<0 : 误差处于极限状态。如果误差的绝对值>min,强控制 (调节幅度比较大)                       如果此时误差绝对值较小,可以考虑实施较弱控制作用。

         当abs(e)>Mmax时,说明误差的绝对值已经很大了,都应该考虑控制器的输入应按最大(或最小) 输出,以                          达到迅速调整误差的效果,使误差绝对值以最大的速度减小。

         当abs(e)<Mmin时,说明误差绝对值很小,此时加入积分,减小静态误差。

    2、pid调参你怎么看

    1).PID调试一般原则 

    a.在输出不振荡时,增大比例增益P。 

    b.在输出不振荡时,减小积分时间常数Ti。 

    c.在输出不振荡时,增大微分时间常数Td。 

    (他们三个任何谁过大都会造成系统的震荡。)
    2).一般步骤

     a.确定比例增益P :确定比例增益P 时,首先去掉PID的积分项和微分项,一般是令Ti=0、Td=0(具体见PID的参数设定说明),使PID为纯比例调节。输入设定为系统允许的最大值的60%~70%,由0逐渐加大比例增益P,直至系统出现振荡;再反过来,从此时的比例增益P逐渐减小,直至系统振荡消失,记录此时的比例增益P,设定PID的比例增益P为当前值的60%~70%。比例增益P调试完成。

    b.确定积分时间常数Ti比例增益P确定后,设定一个较大的积分时间常数Ti的初值,然后逐渐减小Ti,直至系统出现振荡,之后在反过来,逐渐加大Ti,直至系统振荡消失。记录此时的Ti,设定PID的积分时间常数Ti为当前值的150%~180%。积分时间常数Ti调试完成。

    c.确定积分时间常数Td 积分时间常数Td一般不用设定,为0即可。若要设定,与确定 P和Ti的方法相同,取不振荡时的30%。
     d.系统空载、带载联调,再对PID参数进行微调,直至满足要求:理想时间两个波,前高后低4比

    3、串级pid简介

        串级pid内外两环并联调节,这样的好处的是增加系统的稳定性,抗干扰。同时调节系统缓慢过度,注意外环都是本身误差,内环是速度,如位置控制外环是位置,内环是速度,是因为位置改变的实现是靠三个方向的速度积分出来的。同样姿态控制中,外环是角度差,内环是加速度,是因为角度的实现是靠角速度过渡来的,他们都是这样的一个过渡过程。实际中如果你追求响应的快捷,你也可以直接控制内环,或者直接控制姿态。

        串级PID两个PID控制算法,只不过把他们串起来了(更精确的说是套起来)。那这么做有什么用?答案是,它增强了系统的抗干扰性(也就是增强稳定性),因为有两个控制器控制飞行器,它会比单个控制器控制更多的变量,使得飞行器的适应能力更强。画出串级PID的原理框图,

        在整定串级PID时的经验则是:先整定内环PID,再整定外环P。因为内环靠近输出,效果直接。

        内环P:从小到大,拉动四轴越来越困难,越来越感觉到四轴在抵抗你的拉动;到比较大的数值时,四轴自己会高频震动,肉眼可见,此时拉扯它,它会快速的振荡几下,过几秒钟后稳定;继续增大,不用加人为干扰,自己发散翻机。
        特别注意:只有内环P的时候,四轴会缓慢的往一个方向下掉,这属于正常现象。这就是系统角速度静差。
        内环I:前述PID原理可以看出,积分只是用来消除静差,因此积分项系数个人觉得没必要弄的很大,因为这样做会降低系统稳定性。从小到大,四轴会定在一个位置不动,不再往下掉;继续增加I的值,四轴会不稳定,拉扯一下会自己发散。
        特别注意:增加I的值,四轴的定角度能力很强,拉动他比较困难,似乎像是在钉钉子一样,但是一旦有强干扰,它就会发散。这是由于积分项太大,拉动一下积分速度快,给  的补偿非常大,因此很难拉动,给人一种很稳定的错觉。
        内环D:这里的微分项D为标准的PID原理下的微分项,即本次误差-上次误差。在角速度环中的微分就是角加速度,原本四轴的震动就比较强烈,引起陀螺的值变化较大,此时做微分就更容易引入噪声。因此一般在这里可以适当做一些滑动滤波或者IIR滤波。从小到大,飞机的性能没有多大改变,只是回中的时候更加平稳;继续增加D的值,可以肉眼看到四轴在平衡位置高频震动(或者听到电机发出滋滋的声音)。前述已经说明D项属于辅助性项,因此如果机架的震动较大,D项可以忽略不加。
       外环P:当内环PID全部整定完成后,飞机已经可以稳定在某一位置而不动了。此时内环P,从小到大,可以明显看到飞机从倾斜位置慢慢回中,用手拉扯它然后放手,它会慢速回中,达到平衡位置;继续增大P的值,用遥控器给不同的角度给定,可以看到飞机跟踪的速度和响应越来越快;继续增加P的值,飞机变得十分敏感,机动性能越来越强,有发散的趋势。

    4、最后给你贴上pixhawk有关pid的源码,就是位置式的很简单,自己理解一下吧。需要说明的是位置式pid容易导致积分的饱和,所以在积分上过了很多处理。如在位置控制中,推力的积分量就是进行了饱和处理。

    __EXPORT float pid_calculate(PID_t *pid, float sp, float val, float val_dot, float dt)
    {
        if (!isfinite(sp) || !isfinite(val) || !isfinite(val_dot) || !isfinite(dt)) {
            return pid->last_output;
        }
     
        float i, d;
     
        /* current error value */
        float error = sp - val;
     
        /* current error derivative */
        if (pid->mode == PID_MODE_DERIVATIV_CALC) {
            d = (error - pid->error_previous) / fmaxf(dt, pid->dt_min);
            pid->error_previous = error;
     
        } else if (pid->mode == PID_MODE_DERIVATIV_CALC_NO_SP) {
            d = (-val - pid->error_previous) / fmaxf(dt, pid->dt_min);
            pid->error_previous = -val;
     
        } else if (pid->mode == PID_MODE_DERIVATIV_SET) {
            d = -val_dot;
     
        } else {
            d = 0.0f;
        }
     
        if (!isfinite(d)) {
            d = 0.0f;
        }
     
        /* calculate PD output */
        float output = (error * pid->kp) + (d * pid->kd);
     
        if (pid->ki > SIGMA) {
            // Calculate the error integral and check for saturation
            i = pid->integral + (error * dt);
     
            /* check for saturation */
            if (isfinite(i)) {
                if ((pid->output_limit < SIGMA || (fabsf(output + (i * pid->ki)) <= pid->output_limit)) &&
                    fabsf(i) <= pid->integral_limit) {
                    /* not saturated, use new integral value */
                    pid->integral = i;
                }
            }
     
            /* add I component to output */
            output += pid->integral * pid->ki;
        }
     
        /* limit output */
        if (isfinite(output)) {
            if (pid->output_limit > SIGMA) {
                if (output > pid->output_limit) {
                    output = pid->output_limit;
     
                } else if (output < -pid->output_limit) {
                    output = -pid->output_limit;
                }
            }
     
            pid->last_output = output;
        }
     
        return pid->last_output;
    }
     
     
    __EXPORT void pid_reset_integral(PID_t *pid)
    {
        pid->integral = 0.0f;
    }

     

    展开全文
  • 飞控串级PID详解

    2016-10-09 10:05:14
    飞控串级PID详解
  • 串级PID算法

    千次阅读 2019-07-25 17:18:45
    单环PID和串级PID的区别(框图表示) 串级PID的优势:增加稳定性,增强抗干扰性(其实不是太理解。。。) 代码实现 定义4个PID的结构体,分别用于x方向内环、外环以及y方向内环、外环(当初做板球系统xy方向用的都...

    单环PID和串级PID的区别(框图表示)

    在这里插入图片描述
    在这里插入图片描述
    串级PID的优势:增加稳定性,增强抗干扰性(其实不是太理解。。。)

    代码实现

    定义4个PID的结构体,分别用于x方向内环、外环以及y方向内环、外环(当初做板球系统xy方向用的都是同一个PID结构体变量,最后居然能调出来,惊了。。。PID真是玄学)
    (一)结构体变量

    //定义PID结构体
    typedef struct
    {
    	float ek;
    	float ek1;
    	float esum;
    	float kp;
    	float ki;
    	float kd;
    } PID_StructureDef;
    
    //需要开x,y两个方向的pid结构体
    PID_StructureDef PID_shell_Structure_x={0,0,0,0,0,0};	//x外环pid结构体
    PID_StructureDef PID_core_Structure_x={0,0,0,0,0,0};	//x内环pid结构体
    
    PID_StructureDef PID_shell_Structure_y={0,0,0,0,0,0};	//y外环pid结构体
    PID_StructureDef PID_core_Structure_y={0,0,0,0,0,0};	//y内环pid结构体
    

    (二)PID结构体变量的参数设置函数

    //设置PID结构体的初始化参数
    void Set_PID_para(float kp,float ki,float kd,PID_StructureDef *PID_Structure)
    {
    	PID_Structure->kp=kp;
    	PID_Structure->ki=ki;
    	PID_Structure->kd=kd;
    }
    

    (三)PID输出计算函数,输入的是外环的误差,返回的是内环的输出

    //PID计算输出
    int PID_Calculate(float error,float gyro,PID_StructureDef *PID_shell_Structure,PID_StructureDef *PID_core_Structure)
    {
    	float shell_output,core_output;
    	
    	PID_shell_Structure->ek=error;
    	//积分限幅
    	if(PID_shell_Structure->esum>300)
    		PID_shell_Structure->esum=300;
    	else if(PID_shell_Structure->esum<-300)
    		PID_shell_Structure->esum=-300;
    	else
    		PID_shell_Structure->esum+=error;
    	shell_output=(PID_shell_Structure->ek)*(PID_shell_Structure->kp)+(PID_shell_Structure->esum)*(PID_shell_Structure->ki);
    	
    	//外环输出,作为内环输入 用陀螺仪当前的角速度作为实际值
    	PID_core_Structure->ek=shell_output-gyro;
    	//内环积分限幅
    	if(PID_core_Structure->esum>500)
    		PID_core_Structure->esum=500;
    	else if(PID_core_Structure->esum<-500)
    		PID_core_Structure->esum=-500;
    	else
    		PID_core_Structure->esum+=PID_core_Structure->ek;
    	core_output=(PID_core_Structure->ek)*(PID_core_Structure->kp)+(PID_core_Structure->esum)*(PID_core_Structure->ki)+(PID_core_Structure->ek-PID_core_Structure->ek1)*(PID_core_Structure->kd);
    	PID_core_Structure->ek1=PID_core_Structure->ek;
    	
    	return (int)core_output;
    }
    

    (四)使用的时候,输入角度误差,以及陀螺仪当前的角速度

    //计算当前姿态的坐标x和y,并实现控制
    void Calculate_Control(void)
    {
    	float temp_pitch,temp_roll,pid_x,pid_y;
    	//获取陀螺仪的三个角速度
    	MPU_Get_Gyroscope(&GRY_x,&GRY_y,&GRY_z);
    	
    	//计算误差值 以及PID xy坐标换算到角度,利用串级pid控制
    	temp_pitch=atan2(Height,Goal_X)-pitch;
    	pid_x=PID_Calculate(temp_pitch,GRY_x,&PID_shell_Structure_x,&PID_core_Structure_x);
    	if(pid_x)
    	{
    		motor_1=0;
    		motor_3=pid_x;
    	}
    	else
    	{
    		motor_3=0;
    		motor_1=-pid_x;
    	}
    	
    	temp_roll=atan2(Height,Goal_Y)-roll;
    	pid_y=PID_Calculate(temp_roll,GRY_y,&PID_shell_Structure_y,&PID_core_Structure_y);
    	if(pid_y)
    	{
    		motor_4=0;
    		motor_2=pid_y;
    	}
    	else
    	{
    		motor_2=0;
    		motor_4=-pid_y;
    	}
    }
    

    注:代码虽然过了编译,但由于硬件出了问题,代码能否实现功能还不知道。。。

    串级PID调参技巧

    Reference:https://blog.csdn.net/nemol1990/article/details/45131603

    展开全文
  • 前言 本文将讲述串级PID与单极PID的区别,并由此引出什么时候用串级PID,对于想深入学习PID的你有一定的帮助。
  • 串级PID调试技巧.zip

    2019-10-27 14:39:48
    理解串级PID提高使用者的理解力,以便于学习和调试
  • 单级串级PID姿态控制框图.vsdx
  • 串级PID介绍

    千次阅读 2020-02-28 12:18:19
    串级PID的模块图如下: 前提条件: 中间变量可观测 中间变量可控 中间变量可以反应扰动的干扰 中间变量的反应比终末变量的反应快 特点: (1) 由于内环回路的存在,改变了原来的对象特性,使内环回路对象的等效时间...
  • 串级PID调试simulink仿真 设计串级PID 串级PID图解: 在设计串级PID的时候,我们从图可以知道,主控制器的输出是副控制器的输入。 主控制器输出可以是输出实际的物理量,也可以输出百分比。若是输出实际物理量的值...
  • 串级PID的直立控制

    2020-12-02 21:41:30
    基于串级PID的直立车控制算法研究 摘要:直立平衡车因其动力学系统同时具有多变量,非线性,不稳定,强耦合等特性,传统的单环PID控制平衡已经略显吃力。本文将采用内环角速度PI控制、外环角度PD控制及最外环速度PI控制...
  • 我先说下这篇文章和我之前对串级PID的理解一样,就是你不可能直接控制那个量,最典型的就是板球自平衡系统用串级PID,这个物理意义非常明显,而我之前也总结了,内环是外环的微分。这里面都说到了。 ...
  • 串级PID笔记

    千次阅读 2018-04-14 23:55:03
    串级PID控制: 1 在选择内环回路参数时,必须把主要干扰包含在内环回路中。 2 因此选取航向的偏差为内环参数,横向距离的片偏差为外环参数。原因为:外环控制器的输出作为内环控制器的设定值,由内环控制器的输出去...
  • PID及串级PID的理解

    2020-12-04 08:24:46
    PID及串级PID的学习比例环节(P)积分环节(I):微分环节(D): (仅供本人学习使用) 在四轴中,PID起着至关重要的作用,对PID学习更加深入才能更了解四轴的平衡状态时如何实现的。 暂时还不理解的内容: pid...
  • 到底什么是串级PID

    2021-02-21 12:32:27
    什么是串级PID?什么是串级PID?顾名思义就是两个串起来的PID,下面是一个双闭环的例子,外环是位置环,内环是速度环,最终的执行器是电机,电机输出产生了速度和位置;具体框图如下图所示;当...
  • 串级PID的一些理解

    万次阅读 多人点赞 2019-05-12 21:29:34
    本篇博文主要来回答为何多旋翼无人机控制使用的是串级PID而非单级PID这一问题。 我们可以从如下几个角度来回答这个问题: 1.输出反馈和状态反馈 首先,以无人机的姿态通道为例,系统的状态变量为姿态角和姿态角...
  • 基于串级PID的直立车控制算法研究

    千次阅读 多人点赞 2020-10-31 09:38:39
    本文将采用内环角速度PI控制、外环角度PD控制及最外环速度PI控制组成的串级 PID算法来控制直立车的平衡及运动,串级PID控制器比常规PID控制系统具有较强的稳定性、抗干扰性。 关键词: 串级PID 直立车 姿态控制 耦合...
  • 上润WP-KS805智能双回路串级PID调节使用说明rar,上润WP-KS805智能双回路串级PID调节使用说明
  • 四轴PID控制算法详解(单环PID、串级PID)

    千次阅读 多人点赞 2019-06-18 14:59:10
    正文开始:这篇文章分为三个部分:PID原理普及常用四轴的两种PID算法讲解(单环PID、串级PID)如何做到垂直起飞、四轴飞行时为何会飘、如何做到脱控?PID原理普及1、  对自动控制系统的基本要求:  &...
  • Pixhawk-串级pid介绍

    千次阅读 2018-03-26 20:34:16
    --Better(根爷) 鉴于串级PID在pixhawk系统中的重要性,无论是误差的补偿,如姿态解算;还是控制的实现,如姿态控制,位置控制,靠的都是串级的pid,这里我们先对串级pid做一个介绍,后面会再接着分析,姿态的控制...
  • PID以及串级PID在实际生产中使用比较广泛,今天看了这篇文章,并结合过往的经验做一个笔记。 1、串级PID的基础是PID,所以在此之前需要了解差分、积分和微分的具体含义。 2、串级PID是按照从里向外,一层一层...
  • 串级PID控制(多闭环PID控制)的理解

    万次阅读 多人点赞 2018-06-22 11:03:00
    网络上很多双闭环或者三闭环PID控制的讲述,其实就是串级PID控制,之前一直没能理解,更不知道如何应用。 现在用伺服电机为例,一起理解一下PID串级控制。 伺服电机一般为三个环控制,所谓三环就是3个闭环负反馈...
  • 湖北文理学院 毕业设计(论文)正文 题 目 专 业 班 级 姓 名 学 号 指导教师 职 称基于MATLAB的串级PID控制系统 机电一体化工程 机电0811班 姜鹏 08862095 2012年 4 月 20 日 摘 要 关键词 MATLABPID控制液位串级控制...
  • 基于串级pid控制的无刷直流电机simulink仿真实现,有相应的参考学习价值
  • PCS7串级PID连线示意图

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 318
精华内容 127
关键字:

串级pid