⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pid_controller.java

📁 这是一个以JAVA编写的程序,本人还没有试过,是一个简单的温度控制系统
💻 JAVA
字号:
package net.sf.dz.controller;import org.freehold.jukebox.logger.LogChannel;/** * Classical PID - Proportional, Integral, Derivative controller. * * @author Copyright &copy; <a href="mailto:vt@freehold.crocodile.org"> Vadim Tkachenko</a> 2001-2002 * @version $Id: PID_Controller.java,v 1.5 2004/06/28 20:35:46 vtt Exp $ */public class PID_Controller extends AbstractProcessController {    /**     * Log channel to use.     */    public static final LogChannel CH_PID = new LogChannel("PID");    /**     * Proportional weight.     */    private double P;    /**     * Integral weight.     */    private double I;    /**     * Integral data set.     */    private IntegralSet integralSet;    /**     * Derivative weight.     */    private double D;    /**     * Differential data set.     */    private DifferentialSet differentialSet;    /**     * Saturation limit.     *     * The controller is considered saturated if the output absolute value     * is greater than this.     */    private double saturationLimit;    /**     * Create unconfigured instance.     *     * This instance can't be used until <code>configure()</code>d.     */    public PID_Controller() {    }    /**     * Create the configured instance.     *     * @param P Proportional weight.     *     * @param I Integral weight.     *     * @param Ispan Integral timespan, milliseconds.     *     * @param D Derivative weight.     *     * @param Dspan Derivative timespan, milliseconds.     *     * @param saturationLimit Anti-windup control value. The controller is     * considered saturated if the output absolute value is greater than     * this. Zero means no anti-windup will be provided.     */    public PID_Controller(final double P,                          final double I, final long Ispan,                          final double D, final long Dspan,                          final double saturationLimit) {        this.P = P;        this.I = I;        this.D = D;        this.integralSet = new IntegralSet(Ispan);        this.differentialSet = new DifferentialSet(Dspan);        this.saturationLimit = saturationLimit;        check();    }    /**     * Check if all the parameters are OK.     *     * @throws IllegalArgumentException if the argument set didn't make     * sense.     */    private void check() {        // This method should be fast because it will be called at the        // beginning of compute() to make sure the controller is initialized        // NOTE: Remember that integralSet and differentialSet are possibly        // unassigned at this point        if (saturationLimit < 0) {            throw new IllegalArgumentException("Check parameters: saturationLimit="                                               + saturationLimit);        }        if (   P == 0            && I == 0            && D == 0) {            throw new IllegalArgumentException("All PID components are zeroed: check the configuration");        }    }    /**     * Read the P, I, D and span values from the configuration.     *     * @exception Throwable if there's a problem with configuration.     */    protected final void configure2() throws Throwable {        P = getConfiguration().getDouble(getConfigurationRoot() + ".pid.P");        I = getConfiguration().getDouble(getConfigurationRoot() + ".pid.I.weight");        long Ispan = getConfiguration().getLong(getConfigurationRoot() + ".pid.I.time");        D = getConfiguration().getDouble(getConfigurationRoot() + ".pid.D.weight");        long Dspan = getConfiguration().getLong(getConfigurationRoot() + ".pid.D.time");        saturationLimit = getConfiguration().getDouble(getConfigurationRoot() + ".pid.SL");        System.err.println("Configuration root: " + getConfigurationRoot());        System.err.println("P I/Ispan D/Dspan SL:   " + P + " "                                     + I + "/" + Ispan + " "                                     + D + "/" + Dspan + " "                                     + saturationLimit);        complain(LOG_DEBUG, CH_PID, "P I/Ispan D/Dspan SL:   " + P + " "                                     + I + "/" + Ispan + " "                                     + D + "/" + Dspan + " "                                     + saturationLimit);        check();        if (I != 0) {            integralSet = new IntegralSet(Ispan);        }        if (D != 0) {            differentialSet = new DifferentialSet(Dspan);        }    }    /**     * {@inheritDoc}     */    protected final double compute() {        try {            check();        } catch (IllegalArgumentException iaex) {            throw new IllegalStateException("Possibly not initialized or improper configuration, cause: " + iaex.getMessage());        }        double pv = getProcessVariable();        double error = getError();        double signal = error * P;        lastP = signal;        if (I != 0) {            double integralInput = error;            if (saturationLimit != 0) {                if (   (getLastKnownSignal() != null)                    && (Math.abs(getLastKnownSignal().doubleValue()) > saturationLimit)) {                    // VT: FIXME: This has to be adjusted according to                    // anti-windup algorithm. Think about making this a                    // template method or a decorator.                    error = 0;                }            }            integralSet.record(getLastModified(), error);            lastI = integralSet.getIntegral() * I;            signal += lastI;        }        if (D != 0) {            differentialSet.record(getLastModified(), error);            lastD = differentialSet.getDifferential() * D;            signal += lastD;        }        lastSignal = signal;        final Double NaN = new Double(Double.NaN);        if (NaN.equals(new Double(signal))) {            throw new IllegalStateException("signal is NaN, components: " + getStatus());        }        return signal;    }    /**     * Last known value of P.     */    private double lastP = 0;    /**     * Last known value of I.     */    private double lastI = 0;    /**     * Last known value of #.     */    private double lastD = 0;    /**     * Last known signal value.     */    private double lastSignal = 0;    /**     * {@inheritDoc}     */    public ProcessControllerStatus getStatus() {        return new PID_Status(getError(), lastSignal, lastP, lastI, lastD);    }    /**     * PID controller status.     */    public class PID_Status extends ProcessControllerStatus {        /**         * Proportional value.         */        public final double p;        /**         * Integral value.         */        public final double i;        /**         * Derivative value.         */        public final double d;        /**         * Create an instance.         *         * @param error Current error value.         *         * @param signal Current signal value.         *         * @param p Current P value.         *         * @param i Current I value.         *         * @param d Current D value.         */        public PID_Status(final double error, final double signal, final double p, final double i, final double d) {            super(error, signal);            this.p = p;            this.i = i;            this.d = d;        }        /**         * Get a string representation of a PID controller status.         *         * @return A string representation of a status put together by a         * superclass, followed by slash delimited P, I, D values.         */        public final String toString() {            return super.toString() + "/" + p + "/" + i + "/" + d;        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -