summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-06-30 15:25:52 -0700
committerKeith Packard <keithp@keithp.com>2009-06-30 15:25:52 -0700
commite506ed4b6efb86eab50204658fcd433b987e3831 (patch)
tree2fa17d91658948bbc3647cc70c10db06f1535b90
parent5b988e0146075d57434f8484e1ec9fcf3e183df2 (diff)
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 <keithp@keithp.com>
-rw-r--r--aoview/Makefile.am17
-rw-r--r--aoview/aoview.h12
-rw-r--r--aoview/aoview_flite.c58
-rw-r--r--aoview/aoview_main.c11
-rw-r--r--aoview/aoview_monitor.c9
-rw-r--r--aoview/aoview_replay.c20
-rw-r--r--aoview/aoview_state.c14
-rw-r--r--aoview/aoview_voice.c41
8 files changed, 143 insertions, 39 deletions
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 <stdio.h>
#include <flite/flite.h>
+#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 <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,
@@ -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);