doc: Micropeak doc updates for 1.3.2
[fw/altos] / micropeak / MicroStats.java
1 /*
2  * Copyright © 2011 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package org.altusmetrum.micropeak;
19
20 import java.io.*;
21 import org.altusmetrum.altoslib_3.*;
22 import org.altusmetrum.altosuilib_1.*;
23
24 public class MicroStats {
25         double          coast_height;
26         double          coast_time;
27
28         double          apogee_height;
29         double          apogee_time;
30
31         double          landed_height;
32         double          landed_time;
33
34         double          max_speed;
35         double          max_accel;
36
37         MicroData       data;
38
39         void find_landing() {
40                 landed_height = 0;
41
42                 for (MicroDataPoint point : data.points()) {
43                         landed_height = point.height;
44                         landed_time = point.time;
45                 }
46
47                 boolean above = false;
48                 for (MicroDataPoint point : data.points()) {
49                         if (point.height > landed_height + 10) {
50                                 above = true;
51                         } else {
52                                 if (above && point.height < landed_height + 2) {
53                                         above = false;
54                                         landed_time = point.time;
55                                 }
56                         }
57                 }
58         }
59
60         void find_apogee() {
61                 apogee_height = data.apogee_height();
62                 double searched_apogee = 0;
63                 apogee_time = 0;
64                 
65                 /* This just finds the apogee time -- we've recorded the
66                  * peak altitude separately in eeprom, and that could
67                  * have occurred after the eeprom was full.
68                  */
69                 for (MicroDataPoint point : data.points()) {
70                         if (point.height > searched_apogee) {
71                                 searched_apogee = point.height;
72                                 apogee_time = point.time;
73                         }
74                 }
75         }
76
77         void find_coast() {
78                 coast_height = 0;
79                 coast_time = 0;
80
81                 for (MicroDataPoint point : data.points()) {
82                         if (point.accel < -9.8)
83                                 break;
84                         coast_time = point.time;
85                         coast_height = point.height;
86                 }
87         }
88
89         void find_max_speed() {
90                 max_speed = 0;
91                 for (MicroDataPoint point : data.points()) {
92                         if (point.time > apogee_time)
93                                 break;
94                         if (point.speed > max_speed)
95                                 max_speed = point.speed;
96                 }
97         }
98
99         void find_max_accel() {
100                 max_accel = 0;
101                 for (MicroDataPoint point : data.points()) {
102                         if (point.time > apogee_time)
103                                 break;
104                         if (point.accel > max_accel)
105                                 max_accel = point.accel;
106                 }
107         }
108
109         double boost_duration() {
110                 return coast_time;
111         }
112
113         double boost_height() {
114                 return coast_height;
115         }
116
117         double  boost_speed() {
118                 return coast_height / coast_time;
119         }
120
121         double boost_accel() {
122                 return boost_speed() / boost_duration();
123         }
124
125         double coast_duration() {
126                 return apogee_time - coast_time;
127         }
128
129         double coast_height() {
130                 return apogee_height - coast_height;
131         }
132
133         double coast_speed() {
134                 return coast_height() / coast_duration();
135         }
136
137         double coast_accel() {
138                 return coast_speed() / coast_duration();
139         }
140
141         double descent_duration() {
142                 return landed_time - apogee_time;
143         }
144
145         double descent_height() {
146                 return apogee_height - landed_height;
147         }
148
149         double descent_speed() {
150                 return descent_height() / descent_duration();
151         }
152
153         public static final int state_startup = -1;
154         public static final int state_pad = 0;
155         public static final int state_boost = 1;
156         public static final int state_coast = 2;
157         public static final int state_descent = 3;
158         public static final int state_landed = 4;
159
160         static final String state_names[] = {
161                 "pad",
162                 "boost",
163                 "coast",
164                 "descent",
165                 "landed"
166         };
167
168         public int state(double t) {
169                 if (t >= landed_time)
170                         return state_landed;
171                 if (t >= apogee_time)
172                         return state_descent;
173                 if (t >= coast_time)
174                         return state_coast;
175                 if (t >= 0)
176                         return state_boost;
177                 return state_pad;
178         }
179
180         public static String state_name(int state) {
181                 if (state < 0 || state > state_landed)
182                         return "unknown";
183                 return state_names[state];
184         }
185
186         public String state_name(double t) {
187                 return state_name(state(t));
188         }
189
190         public MicroStats(MicroData data) {
191
192                 this.data = data;
193
194                 find_coast();
195                 find_apogee();
196                 find_landing();
197                 find_max_speed();
198                 find_max_accel();
199         }
200
201         public MicroStats() {
202                 this(new MicroData());
203         }
204 }