[android学习笔记]打造一个pid控制器

qq:1019157263

未完待续...

晚些传

PID算法的应用:

  PID控制算法作为自动控制系统中广泛应用的一种控制算法,小到控制一个元件的温度,大到控制无人机的飞行姿态和飞行速度等等,都可以使用PID控制。控制器问世至今已有近 70 年历史,它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。

常见应用如下:

  1、利用PID控制实现的压力、温度、流量、液位控制器;

  2、能实现PID控制功能的可编程控制器(PLC);

  3、还有可实现PID控制的PC系统;

  4、可编程控制器(PLC) 是利用其闭环控制模块来实现PID控制。

PID算法介绍:

PID控制的原理是比例,积分,微分三个环节并联闭环回路控制

1. 比例环节

   成比例地反映控制系统的偏差信号e(t),偏差一旦产生,控制器立即产生控制作用,以减小偏差。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。
   P参数越小比例作用越强,动态响应越快,消除误差的能力越强。但实际系统是有惯性的,控制输出变化后,实际y(t)值变化还需等待一段时间才会缓慢变化。由于实际系统是有惯性的,比例作用不宜太强,比例作用太强会引起系统振荡不稳定。P参数的大小应在以上定量计算的基础上根据系统响应情况,现场调试决定,通常将P参数由大向小调,以能达到最快响应又无超调(或无大的超调)为最佳参数。

2. 积分环节

   控制器的输出与输入误差信号的积分成正比关系。主要用于消除静差,提高系统的无差度。积分作用的强弱取决于积分时间常数T,T越大,积分作用越弱,反之则越强。

   积分作用消除静差的原理是,只要有误差存在,就对误差进行积分,使输出继续增大或减小,一直到误差为零,积分停止,输出不再变化,系统的PV值保持稳定,y(t)值等于u(t)值,达到无差调节的效果。

3微分环节

   微分作用主要是用来克服被控对象的滞后,常用于温度控制系统。除采用微分作用外,在使用控制系统时要注意测量传送的滞后问题,如温度测量元件的选择和安装位置等。 

在常规PID控制器中,微分作用的输出变化与微分时间和偏差变化的速度成比例,而与偏差的大小无关,偏差变化的速度越大,微分时间越长,则微分作用的输出变化越大。但如果微分作用过强,则可能由于变化太快而由其自身引起振荡,使控制器输出中产生明显的“尖峰”或“突跳”。为了避免这一扰动,在PID调节器和DCS中可使用微分先行PID运算规律,即只对测量值PV进行微分,当人工改变控制器的给定值SP时,不会造成控制器输出的突变,避免了改变SP的瞬间给控制系统带来的扰动。如TDC-3000,则在常规PID算法中增加一个软开关,组态时供用户选择控制器对偏差、还是测量值进行微分。

当输入阶跃信号后,微分器一开始输出的最大变化值与微分作用消失后的输出变化的比值就是微分放大倍数Kd,即微分增益,微分増益的单位是时间,设置微分时间(或者微分增益)为零会取消微分的功能。

 

pid工作原理示意图:

 

 

模拟公式是:

  

数字pid(位置式算法):

 

数字pid(增量式算法):可以节约计算量,减少内存消耗

 

 实际在写程序时积分环节就是求和,微分环节就是差分,比例就是乘积

效果图:

 

2

 

 

 

话不多说上部分核心java代码:

这里只有 部分代码,因为是android的app对各种耗时操作的限制会很麻烦,稍不注意就阻塞崩溃了,所以写了大量的防护线程安全的代码

这里只上了部分代码

还有部分操作线程的代码没上,

double Kp=P.getProgress()/10;
                        double Ti=I.getProgress()/10;
                        double Td=D.getProgress()/10;
                        double inits=init.getProgress();
                        double inputs=input.getProgress();
                        double outs=out.getProgress();                    
                        double ek=inputs-inits;
                        double ekx=ek-ek1;
                        LineChart chart = (LineChart) findViewById(R.id.chart1);//
             
                        ek1=ek;
                        en=en+ek;

                        double uk=(Kp*ek)+(((Kp*(outs*0.01))/Ti)*en)+((Kp*Td)/(outs*0.01))*ekx;//位置式算法
                        Thread.sleep(15);

 

上xml布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="20dp">

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">

            <TextView
                android:layout_width="30dp"
                android:layout_height="match_parent"
                android:text="P:"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:gravity="center"/>

            <SeekBar
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:max="100"
                android:progress="23"
                android:id="@+id/P"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">

            <TextView
                android:layout_width="30dp"
                android:layout_height="match_parent"
                android:text="I:"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:gravity="center"/>

            <SeekBar
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:progress="51"
                android:id="@+id/I"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="30dp"
                android:layout_height="match_parent"
                android:text="D:"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:gravity="center"/>

            <SeekBar
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:progress="19"
                android:id="@+id/D"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="PID系数值"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:id="@+id/mainTextView1"
                android:textSize="10sp"
                android:gravity="center"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Small Text"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:id="@+id/sss"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:gravity="center">

            <TextView
                android:layout_width="30dp"
                android:layout_height="match_parent"
                android:text="out:"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textSize="15sp"
                android:gravity="center"/>

            <SeekBar
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/init"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:gravity="center">

            <TextView
                android:layout_width="30dp"
                android:layout_height="match_parent"
                android:text="input:"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textSize="15sp"
                android:gravity="center"/>

            <SeekBar
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:progress="50"
                android:id="@+id/input"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:gravity="center">

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Start Server"
                android:textSize="10sp"
                android:id="@+id/mainButton1"
                android:onClick="onButton1Click"/>

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Stop Server"
                android:textSize="10sp"
                android:onClick="onButton2Click"
                android:id="@+id/mainButton2"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:gravity="center">

            <TextView
                android:layout_width="30dp"
                android:layout_height="match_parent"
                android:text="T:"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textSize="15sp"
                android:gravity="center"/>

            <SeekBar
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:progress="83"
                android:id="@+id/out"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/xxx">

            <com.github.mikephil.charting.charts.LineChart
                android:id="@+id/chart1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_above="@+id/seekBar1"/>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>
posted @ 2019-04-15 22:22  sunny开始学坏  阅读(782)  评论(2编辑  收藏  举报