Package ptolemy.domains.ct.demo.Thermostat

Source Code of ptolemy.domains.ct.demo.Thermostat.Thermostat

/* A thermostat control demo that uses Ptolemy II CT and FSM domains.

Copyright (c) 1998-2006 The Regents of the University of California.
All rights reserved.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the above
copyright notice and the following two paragraphs appear in all copies
of this software.

IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.

PT_COPYRIGHT_VERSION_2
COPYRIGHTENDKEY

*/
package ptolemy.domains.ct.demo.Thermostat;

import ptolemy.actor.IOPort;
import ptolemy.actor.TypedCompositeActor;
import ptolemy.actor.TypedIOPort;
import ptolemy.actor.TypedIORelation;
import ptolemy.actor.lib.Const;
import ptolemy.actor.lib.Expression;
import ptolemy.actor.lib.Scale;
import ptolemy.actor.lib.gui.TimedPlotter;
import ptolemy.data.DoubleToken;
import ptolemy.data.StringToken;
import ptolemy.data.type.BaseType;
import ptolemy.domains.ct.kernel.CTCompositeActor;
import ptolemy.domains.ct.kernel.CTEmbeddedDirector;
import ptolemy.domains.ct.kernel.CTMultiSolverDirector;
import ptolemy.domains.ct.kernel.HSFSMDirector;
import ptolemy.domains.ct.lib.Integrator;
import ptolemy.domains.ct.lib.ZeroCrossingDetector;
import ptolemy.domains.fsm.kernel.FSMActor;
import ptolemy.domains.fsm.kernel.State;
import ptolemy.domains.fsm.kernel.Transition;
import ptolemy.kernel.Relation;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.Workspace;
import ptolemy.plot.Plot;

//////////////////////////////////////////////////////////////////////////
//// Thermostat

