Integrate flite into aoview directly. Fix great circle computation.
authorKeith Packard <keithp@keithp.com>
Tue, 30 Jun 2009 22:25:52 +0000 (15:25 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 30 Jun 2009 22:25:52 +0000 (15:25 -0700)
Use a separate thread for flite rather than a separate program.
Save voice state to gconf.
Add filters for replay file selection

Signed-off-by: Keith Packard <keithp@keithp.com>
aoview/Makefile.am
aoview/aoview.h
aoview/aoview_flite.c
aoview/aoview_main.c
aoview/aoview_monitor.c
aoview/aoview_replay.c
aoview/aoview_state.c
aoview/aoview_voice.c

index 28c3d646d96615651629df5ae5ad60d62958cb27..c354aa0f033d13197a00560105ae2bc787e9bde5 100644 (file)
@@ -1,13 +1,9 @@
 VERSION=$(shell git describe)
 AM_CFLAGS=$(GNOME_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\" @FLITE_INCS@
 
 VERSION=$(shell git describe)
 AM_CFLAGS=$(GNOME_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\" @FLITE_INCS@
 
-if USE_FLITE
-FLITE_PROG=aoview_flite
-endif
+bin_PROGRAMS=aoview
 
 
-bin_PROGRAMS=aoview $(FLITE_PROG) aoview_slowtelem
-
-aoview_LDADD=$(GNOME_LIBS)
+aoview_LDADD=$(GNOME_LIBS) $(FLITE_LIBS)
 
 aoview_SOURCES = \
        aoview_main.c \
 
 aoview_SOURCES = \
        aoview_main.c \
@@ -25,16 +21,9 @@ aoview_SOURCES = \
        aoview_voice.c \
        aoview_replay.c \
        aoview_label.c \
        aoview_voice.c \
        aoview_replay.c \
        aoview_label.c \
+       aoview_flite.c \
        aoview.h
 
        aoview.h
 
-aoview_flite_SOURCES = \
-       aoview_flite.c
-
-aoview_slowtelem_SOURCES = \
-       aoview_slowtelem.c
-
-aoview_flite_LDADD=@FLITE_LIBS@
-
 BUILT_SOURCES = aoview_glade.h
 
 CLEANFILES = aoview_glade.h
 BUILT_SOURCES = aoview_glade.h
 
 CLEANFILES = aoview_glade.h
index d49bd6f4968e656d45a5ecc4194f0773a605cf27..7807b2facb74580de34caf70d970892a6e00e0f5 100644 (file)
@@ -111,6 +111,7 @@ struct aostate {
 
        double  distance;
        double  bearing;
 
        double  distance;
        double  bearing;
+       int     gps_height;
 };
 
 /* GPS is 'stable' when we've seen at least this many samples */
 };
 
 /* GPS is 'stable' when we've seen at least this many samples */
@@ -125,6 +126,9 @@ aoview_monitor_connect(char *tty);
 gboolean
 aoview_monitor_parse(char *line);
 
 gboolean
 aoview_monitor_parse(char *line);
 
+void
+aoview_monitor_reset(void);
+
 struct aoview_serial *
 aoview_serial_open(const char *tty);
 
 struct aoview_serial *
 aoview_serial_open(const char *tty);
 
@@ -270,4 +274,12 @@ void aoview_label_init(GladeXML *xml);
 void
 aoview_label_show(struct aostate *state);
 
 void
 aoview_label_show(struct aostate *state);
 
+/* aoview_flite.c */
+
+FILE *
+aoview_flite_start(void);
+
+void
+aoview_flite_stop(void);
+
 #endif /* _AOVIEW_H_ */
 #endif /* _AOVIEW_H_ */
index daa3ed36c69ba0bfacdc707fc4e03679d6a7b2aa..bca19043083f0cc6078d1699313623617d851c7e 100644 (file)
 
 #include <stdio.h>
 #include <flite/flite.h>
 
 #include <stdio.h>
 #include <flite/flite.h>
+#include "aoview.h"
 
 cst_voice *register_cmu_us_kal();
 
 cst_voice *register_cmu_us_kal();
+static cst_voice *voice;
 
 
-int
-main(int argc, char **argv)
+static FILE *pipe_write;
+static GThread *aoview_flite_thread;
+
+gpointer
+aoview_flite_task(gpointer data)
 {
 {
+       FILE            *input = data;
        char            line[1024];
        char            line[1024];
-       cst_voice       *v;
 
 
-       flite_init();
-       v = register_cmu_us_kal();
-       if (!v) {
-               perror("register voice");
-               exit(1);
+       while (fgets(line, sizeof (line) - 1, input) != NULL)
+               flite_text_to_speech(line, voice, "play");
+       return NULL;
+}
+
+void
+aoview_flite_stop(void)
+{
+       int status;
+       if (pipe_write) {
+               fclose(pipe_write);
+               pipe_write = NULL;
+       }
+       if (aoview_flite_thread) {
+               g_thread_join(aoview_flite_thread);
+               aoview_flite_thread = NULL;
        }
        }
-       while (fgets(line, sizeof (line) - 1, stdin) != NULL) {
-               flite_text_to_speech(line, v, "play");
+}
+
+FILE *
+aoview_flite_start(void)
+{
+       static once;
+       int     p[2];
+       GError  *error;
+       FILE    *pipe_read;
+
+       if (!once) {
+               flite_init();
+               voice = register_cmu_us_kal();
+               if (!voice) {
+                       perror("register voice");
+                       exit(1);
+               }
        }
        }
-       exit (0);
+       aoview_flite_stop();
+       pipe(p);
+       pipe_read = fdopen(p[0], "r");
+       pipe_write = fdopen(p[1], "w");
+       g_thread_create(aoview_flite_task, pipe_read, TRUE, &error);
+       return pipe_write;
 }
 }
index 99de14732b3fc7961e4ce80270daf8202c290025..36a82e0e1212dc3da35006dc8e42708266495c51 100644 (file)
@@ -31,6 +31,8 @@ static void destroy_event(GtkWidget *widget, gpointer data)
        gtk_main_quit();
 }
 
        gtk_main_quit();
 }
 
