From fb6cc5f059e7db3ae08bbdcbbb647031511c3bc6 Mon Sep 17 00:00:00 2001 From: plaa Date: Sun, 19 Feb 2012 18:41:04 +0000 Subject: [PATCH] Display computer motor class in motor selection dialog git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@430 180e2498-e6e9-4542-8430-84ac67f01cd8 --- core/ChangeLog | 4 + .../dialogs/motor/thrustcurve/MotorClass.java | 89 ++++++++++++ .../ThrustCurveMotorSelectionPanel.java | 135 ++++++++++-------- 3 files changed, 166 insertions(+), 62 deletions(-) create mode 100644 core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorClass.java diff --git a/core/ChangeLog b/core/ChangeLog index e86da4f1..e1df0361 100644 --- a/core/ChangeLog +++ b/core/ChangeLog @@ -1,3 +1,7 @@ +2012-02-19 Sampo Niskanen + + * Display computed motor class + 2012-02-16 Sampo Niskanen * [BUG] Freeze when dropping component on child component diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorClass.java b/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorClass.java new file mode 100644 index 00000000..b6b35561 --- /dev/null +++ b/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorClass.java @@ -0,0 +1,89 @@ +package net.sf.openrocket.gui.dialogs.motor.thrustcurve; + +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.BugException; + +/** + * NAR approved motor classes (http://www.nar.org/NARmotors.html). + * + * @author Sampo Niskanen + */ +public enum MotorClass { + + A18("1/8A", 0, 0.3125), + A14("1/4A", 0.3125, 0.625), + A12("1/2A", 0.625, 1.25), + A("A", 1.25, 2.5), + B("B", 2.5, 5), + C("C", 5, 10), + D("D", 10, 20), + E("E", 20, 40), + F("F", 40, 80), + G("G", 80, 160), + H("H", 160, 320), + I("I", 320, 640), + J("J", 640, 1280), + K("K", 1280, 2560), + L("L", 2560, 5120), + M("M", 5120, 10240), + N("N", 10240, 20480), + O("O", 20480, 40960), + OVER("> O", 40960, Double.MAX_VALUE) { + @Override + public String getDescription(double impulse) { + return "Over O"; + } + + @Override + public String getClassDescription() { + return "Over O-class (over " + UnitGroup.UNITS_IMPULSE.toStringUnit(40960) + ")"; + } + }; + + + private final String className; + private final double min; + private final double max; + + + private MotorClass(String className, double min, double max) { + this.className = className; + this.min = min; + this.max = max; + } + + + public String getDescription(double impulse) { + double percent = (impulse - min) / (max - min) * 100; + if (percent < 1) { + // 0% looks stupid + percent = 1; + } + return String.format("%d%% %s", Math.round(percent), className); + } + + public String getClassDescription() { + return "Class " + className + " (" + UnitGroup.UNITS_IMPULSE.toStringUnit(min) + " - " + UnitGroup.UNITS_IMPULSE.toStringUnit(max) + ")"; + } + + + /** + * Find the appropriate motor class for the provided impulse. + */ + public static MotorClass getMotorClass(double impulse) { + double epsilon = 0.0000001; + + // Round large values so 640.1 Ns (which is displayed as 640 Ns) is counted as I-class + if (impulse >= 100) { + impulse = Math.rint(impulse); + } + + for (MotorClass m : MotorClass.values()) { + if (impulse <= m.max + epsilon) { + return m; + } + } + throw new BugException("Could not find motor class for impulse " + impulse); + } + +} diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java b/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java index d49e58f5..646e402e 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java +++ b/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java @@ -54,7 +54,6 @@ import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.motor.Motor; -import net.sf.openrocket.motor.MotorDigest; import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; @@ -75,19 +74,19 @@ import org.jfree.data.xy.XYSeriesCollection; public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelector { private static final LogHelper log = Application.getLogger(); private static final Translator trans = Application.getTranslator(); - + private static final double MOTOR_SIMILARITY_THRESHOLD = 0.95; private static final int SHOW_ALL = 0; private static final int SHOW_SMALLER = 1; private static final int SHOW_EXACT = 2; private static final String[] SHOW_DESCRIPTIONS = { - //// Show all motors - trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc1"), + //// Show all motors + trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc1"), //// Show motors with diameter less than that of the motor mount - trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc2"), + trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc2"), //// Show motors with diameter equal to that of the motor mount - trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc3") + trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc3") }; private static final int SHOW_MAX = 2; @@ -101,14 +100,14 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec private static final ThrustCurveMotorComparator MOTOR_COMPARATOR = new ThrustCurveMotorComparator(); - - + + private final List database; private final double diameter; private CloseableDialog dialog = null; - + private final ThrustCurveMotorDatabaseModel model; private final JTable table; private final TableRowSorter sorter; @@ -118,12 +117,13 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec private final JTextField searchField; private String[] searchTerms = new String[0]; - + private final JLabel curveSelectionLabel; private final JComboBox curveSelectionBox; private final DefaultComboBoxModel curveSelectionModel; private final JLabel totalImpulseLabel; + private final JLabel classificationLabel; private final JLabel avgThrustLabel; private final JLabel maxThrustLabel; private final JLabel burnTimeLabel; @@ -159,7 +159,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec this.diameter = diameter; - + // Construct the database (adding the current motor if not in the db already) List db; // TODO - ugly blind cast. @@ -185,8 +185,8 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec } database = db; - - + + //// GUI JPanel panel; @@ -195,8 +195,8 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec panel = new JPanel(new MigLayout("fill")); this.add(panel, "grow"); - - + + // Selection label //// Select rocket motor: label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Selrocketmotor"), Style.BOLD); @@ -246,12 +246,12 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec }); panel.add(hideSimilarBox, "gapleft para, spanx, growx, wrap para"); - + // Motor selection table model = new ThrustCurveMotorDatabaseModel(database); table = new JTable(model); - + // Set comparators and widths table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); sorter = new TableRowSorter(model); @@ -290,22 +290,22 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec } }); - + JScrollPane scrollpane = new JScrollPane(); scrollpane.setViewportView(table); panel.add(scrollpane, "grow, width :500:, height :300:, spanx, wrap para"); - - - + + + // Motor mount diameter label //// Motor mount diameter: - label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Motormountdia")+ " " + + label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Motormountdia") + " " + UnitGroup.UNITS_MOTOR_DIMENSIONS.getDefaultUnit().toStringUnit(diameter)); panel.add(label, "gapright 30lp, spanx, split"); - - + + // Search field //// Search: label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Search")); @@ -345,15 +345,15 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec }); panel.add(searchField, "growx, wrap"); - - + + // Vertical split this.add(panel, "grow"); this.add(new JSeparator(JSeparator.VERTICAL), "growy, gap para para"); panel = new JPanel(new MigLayout("fill")); - - + + // Thrust curve selection //// Select thrust curve: curveSelectionLabel = new JLabel(trans.get("TCMotorSelPan.lbl.Selectthrustcurve")); @@ -373,10 +373,10 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec }); panel.add(curveSelectionBox, "growx, wrap para"); - - - - + + + + // Ejection charge delay: panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Ejectionchargedelay"))); @@ -404,16 +404,20 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec panel.add(new StyledLabel(trans.get("TCMotorSelPan.lbl.NumberofsecondsorNone"), -3), "skip, wrap para"); setDelays(false); - + panel.add(new JSeparator(), "spanx, growx, wrap para"); - - + + // Thrust curve info //// Total impulse: panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Totalimpulse"))); totalImpulseLabel = new JLabel(); - panel.add(totalImpulseLabel, "wrap"); + panel.add(totalImpulseLabel, "split"); + classificationLabel = new JLabel(); + classificationLabel.setEnabled(false); // Gray + // classificationLabel.setForeground(Color.GRAY); + panel.add(classificationLabel, "gapleft unrel, wrap"); //// Avg. thrust: panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Avgthrust"))); @@ -454,7 +458,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec digestLabel = null; } - + comment = new JTextArea(5, 5); GUIUtil.changeFontSize(comment, -2); withCommentFont = comment.getFont(); @@ -465,9 +469,9 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec scrollpane = new JScrollPane(comment); panel.add(scrollpane, "spanx, growx, wrap para"); - - - + + + // Thrust curve plot chart = ChartFactory.createXYLineChart( null, // title @@ -480,7 +484,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec false // urls ); - + // Add the data and formatting to the plot XYPlot plot = chart.getXYPlot(); @@ -533,20 +537,20 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec zoomIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); layer.add(zoomIcon, (Integer) 1); - + panel.add(layer, "width 300:300:, height 180:180:, grow, spanx"); - - + + this.add(panel, "grow"); - - + + // Sets the filter: int showMode = Application.getPreferences().getChoice(net.sf.openrocket.startup.Preferences.MOTOR_DIAMETER_FILTER, SHOW_MAX, SHOW_EXACT); filterComboBox.setSelectedIndex(showMode); - + // Update the panel data updateData(); selectedDelay = delay; @@ -599,7 +603,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec } - + private void changeLabelFont(ValueAxis axis, float size) { Font font = axis.getTickLabelFont(); font = font.deriveFont(font.getSize2D() + size); @@ -638,6 +642,9 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec curveSelectionBox.setEnabled(false); curveSelectionLabel.setEnabled(false); totalImpulseLabel.setText(""); + totalImpulseLabel.setToolTipText(null); + classificationLabel.setText(""); + classificationLabel.setToolTipText(null); avgThrustLabel.setText(""); maxThrustLabel.setText(""); burnTimeLabel.setText(""); @@ -652,12 +659,12 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec return; } - + // Check which thrust curves to display List motors = getFilteredCurves(); final int index = motors.indexOf(selectedMotor); - + // Update the thrust curve selection box curveSelectionModel.removeAllElements(); for (int i = 0; i < motors.size(); i++) { @@ -673,10 +680,15 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec curveSelectionLabel.setEnabled(false); } - + // Update thrust curve data - totalImpulseLabel.setText(UnitGroup.UNITS_IMPULSE.getDefaultUnit().toStringUnit( - selectedMotor.getTotalImpulseEstimate())); + double impulse = selectedMotor.getTotalImpulseEstimate(); + MotorClass mc = MotorClass.getMotorClass(impulse); + totalImpulseLabel.setText(UnitGroup.UNITS_IMPULSE.getDefaultUnit().toStringUnit(impulse)); + classificationLabel.setText("(" + mc.getDescription(impulse) + ")"); + totalImpulseLabel.setToolTipText(mc.getClassDescription()); + classificationLabel.setToolTipText(mc.getClassDescription()); + avgThrustLabel.setText(UnitGroup.UNITS_FORCE.getDefaultUnit().toStringUnit( selectedMotor.getAverageThrustEstimate())); maxThrustLabel.setText(UnitGroup.UNITS_FORCE.getDefaultUnit().toStringUnit( @@ -694,7 +706,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec setComment(selectedMotor.getDescription()); - + // Update the plot XYPlot plot = chart.getXYPlot(); @@ -721,7 +733,6 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec plot.setDataset(dataset); } - private List getFilteredCurves() { List motors = selectedMotorSet.getMotors(); if (hideSimilarBox.isSelected()) { @@ -797,7 +808,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec } - + /** * Select the default motor from this ThrustCurveMotorSet. This uses primarily motors * that the user has previously used, and secondarily a heuristic method of selecting which @@ -814,7 +825,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec return set.getMotors().get(0); } - + // Find which motor has been used the most recently List list = set.getMotors(); Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE); @@ -867,7 +878,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec } if (!Double.isNaN(closest)) { selectedDelay = closest; - //// None + //// None delayBox.setSelectedItem(ThrustCurveMotor.getDelayString(closest, trans.get("TCMotorSelPan.delayBox.None"))); } else { delayBox.setSelectedItem("None"); @@ -876,7 +887,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec } else { selectedDelay = currentDelay; - //// None + //// None delayBox.setSelectedItem(ThrustCurveMotor.getDelayString(currentDelay, trans.get("TCMotorSelPan.delayBox.None"))); } @@ -885,11 +896,11 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec } - - + + ////////////////////// - + private class CurveSelectionRenderer implements ListCellRenderer { private final ListCellRenderer renderer; -- 2.30.2