From: Keith Packard Date: Tue, 30 Jun 2009 22:25:52 +0000 (-0700) Subject: Integrate flite into aoview directly. Fix great circle computation. X-Git-Tag: 0.5~39 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=e506ed4b6efb86eab50204658fcd433b987e3831 Integrate flite into aoview directly. Fix great circle computation. 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 --- diff --git a/aoview/Makefile.am b/aoview/Makefile.am index 28c3d646..c354aa0f 100644 --- a/aoview/Makefile.am +++ b/aoview/Makefile.am @@ -1,13 +1,9 @@ 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 \ @@ -25,16 +21,9 @@ aoview_SOURCES = \ aoview_voice.c \ aoview_replay.c \ aoview_label.c \ + aoview_flite.c \ 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 diff --git a/aoview/aoview.h b/aoview/aoview.h index d49bd6f4..7807b2fa 100644 --- a/aoview/aoview.h +++ b/aoview/aoview.h @@ -111,6 +111,7 @@ struct aostate { double distance; double bearing; + int gps_height; }; /* 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); +void +aoview_monitor_reset(void); + 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); +/* aoview_flite.c */ + +FILE * +aoview_flite_start(void); + +void +aoview_flite_stop(void); + #endif /* _AOVIEW_H_ */ diff --git a/aoview/aoview_flite.c b/aoview/aoview_flite.c index daa3ed36..bca19043 100644 --- a/aoview/aoview_flite.c +++ b/aoview/aoview_flite.c @@ -17,23 +17,59 @@ #include #include +#include "aoview.h" 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]; - 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; } diff --git a/aoview/aoview_main.c b/aoview/aoview_main.c index 99de1473..36a82e0e 100644 --- a/aoview/aoview_main.c +++ b/aoview/aoview_main.c @@ -31,6 +31,8 @@ static void destroy_event(GtkWidget *widget, gpointer data) gtk_main_quit(); } +extern int _Xdebug; + 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'}, + { "sync", 0, 0, 's'}, { 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; @@ -53,11 +56,15 @@ int main(int argc, char **argv) case 'd': device = optarg; break; + case 's': + _Xdebug = 1; + break; default: usage(); } } + g_thread_init(NULL); gtk_init(&argc, &argv); glade_init(); @@ -95,6 +102,8 @@ int main(int argc, char **argv) aoview_label_init(xml); + aoview_voice_speak("rocket flight monitor ready\n"); + gtk_main(); return 0; diff --git a/aoview/aoview_monitor.c b/aoview/aoview_monitor.c index faa24474..f7f646ae 100644 --- a/aoview/aoview_monitor.c +++ b/aoview/aoview_monitor.c @@ -31,7 +31,6 @@ aoview_monitor_disconnect(void) aoview_serial_close(monitor_serial); monitor_serial = NULL; } - aoview_table_clear(); aoview_log_new(); } @@ -134,6 +133,12 @@ aoview_monitor_parse(char *line) return TRUE; } +void +aoview_monitor_reset(void) +{ + memset(&state, '\0', sizeof (state)); +} + 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; + aoview_table_clear(); + aoview_monitor_reset(); aoview_serial_set_callback(monitor_serial, aoview_monitor_callback, monitor_serial, diff --git a/aoview/aoview_replay.c b/aoview/aoview_replay.c index 42728961..3eadb442 100644 --- a/aoview/aoview_replay.c +++ b/aoview/aoview_replay.c @@ -107,6 +107,7 @@ aoview_replay_open(GtkWidget *widget, gpointer data) gtk_widget_destroy(dialog); } else { replay_tick = -1; + aoview_monitor_reset(); 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) { + 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); + 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); diff --git a/aoview/aoview_state.c b/aoview/aoview_state.c index 4ba1854e..030db99f 100644 --- a/aoview/aoview_state.c +++ b/aoview/aoview_state.c @@ -18,7 +18,7 @@ #include "aoview.h" #include -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, @@ -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")) { - if (state->locked) { + if (state->locked && state->nsat > 4) { 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); + if (state->npad) { + state->gps_height = state->alt - state->pad_alt; + } else { + state->gps_height = 0; + } } void @@ -167,8 +172,6 @@ aoview_state_speak(struct aostate *state) 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'); - 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, @@ -239,5 +242,4 @@ void aoview_state_init(GladeXML *xml) { aoview_state_new(); - aoview_voice_speak("initializing rocket flight monitoring system\n"); } diff --git a/aoview/aoview_voice.c b/aoview/aoview_voice.c index 7f4e576e..f7c099b1 100644 --- a/aoview/aoview_voice.c +++ b/aoview/aoview_voice.c @@ -25,13 +25,13 @@ FILE *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) { - pclose(aoview_flite); + aoview_flite_stop(); aoview_flite = NULL; } } @@ -65,26 +65,55 @@ void aoview_voice_speak(char *format, ...) static GtkCheckMenuItem *voice_enable; +#define ALTOS_VOICE_PATH "/apps/aoview/voice" + 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_speak("enable voice system\n"); + aoview_voice_speak("enable voice\n"); } else { - aoview_voice_speak("disable voice system\n"); + aoview_voice_speak("disable voice\n"); 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) { - aoview_voice_open(); + gboolean enabled; + GConfClient *gconf_client; 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);