+extern int _Xdebug;
+
 int main(int argc, char **argv)
 {
        GladeXML *xml = NULL;
 int main(int argc, char **argv)
 {
        GladeXML *xml = NULL;
@@ -40,12 +42,13 @@ int main(int argc, char **argv)
 
        static struct option long_options[] = {
                { "device", 1, 0, 'd'},
 
        static struct option long_options[] = {
                { "device", 1, 0, 'd'},
+               { "sync", 0, 0, 's'},
                { 0, 0, 0, 0 }
        };
        for (;;) {
                int c, temp;
 
                { 0, 0, 0, 0 }
        };
        for (;;) {
                int c, temp;
 
-               c = getopt_long_only(argc, argv, "d:", long_options, &temp);
+               c = getopt_long_only(argc, argv, "sd:", long_options, &temp);
                if (c == -1)
                        break;
 
                if (c == -1)
                        break;
 
@@ -53,11 +56,15 @@ int main(int argc, char **argv)
                case 'd':
                        device = optarg;
                        break;
                case 'd':
                        device = optarg;
                        break;
+               case 's':
+                       _Xdebug = 1;
+                       break;
                default:
                        usage();
                }
        }
 
                default:
                        usage();
                }
        }
 
+       g_thread_init(NULL);
        gtk_init(&argc, &argv);
        glade_init();
 
        gtk_init(&argc, &argv);
        glade_init();
 
@@ -95,6 +102,8 @@ int main(int argc, char **argv)
 
        aoview_label_init(xml);
 
 
        aoview_label_init(xml);
 
+       aoview_voice_speak("rocket flight monitor ready\n");
+
        gtk_main();
 
        return 0;
        gtk_main();
 
        return 0;
index faa24474de50feaee06b02277ed653a21300dd33..f7f646ae817b7792487607e585f40f70244e1753 100644 (file)
@@ -31,7 +31,6 @@ aoview_monitor_disconnect(void)
                aoview_serial_close(monitor_serial);
                monitor_serial = NULL;
        }
                aoview_serial_close(monitor_serial);
                monitor_serial = NULL;
        }
-       aoview_table_clear();
        aoview_log_new();
 }
 
        aoview_log_new();
 }
 
@@ -134,6 +133,12 @@ aoview_monitor_parse(char *line)
        return TRUE;
 }
 
        return TRUE;
 }
 
