Skip to content

Commit

Permalink
Pre-Test
Browse files Browse the repository at this point in the history
  • Loading branch information
marl0rd committed Jun 19, 2014
1 parent f60f81d commit 377f697
Show file tree
Hide file tree
Showing 5 changed files with 320 additions and 54 deletions.
15 changes: 13 additions & 2 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import process.SecondOrderSystem;
import gui.Gui;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
* Created by marlon on 6/13/14.
*/
public class Main {
public class Main extends Application {
public static void main(String[] args){
launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
Gui gui = new Gui();
Scene scene = new Scene(gui);
primaryStage.setScene(scene);
primaryStage.show();
}
}
101 changes: 101 additions & 0 deletions src/main/java/conicaltank/ConicalTankTransferFunction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package conicaltank;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.DoublePropertyBase;

/**
* Created by marlon on 6/18/14.
*
* G(s) = gain
* ---------
* tau*s + 1
*/
public class ConicalTankTransferFunction {

// PROPERTIES //
private static final double HEIGHT = 10.0;
private static final double RADIUS = 5.0;
private static final double GRAVITY = 9.8;
private static final double OBSTRUCTION = 1.5;

private DoubleProperty heightOperationPoint;
private DoubleProperty inflowOperationPoint;

private double gain;
private double tau;

// CONSTRUCTOR //
public ConicalTankTransferFunction() {
this.heightOperationPoint = new DoublePropertyBase(0.0001) {
@Override protected void invalidated() {
set(get());
}
@Override public Object getBean() {
return this;
}
@Override public String getName() {
return "heightOperationPoint";
}
};
this.inflowOperationPoint = new DoublePropertyBase(1.0) {
@Override
protected void invalidated() {
recalculate();
set(get());
}
@Override public Object getBean() {
return this;
}
@Override public String getName() {
return "inflowOperationPoint";
}
};
recalculate();
}

// METHODS //
private void recalculate(){
double alpha = ((9/2) *
(OBSTRUCTION * Math.pow(HEIGHT,2) * Math.sqrt(2*GRAVITY) * Math.pow(heightOperationPoint.get(), -5/2)) /
(2 * Math.PI * Math.pow(RADIUS,2))) -
((6 * Math.pow(HEIGHT,2) * inflowOperationPoint.get() * Math.pow(heightOperationPoint.get(),-3)) /
(Math.PI * Math.pow(RADIUS,2)));

double beta = (3 * Math.pow(HEIGHT,2) * Math.pow(heightOperationPoint.get(),-2)) /
(Math.PI * Math.pow(RADIUS,2));

gain = beta / alpha;
tau = 1 / alpha;
}

// SETTERS AND GETTERS //
public double getGain() {
recalculate();
return gain;
}
public double getTau() {
recalculate();
return tau;
}


public double getHeightOperationPoint() {
return heightOperationPoint.get();
}
public DoubleProperty heightOperationPointProperty() {
return heightOperationPoint;
}
public void setHeightOperationPoint(double heightOperationPoint) {
this.heightOperationPoint.set(heightOperationPoint);
}

public double getInflowOperationPoint() {
return inflowOperationPoint.get();
}
public DoubleProperty inflowOperationPointProperty() {
return inflowOperationPoint;
}
public void setInflowOperationPoint(double inflowOperationPoint) {
this.inflowOperationPoint.set(inflowOperationPoint);
}
}
116 changes: 80 additions & 36 deletions src/main/java/gui/Gui.java
Original file line number Diff line number Diff line change
@@ -1,42 +1,54 @@
package gui;

import javafx.beans.property.*;
import conicaltank.ConicalTankTransferFunction;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import process.SystemSimulator;

import java.io.IOException;
import java.net.URL;
import java.sql.Timestamp;
import java.util.ResourceBundle;

/**
* Created by marlon on 6/16/14.
*/
public class Gui extends AnchorPane{
public class Gui extends AnchorPane implements Initializable{
private static final int TRENDING_DATA_LIMIT = 50;
private static final long SAMPLING_TIME = 500;

@FXML private TextField tankAreaTextField;
@FXML private TextField gravityTextField;
@FXML private TextField obstructionTextField;
@FXML private TextField samplingTimeTextField;
@FXML private TextField kp;
@FXML private TextField Ti;
@FXML private Button applyButton;
@FXML private CategoryAxis categoryAxis;
@FXML private NumberAxis numberAxis;
@FXML private LineChart<Double, Timestamp> trendings;
@FXML private TextField heightSetPointTextField;
@FXML private Button newHeightEnteredButton;
@FXML private MenuItem startSimulationMenuItem;
@FXML private MenuItem stopSimulationMenuItem;
@FXML private Label heightOperationPointLabel;
@FXML private Label inflowOperationPointLabel;
@FXML private Label samplingTimeLabel;
@FXML private Label kpLabel;
@FXML private Label kiLabel;
@FXML private Label tauLabel;
@FXML private Label gainLabel;
@FXML private Label inputLabel;
@FXML private Label outputLabel;

private DoubleProperty output;
private long lastUpdate;
private ObjectProperty<Timestamp> timestamp;
@FXML private CategoryAxis categoryAxis;
@FXML private NumberAxis numberAxis;
@FXML private LineChart<Double, Timestamp> trendings;
private final XYChart.Series<Double, Timestamp> outputTrendingSeries;

private final XYChart.Series<Double, Timestamp> systemOutput = new XYChart.Series<>();
private ConicalTankTransferFunction conicalTank;
private SystemSimulator processSimulator;
private long lastUpdate;

public Gui() {
try {
Expand All @@ -48,32 +60,64 @@ public Gui() {
throw new RuntimeException(exception);
}

output = new SimpleDoubleProperty(this, "systemOutput", 0.0);
lastUpdate = System.currentTimeMillis();
timestamp = new ObjectPropertyBase<Timestamp>(new Timestamp(System.currentTimeMillis())) {
@Override protected void invalidated() {
if ((System.currentTimeMillis() - lastUpdate) > SAMPLING_TIME) {
systemOutput.getData().add(new XYChart.Data<>(output.getValue(), new Timestamp(System.currentTimeMillis())));
while (systemOutput.getData().size() > TRENDING_DATA_LIMIT) {
systemOutput.getData().remove(0);
}
}
}
@Override public Object getBean() {
return this;
}
@Override public String getName() {
return "timestamp";
}
};

outputTrendingSeries = new XYChart.Series<>();
numberAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(numberAxis) {
@Override
public String toString(Number object) {
return String.format("%6.2f", object);
}
});
trendings.getData().add(systemOutput);
trendings.getData().add(outputTrendingSeries);

conicalTank = new ConicalTankTransferFunction();
}

@Override
public void initialize(URL location, ResourceBundle resources) {
registerListeners();
}

private void registerListeners() {
startSimulationMenuItem.setOnAction(value -> startSimulation());
stopSimulationMenuItem.setOnAction(value -> stopSimulation());
newHeightEnteredButton.setOnAction(value -> recalculate());

heightOperationPointLabel.textProperty().bind(conicalTank.heightOperationPointProperty().asString());
inflowOperationPointLabel.textProperty().bind(conicalTank.inflowOperationPointProperty().asString());
samplingTimeLabel.textProperty().bind(processSimulator.getProcess().samplingTimeProperty().asString());
tauLabel.textProperty().bind(processSimulator.getProcess().tauProperty().asString());
gainLabel.textProperty().bind(processSimulator.getProcess().gainProperty().asString());
inputLabel.textProperty().bind(processSimulator.getProcess().inputProperty().asString());
outputLabel.textProperty().bind(processSimulator.getProcess().outputProperty().asString());
processSimulator.timeStampProperty().addListener((observable, oldValue, newValue) -> updateTrending(newValue));
// kpLabel;
// kiLabel;
}

private void startSimulation(){
lastUpdate = System.currentTimeMillis();
processSimulator = new SystemSimulator();
processSimulator.run();
}

private void stopSimulation(){
processSimulator.interrupt();
}

private void updateTrending(Timestamp currentTime){
if ((System.currentTimeMillis() - lastUpdate) > SAMPLING_TIME) {
outputTrendingSeries.getData().add(new XYChart.Data<>(processSimulator.getProcess().getOutput(), currentTime));
while (outputTrendingSeries.getData().size() > TRENDING_DATA_LIMIT) {
outputTrendingSeries.getData().remove(0);
}
lastUpdate = currentTime.getTime();
}
}

private void recalculate() {
conicalTank.setHeightOperationPoint(Double.parseDouble(heightOperationPointLabel.getText()));
processSimulator.getProcess().setGain(conicalTank.getGain());
processSimulator.getProcess().setTau(conicalTank.getTau());
}

}
78 changes: 62 additions & 16 deletions src/main/java/process/FirstOrderSystem.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,82 @@
package process;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleLongProperty;

/**
* Created by marlon on 6/16/14.
*
* The transfer function is in form:
*
* G(s) = zero
* ------
* s+pole
* G(s) = gain
* ---------
* tau*s + 1
*
*/
public class FirstOrderSystem {
private double zero;
private double pole;
private DoubleProperty input;
private DoubleProperty output;
private DoubleProperty gain;
private DoubleProperty tau;
private LongProperty samplingTime;

public FirstOrderSystem(double zero) {
this.zero = zero;
public FirstOrderSystem() {
input = new SimpleDoubleProperty(this, "input", 0.0);
output = new SimpleDoubleProperty(this, "output", 0.0);
gain = new SimpleDoubleProperty(this, "gaing", 0.0);
tau = new SimpleDoubleProperty(this, "tau", 0.0);
samplingTime = new SimpleLongProperty(this, "samplingTime", 100);
}

public double getZero() {
return zero;
public double getInput() {
return input.get();
}
public DoubleProperty inputProperty() {
return input;
}
public void setInput(double input) {
this.input.set(input);
}

public void setZero(double zero) {
this.zero = zero;
public double getOutput() {
return output.get();
}
public DoubleProperty outputProperty() {
return output;
}
public void setOutput(double output) {
this.output.set(output);
}

public double getPole() {
return pole;
public double getGain() {
return gain.get();
}
public DoubleProperty gainProperty() {
return gain;
}
public void setGain(double gain) {
this.gain.set(gain);
}

public void setPole(double pole) {
this.pole = pole;
public double getTau() {
return tau.get();
}
public DoubleProperty tauProperty() {
return tau;
}
public void setTau(double tau) {
this.tau.set(tau);
}

public long getSamplingTime() {
return samplingTime.get();
}
public LongProperty samplingTimeProperty() {
return samplingTime;
}
public void setSamplingTime(long samplingTime) {
this.samplingTime.set(samplingTime);
}
}
}
Loading

0 comments on commit 377f697

Please sign in to comment.