Move flight data secondary data copying to constructor
This commit is contained in:
parent
70e678e990
commit
e9146a35d4
@ -11,7 +11,6 @@ import java.util.List;
|
|||||||
import net.sf.openrocket.logging.Warning;
|
import net.sf.openrocket.logging.Warning;
|
||||||
import net.sf.openrocket.logging.WarningSet;
|
import net.sf.openrocket.logging.WarningSet;
|
||||||
import net.sf.openrocket.document.Simulation;
|
import net.sf.openrocket.document.Simulation;
|
||||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
|
||||||
import net.sf.openrocket.simulation.FlightData;
|
import net.sf.openrocket.simulation.FlightData;
|
||||||
import net.sf.openrocket.simulation.FlightDataBranch;
|
import net.sf.openrocket.simulation.FlightDataBranch;
|
||||||
import net.sf.openrocket.simulation.FlightDataType;
|
import net.sf.openrocket.simulation.FlightDataType;
|
||||||
@ -75,7 +74,7 @@ public class CSVExport {
|
|||||||
writer.println();
|
writer.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
writeData(writer, simulation, branch, fields, units, fieldSeparator, decimalPlaces, isExponentialNotation,
|
writeData(writer, branch, fields, units, fieldSeparator, decimalPlaces, isExponentialNotation,
|
||||||
eventComments, commentStarter);
|
eventComments, commentStarter);
|
||||||
|
|
||||||
|
|
||||||
@ -90,60 +89,17 @@ public class CSVExport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeData(PrintWriter writer, Simulation simulation, FlightDataBranch branch,
|
private static void writeData(PrintWriter writer, FlightDataBranch branch,
|
||||||
FlightDataType[] fields, Unit[] units, String fieldSeparator, int decimalPlaces, boolean isExponentialNotation,
|
FlightDataType[] fields, Unit[] units, String fieldSeparator, int decimalPlaces, boolean isExponentialNotation,
|
||||||
boolean eventComments, String commentStarter) {
|
boolean eventComments, String commentStarter) {
|
||||||
final FlightData data = simulation.getSimulatedData();
|
|
||||||
final int stageNr = data.getStageNr(branch);
|
|
||||||
AxialStage stage = simulation.getRocket().getStage(stageNr);
|
|
||||||
|
|
||||||
// Time variable
|
// Time variable
|
||||||
List<Double> time = branch.get(FlightDataType.TYPE_TIME);
|
List<Double> time = branch.get(FlightDataType.TYPE_TIME);
|
||||||
|
|
||||||
// Extra stages don't contain all the simulation data. Instead, the data is stored in the sustainer stage
|
|
||||||
// (since the data is the same for all stages until there is separation).
|
|
||||||
// For CSV export however, we want to copy the data from the sustainer stage to the extra stage.
|
|
||||||
boolean copySustainerData = stageNr > 0 && time != null && time.get(0) > 0;
|
|
||||||
FlightDataBranch sustainerBranch = null;
|
|
||||||
Double firstBranchTime = null;
|
|
||||||
int lastSustainerIndex = 0;
|
|
||||||
if (copySustainerData) {
|
|
||||||
firstBranchTime = time.get(0);
|
|
||||||
sustainerBranch = data.getBranch(0);
|
|
||||||
List<Double> sustainerTime = sustainerBranch.get(FlightDataType.TYPE_TIME);
|
|
||||||
|
|
||||||
if (sustainerTime != null) {
|
|
||||||
for (int i = 0; i < sustainerTime.size(); i++) {
|
|
||||||
if (sustainerTime.get(i) >= firstBranchTime) {
|
|
||||||
lastSustainerIndex = i - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Double> timeToCopy = sustainerTime.subList(0, lastSustainerIndex + 1);
|
|
||||||
time.addAll(0, timeToCopy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number of data points
|
// Number of data points
|
||||||
int n = time != null ? time.size() : branch.getLength();
|
int n = time != null ? time.size() : branch.getLength();
|
||||||
|
|
||||||
// Flight events in occurrence order
|
// Flight events in occurrence order
|
||||||
List<FlightEvent> events = branch.getEvents();
|
List<FlightEvent> events = branch.getEvents();
|
||||||
if (copySustainerData) {
|
|
||||||
List<FlightEvent> sustainerEvents = sustainerBranch.getEvents();
|
|
||||||
|
|
||||||
// Copy all events from the sustainer that belong to this stage
|
|
||||||
for (FlightEvent event : sustainerEvents) {
|
|
||||||
// Stage separation is present both in the sustainer data and extra stage data (don't really know why...)
|
|
||||||
if (event.getType() == FlightEvent.Type.STAGE_SEPARATION) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (stage == event.getSource() || stage.containsChild(event.getSource())) {
|
|
||||||
events.add(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Collections.sort(events);
|
Collections.sort(events);
|
||||||
int eventPosition = 0;
|
int eventPosition = 0;
|
||||||
|
|
||||||
@ -151,11 +107,6 @@ public class CSVExport {
|
|||||||
List<List<Double>> fieldValues = new ArrayList<>();
|
List<List<Double>> fieldValues = new ArrayList<>();
|
||||||
for (FlightDataType t : fields) {
|
for (FlightDataType t : fields) {
|
||||||
List<Double> values = branch.get(t);
|
List<Double> values = branch.get(t);
|
||||||
if (copySustainerData) {
|
|
||||||
List<Double> sustainerValues = sustainerBranch.get(t);
|
|
||||||
List<Double> valuesToCopy = sustainerValues.subList(0, lastSustainerIndex + 1);
|
|
||||||
values.addAll(0, valuesToCopy);
|
|
||||||
}
|
|
||||||
fieldValues.add(values);
|
fieldValues.add(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +489,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
SimulationStatus boosterStatus = new SimulationStatus(currentStatus);
|
SimulationStatus boosterStatus = new SimulationStatus(currentStatus);
|
||||||
|
|
||||||
// Prepare the new simulation branch
|
// Prepare the new simulation branch
|
||||||
boosterStatus.setFlightData(new FlightDataBranch(boosterStage.getName(), currentStatus.getFlightData()));
|
boosterStatus.setFlightData(new FlightDataBranch(boosterStage.getName(), boosterStage, currentStatus.getFlightData()));
|
||||||
boosterStatus.getFlightData().addEvent(event);
|
boosterStatus.getFlightData().addEvent(event);
|
||||||
|
|
||||||
// Mark the current status as having dropped the current stage and all stages below it
|
// Mark the current status as having dropped the current stage and all stages below it
|
||||||
|
@ -6,6 +6,7 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.util.ArrayList;
|
import net.sf.openrocket.util.ArrayList;
|
||||||
import net.sf.openrocket.util.Monitorable;
|
import net.sf.openrocket.util.Monitorable;
|
||||||
import net.sf.openrocket.util.Mutable;
|
import net.sf.openrocket.util.Mutable;
|
||||||
@ -30,11 +31,10 @@ public class FlightDataBranch implements Monitorable {
|
|||||||
/** The name of this flight data branch. */
|
/** The name of this flight data branch. */
|
||||||
private final String branchName;
|
private final String branchName;
|
||||||
|
|
||||||
private final Map<FlightDataType, ArrayList<Double>> values =
|
private final Map<FlightDataType, ArrayList<Double>> values = new LinkedHashMap<>();
|
||||||
new LinkedHashMap<FlightDataType, ArrayList<Double>>();
|
|
||||||
|
|
||||||
private final Map<FlightDataType, Double> maxValues = new HashMap<FlightDataType, Double>();
|
private final Map<FlightDataType, Double> maxValues = new HashMap<>();
|
||||||
private final Map<FlightDataType, Double> minValues = new HashMap<FlightDataType, Double>();
|
private final Map<FlightDataType, Double> minValues = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* time for the rocket to reach apogee if the flight had been no recovery deployment
|
* time for the rocket to reach apogee if the flight had been no recovery deployment
|
||||||
@ -77,23 +77,19 @@ public class FlightDataBranch implements Monitorable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a flight data branch with one data point copied from its parent. Intended for use
|
* Make a flight data branch with all data points copied from its parent. Intended for use
|
||||||
* when creating a new branch upon stage separation, so the data at separation is present
|
* when creating a new branch upon stage separation, so the data at separation is present
|
||||||
* in both branches (and if the new branch has an immediate exception, it can be plotted)
|
* in both branches (and if the new branch has an immediate exception, it can be plotted)
|
||||||
|
*
|
||||||
|
* @param branchName the name of the new branch.
|
||||||
|
* @param srcComponent the component that is the source of the new branch.
|
||||||
|
* @param parent the parent branch to copy data from.
|
||||||
*/
|
*/
|
||||||
public FlightDataBranch(String branchName, FlightDataBranch parent) {
|
public FlightDataBranch(String branchName, RocketComponent srcComponent, FlightDataBranch parent) {
|
||||||
this.branchName = branchName;
|
this.branchName = branchName;
|
||||||
|
|
||||||
// need to have at least one type to set up values
|
// Copy all the values from the parent
|
||||||
values.put(FlightDataType.TYPE_TIME, new ArrayList<Double>());
|
copyValuesFromBranch(parent, srcComponent);
|
||||||
minValues.put(FlightDataType.TYPE_TIME, Double.NaN);
|
|
||||||
maxValues.put(FlightDataType.TYPE_TIME, Double.NaN);
|
|
||||||
|
|
||||||
// copy all values into new FlightDataBranch
|
|
||||||
this.addPoint();
|
|
||||||
for (FlightDataType t : parent.getTypes()) {
|
|
||||||
this.setValue(t, parent.getLast(t));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,12 +111,27 @@ public class FlightDataBranch implements Monitorable {
|
|||||||
public void addPoint() {
|
public void addPoint() {
|
||||||
mutable.check();
|
mutable.check();
|
||||||
|
|
||||||
for (FlightDataType t : values.keySet()) {
|
for (FlightDataType type : values.keySet()) {
|
||||||
values.get(t).add(Double.NaN);
|
sanityCheckValues(type, Double.NaN);
|
||||||
|
values.get(type).add(Double.NaN);
|
||||||
}
|
}
|
||||||
modID++;
|
modID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sanityCheckValues(FlightDataType type, Double value) {
|
||||||
|
ArrayList<Double> list = values.get(type);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
list = new ArrayList<>();
|
||||||
|
int n = getLength();
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
list.add(Double.NaN);
|
||||||
|
}
|
||||||
|
values.put(type, list);
|
||||||
|
minValues.put(type, value);
|
||||||
|
maxValues.put(type, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value for a specific data type at the latest point. New variable types can be
|
* Set the value for a specific data type at the latest point. New variable types can be
|
||||||
@ -132,20 +143,10 @@ public class FlightDataBranch implements Monitorable {
|
|||||||
*/
|
*/
|
||||||
public void setValue(FlightDataType type, double value) {
|
public void setValue(FlightDataType type, double value) {
|
||||||
mutable.check();
|
mutable.check();
|
||||||
|
|
||||||
|
sanityCheckValues(type, value);
|
||||||
ArrayList<Double> list = values.get(type);
|
ArrayList<Double> list = values.get(type);
|
||||||
|
|
||||||
if (list == null) {
|
|
||||||
list = new ArrayList<Double>();
|
|
||||||
int n = getLength();
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
list.add(Double.NaN);
|
|
||||||
}
|
|
||||||
values.put(type, list);
|
|
||||||
minValues.put(type, value);
|
|
||||||
maxValues.put(type, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list.size() > 0) {
|
if (list.size() > 0) {
|
||||||
list.set(list.size() - 1, value);
|
list.set(list.size() - 1, value);
|
||||||
}
|
}
|
||||||
@ -161,7 +162,44 @@ public class FlightDataBranch implements Monitorable {
|
|||||||
}
|
}
|
||||||
modID++;
|
modID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all the current values in the branch and copies the values from the given branch.
|
||||||
|
* @param srcBranch the branch to copy values from
|
||||||
|
* @param srcComponent the component that is the source of this branch (used for copying events)
|
||||||
|
*/
|
||||||
|
private void copyValuesFromBranch(FlightDataBranch srcBranch, RocketComponent srcComponent) {
|
||||||
|
this.values.clear();
|
||||||
|
|
||||||
|
// Need to have at least one type to set up values
|
||||||
|
values.put(FlightDataType.TYPE_TIME, new ArrayList<>());
|
||||||
|
minValues.put(FlightDataType.TYPE_TIME, Double.NaN);
|
||||||
|
maxValues.put(FlightDataType.TYPE_TIME, Double.NaN);
|
||||||
|
|
||||||
|
if (srcBranch == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy flight data
|
||||||
|
for (int i = 0; i < srcBranch.getLength(); i++) {
|
||||||
|
this.addPoint();
|
||||||
|
for (FlightDataType type : srcBranch.getTypes()) {
|
||||||
|
this.setValue(type, srcBranch.getByIndex(type, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy flight events belonging to this branch
|
||||||
|
List<FlightEvent> sustainerEvents = srcBranch.getEvents();
|
||||||
|
for (FlightEvent event : sustainerEvents) {
|
||||||
|
// Stage separation is already added elsewhere, so don't copy it over (otherwise you have a duplicate)
|
||||||
|
if (event.getType() == FlightEvent.Type.STAGE_SEPARATION) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (srcComponent != null && (srcComponent == event.getSource() || srcComponent.containsChild(event.getSource()))) {
|
||||||
|
events.add(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the branch name.
|
* Return the branch name.
|
||||||
@ -203,6 +241,23 @@ public class FlightDataBranch implements Monitorable {
|
|||||||
return null;
|
return null;
|
||||||
return list.clone();
|
return list.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the specified type at the specified index.
|
||||||
|
* @param type the variable type
|
||||||
|
* @param index the data index of the value
|
||||||
|
* @return the value at the specified index
|
||||||
|
*/
|
||||||
|
public Double getByIndex(FlightDataType type, int index) {
|
||||||
|
if (index < 0 || index >= getLength()) {
|
||||||
|
throw new IllegalArgumentException("Index out of bounds");
|
||||||
|
}
|
||||||
|
ArrayList<Double> list = values.get(type);
|
||||||
|
if (list == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return list.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the last value of the specified type in the branch, or NaN if the type is
|
* Return the last value of the specified type in the branch, or NaN if the type is
|
||||||
|
@ -192,9 +192,8 @@ public class SimulationPlot {
|
|||||||
}
|
}
|
||||||
data[axis].addSeries(series);
|
data[axis].addSeries(series);
|
||||||
}
|
}
|
||||||
// For each of the secondary branches, we use data from branch 0 for the earlier times
|
// Secondary branches
|
||||||
for (int branchIndex = 1; branchIndex < branchCount; branchIndex++) {
|
for (int branchIndex = 1; branchIndex < branchCount; branchIndex++) {
|
||||||
FlightDataBranch primaryBranch = simulation.getSimulatedData().getBranch(0);
|
|
||||||
FlightDataBranch thisBranch = simulation.getSimulatedData().getBranch(branchIndex);
|
FlightDataBranch thisBranch = simulation.getSimulatedData().getBranch(branchIndex);
|
||||||
|
|
||||||
// Ignore empty branches
|
// Ignore empty branches
|
||||||
@ -206,25 +205,10 @@ public class SimulationPlot {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get first time index used in secondary branch;
|
|
||||||
double firstSampleTime = thisBranch.get(FlightDataType.TYPE_TIME).get(0);
|
|
||||||
|
|
||||||
XYSeries series = new XYSeries(seriesCount++, false, true);
|
XYSeries series = new XYSeries(seriesCount++, false, true);
|
||||||
series.setDescription(thisBranch.getBranchName() + ": " + name);
|
series.setDescription(thisBranch.getBranchName() + ": " + name);
|
||||||
|
|
||||||
// Copy the first points from the primaryBranch.
|
// Copy all the data from the secondary branch
|
||||||
List<Double> primaryT = primaryBranch.get(FlightDataType.TYPE_TIME);
|
|
||||||
List<Double> primaryx = primaryBranch.get(domainType);
|
|
||||||
List<Double> primaryy = primaryBranch.get(type);
|
|
||||||
|
|
||||||
for (int j = 0; j < primaryT.size(); j++) {
|
|
||||||
if (primaryT.get(j) >= firstSampleTime) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
series.add(domainUnit.toUnit(primaryx.get(j)), unit.toUnit(primaryy.get(j)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now copy all the data from the secondary branch
|
|
||||||
List<Double> plotx = thisBranch.get(domainType);
|
List<Double> plotx = thisBranch.get(domainType);
|
||||||
List<Double> ploty = thisBranch.get(type);
|
List<Double> ploty = thisBranch.get(type);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user