+void
+aoview_monitor_reset(void)
+{
+       memset(&state, '\0', sizeof (state));
+}
+
 static void
 aoview_monitor_callback(gpointer user_data,
                        struct aoview_serial *serial,
 static void
 aoview_monitor_callback(gpointer user_data,
                        struct aoview_serial *serial,
@@ -175,6 +180,8 @@ aoview_monitor_connect(char *tty)
        monitor_serial = aoview_serial_open(tty);
        if (!monitor_serial)
                return FALSE;
        monitor_serial = aoview_serial_open(tty);
        if (!monitor_serial)
                return FALSE;
+       aoview_table_clear();
+       aoview_monitor_reset();
        aoview_serial_set_callback(monitor_serial,
                                   aoview_monitor_callback,
                                   monitor_serial,
        aoview_serial_set_callback(monitor_serial,
                                   aoview_monitor_callback,
                                   monitor_serial,
index 42728961cb73f14db1720282ad3ee8882b4d229e..3eadb442a463cdbfd0ba49e1e5c2b67941162224 100644 (file)
@@ -107,6 +107,7 @@ aoview_replay_open(GtkWidget *widget, gpointer data)
                gtk_widget_destroy(dialog);
        } else {
                replay_tick = -1;
                gtk_widget_destroy(dialog);
        } else {
                replay_tick = -1;
+               aoview_monitor_reset();
                aoview_replay_read(NULL);
        }
        gtk_widget_hide(GTK_WIDGET(replay_dialog));
                aoview_replay_read(NULL);
        }
        gtk_widget_hide(GTK_WIDGET(replay_dialog));
@@ -115,9 +116,28 @@ aoview_replay_open(GtkWidget *widget, gpointer data)
 void
 aoview_replay_init(GladeXML *xml)
 {
 void
 aoview_replay_init(GladeXML *xml)
 {
+       GtkFileFilter   *telem_filter;
+       GtkFileFilter   *all_filter;
+       GtkFileFilter   *log_filter;
+
+       telem_filter = gtk_file_filter_new();
+       gtk_file_filter_add_pattern(telem_filter, "*.telem");
+       gtk_file_filter_set_name(telem_filter, "Telemetry Files");
+
+       log_filter = gtk_file_filter_new();
+       gtk_file_filter_add_pattern(log_filter, "*.log");
+       gtk_file_filter_set_name(log_filter, "Log Files");
+
+       all_filter = gtk_file_filter_new();
+       gtk_file_filter_add_pattern(all_filter, "*");
+       gtk_file_filter_set_name(all_filter, "All Files");
+
        replay_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "ao_replay_dialog"));
        assert(replay_dialog);
        gtk_file_chooser_set_current_folder(replay_dialog, aoview_file_dir);
        replay_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "ao_replay_dialog"));
        assert(replay_dialog);
        gtk_file_chooser_set_current_folder(replay_dialog, aoview_file_dir);
+       gtk_file_chooser_add_filter(replay_dialog, telem_filter);
+       gtk_file_chooser_add_filter(replay_dialog, log_filter);
+       gtk_file_chooser_add_filter(replay_dialog, all_filter);
 
        replay_ok = glade_xml_get_widget(xml, "ao_replay_ok");
        assert(replay_ok);
 
        replay_ok = glade_xml_get_widget(xml, "ao_replay_ok");
        assert(replay_ok);
index 4ba1854e0237fc3584786aa2793f6901b957c6a3..030db99ffca94eb8fd4a5db237425e5b3c13f2f6 100644 (file)
@@ -18,7 +18,7 @@
 #include "aoview.h"
 #include <math.h>
 
 #include "aoview.h"
 #include <math.h>
 
-static inline double sqr(a) { return a * a; };
+static inline double sqr(double a) { return a * a; };
 
 static void
 aoview_great_circle (double start_lat, double start_lon,
 
 static void
 aoview_great_circle (double start_lat, double start_lon,
@@ -103,7 +103,7 @@ aoview_state_derive(struct aostate *state)
        state->main_sense = state->main / 32767.0 * 15.0;
        state->battery = state->batt / 32767.0 * 5.0;
        if (!strcmp(state->state, "pad")) {
        state->main_sense = state->main / 32767.0 * 15.0;
        state->battery = state->batt / 32767.0 * 5.0;
        if (!strcmp(state->state, "pad")) {
-               if (state->locked) {
+               if (state->locked && state->nsat > 4) {
                        state->npad++;
                        state->pad_lat_total += state->lat;
                        state->pad_lon_total += state->lon;
                        state->npad++;
                        state->pad_lat_total += state->lat;
                        state->pad_lon_total += state->lon;
@@ -128,6 +128,11 @@ aoview_state_derive(struct aostate *state)
                state->max_height = state->height;
        aoview_great_circle(state->pad_lat, state->pad_lon, state->lat, state->lon,
                            &state->distance, &state->bearing);
                state->max_height = state->height;
        aoview_great_circle(state->pad_lat, state->pad_lon, state->lat, state->lon,
                            &state->distance, &state->bearing);
+       if (state->npad) {
+               state->gps_height = state->alt - state->pad_alt;
+       } else {
+               state->gps_height = 0;
+       }
 }
 
 void
 }
 
 void
@@ -167,8 +172,6 @@ aoview_state_speak(struct aostate *state)
                                           state->flight_vel / 2700);
                last_tick = state->tick;
                last_altitude = this_altitude;
                                           state->flight_vel / 2700);
                last_tick = state->tick;
                last_altitude = this_altitude;
-               printf ("report at tick %d height %d\n",
-                       state->tick, this_altitude);
        }
 }
 
        }
 }
 
