2 * Copyright © 2010 Keith Packard <keithp@keithp.com>
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; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 package org.altusmetrum.altoslib_11;
24 public class AltosCSV implements AltosWriter {
27 boolean header_written;
33 boolean has_flight_state;
37 boolean has_companion;
39 AltosFlightSeries series;
42 static final int ALTOS_CSV_VERSION = 5;
51 * time (seconds since boost)
52 * clock (tick count / 100)
65 * accelerometer speed (m/s)
66 * barometer speed (m/s)
74 * Advanced sensors (if available)
85 * GPS data (if available)
88 * nsat (used for solution)
99 * from_pad_azimuth (deg true)
101 * from_pad_elevation (deg from horizon)
107 * C/N0 data for all 32 valid SDIDs
110 * companion_id (1-255. 10 is TeleScience)
111 * time of last companion data (seconds since boost)
112 * update_period (0.1-2.55 minimum telemetry interval)
114 * channel data for all 12 possible channels
117 void write_general_header() {
118 out.printf("version,serial,flight,call,time,clock,rssi,lqi");
122 return series.time(indices);
126 return (int) series.value(AltosFlightSeries.rssi_name, indices);
130 return (int) series.value(AltosFlightSeries.status_name, indices);
133 void write_general() {
134 double time = time();
135 out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d",
136 ALTOS_CSV_VERSION, series.cal_data.serial,
137 series.cal_data.flight, series.cal_data.callsign,
139 rssi(), status() & 0x7f);
142 void write_flight_header() {
143 out.printf("state,state_name");
147 return (int) series.value(AltosFlightSeries.state_name, indices);
150 void write_flight() {
152 out.printf("%d,%8s", state, AltosLib.state_name(state));
155 void write_basic_header() {
156 out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,drogue_voltage,main_voltage");
159 double acceleration() { return series.value(AltosFlightSeries.accel_name, indices); }
160 double pressure() { return series.value(AltosFlightSeries.pressure_name, indices); }
161 double altitude() { return series.value(AltosFlightSeries.altitude_name, indices); }
162 double height() { return series.value(AltosFlightSeries.height_name, indices); }
163 double speed() { return series.value(AltosFlightSeries.speed_name, indices); }
164 double temperature() { return series.value(AltosFlightSeries.temperature_name, indices); }
165 double apogee_voltage() { return series.value(AltosFlightSeries.apogee_voltage_name, indices); }
166 double main_voltage() { return series.value(AltosFlightSeries.main_voltage_name, indices); }
169 out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f",
181 void write_battery_header() {
182 out.printf("battery_voltage");
185 double battery_voltage() { return series.value(AltosFlightSeries.battery_voltage_name, indices); }
187 void write_battery() {
188 out.printf("%5.2f", battery_voltage());
191 void write_advanced_header() {
192 out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z");
195 void write_advanced() {
197 out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f",
198 state.accel_along(), state.accel_across(), state.accel_through(),
199 state.gyro_roll(), state.gyro_pitch(), state.gyro_yaw(),
200 state.mag_along(), state.mag_across(), state.mag_through());
204 void write_gps_header() {
206 out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop");
212 AltosGPS gps = state.gps;
214 gps = new AltosGPS();
216 AltosGreatCircle from_pad = state.from_pad;
217 if (from_pad == null)
218 from_pad = new AltosGreatCircle();
220 out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f",
243 void write_gps_sat_header() {
244 for(int i = 1; i <= 32; i++) {
245 out.printf("sat%02d", i);
251 void write_gps_sat() {
253 AltosGPS gps = state.gps;
254 for(int i = 1; i <= 32; i++) {
256 if (gps != null && gps.cc_gps_sat != null) {
257 for(int j = 0; j < gps.cc_gps_sat.length; j++)
258 if (gps.cc_gps_sat[j].svid == i) {
259 c_n0 = gps.cc_gps_sat[j].c_n0;
263 out.printf ("%3d", c_n0);
270 void write_companion_header() {
271 out.printf("companion_id,companion_time,companion_update,companion_channels");
272 for (int i = 0; i < 12; i++)
273 out.printf(",companion_%02d", i);
276 void write_companion() {
278 AltosCompanion companion = state.companion;
280 int channels_written = 0;
281 if (companion == null) {
282 out.printf("0,0,0,0");
284 out.printf("%3d,%5.2f,%5.2f,%2d",
286 (companion.tick - boost_tick) / 100.0,
287 companion.update_period / 100.0,
289 for (; channels_written < companion.channels; channels_written++)
290 out.printf(",%5d", companion.companion_data[channels_written]);
292 for (; channels_written < 12; channels_written++)
297 void write_header() {
298 out.printf("#"); write_general_header();
299 if (has_flight_state) {
301 write_flight_header();
305 write_basic_header();
309 write_battery_header();
313 write_advanced_header();
321 write_gps_sat_header();
325 write_companion_header();
332 if (has_flight_state) {
363 private void write() {
364 if (state() == AltosLib.ao_flight_startup)
366 if (!header_written) {
368 header_written = true;
373 private PrintStream out() {
377 public void close() {
381 public void write(AltosFlightSeries series) {
382 // series.write_comments(out());
384 this.series = series;
388 has_flight_state = false;
391 has_advanced = false;
394 has_companion = false;
396 if (series.has_series(AltosFlightSeries.state_name))
397 has_flight_state = true;
398 if (series.has_series(AltosFlightSeries.accel_name) || series.has_series(AltosFlightSeries.pressure_name))
400 if (series.has_series(AltosFlightSeries.battery_voltage_name))
402 if (series.has_series(AltosFlightSeries.accel_across_name))
405 if (state.gps != null) {
407 if (state.gps.cc_gps_sat != null)
410 if (state.companion != null)
411 has_companion = true;
414 indices = series.indices();
418 if (!series.step_indices(indices))
423 public AltosCSV(PrintStream in_out, File in_name) {
428 public AltosCSV(File in_name) throws FileNotFoundException {
429 this(new PrintStream(in_name), in_name);
432 public AltosCSV(String in_string) throws FileNotFoundException {
433 this(new File(in_string));