package me.drton.flightplot.processors;
import me.drton.flightplot.processors.tools.LowPassFilter;
import me.drton.flightplot.processors.tools.PID;
import java.util.HashMap;
import java.util.Map;
/**
* User: ton Date: 20.06.13 Time: 6:06
*/
public class PosPIDControlSimulator extends PlotProcessor {
private double startTime;
private double startSP;
private double startSPRate;
private double thrustK;
private double accScale;
private double drag;
private double awuRate;
private LowPassFilter propeller = new LowPassFilter();
private PID pidPos = new PID();
private double pos;
private double rate;
private double posSP;
private double timePrev;
@Override
public Map<String, Object> getDefaultParameters() {
Map<String, Object> params = new HashMap<String, Object>();
params.put("Start Time", 100.0);
params.put("Start SP", 1.0);
params.put("Start SP Rate", 1.0);
params.put("Thrust T", 0.03);
params.put("Thrust K", 40.0);
params.put("Ctrl P", 0.1);
params.put("Ctrl I", 0.05);
params.put("Ctrl D", 0.1);
params.put("Ctrl Limit", 0.2);
params.put("AWU Rate", 1.0);
params.put("Acc Scale", 1.0);
params.put("Drag", 0.0);
return params;
}
@Override
public void init() {
propeller.reset();
pos = 0.0;
rate = 0.0;
posSP = 0.0;
timePrev = Double.NaN;
startTime = (Double) parameters.get("Start Time");
startSP = (Double) parameters.get("Start SP");
startSPRate = (Double) parameters.get("Start SP Rate");
thrustK = (Double) parameters.get("Thrust K");
accScale = (Double) parameters.get("Acc Scale");
drag = (Double) parameters.get("Drag");
awuRate = (Double) parameters.get("AWU Rate");
propeller.setT((Double) parameters.get("Thrust T"));
pidPos.reset();
pidPos.setK((Double) parameters.get("Ctrl P"), (Double) parameters.get("Ctrl I"),
(Double) parameters.get("Ctrl D"), (Double) parameters.get("Ctrl Limit"), PID.MODE.DERIVATIVE_CALC);
addSeries("Pos");
addSeries("Rate");
addSeries("Acc");
addSeries("Ctrl");
}
@Override
public void process(double time, Map<String, Object> update) {
if (update.containsKey("ATT.Roll")) { // Act only on attitude updates
if (!Double.isNaN(timePrev)) {
double dt = time - timePrev;
double spRate = 0.0;
if (time > startTime && posSP < startSP) {
spRate = startSPRate;
posSP += startSPRate * dt;
}
double force = propeller.getOutput(time, 0.0);
double acc = force * thrustK - drag * rate;
rate += acc * dt;
pos += rate * dt;
double awuW =
awuRate == 0.0 ? 1.0 : Math.exp(-(spRate * spRate + rate * rate) / 2.0 / awuRate / awuRate);
double thrustControl = pidPos.getOutput(posSP, pos, spRate - rate, dt, awuW);
propeller.setInput(thrustControl);
addPoint(0, time, pos);
addPoint(1, time, rate);
if (accScale != 0.0)
addPoint(2, time, acc * accScale);
addPoint(3, time, pidPos.getIntegral() * 10);
}
timePrev = time;
}
}
}