cleared some warnings
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / visual / BurnPanel.java
1 package com.billkuker.rocketry.motorsim.visual;\r
2 \r
3 import java.awt.BorderLayout;\r
4 import java.awt.Dimension;\r
5 import java.awt.GridLayout;\r
6 import java.text.NumberFormat;\r
7 \r
8 import javax.measure.quantity.Duration;\r
9 import javax.measure.quantity.Force;\r
10 import javax.measure.quantity.Pressure;\r
11 import javax.measure.quantity.Velocity;\r
12 import javax.measure.unit.SI;\r
13 import javax.swing.JFrame;\r
14 import javax.swing.JLabel;\r
15 import javax.swing.JPanel;\r
16 import javax.swing.JSlider;\r
17 import javax.swing.JSplitPane;\r
18 import javax.swing.WindowConstants;\r
19 import javax.swing.event.ChangeEvent;\r
20 import javax.swing.event.ChangeListener;\r
21 \r
22 import org.jscience.physics.amount.Amount;\r
23 \r
24 import com.billkuker.rocketry.motorsim.Burn;\r
25 import com.billkuker.rocketry.motorsim.Burn.Interval;\r
26 import com.billkuker.rocketry.motorsim.RocketScience;\r
27 \r
28 public class BurnPanel extends JPanel {\r
29         private static final long serialVersionUID = 1L;\r
30         private Burn burn;\r
31         Chart<Duration, Pressure> pressure;\r
32         Chart<Duration, Force> thrust;\r
33         Chart<Pressure, Velocity> burnRate;\r
34         GrainPanel grain;\r
35         Amount<Duration> displayedTime = Amount.valueOf(0, SI.SECOND);\r
36         \r
37         public BurnPanel(Burn b){\r
38                 super( new BorderLayout() );\r
39                 burn = b;\r
40                 \r
41                 try {\r
42                         pressure = new Chart<Duration, Pressure>(\r
43                                         SI.SECOND,\r
44                                         SI.MEGA(SI.PASCAL),\r
45                                         b,\r
46                                         "pressure");\r
47                         pressure.setDomain(burn.getData().keySet());\r
48                         \r
49                         thrust = new Chart<Duration, Force>(\r
50                                         SI.SECOND,\r
51                                         SI.NEWTON,\r
52                                         b,\r
53                                         "thrust");\r
54                         thrust.setDomain(burn.getData().keySet());\r
55                         \r
56                         burnRate = new Chart<Pressure, Velocity>(\r
57                                         SI.MEGA(SI.PASCAL),\r
58                                         SI.METERS_PER_SECOND,\r
59                                         burn.getMotor().getFuel(),\r
60                                         "burnRate");\r
61                         burnRate.setDomain(\r
62                                         burnRate.new IntervalDomain(\r
63                                                         Amount.valueOf(0, SI.MEGA(SI.PASCAL)),\r
64                                                         Amount.valueOf(11, SI.MEGA(SI.PASCAL)),\r
65                                                         20\r
66                                                         ));\r
67                         \r
68                         \r
69                         JSplitPane tp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, thrust, pressure);\r
70                         tp.setDividerLocation(.5);\r
71                         tp.setResizeWeight(.5);\r
72                         \r
73                         grain = new GrainPanel(burn.getMotor().getGrain()){\r
74                                 private static final long serialVersionUID = 1L;\r
75                                 @Override protected void addComponents(java.awt.Component crossSection, java.awt.Component slider, java.awt.Component label, java.awt.Component area, java.awt.Component volume) {\r
76                                         JSplitPane h = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, crossSection, area); \r
77                                         add(h, BorderLayout.CENTER);\r
78                                         h.resetToPreferredSizes();\r
79                                 };\r
80                         };\r
81                         \r
82                         JSplitPane grains = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, grain, burnRate);\r
83                         grains.setDividerLocation(.5);\r
84                         grains.setResizeWeight(.5);\r
85                         \r
86                         JSplitPane main = new JSplitPane(JSplitPane.VERTICAL_SPLIT, grains, tp);\r
87                         Dimension minimumSize = new Dimension(800, 200);\r
88                         grains.setMinimumSize(minimumSize);\r
89                         tp.setMinimumSize(minimumSize);\r
90                         main.setDividerLocation(.5);\r
91                         main.setResizeWeight(.5);\r
92                         \r
93                         add( main, BorderLayout.CENTER );\r
94                         \r
95                         add( new SL(), BorderLayout.SOUTH);\r
96                         \r
97                         \r
98 \r
99                                 Amount<RocketScience.Impulse> ns = Amount.valueOf(0, RocketScience.NEWTON_SECOND);\r
100                                 \r
101                                 Amount<Duration> thrustTime = Amount.valueOf(0, SI.SECOND);\r
102                                 Amount<Force> maxThrust = Amount.valueOf(0, SI.NEWTON);\r
103                                 Amount<Pressure> maxPressure = Amount.valueOf(0, SI.MEGA(SI.PASCAL));\r
104 \r
105                                 for( Interval i: burn.getData().values() ){\r
106                                         ns = ns.plus(i.dt.times(i.thrust));\r
107                                         if ( i.thrust.isGreaterThan(Amount.valueOf(0.01, SI.NEWTON))){\r
108                                                 thrustTime = thrustTime.plus(i.dt);\r
109                                         }\r
110                                         if ( i.thrust.isGreaterThan(maxThrust))\r
111                                                 maxThrust = i.thrust;\r
112                                         if ( i.chamberPressure.isGreaterThan(maxPressure))\r
113                                                 maxPressure = i.chamberPressure;\r
114                                 }\r
115                                 \r
116                                 Amount<Force> averageThrust = Amount.valueOf(0, SI.NEWTON);\r
117                                 if ( thrustTime.isGreaterThan(Amount.valueOf(0, SI.SECOND)))\r
118                                         averageThrust = ns.divide(thrustTime).to(SI.NEWTON);\r
119 \r
120                                 float cnf = (float)(Math.log(ns.doubleValue(RocketScience.NEWTON_SECOND)/1.25) / Math.log(2));\r
121                                 int cn = (int)cnf;\r
122                                 float fraction = cnf - cn;\r
123                                 int percent = (int)(100 * fraction);\r
124                                 char cl = (char)((int)'A' + cn);\r
125 \r
126                                 \r
127                                 Amount<Duration> isp = ns.divide(\r
128                                                 b.getMotor().getGrain().volume(Amount.valueOf(0, SI.MILLIMETER))\r
129                                                         .times(b.getMotor().getFuel().getIdealDensity().times(b.getMotor().getFuel().getDensityRatio()))\r
130                                                 ).to(SI.METERS_PER_SECOND).divide(Amount.valueOf(9.81, SI.METERS_PER_SQUARE_SECOND)).to(SI.SECOND);\r
131                         \r
132                         JPanel text = new JPanel(new GridLayout(2,5));\r
133 \r
134                         text.add(new JLabel("Rating"));\r
135                         text.add(new JLabel("Total Impulse"));\r
136                         text.add(new JLabel("ISP"));\r
137                         text.add(new JLabel("Max Thrust"));\r
138                         text.add(new JLabel("Average Thust"));\r
139                         text.add(new JLabel("Max Pressure"));\r
140                         \r
141                         text.add(new JLabel(percent + "% " + new String(new char[]{cl}) + "-" +Math.round(averageThrust.doubleValue(SI.NEWTON))));\r
142                         text.add(new JLabel(RocketScience.approx(ns)));\r
143                         text.add(new JLabel(RocketScience.approx(isp)));                        \r
144                         text.add(new JLabel(RocketScience.approx(maxThrust)));\r
145                         text.add(new JLabel(RocketScience.approx(averageThrust)));\r
146                         text.add(new JLabel(RocketScience.approx(maxPressure)));\r
147                         \r
148                         add(text, BorderLayout.NORTH);\r
149                         \r
150                         \r
151                 } catch (NoSuchMethodException e){\r
152                         throw new Error(e);\r
153                 }\r
154                 \r
155 \r
156         }\r
157         \r
158         private class SL extends JSlider implements ChangeListener{\r
159                 private static final long serialVersionUID = 1L;\r
160                 private static final int STEPS = 80;\r
161                 public SL(){\r
162                         addChangeListener(this);\r
163                         setMinimum(0);\r
164                         setMaximum(STEPS);\r
165                         setValue(0);\r
166                 }\r
167                 \r
168                 public void stateChanged(ChangeEvent e) {\r
169                         double t = ((SL)e.getSource()).getValue();\r
170                         displayedTime = burn.burnTime().divide(STEPS).times(t);\r
171                         \r
172                         //Find the nearest key in the data set\r
173                         displayedTime =burn.getData().tailMap(displayedTime).firstKey();\r
174                         \r
175                         NumberFormat nf = NumberFormat.getInstance();\r
176                         nf.setMaximumFractionDigits(2);\r
177                         \r
178                         pressure.mark(displayedTime);\r
179                         thrust.mark(displayedTime);\r
180                         \r
181                         grain.setDisplayedRegression(burn.getData().get(displayedTime).regression);\r
182                         \r
183                         burnRate.mark(burn.getData().get(displayedTime).chamberPressure);\r
184                         \r
185                         \r
186                         /*\r
187                         double r = ((SL)e.getSource()).getValue();\r
188                         displayedRegression = grain.webThickness().divide(STEPS).times(r);\r
189                         NumberFormat nf = NumberFormat.getInstance();\r
190                         nf.setMaximumFractionDigits(2);\r
191                         l.setText("Regression: " + nf.format(displayedRegression.doubleValue(SI.MILLIMETER)) + "mm");\r
192                         area.mark(displayedRegression);\r
193                         volume.mark(displayedRegression);\r
194                         if ( xc != null )\r
195                                 xc.repaint();\r
196                         */\r
197                 }\r
198         }\r
199         \r
200         public void showAsWindow(){\r
201                 JFrame f = new JFrame();\r
202                 f.setTitle(burn.getMotor().getName());\r
203                 f.setSize(1280,720);\r
204                 f.setLocation(0, 0);\r
205                 f.setContentPane(this);\r
206                 f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);\r
207                 f.setVisible(true);\r
208         }\r
209 }\r