ao-tools: Add ao-fakeflight
[fw/altos] / ao-tools / ao-fakeflight / ao-fakeflight.c
diff --git a/ao-tools/ao-fakeflight/ao-fakeflight.c b/ao-tools/ao-fakeflight/ao-fakeflight.c
new file mode 100644 (file)
index 0000000..8a99259
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2014 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao-fakeflight.h"
+
+char *state_name[] = {
+       [state_ascent] = "ascent",
+       [state_drogue] = "drogue",
+       [state_main] = "main",
+       [state_landed] = "landed",
+};
+
+struct rocket o5778 = {
+       .models = {
+               [state_ascent] = {
+                       .cd = 0.5,
+                       .diameter = .100
+               },
+               [state_drogue] = {
+                       .cd = 1.3,
+                       .diameter = .300
+               },
+               [state_main] = {
+                       .cd = 1.3,
+                       .diameter = 1.0
+               },
+       },
+       .empty_mass = 15.0,
+       .main_deploy = 250,
+       .motors = {
+               [0] = {
+                       .fuel_mass = 18.021,
+                       .average_thrust = 5778.0,
+                       .burn_time = 8.52,
+                       .delay = 0.0,
+               },
+               [1] = {
+                       .fuel_mass = 18.021,
+                       .average_thrust = 5778.0,
+                       .burn_time = 0, /* 17.04 */
+                       .delay = 18.0,
+               },
+       },
+};
+
+struct rocket n5778 = {
+       .models = {
+               [state_ascent] = {
+                       .cd = 0.5,
+                       .diameter = .100
+               },
+               [state_drogue] = {
+                       .cd = 1.3,
+                       .diameter = .300
+               },
+               [state_main] = {
+                       .cd = 1.3,
+                       .diameter = 1.0
+               },
+       },
+       .empty_mass = 15.0,
+       .main_deploy = 250,
+       .motors = {
+               [0] = {
+                       .fuel_mass = 9.0105,
+                       .average_thrust = 5778.0,
+                       .burn_time = 4.26,
+                       .delay = 0.0,
+               },
+       },
+};
+
+/*
+ * Move the flight one tick forward
+ */
+void
+step(struct flight *f, struct rocket *r)
+{
+       double  drag = rocket_drag(f, r);
+       double  thrust = rocket_thrust(f, r);
+       double  gravity = rocket_gravity(f, r);
+       double  mass = rocket_mass(f, r);
+       double  accel;
+
+       /* This is our acceleration relative to the earth */
+       accel = (drag + thrust - gravity) / mass;
+
+       /* Because the accelerometer is also affected by gravity, it
+        * only measures *other* forces applied to the rocket
+        */
+       f->accel = (drag + thrust) / mass;
+
+       f->altitude += f->speed * STEP + 0.5 * (accel * STEP) * (accel * STEP);
+       f->speed += accel * STEP;
+       f->time += STEP;
+}
+
+void
+init(struct flight *f, struct rocket *r)
+{
+       double gravity = rocket_gravity(f, r);
+
+       /* The pad is pushing up on the rocket to counter
+        * gravity, so the accelerometer, which only measures
+        * forces other than gravity, sees only this
+        */
+       f->accel = gravity / rocket_mass(f, r);
+       f->speed = 0;
+       f->altitude = 0;
+       f->time += STEP;
+}
+
+void
+fly(FILE *file, struct rocket *r)
+{
+       struct flight f = {
+               .time = -1,
+               .altitude = 0,
+               .speed = 0,
+               .accel = 0,
+               .state = state_ascent,
+       };
+
+       double  max_speed = 0;
+       double  max_alt = 0;
+       double  max_accel = 0;
+
+
+       ao_show_header(file, r);
+       while (f.time < 0) {
+               init(&f, r);
+               ao_log(file, &f, r);
+       }
+       while (f.altitude >= 0) {
+               step(&f, r);
+               switch (f.state) {
+               case state_ascent:
+                       if (f.speed >= 0)
+                               break;
+                       f.state = state_drogue;
+                       /* fall through */
+               case state_drogue:
+                       if (f.altitude > o5778.main_deploy)
+                               break;
+                       f.state = state_main;
+                       /* fall through */
+               case state_main:
+                       break;
+               }
+               ao_log(file, &f, r);
+               max_speed = fmax(max_speed, f.speed);
+               max_accel = fmax(max_accel, f.accel);
+               max_alt = fmax(max_alt, f.altitude);
+       }
+       fprintf(stderr, "max alt %9.1f speed %9.1f accel %9.1f\n",
+               max_alt, max_speed, max_accel);
+}
+
+int
+main(int argc, char **argv)
+{
+       fly(stdout, &o5778);
+//     fly(stdout, &n5778);
+       return 0;
+}