/**
This applet shows a simple thermostat system. The temperature of the room
is expected to be controlled between Tl and Th
<p>
The system has two states, heating and cooling. In the heating state,
the temperature of the room is increased linearly, in terms of a differential
equation:
<pre>
<CODE>    dx/dt = 1</CODE>
</pre>
In the cooling state, the temperature is dropped linearly, i.e.
<pre>
<CODE>    dx/dt = -1</CODE>
</pre>
The control rule is that if the temperature reaches Th degree, then switch
the controller to the cooling state; if the temperature decreases to Tl degree
then switch the controller to the heating state.
<p>
We use this demo to illustrate the accuracy of detecting events, and the
ability of simulating hybrid system in Ptolemy II.
@author Jie Liu
@version $Id: Thermostat.java,v 1.69 2006/08/21 23:14:21 cxh Exp $
@since Ptolemy II 0.3
@Pt.ProposedRating Red (liuj)
@Pt.AcceptedRating Red (cxh)
*/
public class Thermostat extends TypedCompositeActor {
    public Thermostat(Workspace workspace) throws IllegalActionException,
            NameDuplicationException {
        super(workspace);
        setName("Thermostat");

        // the top level CT director
        CTMultiSolverDirector topdir = new CTMultiSolverDirector(this,
                "CTTopLevelDirector");

        //StreamListener dbl = new StreamListener();
        //topdir.addDebugListener(dbl);
        // a const source
        Const source = new Const(this, "Const");
        source.value.setToken(new DoubleToken(1.0));

        // the plot
        TimedPlotter responsePlot = new TimedPlotter(this, "plot");
        Plot newPlot = new Plot();
        responsePlot.plot = newPlot;
        newPlot.setGrid(true);
        newPlot.setTitle("Thermostat");
        newPlot.addLegend(0, "Temperature");
        newPlot.setConnected(true);
        newPlot.setImpulses(false);

        //newPlot.addLegend(1, "Trigger");
        newPlot.setXRange(0.0, 5.0);
        newPlot.setYRange(0.0, 0.2);
        newPlot.setSize(500, 300);

        CTCompositeActor hs = new CTCompositeActor(this, "HS");

        // the ports
        TypedIOPort hsin = (TypedIOPort) hs.newPort("input");
        hsin.setInput(true);
        hsin.setTypeEquals(BaseType.DOUBLE);

        //TypedIOPort hsout = (TypedIOPort)hs.newPort("output");
        //hsout.setOutput(true);
        //hsout.setTypeEquals(BaseType.DOUBLE);
        TypedIOPort hsst = (TypedIOPort) hs.newPort("state");
        hsst.setOutput(true);
        hsst.setTypeEquals(BaseType.DOUBLE);

        //TypedIOPort hstr = (TypedIOPort)hs.newPort("trig");
        //hstr.setOutput(true);
        //hstr.setTypeEquals(BaseType.DOUBLE);
        FSMActor ctrl = new FSMActor(hs, "Controller");

        //ctrl.addDebugListener(dbl);
        State ctrlInc = new State(ctrl, "Increasing");
        State ctrlDec = new State(ctrl, "Decreasing");
        ctrl.initialStateName.setExpression("Increasing");

        Transition ctrlTr1 = new Transition(ctrl, "ctrlTr1");
        ctrlInc.outgoingPort.link(ctrlTr1);
        ctrlDec.incomingPort.link(ctrlTr1);
        ctrlTr1.setGuardExpression("output_isPresent");
        ctrlTr1.setActions
                .setExpression("Decreasing.Integrator.initialState = state");
        ctrlTr1.reset.setExpression("true");

        Transition ctrlTr2 = new Transition(ctrl, "ctrlTr2");
        ctrlDec.outgoingPort.link(ctrlTr2);
        ctrlInc.incomingPort.link(ctrlTr2);
        ctrlTr2.setGuardExpression("output_isPresent");
        ctrlTr2.setActions
                .setExpression("Increasing.Integrator.initialState = state");
        ctrlTr2.reset.setExpression("true");

        IOPort ctrlIn = new TypedIOPort(ctrl, "output");
        ctrlIn.setInput(true);

        IOPort ctrlSt = new TypedIOPort(ctrl, "state");
        ctrlSt.setInput(true);

        // the hybrid system director
        HSFSMDirector hsdir = new HSFSMDirector(hs, "HSFSMDirector");

        //hs.setDirector(hsdir);
        hsdir.controllerName.setExpression("Controller");

        //hsdir.addDebugListener(dbl);
        CTCompositeActor ctInc = new CTCompositeActor(hs, "Increasing");

        //ZeroOrderHold ctIncH = new ZeroOrderHold(ctInc, "Hold");
        Integrator ctIncI = new Integrator(ctInc, "Integrator");

        //ctIncI.addDebugListener(dbl);
        ZeroCrossingDetector ctIncD = new ZeroCrossingDetector(ctInc, "ZD");

        //ctIncD.addDebugListener(dbl);
        Expression ctIncGF = new Expression(ctInc, "EXPRESSION");

        TypedIOPort ctIncGFi = (TypedIOPort) ctIncGF.newPort("in");
        ctIncGFi.setInput(true);
        ctIncGFi.setTypeEquals(BaseType.DOUBLE);
        ctIncGF.output.setTypeEquals(BaseType.DOUBLE);
        ctIncGF.expression.setExpression("in - 0.2");

        // the ports
        TypedIOPort ctIncIn = (TypedIOPort) ctInc.newPort("input");
        ctIncIn.setInput(true);
        ctIncIn.setTypeEquals(BaseType.DOUBLE);

        TypedIOPort ctIncOut = (TypedIOPort) ctInc.newPort("output");
        ctIncOut.setOutput(true);
        ctIncOut.setTypeEquals(BaseType.DOUBLE);

        TypedIOPort ctIncSt = (TypedIOPort) ctInc.newPort("state");
        ctIncSt.setOutput(true);
        ctIncSt.setTypeEquals(BaseType.DOUBLE);

        TypedIOPort ctIncTr = (TypedIOPort) ctInc.newPort("trig");
        ctIncTr.setOutput(true);
        ctIncTr.setTypeEquals(BaseType.DOUBLE);

        // connect ctInc
        //ctInc.connect(ctIncIn, ctIncH.input);
        //ctInc.connect(ctIncH.output, ctIncI.input);
        ctInc.connect(ctIncIn, ctIncI.input);

        Relation ctIncR2 = ctInc.newRelation("R2");
        ctIncGF.output.link(ctIncR2);
        ctIncD.trigger.link(ctIncR2);
        ctIncTr.link(ctIncR2);
        ctInc.connect(ctIncD.output, ctIncOut);

        //ctInc.connect(ctIncS.output, ctIncSt);
        TypedIORelation ctIncR1 = (TypedIORelation) ctInc
                .newRelation("CTIncR1");
        ctIncI.output.link(ctIncR1);

        //ctIncS.input.link(ctIncR1);
        ctIncGFi.link(ctIncR1);
        ctIncSt.link(ctIncR1);

        CTEmbeddedDirector ctIncDir = new CTEmbeddedDirector(ctInc, "CTIncDir");

        //ctIncDir.addDebugListener(dbl);
        CTCompositeActor ctDec = new CTCompositeActor(hs, "Decreasing");

        //ctDec.addDebugListener(dbl);
        //ZeroOrderHold ctDecH = new ZeroOrderHold(ctDec, "Hold");
        Integrator ctDecI = new Integrator(ctDec, "Integrator");
        Scale ctGain = new Scale(ctDec, "Gain");
        ZeroCrossingDetector ctDecD = new ZeroCrossingDetector(ctDec, "ZD");

        Expression ctDecGF = new Expression(ctDec, "EXPRESSION");
        TypedIOPort ctDecGFi = (TypedIOPort) ctDecGF.newPort("in");
        ctDecGFi.setInput(true);
        ctDecGFi.setTypeEquals(BaseType.DOUBLE);
        ctDecGF.output.setTypeEquals(BaseType.DOUBLE);
        ctDecGF.expression.setExpression("in + 0.0");

        // the ports
        TypedIOPort ctDecIn = (TypedIOPort) ctDec.newPort("input");
        ctDecIn.setInput(true);
        ctDecIn.setTypeEquals(BaseType.DOUBLE);

        TypedIOPort ctDecOut = (TypedIOPort) ctDec.newPort("output");
        ctDecOut.setOutput(true);
        ctDecOut.setTypeEquals(BaseType.DOUBLE);

        TypedIOPort ctDecSt = (TypedIOPort) ctDec.newPort("state");
        ctDecSt.setOutput(true);
        ctDecSt.setTypeEquals(BaseType.DOUBLE);

        TypedIOPort ctDecTr = (TypedIOPort) ctDec.newPort("trig");
        ctDecTr.setOutput(true);
        ctDecTr.setTypeEquals(BaseType.DOUBLE);

        // connect ctDec
        //ctDec.connect(ctDecIn, ctDecH.input);
        //ctDec.connect(ctDecH.output, ctGain.input);
        ctDec.connect(ctDecIn, ctGain.input);
        ctDec.connect(ctGain.output, ctDecI.input);

        Relation ctDecR2 = ctDec.newRelation("R2");
        ctDecGF.output.link(ctDecR2);
        ctDecD.trigger.link(ctDecR2);
        ctDecTr.link(ctDecR2);
        ctDec.connect(ctDecD.output, ctDecOut);

        //ctDec.connect(ctDecS.output, ctDecSt);
        TypedIORelation ctDecR1 = (TypedIORelation) ctDec
                .newRelation("CTDecR1");
        ctDecI.output.link(ctDecR1);

        //ctDecS.input.link(ctDecR1);
        ctDecGFi.link(ctDecR1);
        ctDecSt.link(ctDecR1);

        CTEmbeddedDirector ctDecDir = new CTEmbeddedDirector(ctDec, "CTDecDir");

        //ctDecDir.addDebugListener(dbl);
        ctrlInc.refinementName.setExpression("Increasing");
        ctrlDec.refinementName.setExpression("Decreasing");

        // connect hs
        TypedIORelation hsr1 = (TypedIORelation) hs.newRelation("HSr1");
        hsin.link(hsr1);
        ctIncIn.link(hsr1);
        ctDecIn.link(hsr1);

        TypedIORelation hsr2 = (TypedIORelation) hs.newRelation("HSr2");
        ctrlIn.link(hsr2);
        ctIncOut.link(hsr2);
        ctDecOut.link(hsr2);

        TypedIORelation hsr3 = (TypedIORelation) hs.newRelation("HSr3");
        hsst.link(hsr3);
        ctIncSt.link(hsr3);
        ctDecSt.link(hsr3);
        ctrlSt.link(hsr3);

        Relation hsr4 = hs.newRelation("HSr4");

        //hstr.link(hsr4);
        ctIncTr.link(hsr4);
        ctDecTr.link(hsr4);

        // connect the top level system
        this.connect(source.output, hsin);

        //sys.connect(hsout, responsePlot.input);
        this.connect(hsst, responsePlot.input);

        //this.connect(hstr, responsePlot.input);
        // try to run the system
        topdir.stopTime.setToken(new DoubleToken(5.0));

        // CT embedded director 1 parameters
        ctIncDir.initStepSize.setToken(new DoubleToken(0.01));
        ctIncDir.minStepSize.setToken(new DoubleToken(1e-3));
        ctIncDir.maxStepSize.setToken(new DoubleToken(0.5));

        StringToken tok = new StringToken(
                "ptolemy.domains.ct.kernel.solver.DerivativeResolver");
        ctIncDir.breakpointODESolver.setToken(tok);

        // Parameter dfsol = (Parameter)ctIncDir.getAttribute("ODESolver");
        tok = new StringToken(
                "ptolemy.domains.ct.kernel.solver.ExplicitRK23Solver");
        ctIncDir.ODESolver.setToken(tok);

        // CT embedded director 2  parameters
        ctDecDir.initStepSize.setToken(new DoubleToken(0.01));
        ctDecDir.minStepSize.setToken(new DoubleToken(1e-3));
        ctDecDir.maxStepSize.setToken(new DoubleToken(0.5));

        tok = new StringToken(
                "ptolemy.domains.ct.kernel.solver.DerivativeResolver");
        ctDecDir.breakpointODESolver.setToken(tok);
        tok = new StringToken(
                "ptolemy.domains.ct.kernel.solver.ExplicitRK23Solver");
        ctDecDir.ODESolver.setToken(tok);
        ctGain.factor.setToken(new DoubleToken(-1.0));

        // CT director parameters
        topdir.initStepSize.setToken(new DoubleToken(0.01));
        topdir.minStepSize.setToken(new DoubleToken(1e-3));
        topdir.maxStepSize.setToken(new DoubleToken(0.5));
        tok = new StringToken(
                "ptolemy.domains.ct.kernel.solver.DerivativeResolver");
        topdir.breakpointODESolver.setToken(tok);
        tok = new StringToken(
                "ptolemy.domains.ct.kernel.solver.ExplicitRK23Solver");
        topdir.ODESolver.setToken(tok);
    }
}
TOP

Related Classes of ptolemy.domains.ct.demo.Thermostat.Thermostat

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.