@@ -203,7 +206,7 @@ aoview_state_notify(struct aostate *state)
        if (state->locked) {
                aoview_state_add_deg("Latitude", state->lat, 'N', 'S');
                aoview_state_add_deg("Longitude", state->lon, 'E', 'W');
        if (state->locked) {
                aoview_state_add_deg("Latitude", state->lat, 'N', 'S');
                aoview_state_add_deg("Longitude", state->lon, 'E', 'W');
-               aoview_table_add_row("GPS alt", "%d", state->alt);
+               aoview_table_add_row("GPS height", "%d", state->gps_height);
                aoview_table_add_row("GPS time", "%02d:%02d:%02d",
                                     state->gps_time.hour,
                                     state->gps_time.minute,
                aoview_table_add_row("GPS time", "%02d:%02d:%02d",
                                     state->gps_time.hour,
                                     state->gps_time.minute,
@@ -239,5 +242,4 @@ void
 aoview_state_init(GladeXML *xml)
 {
        aoview_state_new();
 aoview_state_init(GladeXML *xml)
 {
        aoview_state_new();
-       aoview_voice_speak("initializing rocket flight monitoring system\n");
 }
 }
index 7f4e576e88dbaaac39c95633f6da0c92bc64ef22..f7c099b1994d3195f2b61ee595c0b554dbad1d60 100644 (file)
@@ -25,13 +25,13 @@ FILE        *aoview_flite;
 void aoview_voice_open(void)
 {
        if (!aoview_flite)
 void aoview_voice_open(void)
 {
        if (!aoview_flite)
-               aoview_flite = popen("aoview_flite", "w");
+               aoview_flite = aoview_flite_start();
 }
 
 void aoview_voice_close(void)
 {
        if (aoview_flite) {
 }
 
 void aoview_voice_close(void)
 {
        if (aoview_flite) {
-               pclose(aoview_flite);
+               aoview_flite_stop();
                aoview_flite = NULL;
        }
 }
                aoview_flite = NULL;
        }
 }
@@ -65,26 +65,55 @@ void aoview_voice_speak(char *format, ...)
 
 static GtkCheckMenuItem        *voice_enable;
 
 
 static GtkCheckMenuItem        *voice_enable;
 
+#define ALTOS_VOICE_PATH       "/apps/aoview/voice"
+
 static void
 aoview_voice_enable(GtkWidget *widget, gpointer data)
 {
 static void
 aoview_voice_enable(GtkWidget *widget, gpointer data)
 {
-       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
+       gboolean        enabled = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+       GError          *error;
+       GConfClient     *gconf_client;
+
+       if (enabled) {
                aoview_voice_open();
                aoview_voice_open();
-               aoview_voice_speak("enable voice system\n");
+               aoview_voice_speak("enable voice\n");
        } else {
        } else {
-               aoview_voice_speak("disable voice system\n");
+               aoview_voice_speak("disable voice\n");
                aoview_voice_close();
        }
                aoview_voice_close();
        }
+       gconf_client = gconf_client_get_default();
+       gconf_client_set_bool(gconf_client,
+                             ALTOS_VOICE_PATH,
+                             enabled,
+                             &error);
 }
 
 void
 aoview_voice_init(GladeXML *xml)
 {
 }
 
 void
 aoview_voice_init(GladeXML *xml)
 {
-       aoview_voice_open();
+       gboolean        enabled;
+       GConfClient     *gconf_client;
 
        voice_enable = GTK_CHECK_MENU_ITEM(glade_xml_get_widget(xml, "voice_enable"));
        assert(voice_enable);
 
 
        voice_enable = GTK_CHECK_MENU_ITEM(glade_xml_get_widget(xml, "voice_enable"));
        assert(voice_enable);
 
+       gconf_client = gconf_client_get_default();
+       enabled = TRUE;
+       if (gconf_client)
+       {
+               GError  *error;
+
+               error = NULL;
+               enabled = gconf_client_get_bool(gconf_client,
+                                               ALTOS_VOICE_PATH,
+                                               &error);
+               if (error)
+                       enabled = TRUE;
+       }
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(voice_enable), enabled);
+       if (enabled)
+               aoview_voice_open();
+
        g_signal_connect(G_OBJECT(voice_enable), "toggled",
                         G_CALLBACK(aoview_voice_enable),
                         voice_enable);
        g_signal_connect(G_OBJECT(voice_enable), "toggled",
                         G_CALLBACK(aoview_voice_enable),
                         voice_enable);