mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-22 20:36:06 +08:00
Remove old GCS and supervision. (#3587)
This commit is contained in:
@@ -61,7 +61,6 @@ STATICINCLUDE=$(PAPARAZZI_HOME)/var/include
|
||||
CONF=$(PAPARAZZI_SRC)/conf
|
||||
AIRBORNE=sw/airborne
|
||||
SIMULATOR=sw/simulator
|
||||
COCKPIT=sw/ground_segment/cockpit
|
||||
TMTC=sw/ground_segment/tmtc
|
||||
GENERATORS=$(PAPARAZZI_SRC)/sw/tools/generators
|
||||
JOYSTICK=sw/ground_segment/joystick
|
||||
@@ -72,11 +71,10 @@ TOOLS=sw/tools
|
||||
# build some stuff in subdirs
|
||||
# nothing should depend on these...
|
||||
#
|
||||
PPRZCENTER=sw/supervision
|
||||
MISC=sw/ground_segment/misc
|
||||
LOGALIZER=sw/logalizer
|
||||
|
||||
SUBDIRS = $(PPRZCENTER) $(LOGALIZER) sw/tools
|
||||
SUBDIRS = $(LOGALIZER) sw/tools
|
||||
SUBDIRS_EXTRA = $(MISC)
|
||||
|
||||
#
|
||||
@@ -138,9 +136,9 @@ conf/tools/blacklisted: conf/tools/blacklisted_example
|
||||
cp conf/tools/blacklisted_example conf/tools/blacklisted
|
||||
|
||||
ground_segment: _print_building conf libpprz subdirs static
|
||||
ground_segment.opt: ground_segment cockpit.opt tmtc.opt
|
||||
ground_segment.opt: ground_segment tmtc.opt
|
||||
|
||||
static: cockpit tmtc generators sim_static joystick static_h
|
||||
static: tmtc generators sim_static joystick static_h
|
||||
|
||||
libpprzlink.update:
|
||||
$(MAKE) -C $(EXT) pprzlink.update
|
||||
@@ -151,12 +149,6 @@ libpprzlink.install:
|
||||
libpprz: libpprzlink.update libpprzlink.install _save_build_version
|
||||
$(MAKE) -C $(LIB)/ocaml
|
||||
|
||||
cockpit: libpprz
|
||||
$(MAKE) -C $(COCKPIT)
|
||||
|
||||
cockpit.opt: libpprz
|
||||
$(MAKE) -C $(COCKPIT) opt
|
||||
|
||||
tmtc: libpprz
|
||||
$(MAKE) -C $(TMTC)
|
||||
|
||||
@@ -193,8 +185,6 @@ $(SUBDIRS): libpprz
|
||||
$(SUBDIRS_EXTRA): libpprz
|
||||
$(MAKE) -C $@
|
||||
|
||||
$(PPRZCENTER): libpprz
|
||||
|
||||
$(LOGALIZER): libpprz
|
||||
|
||||
static_h: pprzlink_protocol $(GEN_HEADERS)
|
||||
@@ -355,7 +345,7 @@ test_full:
|
||||
|
||||
|
||||
.PHONY: all print_build_version _print_building _save_build_version init dox ground_segment ground_segment.opt \
|
||||
subdirs $(SUBDIRS) conf ext libpprz libpprzlink.update libpprzlink.install cockpit cockpit.opt tmtc tmtc.opt generators\
|
||||
subdirs $(SUBDIRS) conf ext libpprz libpprzlink.update libpprzlink.install tmtc tmtc.opt generators\
|
||||
static sim_static opencv_bebop\
|
||||
clean cleanspaces ab_clean dist_clean distclean dist_clean_irreversible \
|
||||
test test_examples test_math test_all_confs
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<program command="sw/ground_segment/cockpit/gcs" name="GCS" icon="gcs.svg" favorite="true">
|
||||
<arg constant="large_left_col.xml" flag="-layout" />
|
||||
</program>
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
<program command="sw/tools/gcs_launch.py" name="PprzGCS" />
|
||||
|
||||
<program command="$pprzgcs" name="PprzGCS" icon="gcs.svg" favorite="true"/>
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#
|
||||
# Copyright (C) 2003 Pascal Brisset, Antoine Drouin
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
#
|
||||
|
||||
# Quiet compilation
|
||||
Q=@
|
||||
|
||||
OCAMLCFLAGS=-thread -ccopt -fPIC
|
||||
|
||||
include ../../Makefile.ocaml
|
||||
OCAMLPATH:=$(shell echo $(PAPARAZZI_SRC)/sw/ground_segment/cockpit/lib:$(OCAMLPATH))
|
||||
export OCAMLPATH
|
||||
|
||||
ifneq ($(USE_LABELGTK),lablgtk2)
|
||||
all :
|
||||
@echo Skipping legacy GCS build \(missing lablgtk2\)
|
||||
|
||||
opt :
|
||||
@echo Skipping legacy GCS.opt build \(missing lablgtk2\)
|
||||
|
||||
else
|
||||
INCLUDES=
|
||||
PKG = -package lablgtk2,pprzlink,gcslib
|
||||
LINKPKG = $(PKG) -linkpkg -dllpath-pkg lablgtk2,pprzlink,gcslib,pprz
|
||||
|
||||
LABLGTK2INIT = $(shell ocamlfind query -p-format lablgtk2.init 2>/dev/null)
|
||||
ifeq ($(LABLGTK2INIT),)
|
||||
LABLGTK2INIT = $(shell ocamlfind query -p-format lablgtk2.auto-init 2>/dev/null)
|
||||
endif
|
||||
|
||||
LABLGTK2GLADE = $(shell ocamlfind query -p-format lablgtk2.glade 2>/dev/null)
|
||||
LABLGTK2CANVAS = $(shell ocamlfind query -p-format lablgtk2-gnome.gnomecanvas 2>/dev/null)
|
||||
|
||||
ML= gtk_setting_time.ml gtk_strip.ml horizon.ml strip.ml gtk_save_settings.ml saveSettings.ml page_settings.ml pages.ml speech.ml plugin.ml sectors.ml map2d.ml editFP.ml intruders.ml shapes.ml live.ml particules.ml papgets.ml gcs.ml
|
||||
MAIN=gcs
|
||||
CMO=$(ML:.ml=.cmo)
|
||||
CMX=$(ML:.ml=.cmx)
|
||||
|
||||
# only compile it lablgtk2 is installed
|
||||
ifeq ($(LABLGTK2INIT),)
|
||||
all :
|
||||
@echo Skipping legacy GCS build \(missing lablgtk2.init\)
|
||||
|
||||
opt :
|
||||
@echo Skipping legacy GCS.opt build \(missing lablgtk2.init\)
|
||||
|
||||
else
|
||||
|
||||
ifeq ($(LABLGTK2GLADE),)
|
||||
|
||||
all :
|
||||
@echo Skipping legacy GCS build \(missing lablgtk2.glade\)
|
||||
|
||||
opt :
|
||||
@echo Skipping legacy GCS.opt build \(missing lablgtk2.glade\)
|
||||
|
||||
else
|
||||
|
||||
ifeq ($(LABLGTK2CANVAS),)
|
||||
|
||||
all :
|
||||
@echo Skipping legacy GCS build \(missing lablgtk2-gnome.gnomecanvas\)
|
||||
|
||||
opt :
|
||||
@echo Skipping legacy GCS.opt build \(missing lablgtk2-gnome.gnomecanvas\)
|
||||
|
||||
else
|
||||
all : $(MAIN)
|
||||
|
||||
opt : $(MAIN).opt
|
||||
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
gcslib :
|
||||
$(Q)$(MAKE) -C lib
|
||||
|
||||
$(MAIN) : $(CMO) $(LIBPPRZCMA) $(LIBPPRZLINKCMA) $(XLIBPPRZCMA) gcslib
|
||||
@echo OL $@
|
||||
$(Q)$(OCAMLC) $(OCAMLCFLAGS) $(INCLUDES) $(LINKPKG) $(CMO) -o $@
|
||||
|
||||
$(MAIN).opt : $(CMX) $(LIBPPRZCMXA) $(LIBPPRZLINKCMXA) $(XLIBPPRZCMXA) gcslib
|
||||
@echo OOL $@
|
||||
$(Q)$(OCAMLOPT) $(OCAMLCFLAGS) $(INCLUDES) -package pprz.xlib,$(LABLGTK2INIT) -linkpkg $(CMX) -o $@
|
||||
|
||||
%.cmo: %.ml
|
||||
@echo OC $<
|
||||
$(Q)$(OCAMLC) $(OCAMLCFLAGS) $(INCLUDES) $(PKG) -c $<
|
||||
%.cmi: %.mli
|
||||
@echo OCI $<
|
||||
$(Q)$(OCAMLC) $(OCAMLCFLAGS) $(INCLUDES) $(PKG) -c $<
|
||||
%.cmx: %.ml
|
||||
@echo OOC $<
|
||||
$(Q)$(OCAMLOPT) $(OCAMLCFLAGS) $(INCLUDES) $(PKG) -c $<
|
||||
|
||||
saveSettings.cmo : gtk_save_settings.cmo
|
||||
saveSettings.cmx: gtk_save_settings.cmx
|
||||
|
||||
gtk_strip.ml : gcs.glade
|
||||
@echo GLADE $@
|
||||
$(Q)lablgladecc2 -root eventbox_strip -hide-default $< | grep -B 1000000 " end" > $@
|
||||
|
||||
gtk_setting_time.ml : gcs.glade
|
||||
@echo GLADE $@
|
||||
$(Q)lablgladecc2 -root setting_time -hide-default $< | grep -B 1000000 " end" > $@
|
||||
|
||||
gtk_save_settings.ml : gcs.glade
|
||||
@echo GLADE $@
|
||||
$(Q)lablgladecc2 -root save_settings -hide-default $< | grep -B 1000000 " end" > $@
|
||||
|
||||
strip.cmo : gtk_strip.cmo gtk_setting_time.cmo
|
||||
|
||||
compass : compass.ml
|
||||
@echo OL $@
|
||||
$(Q)$(OCAMLC) $(OCAMLCFLAGS) $(INCLUDES) $(LINKPKG) gtkInit.cmo $^ -o $@
|
||||
|
||||
|
||||
clean:
|
||||
$(Q)rm -f *~* *.cm* *.o *.out *.opt map2d gcs .depend gtk_strip.ml gtk_setting_time.ml gtk_save_settings.ml compass ant_track ant_track_pmm ant_track_pmm_gtk3 actuators
|
||||
$(MAKE) -C lib clean
|
||||
|
||||
.PHONY: all opt clean
|
||||
|
||||
|
||||
CC = gcc
|
||||
CFLAGS=-g -O2 -Wall $(shell pkg-config gtk+-2.0 --cflags) -fPIC
|
||||
LDFLAGS=$(shell pkg-config gtk+-2.0 --libs) -s -lglibivy -lm -lpcre
|
||||
|
||||
|
||||
ant_track : ant_track.c
|
||||
$(CC) $(CFLAGS) -g -o $@ $^ $(LDFLAGS)
|
||||
|
||||
ant_track_pmm : ant_track_pmm.c
|
||||
$(CC) -g -O2 -Wall $(shell pkg-config gtk+-3.0 --cflags) -fPIC -g -o $@ $^ $(shell pkg-config gtk+-3.0 --libs) -s -lglibivy -lm -lpcre -rdynamic
|
||||
|
||||
actuators : actuators.c
|
||||
$(CC) $(CFLAGS) -g -o $@ $^ $(LDFLAGS)
|
||||
|
||||
|
||||
#
|
||||
# Dependencies
|
||||
#
|
||||
|
||||
.depend: Makefile
|
||||
@echo DEPEND $@
|
||||
$(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) -I lib $(ML) lib/*.mli *.mli > .depend
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include .depend
|
||||
endif
|
||||
@@ -1,67 +0,0 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Ivy/ivy.h>
|
||||
#include <Ivy/ivyglibloop.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
gint ac_id = 42;
|
||||
GtkWidget *spin; /* awfull but a lot easier */
|
||||
|
||||
void on_scale_value_changed (GtkScale *scale, gpointer user_data) {
|
||||
gfloat cf = gtk_range_get_value(GTK_RANGE(scale));
|
||||
gint c = (gint)rint(cf);
|
||||
|
||||
gfloat sf = gtk_spin_button_get_value (( GtkSpinButton*)spin);
|
||||
gint s = (gint)rint(sf);
|
||||
|
||||
IvySendMsg("actuators_gtk RAW_DATALINK %d SET_ACTUATOR;%d;%d;%d", ac_id, c, s, ac_id);
|
||||
}
|
||||
|
||||
GtkWidget* build_gui ( void ) {
|
||||
GtkWidget *window1;
|
||||
GtkWidget *vbox1;
|
||||
|
||||
window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window1), "Set Actuators");
|
||||
gtk_window_set_default_size(GTK_WINDOW (window1), 320, -1);
|
||||
|
||||
vbox1 = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window1), vbox1);
|
||||
|
||||
GtkWidget *scale = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (1500, 1000, 2000, 1, 1, 0)));
|
||||
gtk_box_pack_start (GTK_BOX (vbox1), scale, TRUE, TRUE, 0);
|
||||
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
|
||||
g_signal_connect ((gpointer) scale, "value_changed",
|
||||
G_CALLBACK (on_scale_value_changed),
|
||||
(gpointer)0);
|
||||
|
||||
spin = gtk_spin_button_new(GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 8, 1, 1, 0)), 1, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox1), spin, TRUE, TRUE, 0);
|
||||
|
||||
return window1;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
if (argc > 1) {
|
||||
ac_id = atoi(argv[1]);
|
||||
} else {
|
||||
g_message("Warning: A/C id not specified; sending to %d", ac_id);
|
||||
}
|
||||
|
||||
GtkWidget* window = build_gui();
|
||||
gtk_widget_show_all(window);
|
||||
|
||||
IvyInit ("Setup Actuators", "Actuators READY", NULL, NULL, NULL, NULL);
|
||||
IvyStart("127.255.255.255");
|
||||
|
||||
gtk_main();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 - Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* Modified by: Mark Griffin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Ivy/ivy.h>
|
||||
#include <Ivy/ivyglibloop.h>
|
||||
|
||||
#define MANUAL 0
|
||||
#define AUTO 1
|
||||
|
||||
static double gps_pos_x;
|
||||
static double gps_pos_y;
|
||||
static double gps_alt;
|
||||
static double home_alt;
|
||||
static double ant_azim;
|
||||
static double ant_elev;
|
||||
static int mode;
|
||||
static int home_found=0;
|
||||
|
||||
GtkWidget *azim_scale;
|
||||
GtkWidget *elev_scale;
|
||||
|
||||
void on_mode_changed (GtkRadioButton *radiobutton, gpointer user_data) {
|
||||
mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobutton)) ? MANUAL : AUTO;
|
||||
IvySendMsg("1ME RAW_DATALINK 80 SETTING;0;0;%d", mode);
|
||||
g_message("Mode changed to %d" , mode);
|
||||
}
|
||||
|
||||
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
|
||||
g_object_set_data_full (G_OBJECT (component), name, \
|
||||
gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
|
||||
|
||||
#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
|
||||
g_object_set_data (G_OBJECT (component), name, widget)
|
||||
|
||||
GtkWidget* build_gui ( void ) {
|
||||
GtkWidget *window1;
|
||||
GtkWidget *vbox1;
|
||||
GtkWidget *vbox2;
|
||||
GtkWidget *table1;
|
||||
GtkWidget *label1;
|
||||
GtkWidget *label2;
|
||||
GtkWidget *label3;
|
||||
GtkWidget *label4;
|
||||
GtkWidget *radiobutton1;
|
||||
GSList *radiobutton1_group = NULL;
|
||||
GtkWidget *radiobutton2;
|
||||
GtkWidget *entry1;
|
||||
|
||||
window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window1), "tracking antenna");
|
||||
|
||||
vbox1 = gtk_vbox_new (FALSE, 0);
|
||||
gtk_widget_show (vbox1);
|
||||
gtk_container_add (GTK_CONTAINER (window1), vbox1);
|
||||
|
||||
vbox2 = gtk_vbox_new (FALSE, 0);
|
||||
gtk_widget_show (vbox2);
|
||||
gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0);
|
||||
|
||||
table1 = gtk_table_new (4, 3, FALSE);
|
||||
gtk_widget_show (table1);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), table1, TRUE, TRUE, 0);
|
||||
gtk_table_set_col_spacings (GTK_TABLE (table1), 5);
|
||||
|
||||
label1 = gtk_label_new ("Azimuth");
|
||||
gtk_widget_show (label1);
|
||||
gtk_table_attach (GTK_TABLE (table1), label1, 0, 1, 1, 2,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5);
|
||||
|
||||
label2 = gtk_label_new ("Elevation");
|
||||
gtk_widget_show (label2);
|
||||
gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 2, 3,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);
|
||||
|
||||
label3 = gtk_label_new ("Id");
|
||||
gtk_widget_show (label3);
|
||||
gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 3, 4,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
|
||||
|
||||
label4 = gtk_label_new ("mode");
|
||||
gtk_widget_show (label4);
|
||||
gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 0, 1,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5);
|
||||
|
||||
radiobutton1 = gtk_radio_button_new_with_mnemonic (NULL, "manual");
|
||||
gtk_widget_show (radiobutton1);
|
||||
gtk_table_attach (GTK_TABLE (table1), radiobutton1, 1, 2, 0, 1,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton1), radiobutton1_group);
|
||||
radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton1));
|
||||
|
||||
radiobutton2 = gtk_radio_button_new_with_mnemonic (NULL, "tracking");
|
||||
gtk_widget_show (radiobutton2);
|
||||
gtk_table_attach (GTK_TABLE (table1), radiobutton2, 2, 3, 0, 1,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton2), radiobutton1_group);
|
||||
radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton2));
|
||||
|
||||
azim_scale = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (144.7, 0, 360, 1, 1, 1)));
|
||||
gtk_widget_show (azim_scale);
|
||||
gtk_table_attach (GTK_TABLE (table1), azim_scale, 1, 3, 1, 2,
|
||||
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
||||
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
||||
gtk_range_set_update_policy (GTK_RANGE (azim_scale), GTK_UPDATE_DELAYED);
|
||||
|
||||
elev_scale = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (32.3, 0, 90, 1, 1, 1)));
|
||||
gtk_widget_show (elev_scale);
|
||||
gtk_table_attach (GTK_TABLE (table1), elev_scale, 1, 3, 2, 3,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
||||
|
||||
entry1 = gtk_entry_new ();
|
||||
gtk_widget_show (entry1);
|
||||
gtk_table_attach (GTK_TABLE (table1), entry1, 1, 3, 3, 4,
|
||||
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
|
||||
g_signal_connect ((gpointer) radiobutton1, "toggled",
|
||||
G_CALLBACK (on_mode_changed),
|
||||
NULL);
|
||||
|
||||
/* Store pointers to all widgets, for use by lookup_widget(). */
|
||||
GLADE_HOOKUP_OBJECT_NO_REF (window1, window1, "window1");
|
||||
GLADE_HOOKUP_OBJECT (window1, vbox1, "vbox1");
|
||||
GLADE_HOOKUP_OBJECT (window1, vbox2, "vbox2");
|
||||
GLADE_HOOKUP_OBJECT (window1, table1, "table1");
|
||||
GLADE_HOOKUP_OBJECT (window1, label1, "label1");
|
||||
GLADE_HOOKUP_OBJECT (window1, label2, "label2");
|
||||
GLADE_HOOKUP_OBJECT (window1, label3, "label3");
|
||||
GLADE_HOOKUP_OBJECT (window1, label4, "label4");
|
||||
GLADE_HOOKUP_OBJECT (window1, radiobutton1, "radiobutton1");
|
||||
GLADE_HOOKUP_OBJECT (window1, radiobutton2, "radiobutton2");
|
||||
GLADE_HOOKUP_OBJECT (window1, entry1, "entry1");
|
||||
|
||||
return window1;
|
||||
}
|
||||
|
||||
/* jump here when a GPS message is received */
|
||||
void on_GPS_STATUS(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
||||
if (home_found == 0) {
|
||||
if (atof(argv[0]) == 3) { /* wait until we have a valid GPS fix */
|
||||
home_alt = atof(argv[4])/100.; /* get the altitude */
|
||||
home_found = 1;
|
||||
}
|
||||
}
|
||||
gps_alt = atof(argv[4])/100.;
|
||||
}
|
||||
|
||||
/* jump here when a NAVIGATION message is received */
|
||||
void on_NAV_STATUS(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
||||
|
||||
if (mode == AUTO) {
|
||||
gps_pos_x = atof(argv[2]);
|
||||
gps_pos_y = atof(argv[3]);
|
||||
/* calculate azimuth */
|
||||
ant_azim = atan2(gps_pos_x, gps_pos_y) * 180. / M_PI;
|
||||
if (ant_azim < 0) ant_azim += 360.;
|
||||
/* calculate elevation */
|
||||
ant_elev = atan2( (gps_alt-home_alt), sqrt(atof(argv[5])) ) * 180. / M_PI;
|
||||
if (ant_elev < 0) ant_elev = 0.;
|
||||
|
||||
gtk_range_set_value(azim_scale, ant_azim);
|
||||
gtk_range_set_value(elev_scale, ant_elev);
|
||||
}
|
||||
/*g_message("home_alt %f gps_alt %f azim %f elev %f", home_alt, gps_alt, ant_azim, ant_elev); */
|
||||
}
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
GtkWidget* window = build_gui();
|
||||
gtk_widget_show_all(window);
|
||||
|
||||
IvyInit ("AntennaTracker", "AntennaTracker READY", NULL, NULL, NULL, NULL);
|
||||
IvyBindMsg(on_GPS_STATUS, NULL, "^\\S* GPS (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)");
|
||||
IvyBindMsg(on_NAV_STATUS, NULL, "^\\S* NAVIGATION (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)");
|
||||
IvyStart("127.255.255.255");
|
||||
|
||||
gtk_main();
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,423 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.3 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<object class="GtkAdjustment" id="azim_pw_span_adjustment">
|
||||
<property name="lower">600</property>
|
||||
<property name="upper">1400</property>
|
||||
<property name="value">1000</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="azimuth_scale_adjustment">
|
||||
<property name="upper">360</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="azimuth_trim_adjustment">
|
||||
<property name="lower">-10</property>
|
||||
<property name="upper">10</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="elev_pw_span_adjustment">
|
||||
<property name="lower">600</property>
|
||||
<property name="upper">1400</property>
|
||||
<property name="value">1000</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="elevation_scale_adjustment">
|
||||
<property name="upper">90</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="elevation_trim_adjustment">
|
||||
<property name="lower">-10</property>
|
||||
<property name="upper">10</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="hnp_scale_adjustment">
|
||||
<property name="upper">360</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
<signal name="value-changed" handler="on_hnp_changed" swapped="no"/>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="name">antenna_tracker</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">baseline</property>
|
||||
<property name="title" translatable="yes">Paparazzi Antenna Tracker</property>
|
||||
<property name="default_width">650</property>
|
||||
<property name="default_height">500</property>
|
||||
<child>
|
||||
<object class="GtkLayout" id="layout1">
|
||||
<property name="name">ant_track_gui</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">baseline</property>
|
||||
<property name="resize_mode">immediate</property>
|
||||
<property name="width">400</property>
|
||||
<property name="height">300</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="radiobutton1">
|
||||
<property name="label" translatable="yes">Manual</property>
|
||||
<property name="name">AUTO</property>
|
||||
<property name="width_request">100</property>
|
||||
<property name="height_request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_mode_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">14</property>
|
||||
<property name="y">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="radiobutton2">
|
||||
<property name="label" translatable="yes">Auto</property>
|
||||
<property name="name">MANUAL</property>
|
||||
<property name="width_request">100</property>
|
||||
<property name="height_request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">radiobutton1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">139</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="azimuth_scale">
|
||||
<property name="name">azimuth</property>
|
||||
<property name="width_request">421</property>
|
||||
<property name="height_request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">baseline</property>
|
||||
<property name="adjustment">azimuth_scale_adjustment</property>
|
||||
<property name="round_digits">1</property>
|
||||
<signal name="value-changed" handler="on_azimuth_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">120</property>
|
||||
<property name="y">64</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="elevation_scale">
|
||||
<property name="name">elevation</property>
|
||||
<property name="width_request">421</property>
|
||||
<property name="height_request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="adjustment">elevation_scale_adjustment</property>
|
||||
<property name="round_digits">1</property>
|
||||
<signal name="value-changed" handler="on_elevation_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">120</property>
|
||||
<property name="y">122</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry1">
|
||||
<property name="name">entry1</property>
|
||||
<property name="width_request">481</property>
|
||||
<property name="height_request">77</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="max_length">43</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">50</property>
|
||||
<property name="y">175</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="id_label">
|
||||
<property name="name">label1</property>
|
||||
<property name="width_request">48</property>
|
||||
<property name="height_request">35</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">id</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">1</property>
|
||||
<property name="y">196</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="set_home_button">
|
||||
<property name="label" translatable="yes">Set Home Here</property>
|
||||
<property name="name">Set_Home_Here</property>
|
||||
<property name="width_request">125</property>
|
||||
<property name="height_request">29</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="resize_mode">immediate</property>
|
||||
<property name="image_position">bottom</property>
|
||||
<signal name="clicked" handler="on_set_home_button_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">299</property>
|
||||
<property name="y">26</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="hnp_scale">
|
||||
<property name="name">horizontal_neutral_point_scale</property>
|
||||
<property name="width_request">420</property>
|
||||
<property name="height_request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text">Used when the antenna tracker cannot be moved to point to the North WHEN AZIMUTH IS SET TO 0 IN MANUAL MODE.
|
||||
For example use it if the antenna tracker is mounted on a vehicle which cannot be steered to look to the North when the Azimuth servo is centered.
|
||||
To center the Azimuth servo set mode to MANUAL and then Azimuth scale to 0
|
||||
</property>
|
||||
<property name="opacity">0.95999999999999996</property>
|
||||
<property name="adjustment">hnp_scale_adjustment</property>
|
||||
<property name="round_digits">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">121</property>
|
||||
<property name="y">229</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="azim_label">
|
||||
<property name="name">Azimuth_label</property>
|
||||
<property name="width_request">70</property>
|
||||
<property name="height_request">30</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Azimuth °</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">1</property>
|
||||
<property name="y">96</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="elev_label">
|
||||
<property name="width_request">70</property>
|
||||
<property name="height_request">30</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Elevation °</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">3</property>
|
||||
<property name="y">154</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="hnp_label">
|
||||
<property name="width_request">108</property>
|
||||
<property name="height_request">30</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Neutral Heading °</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">8</property>
|
||||
<property name="y">261</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="azim_servo_pw_label">
|
||||
<property name="width_request">100</property>
|
||||
<property name="height_request">29</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">1500 us</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">540</property>
|
||||
<property name="y">97</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="elev_servo_pw_label">
|
||||
<property name="width_request">71</property>
|
||||
<property name="height_request">26</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">1000 us</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">556</property>
|
||||
<property name="y">157</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="reset_home_button">
|
||||
<property name="label" translatable="yes">Reset Home</property>
|
||||
<property name="width_request">116</property>
|
||||
<property name="height_request">27</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_reset_home_button_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">500</property>
|
||||
<property name="y">28</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="elevation_trim_scale">
|
||||
<property name="width_request">200</property>
|
||||
<property name="height_request">50</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Adjust the elevation of the Antenna in case the best reception is not parallel with the antenna's mechanical longitudinal axis.
|
||||
This adjustment works realtime in both modes.</property>
|
||||
<property name="adjustment">elevation_trim_adjustment</property>
|
||||
<property name="show_fill_level">True</property>
|
||||
<property name="round_digits">1</property>
|
||||
<signal name="value-changed" handler="on_elev_trim_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">342</property>
|
||||
<property name="y">334</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="elev_trim_label">
|
||||
<property name="width_request">94</property>
|
||||
<property name="height_request">26</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Elevation trim °</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">398</property>
|
||||
<property name="y">314</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="azimuth_trim_scale">
|
||||
<property name="width_request">200</property>
|
||||
<property name="height_request">50</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Adjust the azimuth of the Antenna in case the best reception is not parallel with the antenna's mechanical longitudinal axis.
|
||||
This adjustment works realtime in both modes.</property>
|
||||
<property name="adjustment">azimuth_trim_adjustment</property>
|
||||
<property name="show_fill_level">True</property>
|
||||
<property name="round_digits">1</property>
|
||||
<signal name="value-changed" handler="on_azim_trim_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">123</property>
|
||||
<property name="y">333</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="elevation_pw_span_scale">
|
||||
<property name="width_request">200</property>
|
||||
<property name="height_request">50</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">After you find the correct setting you can make a shell script and run the Antenna tracker command with the --tilt_epa=xxxx option so the changes became more permanent.
|
||||
From command prompt run the antenna tracker executable with the --help parameter for more help. </property>
|
||||
<property name="adjustment">elev_pw_span_adjustment</property>
|
||||
<property name="show_fill_level">True</property>
|
||||
<property name="round_digits">1</property>
|
||||
<signal name="value-changed" handler="on_elev_pw_span_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">341</property>
|
||||
<property name="y">433</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="azimuth_pw_span_scale">
|
||||
<property name="width_request">200</property>
|
||||
<property name="height_request">50</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">After you find the correct setting you can make a shell script and run the Antenna tracker command with the --pan_epa=xxxx option so the changes became more permanent.
|
||||
From command prompt run the antenna tracker executable with the --help parameter for more help. </property>
|
||||
<property name="adjustment">azim_pw_span_adjustment</property>
|
||||
<property name="show_fill_level">True</property>
|
||||
<property name="round_digits">1</property>
|
||||
<signal name="value-changed" handler="on_azim_pw_span_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">126</property>
|
||||
<property name="y">432</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="azim_trim_label">
|
||||
<property name="width_request">89</property>
|
||||
<property name="height_request">20</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Azimuth trim °</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">181</property>
|
||||
<property name="y">319</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="elev_pw_span_label">
|
||||
<property name="width_request">181</property>
|
||||
<property name="height_request">28</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Elevation servo PW range (us)
|
||||
decrease -- increase</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">354</property>
|
||||
<property name="y">408</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="azim_pw_span_label">
|
||||
<property name="width_request">176</property>
|
||||
<property name="height_request">28</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Azimuth servo PW range (us)
|
||||
decrease -- increase</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">143</property>
|
||||
<property name="y">407</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="servo_pw_label">
|
||||
<property name="width_request">69</property>
|
||||
<property name="height_request">21</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Servo PW</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">556</property>
|
||||
<property name="y">76</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -1,155 +0,0 @@
|
||||
(*
|
||||
* Compass display for a manned vehicle
|
||||
*
|
||||
* Copyright (C) 2004-2009 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
open Printf
|
||||
open Latlong
|
||||
|
||||
module Tm_Pprz = PprzLink.Messages (struct let name = "telemetry" end)
|
||||
|
||||
let width = 200
|
||||
let height = width
|
||||
let background = `NAME "grey"
|
||||
let fore = `BLACK
|
||||
|
||||
let arrow = [1,1; 2,1; 0,3; -2,1; -1,1; -1,-3; 1,-3; 1,1]
|
||||
|
||||
let rot = fun angle ->
|
||||
let angle = (Deg>>Rad)(-. angle) in
|
||||
let ca = cos angle and sa = sin angle in
|
||||
fun (x,y) ->
|
||||
let x = float x and y = float y in
|
||||
(truncate (ca*.x-.sa*.y), truncate (sa*.x+.ca*.y))
|
||||
|
||||
let n = 100
|
||||
let circle = fun (dr:GDraw.pixmap) (x,y) r ->
|
||||
let r = float r in
|
||||
let points = Array.init n
|
||||
(fun i ->
|
||||
let a = float i /. float n *. 2.*.pi in
|
||||
(x + truncate (r*.cos a), y + truncate (r*.sin a))) in
|
||||
dr#polygon (Array.to_list points)
|
||||
|
||||
let draw = fun (da_object:Gtk_tools.pixmap_in_drawin_area) desired_course course_opt distance ->
|
||||
let da = da_object#drawing_area in
|
||||
let {Gtk.width=width; height=height} = da#misc#allocation in
|
||||
let dr = da_object#get_pixmap () in
|
||||
dr#set_foreground background;
|
||||
dr#rectangle ~x:0 ~y:0 ~width ~height ~filled:true ();
|
||||
let s = (min width height) / 8 in
|
||||
|
||||
(* Text *)
|
||||
let context = da#misc#create_pango_context in
|
||||
context#set_font_by_name (sprintf "sans %d" (s/3));
|
||||
let print_string = fun x y string ->
|
||||
let layout = context#create_layout in
|
||||
let fd = Pango.Context.get_font_description (Pango.Layout.get_context layout) in
|
||||
Pango.Font.modify fd ~weight:`BOLD ();
|
||||
context#set_font_description fd;
|
||||
let from_codeset = "ISO-8859-15"
|
||||
and to_codeset = "UTF-8" in
|
||||
Pango.Layout.set_text layout (Glib.Convert.convert ~from_codeset ~to_codeset string);
|
||||
let (w,h) = Pango.Layout.get_pixel_size layout in
|
||||
dr#put_layout ~x:(x-w/2) ~y:(y-h/2) ~fore layout in
|
||||
|
||||
let course = match course_opt with None -> 0. | Some c -> c in
|
||||
let rotation = rot (desired_course -. course) in
|
||||
let translate = fun (x, y) -> (4*s+x, 4*s-y) in
|
||||
|
||||
(* Arrow *)
|
||||
if distance > 5. then
|
||||
match course_opt with
|
||||
None ->
|
||||
print_string (4*s) (4*s) "?"
|
||||
| Some _ ->
|
||||
let points = List.map (fun (x, y) -> translate (rotation (x*s/2,y*s/2))) arrow in
|
||||
dr#set_foreground fore;
|
||||
dr#polygon ~filled:true points;
|
||||
circle dr (4*s,4*s) (2*s);
|
||||
circle dr (4*s,4*s) (3*s)
|
||||
else
|
||||
print_string (4*s) (4*s) "STOP";
|
||||
|
||||
(* Distance and bearing to target, current track *)
|
||||
print_string (7*s) s (sprintf "%.0f m" distance);
|
||||
print_string (7*s) (s/2) "Dist.";
|
||||
print_string s s (sprintf "%.0f°" desired_course);
|
||||
print_string s (s/2) "Brg";
|
||||
print_string s (7*s) (match course_opt with None -> "---" | _ -> sprintf "%.0f°" course);
|
||||
print_string s (7*s+s/2) "Track";
|
||||
|
||||
(* Cardinal points *)
|
||||
let rotation = rot (-. course) in
|
||||
let cards = [(0, 10, "N"); (0, -10, "S"); (10, 0, "E"); (-10, 0, "W");
|
||||
(7, 7, "NE"); (7, -7, "SE");(-7,-7,"SW");(-7,7,"NW")] in
|
||||
List.iter (fun (x,y,string)->
|
||||
let (x,y) = translate (rotation ((x*5*s)/20, (y*5*s)/20)) in
|
||||
print_string x y string)
|
||||
cards;
|
||||
|
||||
(new GDraw.drawable da#misc#window)#put_pixmap ~x:0 ~y:0 dr#pixmap
|
||||
|
||||
(*********************** Main ************************************************)
|
||||
let _ =
|
||||
let ivy_bus = ref Defivybus.default_ivy_bus in
|
||||
Arg.parse
|
||||
[ "-b", Arg.String (fun x -> ivy_bus := x), (sprintf "<ivy bus> Default is %s" !ivy_bus)]
|
||||
(fun x -> prerr_endline ("WARNING: don't do anything with "^x))
|
||||
"Usage: ";
|
||||
|
||||
(** Connect to the Ivy bus *)
|
||||
Ivy.init "Paparazzi UGV Compass" "READY" (fun _ _ -> ());
|
||||
Ivy.start !ivy_bus;
|
||||
|
||||
(** Open the window *)
|
||||
let icon = GdkPixbuf.from_file Env.icon_file in
|
||||
let window = GWindow.window ~icon ~title:"UGV Compass" () in
|
||||
let quit = fun () -> GMain.Main.quit (); exit 0 in
|
||||
ignore (window#connect#destroy ~callback:quit);
|
||||
|
||||
let da = new Gtk_tools.pixmap_in_drawin_area ~width ~height ~packing:window#add () in
|
||||
da#drawing_area#misc#realize ();
|
||||
|
||||
(* Listening messages *)
|
||||
let course = ref None in (* deg *)
|
||||
let desired_course = ref 0. in (* deg *)
|
||||
let get_navigation = fun _ values ->
|
||||
let distance = (try sqrt (PprzLink.float_assoc "dist2_wp" values) with _ -> PprzLink.float_assoc "dist_wp" values) in
|
||||
draw da !desired_course !course distance in
|
||||
ignore (Tm_Pprz.message_bind "NAVIGATION" get_navigation);
|
||||
let get_gps = fun _ values ->
|
||||
(* if speed < 1m/s, the course information is not relevant *)
|
||||
course :=
|
||||
if PprzLink.int_assoc "speed" values > 100 then
|
||||
Some (float (PprzLink.int_assoc "course" values) /. 10.)
|
||||
else
|
||||
None in
|
||||
ignore (Tm_Pprz.message_bind "GPS" get_gps);
|
||||
let get_desired = fun _ values ->
|
||||
desired_course := (Rad>>Deg) (PprzLink.float_assoc "course" values) in
|
||||
ignore (Tm_Pprz.message_bind "DESIRED" get_desired);
|
||||
|
||||
(** Start the main loop *)
|
||||
window#show ();
|
||||
GMain.main ()
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
(***************** Editing ONE (single) flight plan **************************)
|
||||
open Printf
|
||||
open Latlong
|
||||
|
||||
let (//) = Filename.concat
|
||||
let fp_example = Env.flight_plans_path // "example.xml"
|
||||
let default_path_maps = Env.paparazzi_home // "data" // "maps"
|
||||
|
||||
(** Dummy flight plan (for map calibration) *)
|
||||
let dummy_fp = fun latlong ->
|
||||
Xml.Element("flight_plan",
|
||||
["lat0", string_of_float ((Rad>>Deg)latlong.posn_lat);
|
||||
"lon0", string_of_float ((Rad>>Deg)latlong.posn_long);
|
||||
"alt", "42.";
|
||||
"MAX_DIST_FROM_HOME", "1000."],
|
||||
[Xml.Element("waypoints", [],[]);
|
||||
Xml.Element("blocks", [],[])])
|
||||
|
||||
|
||||
|
||||
let current_fp = ref None
|
||||
|
||||
(** Wrapper checking there is currently no flight plan loaded *)
|
||||
let if_none = fun f ->
|
||||
match !current_fp with
|
||||
Some _ ->
|
||||
GToolbox.message_box ~title:"Error" "Only one editable flight plan at a time"
|
||||
| None ->
|
||||
f ()
|
||||
|
||||
let set_window_title = fun geomap ->
|
||||
let title_suffix =
|
||||
match !current_fp with
|
||||
None -> ""
|
||||
| Some (_fp, xml_file) -> sprintf " (%s)" (Filename.basename xml_file) in
|
||||
match GWindow.toplevel geomap#canvas with
|
||||
Some w ->
|
||||
w#set_title (sprintf "Flight Plan Editor%s" title_suffix)
|
||||
| None -> ()
|
||||
|
||||
|
||||
|
||||
let save_fp = fun geomap ->
|
||||
match !current_fp with
|
||||
None -> () (* Nothing to save *)
|
||||
| Some (fp, filename) ->
|
||||
match GToolbox.select_file ~title:"Save Flight Plan" ~filename () with
|
||||
None -> ()
|
||||
| Some file ->
|
||||
let f = open_out file in
|
||||
let fp_path = Str.replace_first (Str.regexp Env.flight_plans_path) "" (Filename.dirname file) in
|
||||
let rel_path = Str.global_replace (Str.regexp (Printf.sprintf "%s[^%s]+" Filename.dir_sep Filename.dir_sep)) (Filename.parent_dir_name // "") fp_path in
|
||||
fprintf f "<!DOCTYPE flight_plan SYSTEM \"%s%s\">\n\n" rel_path "flight_plan.dtd";
|
||||
fprintf f "%s\n" (ExtXml.to_string_fmt fp#xml);
|
||||
close_out f;
|
||||
current_fp := Some (fp, file);
|
||||
set_window_title geomap
|
||||
|
||||
|
||||
let close_fp = fun geomap ->
|
||||
match !current_fp with
|
||||
None -> () (* Nothing to close *)
|
||||
| Some (fp, _filename) ->
|
||||
let close = fun () ->
|
||||
fp#destroy ();
|
||||
geomap#clear_georefs ();
|
||||
current_fp := None in
|
||||
match GToolbox.question_box ~title:"Closing flight plan" ~buttons:["Close"; "Save&Close"; "Cancel"] "Do you want to save/close ?" with
|
||||
2 -> save_fp geomap; close ()
|
||||
| 1 -> close ()
|
||||
| _ -> ()
|
||||
|
||||
let load_xml_fp = fun geomap editor_frame _accel_group ?(xml_file=Env.flight_plans_path) xml ->
|
||||
Map2d.set_georef_if_none geomap (MapFP.georef_of_xml xml);
|
||||
let fp = new MapFP.flight_plan ~editable:true ~show_moved:false geomap "red" Env.flight_plan_dtd xml in
|
||||
editor_frame#add fp#window;
|
||||
current_fp := Some (fp,xml_file);
|
||||
|
||||
(** Add waypoints as geo references *)
|
||||
List.iter
|
||||
(fun w ->
|
||||
let (_i, w) = fp#index w in
|
||||
geomap#add_info_georef (sprintf "%s" w#name) (w :> < pos : Latlong.geographic >))
|
||||
fp#waypoints;
|
||||
|
||||
fp
|
||||
|
||||
let labelled_entry = fun ?width_chars text value h ->
|
||||
let _ = GMisc.label ~text ~packing:h#add () in
|
||||
GEdit.entry ?width_chars ~text:value ~packing:h#add ()
|
||||
|
||||
let new_fp = fun geomap editor_frame accel_group () ->
|
||||
if_none (fun () ->
|
||||
let dialog = GWindow.window ~border_width:10 ~title:"New flight plan" () in
|
||||
let dvbx = GPack.box `VERTICAL ~packing:dialog#add () in
|
||||
let h = GPack.hbox ~packing:dvbx#pack () in
|
||||
let default_latlong =
|
||||
match geomap#georef with
|
||||
None -> "WGS84 37.21098 -113.45678"
|
||||
| Some geo -> Latlong.string_of geo in
|
||||
let latlong = labelled_entry ~width_chars:25 "Geographic Reference" default_latlong h in
|
||||
let alt0 = labelled_entry ~width_chars:4 "Ground Alt" "380" h in
|
||||
let h = GPack.hbox ~packing:dvbx#pack () in
|
||||
let alt = labelled_entry ~width_chars:4 "Default Alt" "430" h in
|
||||
let qfu = labelled_entry ~width_chars:4 "QFU" "270" h in
|
||||
let mdfh = labelled_entry ~width_chars:4 "Max distance from HOME" "500" h in
|
||||
|
||||
let h = GPack.hbox ~packing:dvbx#pack () in
|
||||
let name = labelled_entry "Name" "Test flight" h in
|
||||
|
||||
let h = GPack.hbox ~packing:dvbx#pack () in
|
||||
let cancel = GButton.button ~stock:`CANCEL ~packing: h#add () in
|
||||
ignore(cancel#connect#clicked ~callback:dialog#destroy);
|
||||
|
||||
let createfp = GButton.button ~stock:`OK ~packing: h#add () in
|
||||
createfp#grab_default ();
|
||||
ignore(createfp#connect#clicked ~callback:
|
||||
begin fun _ ->
|
||||
let xml = ExtXml.parse_file fp_example in
|
||||
let s = ExtXml.subst_attrib in
|
||||
let wgs84 = Latlong.of_string latlong#text in
|
||||
let xml = s "lat0" (deg_string_of_rad wgs84.posn_lat) xml in
|
||||
let xml = s "lon0" (deg_string_of_rad wgs84.posn_long) xml in
|
||||
let xml = s "ground_alt" alt0#text xml in
|
||||
let xml = s "qfu" qfu#text xml in
|
||||
let xml = s "alt" alt#text xml in
|
||||
let xml = s "max_dist_from_home" mdfh#text xml in
|
||||
let xml = s "name" name#text xml in
|
||||
ignore (load_xml_fp geomap editor_frame accel_group xml);
|
||||
dialog#destroy ()
|
||||
end);
|
||||
dialog#show ())
|
||||
|
||||
|
||||
let loading_error = fun xml_file e ->
|
||||
let m = sprintf "Error while loading %s:\n%s" xml_file e in
|
||||
GToolbox.message_box ~title:"Error" m
|
||||
|
||||
|
||||
|
||||
let load_xml_file = fun geomap editor_frame accel_group xml_file ->
|
||||
try
|
||||
let xml = Xml.parse_file xml_file in
|
||||
ignore (load_xml_fp geomap editor_frame accel_group ~xml_file xml);
|
||||
geomap#fit_to_window ();
|
||||
set_window_title geomap
|
||||
with
|
||||
Dtd.Prove_error(e) -> loading_error xml_file (Dtd.prove_error e)
|
||||
| Dtd.Check_error(e) -> loading_error xml_file (Dtd.check_error e)
|
||||
| Xml.Error e -> loading_error xml_file (Xml.error e)
|
||||
|
||||
|
||||
|
||||
(** Loading a flight plan for edition *)
|
||||
let load_fp = fun geomap editor_frame accel_group () ->
|
||||
if_none (fun () ->
|
||||
match GToolbox.select_file ~title:"Open flight plan" ~filename:(Env.flight_plans_path // "*.xml") () with
|
||||
None -> ()
|
||||
| Some xml_file -> load_xml_file geomap editor_frame accel_group xml_file)
|
||||
|
||||
let create_wp = fun geomap geo ->
|
||||
match !current_fp with
|
||||
None ->
|
||||
GToolbox.message_box ~title:"Error" "Load a flight plan first";
|
||||
failwith "create_wp"
|
||||
| Some (fp,_) ->
|
||||
let w = fp#add_waypoint geo in
|
||||
geomap#add_info_georef (sprintf "%s" w#name) (w :> < pos : Latlong.geographic >);
|
||||
w
|
||||
|
||||
|
||||
|
||||
let ref_point_of_waypoint = fun xml ->
|
||||
Xml.Element("point", ["x",Xml.attrib xml "x";
|
||||
"y",Xml.attrib xml "y";
|
||||
"geo", Xml.attrib xml "name"],[])
|
||||
|
||||
|
||||
(** Calibration of chosen image (requires a dummy flight plan) *)
|
||||
let calibrate_map = fun (geomap:MapCanvas.widget) editor_frame accel_group () ->
|
||||
match !current_fp with
|
||||
| Some (_fp,_) -> GToolbox.message_box ~title:"Error" "Close current flight plan before calibration"
|
||||
| None ->
|
||||
match GToolbox.select_file ~filename:(default_path_maps // "") ~title:"Open Image" () with
|
||||
None -> ()
|
||||
| Some image ->
|
||||
(** Displaying the image in the NW corner *)
|
||||
let pixbuf = GdkPixbuf.from_file image in
|
||||
let pix = GnoCanvas.pixbuf ~pixbuf ~props:[`ANCHOR `NW] geomap#canvas#root in
|
||||
let (x0, y0) = geomap#canvas#get_scroll_offsets in
|
||||
let (x,y) = geomap#canvas#window_to_world ~winx:(float x0) ~winy:(float y0) in
|
||||
pix#move ~x ~y;
|
||||
|
||||
(** Open a dummy flight plan *)
|
||||
let dummy_georef =
|
||||
match geomap#georef with
|
||||
None -> {posn_lat = (Deg>>Rad)43.; posn_long = (Deg>>Rad)1. }
|
||||
| Some geo -> geo in
|
||||
let fp_xml = dummy_fp dummy_georef in
|
||||
let fp = load_xml_fp geomap editor_frame accel_group fp_xml in
|
||||
|
||||
(** Dialog to finish calibration *)
|
||||
let dialog = GWindow.window ~border_width:10 ~title:"Map calibration" () in
|
||||
let v = GPack.vbox ~packing:dialog#add () in
|
||||
let _ = GMisc.label ~text:"Choose 2 (or more) waypoints (Ctrl-Left)\nRename the waypoints with their geographic coordinates\nFor example: 'WGS84 43.123456 1.234567' or 'UTM 530134 3987652 12' or 'LBT2e 123456 543210'\nClick the button below to save the XML result file\n" ~packing:v#add () in
|
||||
let h = GPack.hbox ~packing:v#pack () in
|
||||
let cancel = GButton.button ~stock:`CLOSE ~packing:h#add () in
|
||||
let cal = GButton.button ~stock:`OK ~packing:h#add () in
|
||||
let destroy = fun () ->
|
||||
dialog#destroy ();
|
||||
close_fp geomap;
|
||||
pix#destroy () in
|
||||
ignore(cancel#connect#clicked ~callback:destroy);
|
||||
ignore(cal#connect#clicked ~callback:(fun _ ->
|
||||
let points = List.map XmlEdit.xml_of_node fp#waypoints in
|
||||
let points = List.map ref_point_of_waypoint points in
|
||||
let xml = Xml.Element ("map",
|
||||
["file", Filename.basename image;
|
||||
"projection", geomap#projection],
|
||||
points) in
|
||||
match GToolbox.select_file ~filename:(default_path_maps//".xml") ~title:"Save calibrated map" () with
|
||||
None -> ()
|
||||
| Some xml_file ->
|
||||
let f = open_out xml_file in
|
||||
Printf.fprintf f "%s\n" (Xml.to_string_fmt xml);
|
||||
close_out f));
|
||||
cal#grab_default ();
|
||||
dialog#show ()
|
||||
@@ -1,8 +0,0 @@
|
||||
val create_wp : MapCanvas.widget -> Latlong.geographic -> MapWaypoints.waypoint
|
||||
val calibrate_map : MapCanvas.widget -> GBin.frame -> Gtk.accel_group -> unit -> unit
|
||||
val new_fp : MapCanvas.widget -> GBin.frame -> Gtk.accel_group -> unit -> unit
|
||||
val load_fp : MapCanvas.widget -> GBin.frame -> Gtk.accel_group -> unit -> unit
|
||||
val load_xml_file : MapCanvas.widget -> GBin.frame -> Gtk.accel_group -> string -> unit
|
||||
val save_fp : MapCanvas.widget -> unit
|
||||
val close_fp : MapCanvas.widget -> unit
|
||||
val set_window_title : MapCanvas.widget -> unit
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,239 +0,0 @@
|
||||
(*
|
||||
* Multi aircrafts map display and flight plan editor
|
||||
*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin / 2011 Tobias Muench, Rolf Noellenburg
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
open Printf
|
||||
open Latlong
|
||||
|
||||
let affine_pos_and_angle xw yw angle =
|
||||
let cos_a = cos angle in
|
||||
let sin_a = sin angle in
|
||||
[| cos_a ; sin_a ; ~-. sin_a; cos_a; xw; yw |]
|
||||
|
||||
|
||||
let affine_pos xw yw = affine_pos_and_angle xw yw 0.
|
||||
|
||||
let arc = fun n r start stop ->
|
||||
let s = (stop -. start) /. float (n-1) in
|
||||
Array.init n (fun i -> let a = start+.float i*.s in (r*.cos a, r*.sin a))
|
||||
|
||||
let floats_of_points = fun ps ->
|
||||
let n = Array.length ps in
|
||||
let a = Array.make (2*n) 0. in
|
||||
for i = 0 to n - 1 do
|
||||
let (x, y) = ps.(i) in
|
||||
a.(2*i)<-x;
|
||||
a.(2*i+1)<-y
|
||||
done;
|
||||
a
|
||||
|
||||
let ruler = fun ?(index_on_right=false) ~text_props ~max_value ~scale ~w ~index_width ~step ~h root ->
|
||||
let r = GnoCanvas.group root in
|
||||
let height = scale *. float max_value in
|
||||
|
||||
(* Grey background *)
|
||||
let _ = GnoCanvas.rect ~x1:0. ~y1:(-.height) ~x2:w ~y2:height ~fill_color:"#808080" r in
|
||||
let props = (text_props@[`ANCHOR `EAST]) in
|
||||
|
||||
(* One step drawer *)
|
||||
let tab = Array.make (max_value/step) false in
|
||||
let draw = fun i ->
|
||||
let i = i * step in
|
||||
let y = -. scale *. float i in
|
||||
let text = Printf.sprintf "%d" i in
|
||||
let _ = GnoCanvas.text ~text ~props ~y ~x:(w*.0.75) r in
|
||||
let _ = GnoCanvas.line ~points:[|w*.0.8;y;w;y|] ~fill_color:"white" r in
|
||||
let y = y -. float step /. 2. *. scale in
|
||||
let _ = GnoCanvas.line ~points:[|w*.0.8;y;w;y|] ~fill_color:"white" r in
|
||||
() in
|
||||
|
||||
let lazy_drawer = fun v ->
|
||||
let v = truncate v / step in
|
||||
for i = max 0 (v - 5) to min (v + 5) (Array.length tab - 1) do (* FIXME *)
|
||||
if not tab.(i) then begin
|
||||
tab.(i) <- true;
|
||||
draw i
|
||||
end
|
||||
done in
|
||||
|
||||
(** Yellow index *)
|
||||
let _ = GnoCanvas.line ~points:[|0.;0.;w;0.|] ~props:[`WIDTH_PIXELS 2] ~fill_color:"yellow" root in
|
||||
let s = index_width in
|
||||
let idx = GnoCanvas.polygon ~points:[|0.;0.;-.s;s/.2.;-.s;-.s/.2.|] ~fill_color:"yellow" root in
|
||||
if index_on_right then
|
||||
idx#affine_absolute (affine_pos_and_angle w 0. pi);
|
||||
|
||||
(** Mask (bottom & top) *)
|
||||
let _ = GnoCanvas.rect ~x1:0. ~y1:(-.height) ~x2:w ~y2:(-.h) ~fill_color:"black" root in
|
||||
let _ = GnoCanvas.rect ~x1:0. ~y1:height ~x2:w ~y2:h ~fill_color:"black" root in
|
||||
r, lazy_drawer
|
||||
|
||||
|
||||
class h = fun ?packing size ->
|
||||
let canvas = GnoCanvas.canvas ~aa:true ~width:size ~height:size ?packing () in
|
||||
let _ =
|
||||
canvas#set_center_scroll_region false;
|
||||
in
|
||||
|
||||
let size = float size in
|
||||
let size2 = size /. 2. in
|
||||
|
||||
let left_margin = size2 /. 10. in
|
||||
let pitch_scale = fun pitch -> pitch *. size2 *. 2. in
|
||||
let speed_scale = size2 /. 10. in
|
||||
let alt_scale = size2 /. 50. in
|
||||
let speed_width = size2/.3. in
|
||||
let alt_width = size2/.2.25 in
|
||||
let index_width = size2 /. 10. in
|
||||
|
||||
let xc = left_margin +. speed_width +. size2
|
||||
and yc = size2*.1.25 in
|
||||
|
||||
let text_props = [`FONT "Sans 8"; `ANCHOR `CENTER; `FILL_COLOR "white"] in
|
||||
|
||||
let disc = GnoCanvas.group canvas#root in
|
||||
let _top = GnoCanvas.rect ~x1:(-.size) ~y1:(-.size2*.5.) ~x2:size ~y2:0. ~fill_color:"#0099cb" disc
|
||||
and _bottom = GnoCanvas.rect ~x1:(-.size) ~y1:0. ~x2:size ~y2:(size2*.5.) ~fill_color:"#986701" disc
|
||||
and _line = GnoCanvas.line ~props:[`WIDTH_PIXELS 4] ~points:[|-.size;0.;size;0.|] ~fill_color:"white" disc
|
||||
and _ = GnoCanvas.line ~points:[|0.;-.size;0.;size|] ~fill_color:"white" disc
|
||||
in
|
||||
let grads = fun ?(text=false) n s a b ->
|
||||
for i = 0 to n do
|
||||
let deg = float i *. a +. b in
|
||||
let y = pitch_scale ((Deg>>Rad)deg) in
|
||||
ignore (GnoCanvas.line ~points:[|-.s; y; s; y|] ~fill_color:"white" disc);
|
||||
ignore (GnoCanvas.line ~points:[|-.s; -.y; s; -.y|] ~fill_color:"white" disc);
|
||||
if text then
|
||||
let text = Printf.sprintf "%d" (truncate deg)
|
||||
and x = 2.*.s in
|
||||
ignore (GnoCanvas.text ~props:text_props ~text ~y:(-.y) ~x disc);
|
||||
ignore (GnoCanvas.text ~props:text_props ~text ~y:(-.y) ~x:(-.x) disc);
|
||||
let text = "-"^text in
|
||||
ignore (GnoCanvas.text ~props:text_props ~text ~y ~x disc);
|
||||
ignore (GnoCanvas.text ~props:text_props ~text ~y ~x:(-.x) disc);
|
||||
done in
|
||||
|
||||
let _ =
|
||||
grads 10 (size2/.10.) 5. 2.5;
|
||||
grads 5 (size2/.7.) 10. 5.;
|
||||
grads ~text:true 5 (size2/.5.) 10. 10. in
|
||||
|
||||
let mask = GnoCanvas.group ~x:xc ~y:yc canvas#root in
|
||||
let _center = GnoCanvas.ellipse ~x1:(-3.) ~y1:(-.3.) ~x2:3. ~y2:3. ~fill_color:"black" mask in
|
||||
let pi6 = pi/.6. in
|
||||
let n = 20 in
|
||||
let arc_above = arc n size2 pi6 (5.*.pi6) in
|
||||
let (x, _y) = arc_above.(n-1) in
|
||||
let rest = [|(x, 0.);(10.*.size, 0.); (10.*.size, 10.*.size); (-.size, 10.*.size);(-.size,0.);(-.x,0.)|] in
|
||||
let points = floats_of_points (Array.append arc_above rest) in
|
||||
let _ =
|
||||
ignore (GnoCanvas.polygon ~fill_color:"black" ~points mask);
|
||||
for i = 0 to Array.length points / 2 - 1 do
|
||||
points.(2*i+1) <- -. points.(2*i+1)
|
||||
done;
|
||||
ignore (GnoCanvas.polygon ~fill_color:"black" ~points mask);
|
||||
let s = size2/. 5. in
|
||||
ignore (GnoCanvas.line ~props:[`WIDTH_PIXELS 4] ~points:[|-.x;0.;-.x-.s;0.;-.x-.s;s|] ~fill_color:"black" mask);
|
||||
ignore (GnoCanvas.line ~props:[`WIDTH_PIXELS 4] ~points:[|x;0.;x+.s;0.;x+.s;s|] ~fill_color:"black" mask);
|
||||
|
||||
(* Top and bottom graduations *)
|
||||
let g = fun a ->
|
||||
let l = GnoCanvas.line~props:[`WIDTH_PIXELS 1] ~fill_color:"white" ~points:[|0.;-.size2;0.;-.1.07*.size2|] mask in
|
||||
l#affine_relative (affine_pos_and_angle 0. 0. ((Deg>>Rad)a)) in
|
||||
for i = 1 to 5 do
|
||||
let a = float (i*10) in
|
||||
g a; g (-.a)
|
||||
done;
|
||||
|
||||
let gg = fun a ->
|
||||
let l = GnoCanvas.line~props:[`WIDTH_PIXELS 2] ~fill_color:"white" ~points:[|0.;-.size2;0.;-.1.15*.size2|] mask in
|
||||
l#affine_relative (affine_pos_and_angle 0. 0. ((Deg>>Rad)a)) in
|
||||
gg 30.; gg (-30.);
|
||||
gg 0.; gg 0.;
|
||||
|
||||
let _30 = fun a ->
|
||||
let t = GnoCanvas.text ~text:"30" ~props:text_props ~x:0. ~y:(-1.28*.size2) mask in
|
||||
t#affine_relative (affine_pos_and_angle 0. 0. ((Deg>>Rad)a)) in
|
||||
_30 30.; _30 (-30.)
|
||||
in
|
||||
|
||||
|
||||
(* Speedometer on the left side *)
|
||||
let speed, mi, mx, lazy_speed =
|
||||
let g = GnoCanvas.group ~x:left_margin ~y:yc canvas#root in
|
||||
let r, lazy_ruler = ruler ~text_props ~index_on_right:true ~max_value:50 ~scale:speed_scale ~w:speed_width ~step:2 ~index_width ~h:(0.75*.size2) g in
|
||||
let mx =
|
||||
GnoCanvas.text ~x:(speed_width/.2.) ~y:(-0.88*.size2) ~props:text_props g
|
||||
and mi =
|
||||
GnoCanvas.text ~x:(speed_width/.2.) ~y:(0.875*.size2) ~props:text_props g in
|
||||
mx#set [`FILL_COLOR "yellow"];
|
||||
mi#set [`FILL_COLOR "yellow"];
|
||||
lazy_ruler 0.;
|
||||
r, mi, mx, lazy_ruler
|
||||
|
||||
(* Altimeter on the right side *)
|
||||
and alt, lazy_alt =
|
||||
let g = GnoCanvas.group ~x:(xc+.size2) ~y:yc canvas#root in
|
||||
ruler ~text_props ~max_value:3000 ~scale:alt_scale ~w:alt_width ~step:10 ~index_width ~h:(0.75*.size2) g
|
||||
in
|
||||
|
||||
object
|
||||
method set_attitude = fun roll pitch ->
|
||||
disc#affine_absolute (affine_pos_and_angle (xc+.((sin roll)*.(pitch_scale pitch))) (yc+.pitch_scale pitch*.(cos roll)) (-.roll))
|
||||
val mutable max_speed = 0.
|
||||
val mutable min_speed = max_float
|
||||
method set_speed = fun (s:float) ->
|
||||
speed#affine_absolute (affine_pos 0. 0.);
|
||||
lazy_speed s;
|
||||
speed#affine_absolute (affine_pos 0. (speed_scale*.s));
|
||||
min_speed <- min min_speed s;
|
||||
max_speed <- max max_speed s;
|
||||
mi#set [`TEXT (sprintf "%.1f" min_speed)];
|
||||
mx#set [`TEXT (sprintf "%.1f" max_speed)]
|
||||
initializer
|
||||
ignore (speed#connect#event ~callback:(function
|
||||
`BUTTON_PRESS _ev ->
|
||||
max_speed <- 0.; min_speed <- max_float; true
|
||||
| _ -> false))
|
||||
|
||||
method set_alt = fun (s:float) ->
|
||||
alt#affine_absolute (affine_pos 0. 0.);
|
||||
lazy_alt s;
|
||||
alt#affine_absolute (affine_pos 0. (alt_scale*.s))
|
||||
|
||||
end
|
||||
|
||||
(*****************************************************************************)
|
||||
(* pfd page *)
|
||||
(*****************************************************************************)
|
||||
class pfd ?(visible = fun _ -> true) (widget: GBin.frame) =
|
||||
let horizon = new h ~packing: widget#add 150 in
|
||||
let _lazy = fun f x -> if visible widget then f x in
|
||||
|
||||
object
|
||||
method set_attitude roll pitch =
|
||||
_lazy (horizon#set_attitude ((Deg>>Rad)roll)) ((Deg>>Rad)pitch)
|
||||
method set_alt (a:float) = _lazy horizon#set_alt a
|
||||
method set_climb (_c:float) = ()
|
||||
method set_speed (c:float) = _lazy horizon#set_speed c
|
||||
end
|
||||
@@ -1,8 +0,0 @@
|
||||
class pfd : ?visible:(GBin.frame -> bool) -> GBin.frame ->
|
||||
object
|
||||
method set_speed : float -> unit
|
||||
method set_alt : float -> unit
|
||||
method set_climb : float -> unit
|
||||
method set_attitude : float -> float -> unit
|
||||
end
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
(*
|
||||
* Copyright (C) 2015 Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*)
|
||||
|
||||
(*open Latlong*)
|
||||
|
||||
type intruder = {
|
||||
intruder_track : MapTrack.track;
|
||||
mutable last_update : float
|
||||
}
|
||||
|
||||
(*let intruders = (string, intruder) Hashtbl.t*)
|
||||
let intruders = Hashtbl.create 1
|
||||
|
||||
let new_intruder = fun id name time geomap ->
|
||||
let track = new MapTrack.track ~size:200 ~icon:"intruder" ~name ~show_carrot:false id geomap in
|
||||
let intruder = { intruder_track = track; last_update = time } in
|
||||
Hashtbl.add intruders id intruder
|
||||
|
||||
let remove_intruder = fun id ->
|
||||
try
|
||||
let intruder = Hashtbl.find intruders id in
|
||||
intruder.intruder_track#destroy ();
|
||||
Hashtbl.remove intruders id
|
||||
with _ -> () (* no intruder *)
|
||||
|
||||
let update_intruder = fun id wgs84 heading alt speed climb time ->
|
||||
try
|
||||
let intruder = Hashtbl.find intruders id in
|
||||
intruder.intruder_track#move_icon wgs84 heading alt speed climb;
|
||||
intruder.last_update <- time;
|
||||
with _ -> () (* no intruder, add a new one ? *)
|
||||
|
||||
let intruder_exist = fun id ->
|
||||
Hashtbl.mem intruders id
|
||||
|
||||
(* remove old intruders after 20s *)
|
||||
let remove_old_intruders = fun () ->
|
||||
Hashtbl.iter
|
||||
(fun id i ->
|
||||
if (Unix.gettimeofday () -. i.last_update) > 20.0 then
|
||||
remove_intruder id
|
||||
) intruders
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
gtk_*.ml
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
description = "Paparazzi GCS lib"
|
||||
requires = "pprz.xlib,pprzlink,lablgtk2-gnome.gnomecanvas,lablgtk2.glade"
|
||||
version = "1.0"
|
||||
directory = ""
|
||||
|
||||
archive(byte) = "gcslib-pprz.cma"
|
||||
archive(native) = "gcslib-pprz.cmxa"
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#
|
||||
# Copyright (C) 2003 Pascal Brisset, Antoine Drouin
|
||||
# Copyright (C) 2022 Gautier Hattenberger
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
#
|
||||
|
||||
|
||||
Q=@
|
||||
|
||||
include ../../../Makefile.ocaml
|
||||
|
||||
# verbose ocamlmklib: Print commands before executing them
|
||||
#VERBOSITY = -verbose
|
||||
VERBOSITY =
|
||||
|
||||
UNAME = $(shell uname -s)
|
||||
ifeq ("$(UNAME)","Darwin")
|
||||
MKTEMP = gmktemp
|
||||
else
|
||||
MKTEMP = mktemp
|
||||
endif
|
||||
|
||||
LABLGTK2GNOMECANVAS = $(shell ocamlfind query -p-format lablgtk2-gnome.gnomecanvas 2>/dev/null)
|
||||
ifeq ($(LABLGTK2GNOMECANVAS),)
|
||||
LABLGTK2GNOMECANVAS = $(shell ocamlfind query -p-format lablgtk2.gnomecanvas 2>/dev/null)
|
||||
endif
|
||||
|
||||
INCLUDES=
|
||||
PKGCOMMON=pprzlink
|
||||
XINCLUDES=
|
||||
XPKGCOMMON=pprzlink,xml-light,glibivy,$(LABLGTK2GNOMECANVAS),lablgtk2.glade
|
||||
|
||||
PKG = -package lablgtk2,pprzlink,pprz.xlib
|
||||
LINKPKG = $(PKG) -linkpkg -dllpath-pkg lablgtk2,pprz.xlib,pprzlink
|
||||
|
||||
XSRC = contrastLabel.ml acIcon.ml wind_sock.ml gtk_papget_editor.ml gtk_papget_text_editor.ml gtk_papget_gauge_editor.ml gtk_papget_led_editor.ml papget_common.ml papget_renderer.ml papget.ml mapCanvas.ml mapWaypoints.ml mapTrack.ml mapGoogle.ml mapIGN.ml ml_gtk_drag.o xmlEdit.ml mapFP.ml
|
||||
XCMO = $(XSRC:.ml=.cmo)
|
||||
XCMX = $(XSRC:.ml=.cmx)
|
||||
|
||||
all : byte native
|
||||
byte : gcslib-pprz.cma
|
||||
native : gcslib-pprz.cmxa
|
||||
|
||||
gcslib-pprz.cma libgcslib-pprz.a: $(XCMO)
|
||||
@echo OL $@
|
||||
$(Q)$(OCAMLMKLIB) $(VERBOSITY) $(XINCLUDES) -o gcslib-pprz $^
|
||||
|
||||
gcslib-pprz.cmxa dllgcslib-pprz.so: $(XCMX)
|
||||
@echo OOL $@
|
||||
$(Q)$(OCAMLMKLIB) $(VERBOSITY) $(XINCLUDES) -o gcslib-pprz $^
|
||||
|
||||
# trying to set correct dependencies for parallel build
|
||||
# these are order only depedencies
|
||||
gcslib-pprz.cma: | libgcslib-pprz.a dllgcslib-pprz.so
|
||||
|
||||
gcslib-pprz.cmxa: | libgcslib-pprz.a dllgcslib-pprz.so
|
||||
|
||||
%.o : %.c
|
||||
@echo OC $<
|
||||
$(Q)$(OCAMLC) -ccopt -fPIC $(INCLUDES) -package $(PKGCOMMON) -c $<
|
||||
|
||||
$(XCMO) $(XCMX): PKGCOMMON=$(XPKGCOMMON)
|
||||
|
||||
|
||||
GTKCFLAGS := $(shell pkg-config --cflags gtk+-2.0) -DGTK_DISABLE_DEPRECATED
|
||||
ml_gtk_drag.o : ml_gtk_drag.c
|
||||
@echo OC $<
|
||||
$(Q)$(OCAMLC) $(INCLUDES) -package $(PKGCOMMON) -c -ccopt "$(GTKCFLAGS)" $<
|
||||
|
||||
%.cmo : %.ml
|
||||
@echo OC $<
|
||||
$(Q)$(OCAMLC) $(INCLUDES) $(PKG) -c $<
|
||||
|
||||
%.cmx : %.ml
|
||||
@echo OOC $<
|
||||
$(Q)$(OCAMLOPT) $(INCLUDES) $(PKG) -c $<
|
||||
|
||||
%.cmi : %.mli
|
||||
@echo OC $<
|
||||
$(Q)$(OCAMLC) $(XINCLUDES) $(INCLUDES) $(PKG) $<
|
||||
|
||||
gtk_papget_editor.ml : widgets.glade
|
||||
@echo GLADE $@
|
||||
$(eval $@_TMP := $(shell $(MKTEMP)))
|
||||
$(Q)grep -v invisible_char $< > $($@_TMP)
|
||||
$(Q)lablgladecc2 -root papget_editor -hide-default $($@_TMP) | grep -B 1000000 " end" > $@
|
||||
$(Q)rm -f $($@_TMP)
|
||||
|
||||
gtk_papget_text_editor.ml : widgets.glade
|
||||
@echo GLADE $@
|
||||
$(eval $@_TMP := $(shell $(MKTEMP)))
|
||||
$(Q)grep -v invisible_char $< > $($@_TMP)
|
||||
$(Q)lablgladecc2 -root table_text_editor -hide-default $($@_TMP) | grep -B 1000000 " end" > $@
|
||||
$(Q)rm -f $($@_TMP)
|
||||
|
||||
gtk_papget_gauge_editor.ml : widgets.glade
|
||||
@echo GLADE $@
|
||||
$(eval $@_TMP := $(shell $(MKTEMP)))
|
||||
$(Q)grep -v invisible_char $< > $($@_TMP)
|
||||
$(Q)lablgladecc2 -root table_gauge_editor -hide-default $($@_TMP) | grep -B 1000000 " end" > $@
|
||||
$(Q)rm -f $($@_TMP)
|
||||
|
||||
gtk_papget_led_editor.ml : widgets.glade
|
||||
@echo GLADE $@
|
||||
$(eval $@_TMP := $(shell $(MKTEMP)))
|
||||
$(Q)grep -v invisible_char $< > $($@_TMP)
|
||||
$(Q)$(Q)lablgladecc2 -root table_led_editor -hide-default $($@_TMP) | grep -B 1000000 " end" > $@
|
||||
$(Q)rm -f $($@_TMP)
|
||||
|
||||
clean :
|
||||
$(Q)rm -f *~ *.cm* *.out *.opt .depend *.a *.o *.so gtk_papget_*.ml
|
||||
|
||||
.PHONY: all byte native clean
|
||||
|
||||
#
|
||||
# Dependencies
|
||||
#
|
||||
|
||||
.depend: Makefile
|
||||
@echo DEPEND $@
|
||||
$(Q)$(OCAMLDEP) $(XSRC) *.mli >> .depend
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include .depend
|
||||
endif
|
||||
@@ -1,214 +0,0 @@
|
||||
(*
|
||||
* A Label with a contrasting outline
|
||||
*
|
||||
* Copyright (C) 2013 Piotr Esden-Tempski <piotr@esden.net>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
type icon = {
|
||||
lines : float array list;
|
||||
ellipse : float array list;
|
||||
width: int
|
||||
}
|
||||
|
||||
let icon_fixedwing_template = {
|
||||
lines = [
|
||||
[| 0.; -6.; 0.; 14.|];
|
||||
[| -9.; 0.; 9.; 0.|];
|
||||
[| -4.; 10.; 4.; 10.|]
|
||||
];
|
||||
ellipse = [];
|
||||
width = 4
|
||||
}
|
||||
|
||||
let icon_flyingwing_template = {
|
||||
lines = [
|
||||
[| -13.; 4.; 0.; -7.; 13.; 4.|];
|
||||
[| -13.; 5.; 0.; 0.; 13.; 5.|];
|
||||
];
|
||||
ellipse = [];
|
||||
width = 4
|
||||
}
|
||||
|
||||
let icon_rotorcraft_template = {
|
||||
lines = [
|
||||
[| 0.; -8.; 0.; 8.|];
|
||||
[| -8.; 0.; 8.; 0.|];
|
||||
[| 6.; -15.; 0.; -24.; -6.; -15.|];
|
||||
];
|
||||
ellipse = [
|
||||
[| 8.; -5.; 18.; 5.|];
|
||||
[| -8.; -5.; -18.; 5.|];
|
||||
[| -5.; 8.; 5.; 18.|];
|
||||
[| -5.; -8.; 5.; -18.|];
|
||||
];
|
||||
width = 2
|
||||
}
|
||||
|
||||
let icon_quadrotor_template = {
|
||||
lines = [
|
||||
[| 6.; -15.; 0.; -24.; -6.; -15.|]; (** Front Marker **)
|
||||
];
|
||||
ellipse = [
|
||||
[| -8.; -8.; 8.; 8.|]; (** Center Ring **)
|
||||
[| 8.; -5.; 18.; 5.|];
|
||||
[| -8.; -5.; -18.; 5.|];
|
||||
[| -5.; 8.; 5.; 18.|];
|
||||
[| -5.; -8.; 5.; -18.|];
|
||||
];
|
||||
width = 1
|
||||
}
|
||||
|
||||
let icon_hexarotor_template = {
|
||||
lines = [
|
||||
[| 6.; -15.; 0.; -24.; -6.; -15.|]; (** Front Marker **)
|
||||
];
|
||||
ellipse = [
|
||||
[| -8.00; -8.00; 8.00; 8.00|]; (** Center Ring **)
|
||||
[| 6.26; 1.50; 16.26; 11.50|];
|
||||
[| -6.26; -1.50; -16.26; -11.50|];
|
||||
[| -5.00; 8.00; 5.00; 18.00|];
|
||||
[| -5.00; -8.00; 5.00; -18.00|];
|
||||
[| 6.26; -1.50; 16.26; -11.50|];
|
||||
[| -6.26; 1.50; -16.26; 11.50|];
|
||||
];
|
||||
width = 1
|
||||
}
|
||||
|
||||
let icon_octorotor_template = {
|
||||
lines = [
|
||||
[| 6.; -15.; 0.; -24.; -6.; -15.|]; (** Front Marker **)
|
||||
];
|
||||
ellipse = [
|
||||
[| -8.00; -8.00; 8.00; 8.00|]; (** Center Ring **)
|
||||
[| 8.00; -5.00; 18.00; 5.00|];
|
||||
[| -8.00; -5.00; -18.00; 5.00|];
|
||||
[| -5.00; 8.00; 5.00; 18.00|];
|
||||
[| -5.00; -8.00; 5.00; -18.00|];
|
||||
[| 4.19; -4.19; 14.19; -14.19|];
|
||||
[| -4.19; 4.19; -14.19; 14.19|];
|
||||
[| 14.19; 14.19; 4.19; 4.19|];
|
||||
[| -14.19; -14.19; -4.19; -4.19|];
|
||||
];
|
||||
width = 1
|
||||
}
|
||||
|
||||
let icon_quadrotor_x_template = {
|
||||
lines = [
|
||||
[| 6.; -15.; 0.; -24.; -6.; -15.|]; (** Front Marker **)
|
||||
];
|
||||
ellipse = [
|
||||
[| -8.00; -8.00; 8.00; 8.00|]; (** Center Ring **)
|
||||
[| 4.19; 4.19; 14.19; 14.19|];
|
||||
[| -4.19; -4.19; -14.19; -14.19|];
|
||||
[| -4.19; 4.19; -14.19; 14.19|];
|
||||
[| 4.19; -4.19; 14.19; -14.19|];
|
||||
];
|
||||
width = 1
|
||||
}
|
||||
|
||||
let icon_quadrotor_xi_template = {
|
||||
lines = [
|
||||
[| 6.;-15.; 0.;-24.; -6.;-15.|]; (** Front Marker **)
|
||||
[| 0.; -4.; 0.; 4.|];
|
||||
[|-4.; -6.; 0.; -4.; 4.; -6.|];
|
||||
[|-4.; 6.; 0.; 4.; 4.; 6.|];
|
||||
];
|
||||
ellipse = [
|
||||
[| 4.19; 4.19; 14.19; 14.19|];
|
||||
[| -4.19; -4.19; -14.19; -14.19|];
|
||||
[| -4.19; 4.19; -14.19; 14.19|];
|
||||
[| 4.19; -4.19; 14.19; -14.19|];
|
||||
];
|
||||
width = 1
|
||||
}
|
||||
|
||||
let icon_hexarotor_x_template = {
|
||||
lines = [
|
||||
[| 6.; -15.; 0.; -24.; -6.; -15.|]; (** Front Marker **)
|
||||
];
|
||||
ellipse = [
|
||||
[| -8.0; -8.00; 8.0; 8.00|]; (** Center Ring **)
|
||||
[| 1.5; 6.26; 11.5; 16.26|];
|
||||
[| -1.5; -6.26; -11.5; -16.26|];
|
||||
[| 8.0; -5.00; 18.0; 5.00|];
|
||||
[| -8.0; -5.00; -18.0; 5.00|];
|
||||
[| 1.5; -6.26; 11.5; -16.26|];
|
||||
[| -1.5; 6.26; -11.5; 16.26|];
|
||||
];
|
||||
width = 1
|
||||
}
|
||||
|
||||
let icon_octorotor_x_template = {
|
||||
lines = [
|
||||
[| 6.; -15.; 0.; -24.; -6.; -15.|]; (** Front Marker **)
|
||||
];
|
||||
ellipse = [
|
||||
[| -8.; -8.; 8.; 8.|]; (** Center Ring **)
|
||||
[| 0.; 7.; 10.; 17.|];
|
||||
[| 7.; 0.; 17.; 10.|];
|
||||
[| 0.; -7.; 10.; -17.|];
|
||||
[| -7.; 0.; -17.; 10.|];
|
||||
[| 0.; 7.; -10.; 17.|];
|
||||
[| 7.; 0.; 17.; -10.|];
|
||||
[| 0.; -7.; -10.; -17.|];
|
||||
[| -7.; 0.; -17.; -10.|];
|
||||
];
|
||||
width = 1
|
||||
}
|
||||
|
||||
let icon_home_template = {
|
||||
lines = [
|
||||
[| -9.; -9.; -9.; 9.; 9.; 9.; 9.; -9.|];
|
||||
[| -12.; -7.; 0.; -15.; 12.; -7.|];
|
||||
];
|
||||
ellipse = [];
|
||||
width = 3;
|
||||
}
|
||||
|
||||
let icon_intruder_template = {
|
||||
lines = [
|
||||
[| 0.; 0.; 0.; -24. |];
|
||||
[| 6.; -15.; 0.; -24.; -6.; -15.|]; (** Front Marker **)
|
||||
];
|
||||
ellipse = [
|
||||
[| -8.; -8.; 8.; 8.|];
|
||||
];
|
||||
width = 1
|
||||
}
|
||||
|
||||
class widget = fun ?(color="red") ?(icon_template=icon_fixedwing_template) (group:GnoCanvas.group) ->
|
||||
let new_line width color points =
|
||||
GnoCanvas.line ~fill_color:color ~props:[`WIDTH_PIXELS width; `CAP_STYLE `ROUND] ~points:points group in
|
||||
let new_ellipse width color points =
|
||||
GnoCanvas.ellipse ~props:[`OUTLINE_COLOR color; `WIDTH_PIXELS width] ~x1:points.(0) ~y1:points.(1) ~x2:points.(2) ~y2:points.(3) group in
|
||||
let icon_bg =
|
||||
(List.map (fun points -> new_line (icon_template.width+2) "black" points) icon_template.lines,
|
||||
List.map (fun points -> new_ellipse (icon_template.width+2) "black" points) icon_template.ellipse) in
|
||||
let icon =
|
||||
(List.map (fun points -> new_line icon_template.width color points) icon_template.lines,
|
||||
List.map (fun points -> new_ellipse icon_template.width color points) icon_template.ellipse) in
|
||||
object(self)
|
||||
method set_color color =
|
||||
List.iter2 (fun segment ellipse -> segment#set [`FILL_COLOR color]; ellipse#set [`FILL_COLOR color]) (fst icon) (snd icon)
|
||||
method set_bg_color color =
|
||||
List.iter2 (fun segment ellipse -> segment#set [`FILL_COLOR color]; ellipse#set [`FILL_COLOR color]) (fst icon_bg) (snd icon_bg)
|
||||
end
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
(*
|
||||
* A Label with a contrasting outline
|
||||
*
|
||||
* Copyright (C) 2013 Piotr Esden-Tempski <piotr@esden.net>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
type icon = {
|
||||
lines : float array list;
|
||||
ellipse : float array list;
|
||||
width: int
|
||||
}
|
||||
|
||||
val icon_fixedwing_template : icon
|
||||
val icon_flyingwing_template : icon
|
||||
val icon_rotorcraft_template : icon
|
||||
val icon_quadrotor_template : icon
|
||||
val icon_hexarotor_template : icon
|
||||
val icon_octorotor_template : icon
|
||||
val icon_quadrotor_x_template : icon
|
||||
val icon_hexarotor_x_template : icon
|
||||
val icon_octorotor_x_template : icon
|
||||
val icon_quadrotor_xi_template : icon
|
||||
val icon_home_template : icon
|
||||
val icon_intruder_template : icon
|
||||
|
||||
class widget :
|
||||
?color : string ->
|
||||
?icon_template : icon ->
|
||||
GnoCanvas.group ->
|
||||
object
|
||||
method set_color : string -> unit
|
||||
method set_bg_color : string -> unit
|
||||
end
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
(*
|
||||
* A Label with a contrasting outline
|
||||
*
|
||||
* Copyright (C) 2013 Piotr Esden-Tempski <piotr@esden.net>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
(*
|
||||
* This module creates labels with outlines by creating 9
|
||||
* overlapping labels slightly offset from eachother. Where the 8
|
||||
* labels in the background have a different color from last center one.
|
||||
*)
|
||||
|
||||
let label_offset_matrix =
|
||||
[
|
||||
(* X Y *)
|
||||
( 0., -1.); (* N *)
|
||||
( 0., 1.); (* S *)
|
||||
( 1., 0.); (* E *)
|
||||
(-1., 0.); (* W *)
|
||||
( 1., -1.); (* NE *)
|
||||
( 1., 1.); (* SE *)
|
||||
(-1., 1.); (* SW *)
|
||||
(-1., -1.); (* NW *)
|
||||
( 0., 0.); (* Z *)
|
||||
]
|
||||
|
||||
class widget = fun ?(name = "Noname") ?(size = 500) ?(bg_color = "black") ?(color = "white") x y (group:GnoCanvas.group) ->
|
||||
let new_text offset =
|
||||
GnoCanvas.text group ~props:[`TEXT name;
|
||||
`X (x +. (fst offset)); `Y (y +. (snd offset));
|
||||
`ANCHOR `SW;
|
||||
`FILL_COLOR (if offset = (0., 0.) then color else bg_color)] in
|
||||
let labels = List.map new_text label_offset_matrix in
|
||||
object(self)
|
||||
method set_name s = List.iter (fun label -> label#set [`TEXT s]) labels
|
||||
method set_x x = List.iter2 (fun label offset -> label#set [`X (x +. (fst offset))])
|
||||
labels label_offset_matrix
|
||||
method set_y y = List.iter2 (fun label offset -> label#set [`Y (y +. (snd offset))])
|
||||
labels label_offset_matrix
|
||||
method affine_absolute a = List.iter (fun label -> label#affine_absolute a) labels
|
||||
end
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
(*
|
||||
* A Label with a contrasting outline
|
||||
*
|
||||
* Copyright (C) 2013 Piotr Esden-Tempski <piotr@esden.net>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
class widget :
|
||||
?name:string ->
|
||||
?size:int ->
|
||||
?bg_color:string ->
|
||||
?color:string ->
|
||||
float ->
|
||||
float ->
|
||||
GnoCanvas.group ->
|
||||
object
|
||||
method set_name : string -> unit
|
||||
method set_x : float -> unit
|
||||
method set_y : float -> unit
|
||||
method affine_absolute : float array -> unit
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,135 +0,0 @@
|
||||
(*
|
||||
* Geographic display
|
||||
*
|
||||
* Copyright (C) 2004-2008 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
type projection = Mercator | UTM | LambertIIe
|
||||
class type geographic = object method pos : Latlong.geographic end
|
||||
|
||||
class widget :
|
||||
?height:int ->
|
||||
?srtm:bool ->
|
||||
?width:int ->
|
||||
?projection:projection ->
|
||||
?georef:Latlong.geographic ->
|
||||
unit ->
|
||||
object
|
||||
method add_info_georef : string -> < pos : Latlong.geographic > -> unit
|
||||
method edit_georef_name : string -> string -> unit
|
||||
method delete_georef : string -> unit
|
||||
method clear_georefs : unit -> unit
|
||||
method altitude : Latlong.geographic -> int
|
||||
method any_event : GdkEvent.any -> bool
|
||||
method arc :
|
||||
?nb_points:int ->
|
||||
?width:int ->
|
||||
?fill_color:string ->
|
||||
float * float -> float -> float -> float -> GnoCanvas.line
|
||||
method background : GnoCanvas.group
|
||||
method background_event : GnoCanvas.item_event -> bool
|
||||
method maps : GnoCanvas.group array
|
||||
method canvas : GnoCanvas.canvas
|
||||
method center : Latlong.geographic -> unit
|
||||
method circle :
|
||||
?group:GnoCanvas.group ->
|
||||
?width:int ->
|
||||
?fill_color:string ->
|
||||
?opacity:int ->
|
||||
?color:string -> Latlong.geographic -> Latlong.fmeter -> GnoCanvas.ellipse
|
||||
method convert_positions_to_points : Latlong.geographic array -> float array
|
||||
method connect_view : (unit -> unit) -> unit
|
||||
method current_zoom : float
|
||||
method display_alt : Latlong.geographic -> unit
|
||||
method display_geo : Latlong.geographic -> unit
|
||||
method display_group : string -> unit
|
||||
method display_pixbuf :
|
||||
?opacity:int ->
|
||||
?level:int ->
|
||||
(int * int) * Latlong.geographic ->
|
||||
(int * int) * Latlong.geographic -> GdkPixbuf.pixbuf -> GnoCanvas.pixbuf
|
||||
method display_xy : string -> unit
|
||||
method factory : GMenu.menu_shell GMenu.factory
|
||||
method file_menu : GMenu.menu
|
||||
method fit_to_window : unit -> unit
|
||||
method fix_bg_coords : Latlong.fmeter * Latlong.fmeter -> Latlong.fmeter * Latlong.fmeter
|
||||
method frame : GPack.box
|
||||
method georef : Latlong.geographic option
|
||||
method georefs : (string * < pos : Latlong.geographic >) list
|
||||
method get_center : unit -> Latlong.geographic
|
||||
method goto : unit -> unit
|
||||
method info : GPack.box
|
||||
method key_press : GdkEvent.Key.t -> bool
|
||||
method menubar : GMenu.menu_shell
|
||||
method mouse_motion : GdkEvent.Motion.t -> bool
|
||||
method move_item :
|
||||
?z:float ->
|
||||
GnomeCanvas.re_p GnoCanvas.item -> Latlong.geographic -> unit
|
||||
method moveto : Latlong.geographic -> unit
|
||||
method of_world : Latlong.fmeter * Latlong.fmeter -> Latlong.geographic
|
||||
method pack_labels : unit
|
||||
method projection : string
|
||||
method photoprojection :
|
||||
?group:GnoCanvas.group ->
|
||||
?width:int ->
|
||||
?fill_color:string ->
|
||||
?color:string ->
|
||||
?number:string -> Latlong.geographic -> Latlong.fmeter -> GnoCanvas.text
|
||||
method polygon :
|
||||
?group:GnoCanvas.group ->
|
||||
?width:int ->
|
||||
?fill_color:string ->
|
||||
?opacity:int ->
|
||||
?color:string -> Latlong.geographic array -> GnoCanvas.polygon
|
||||
method pt2D_of : Latlong.geographic -> Geometry_2d.pt_2D
|
||||
method region : ((float * float) * (Latlong.fmeter * Latlong.fmeter)) option
|
||||
method register_to_fit : geographic -> unit
|
||||
method root : GnoCanvas.group
|
||||
method segment :
|
||||
?group:GnoCanvas.group ->
|
||||
?width:int ->
|
||||
?fill_color:string -> Latlong.geographic -> Latlong.geographic -> GnoCanvas.line
|
||||
method set_georef : Latlong.geographic -> unit
|
||||
method set_utc_time : int -> int -> int -> unit
|
||||
method set_wind_sock : float -> string -> unit
|
||||
method still : GnoCanvas.group
|
||||
method switch_background : bool -> unit
|
||||
method switch_utc_time : bool -> unit
|
||||
method switch_utm_grid : bool -> unit
|
||||
method text :
|
||||
?group:GnoCanvas.group ->
|
||||
?fill_color:string ->
|
||||
?x_offset:float ->
|
||||
?y_offset:float -> Latlong.geographic -> string -> GnoCanvas.text
|
||||
method toolbar : GPack.box
|
||||
method top_still : float
|
||||
method utc_time : GnoCanvas.text
|
||||
method wind_sock : Wind_sock.item
|
||||
method window_to_world :
|
||||
winx:float -> winy:float -> Latlong.fmeter * Latlong.fmeter
|
||||
method world_of : Latlong.geographic -> Latlong.fmeter * Latlong.fmeter
|
||||
method zoom : float -> unit
|
||||
method zoom_adj : GData.adjustment
|
||||
method zoom_down : unit -> unit
|
||||
method zoom_in_place : float -> unit
|
||||
method zoom_in_center : float -> unit
|
||||
method zoom_up : unit -> unit
|
||||
end
|
||||
@@ -1,401 +0,0 @@
|
||||
(*
|
||||
* Displaying and editing a flight plan on a MapCanvas
|
||||
*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
open Printf
|
||||
open Latlong
|
||||
|
||||
let (//) = Filename.concat
|
||||
|
||||
let sof = string_of_float
|
||||
let sof1 = fun x -> sprintf "%.1f" x
|
||||
let sof6 = fun x -> sprintf "%.6f" x
|
||||
let float_attr = fun xml a -> float_of_string (ExtXml.attrib xml a)
|
||||
let rec assoc_nocase at = function
|
||||
[] -> raise Not_found
|
||||
| (a, v)::avs ->
|
||||
if String.uppercase_ascii at = String.uppercase_ascii a then v else assoc_nocase at avs
|
||||
|
||||
(** Returns the WGS84 coordinates of a waypoint, either from its relative x and
|
||||
y coordinates or from its lat and long *)
|
||||
let geo_of_xml = fun utm_ref get_attrib ->
|
||||
try
|
||||
let x = get_attrib "x"
|
||||
and y = get_attrib "y" in
|
||||
Latlong.of_utm WGS84 (utm_add utm_ref (x, y))
|
||||
with
|
||||
Not_found | Xml.No_attribute _ ->
|
||||
try
|
||||
let lat = get_attrib "lat"
|
||||
and lon = get_attrib "lon" in
|
||||
make_geo_deg lat lon
|
||||
with
|
||||
Not_found -> failwith (sprintf "x and y or lat and lon attributes expected in waypoint")
|
||||
|
||||
|
||||
(** Connect a change in the XML editor to the graphical rep *)
|
||||
let update_wp utm_ref (wp:MapWaypoints.waypoint) = function
|
||||
XmlEdit.Deleted -> wp#delete ()
|
||||
| XmlEdit.New_child _ -> failwith "update_wp"
|
||||
| XmlEdit.Modified attribs ->
|
||||
try
|
||||
let float_attrib = fun a -> float_of_string (assoc_nocase a attribs) in
|
||||
|
||||
let wgs84 = geo_of_xml utm_ref float_attrib in
|
||||
|
||||
wp#geomap#edit_georef_name wp#name (assoc_nocase "name" attribs);
|
||||
wp#set wgs84;
|
||||
wp#set_name (assoc_nocase "name" attribs)
|
||||
with
|
||||
_ -> ()
|
||||
|
||||
let iter_stages = fun f xml_tree ->
|
||||
let xml_blocks = XmlEdit.child (XmlEdit.root xml_tree) "blocks" in
|
||||
let rec loop = fun n ->
|
||||
f n;
|
||||
List.iter loop (XmlEdit.children n) in
|
||||
loop xml_blocks
|
||||
|
||||
let try_replace_attrib = fun node tag prev_v v ->
|
||||
try
|
||||
if XmlEdit.attrib node tag = prev_v then
|
||||
XmlEdit.set_attrib node (tag, v)
|
||||
with
|
||||
Not_found -> ()
|
||||
|
||||
(** Update all the references to waypoint names (attribute "wp") *)
|
||||
(** FIXME This function is disabled for now since it is making
|
||||
* a huge mess when reordering the waypoints *)
|
||||
(*let update_wp_refs previous_name xml_tree = function
|
||||
XmlEdit.Deleted -> () (** FIXME *)
|
||||
| XmlEdit.New_child _ -> ()
|
||||
| XmlEdit.Modified attribs ->
|
||||
try
|
||||
let new_name = assoc_nocase "name" attribs in
|
||||
let update = fun node ->
|
||||
try_replace_attrib node "wp" !previous_name new_name;
|
||||
try_replace_attrib node "from" !previous_name new_name in
|
||||
iter_stages update xml_tree;
|
||||
previous_name := new_name
|
||||
with
|
||||
Not_found -> ()
|
||||
*)
|
||||
|
||||
let waypoints_node = fun xml_tree ->
|
||||
let xml_root = XmlEdit.root xml_tree in
|
||||
XmlEdit.child xml_root "waypoints"
|
||||
|
||||
let is_relative_waypoint = fun node ->
|
||||
try
|
||||
ignore (XmlEdit.attrib node "x");
|
||||
ignore (XmlEdit.attrib node "y");
|
||||
true
|
||||
with
|
||||
Not_found -> false
|
||||
|
||||
|
||||
let absolute_coords = fun wp ->
|
||||
let wgs84 = wp#pos in
|
||||
[ "lat", sof6 ((Rad>>Deg) wgs84.posn_lat);
|
||||
"lon", sof6 ((Rad>>Deg) wgs84.posn_long) ]
|
||||
|
||||
|
||||
(** Connect a change from the graphical rep to the xml tree *)
|
||||
let update_xml = fun xml_tree utm0 wp id ->
|
||||
let xml_wpts = XmlEdit.children (waypoints_node xml_tree) in
|
||||
let node = List.find (fun w -> XmlEdit.id w = id) xml_wpts in
|
||||
let default_alt = float_of_string (XmlEdit.attrib (XmlEdit.root xml_tree) "alt") in
|
||||
if wp#deleted then begin
|
||||
XmlEdit.delete node
|
||||
end else
|
||||
let coords =
|
||||
if is_relative_waypoint node then
|
||||
let utm = utm_of WGS84 wp#pos in
|
||||
try
|
||||
let (dx, dy) = utm_sub utm utm0 in
|
||||
["x",sof1 dx; "y",sof1 dy]
|
||||
with
|
||||
_ ->
|
||||
prerr_endline "MapFP.update_xml: waypoint too far from ref; using absolute geodetic coordinates";
|
||||
absolute_coords wp
|
||||
else (* Absolute waypoint: use lat and lon attributes *)
|
||||
absolute_coords wp in
|
||||
|
||||
let alt_attrib =
|
||||
if abs_float (wp#alt -. default_alt) < 1. then [] else ["alt", sof1 wp#alt] in
|
||||
XmlEdit.set_attribs node (("name",wp#name) :: alt_attrib @ coords)
|
||||
|
||||
|
||||
|
||||
|
||||
let new_wp = fun ?(editable = false) (geomap:MapCanvas.widget) xml_tree waypoints utm_ref ?(alt = 0.) node ->
|
||||
let float_attrib = fun a -> float_of_string (XmlEdit.attrib node a) in
|
||||
|
||||
let wgs84 = geo_of_xml utm_ref float_attrib in
|
||||
|
||||
let alt = try float_attrib "alt" with _ -> alt in
|
||||
let name = XmlEdit.attrib node "name" in
|
||||
let show = editable || name.[0] <> '_' in
|
||||
let wp = MapWaypoints.waypoint ~show waypoints ~name ~alt wgs84 in
|
||||
geomap#register_to_fit (wp:>MapCanvas.geographic);
|
||||
XmlEdit.connect node (update_wp utm_ref wp);
|
||||
(*XmlEdit.connect node (update_wp_refs (ref name) xml_tree);*) (* FIXME broken functionality *)
|
||||
let id = XmlEdit.id node in
|
||||
if editable then
|
||||
wp#connect (fun () -> update_xml xml_tree utm_ref wp id);
|
||||
wp
|
||||
|
||||
let gensym =
|
||||
let x = ref 0 in
|
||||
fun p -> incr x; Printf.sprintf "%s%d" p !x
|
||||
|
||||
let rec new_gensym = fun p l ->
|
||||
let s = gensym p in
|
||||
if List.mem s l then new_gensym p l else s
|
||||
|
||||
let georef_of_xml = fun xml ->
|
||||
let lat0 = Latlong.deg_of_string (ExtXml.attrib xml "lat0")
|
||||
and lon0 = Latlong.deg_of_string (ExtXml.attrib xml "lon0") in
|
||||
{ posn_lat = (Deg>>Rad)lat0; posn_long = (Deg>>Rad)lon0 }
|
||||
|
||||
|
||||
let display_lines = fun ?group color (geomap:MapCanvas.widget) points ->
|
||||
let n = Array.length points in
|
||||
let l = ref [] in
|
||||
for i = 0 to n - 1 do
|
||||
l := !l @ [(geomap#segment ?group ~width:3 ~fill_color:color points.(i) points.((i+1)mod n))]
|
||||
done;
|
||||
!l
|
||||
|
||||
let space_regexp = Str.regexp " "
|
||||
let comma_regexp = Str.regexp ","
|
||||
let wgs84_of_kml_point = fun s ->
|
||||
match Str.split comma_regexp s with
|
||||
[long; lat; altitude] ->
|
||||
let lat = float_of_string lat
|
||||
and long = float_of_string long in
|
||||
{posn_lat = (Deg>>Rad) lat; posn_long = (Deg>>Rad) long}
|
||||
| _ -> failwith (Printf.sprintf "wgs84_of_kml_point: %s" s)
|
||||
|
||||
|
||||
(** It should be somewhere else ! *)
|
||||
let display_kml = fun ?group color geomap xml ->
|
||||
try
|
||||
let document = ExtXml.child xml "Document" in
|
||||
let rec loop = fun child ->
|
||||
let tag = String.lowercase_ascii (Xml.tag child) in
|
||||
match tag with
|
||||
| "linestring" | "linearring" ->
|
||||
let coordinates = ExtXml.child child "coordinates" in
|
||||
begin
|
||||
match Xml.children coordinates with
|
||||
[Xml.PCData text] ->
|
||||
let points = Str.split space_regexp text in
|
||||
let points = List.map wgs84_of_kml_point points in
|
||||
(* remove a point if polygon (first in this case) since first and last are the same *)
|
||||
let points = if tag = "linearring" && List.length points > 0 then List.tl points else points in
|
||||
ignore(display_lines ?group color geomap (Array.of_list points))
|
||||
| _ -> failwith "coordinates expected"
|
||||
end
|
||||
| "folder" | "placemark" | "polygon" | "outerboundaryis" ->
|
||||
List.iter loop (Xml.children child)
|
||||
| _ -> () in
|
||||
List.iter loop (Xml.children document)
|
||||
with Xml.Not_element xml -> failwith (Xml.to_string xml)
|
||||
|
||||
|
||||
|
||||
|
||||
class flight_plan = fun ?format_attribs ?editable ~show_moved geomap color fp_dtd xml ->
|
||||
(** Xml Editor *)
|
||||
let xml_tree_view, xml_window = XmlEdit.create ?format_attribs ?editable (Dtd.parse_file fp_dtd) xml in
|
||||
let xml_root = XmlEdit.root xml_tree_view in
|
||||
let xml_wpts = XmlEdit.child xml_root "waypoints" in
|
||||
|
||||
(** Geographic ref *)
|
||||
let alt = float_attr xml "alt" in
|
||||
let ref_wgs84 = georef_of_xml xml in
|
||||
let utm0 = utm_of WGS84 ref_wgs84 in
|
||||
|
||||
(** The graphical waypoints *)
|
||||
let wpts_group = new MapWaypoints.group ~show_moved ~color ?editable geomap in
|
||||
|
||||
let array_of_waypoints = ref (Array.make 13 None) in
|
||||
let add_wp_to_array = fun index w ->
|
||||
let n = Array.length !array_of_waypoints in
|
||||
if index >= n then begin
|
||||
let new_array = Array.make (n*2) None in
|
||||
Array.blit !array_of_waypoints 0 new_array 0 n;
|
||||
array_of_waypoints := new_array
|
||||
end;
|
||||
!array_of_waypoints.(index) <- Some w in
|
||||
|
||||
let yaws = Hashtbl.create 5 in (* Yes Another Waypoints Store *)
|
||||
let create_wp =
|
||||
let i = ref 1 in
|
||||
fun node ->
|
||||
let w = new_wp ?editable geomap xml_tree_view wpts_group utm0 ~alt node in
|
||||
Hashtbl.add yaws (XmlEdit.attrib node "name") (!i, w);
|
||||
add_wp_to_array !i w;
|
||||
incr i;
|
||||
w in
|
||||
|
||||
(* The sectors *)
|
||||
(* Parse and store sectors *)
|
||||
let sectors =
|
||||
let waypoints = ExtXml.child xml "waypoints" in
|
||||
try
|
||||
List.fold_left (fun l x ->
|
||||
match String.lowercase_ascii (Xml.tag x) with
|
||||
"kml" ->
|
||||
let file = ExtXml.attrib x "file" in
|
||||
display_kml ~group:wpts_group#group color geomap (ExtXml.parse_file (Env.flight_plans_path // file));
|
||||
l
|
||||
| "sector" ->
|
||||
let wgs84 = fun wp_name ->
|
||||
let wp_name = Xml.attrib wp_name "name" in
|
||||
let select = fun wp -> Xml.attrib wp "name" = wp_name in
|
||||
let wp = ExtXml.child waypoints ~select "waypoint" in
|
||||
let float_attr = fun xml a -> float_of_string (Xml.attrib xml a) in
|
||||
geo_of_xml utm0 (float_attr wp) in
|
||||
let points = List.map wgs84 (Xml.children x) in
|
||||
let points = Array.of_list points in
|
||||
let color_sector = ExtXml.attrib_or_default x "color" color in
|
||||
let segments = display_lines ~group:wpts_group#group color_sector geomap points in
|
||||
let wp_names = List.map (fun wp -> Xml.attrib wp "name") (Xml.children x) in
|
||||
[(wp_names, segments, color_sector)] @ l
|
||||
| _ -> failwith "Unknown sectors child")
|
||||
[] (Xml.children (ExtXml.child xml "sectors"))
|
||||
with Not_found -> [] in
|
||||
|
||||
(* The waypoints *)
|
||||
let _ = List.iter
|
||||
(fun wp ->
|
||||
let w = create_wp wp in
|
||||
let name = XmlEdit.attrib wp "name" in
|
||||
if name = "HOME" then begin
|
||||
let c = ref (GnoCanvas.ellipse geomap#canvas#root) in
|
||||
let update = fun _ ->
|
||||
try
|
||||
let max_dist_from_home = float_of_string (XmlEdit.attrib xml_root "MAX_DIST_FROM_HOME") in
|
||||
!c#destroy ();
|
||||
c := geomap#circle ~group:wpts_group#group ~width:5 ~color w#pos max_dist_from_home
|
||||
with _ -> () in
|
||||
update ();
|
||||
w#connect update;
|
||||
XmlEdit.connect wp update;
|
||||
XmlEdit.connect xml_root update
|
||||
end)
|
||||
(XmlEdit.children xml_wpts) in
|
||||
|
||||
(** Expands the blocks *)
|
||||
let _ =
|
||||
XmlEdit.expand_node xml_tree_view xml_root;
|
||||
let blocks = XmlEdit.child xml_root "blocks" in
|
||||
XmlEdit.expand_node xml_tree_view blocks in
|
||||
|
||||
object
|
||||
method georef = ref_wgs84
|
||||
method window = xml_window
|
||||
method destroy () =
|
||||
wpts_group#group#destroy ();
|
||||
xml_window#destroy ()
|
||||
method show () = wpts_group#group#show ()
|
||||
method hide () = wpts_group#group#hide ()
|
||||
method index wp = Hashtbl.find yaws (XmlEdit.attrib wp "name")
|
||||
method get_wp = fun i ->
|
||||
if i >= Array.length !array_of_waypoints then
|
||||
raise Not_found;
|
||||
match !array_of_waypoints.(i) with
|
||||
None -> raise Not_found
|
||||
| Some w -> w
|
||||
method waypoints = XmlEdit.children (waypoints_node xml_tree_view)
|
||||
method xml = XmlEdit.xml_of_view xml_tree_view
|
||||
method highlight_stage = fun block_no stage_no ->
|
||||
let block_no = string_of_int block_no in
|
||||
let stage_no = string_of_int stage_no in
|
||||
let blocks = XmlEdit.child xml_root "blocks" in
|
||||
List.iter
|
||||
(fun b ->
|
||||
if XmlEdit.attrib b "no" = block_no then begin
|
||||
XmlEdit.set_background ~all:true b "#00c000";
|
||||
let rec f = fun s ->
|
||||
try
|
||||
if XmlEdit.attrib s "no" = stage_no then
|
||||
XmlEdit.set_background s "#00ff00"
|
||||
else
|
||||
List.iter f (XmlEdit.children s)
|
||||
with
|
||||
Not_found -> () in
|
||||
List.iter f (XmlEdit.children b)
|
||||
end else
|
||||
XmlEdit.set_background ~all:true b "white")
|
||||
(XmlEdit.children blocks)
|
||||
|
||||
method add_waypoint (geo:geographic) =
|
||||
let wpt_names = List.map (fun n -> XmlEdit.attrib n "name") (XmlEdit.children xml_wpts) in
|
||||
let name = new_gensym "wp" wpt_names in
|
||||
let utm = utm_of WGS84 geo in
|
||||
let (dx, dy) = utm_sub utm utm0 in
|
||||
let node = XmlEdit.add_child xml_wpts "waypoint" ["x",sof dx;"y",sof dy;"name",name] in
|
||||
create_wp node
|
||||
|
||||
method insert_path = fun path ->
|
||||
let xml_block =
|
||||
try XmlEdit.parent (XmlEdit.selection xml_tree_view) "block" with
|
||||
_ ->
|
||||
let xml_blocks = XmlEdit.child xml_root "blocks" in
|
||||
XmlEdit.child xml_blocks "block" in
|
||||
let path_node = XmlEdit.add_child xml_block "path" ["radius", "42."] in
|
||||
List.iter
|
||||
(fun ((wp:MapWaypoints.waypoint), r) ->
|
||||
let _n = XmlEdit.add_child path_node "path_point" ["wp", wp#name; "radius", sof r] in
|
||||
()
|
||||
)
|
||||
path
|
||||
|
||||
method connect_activated = fun cb -> XmlEdit.connect_activated xml_tree_view cb
|
||||
|
||||
method update_sectors = fun wp_name ->
|
||||
List.iter (fun (wps_name, segments, color) ->
|
||||
let wp_in_sector = List.exists (fun name -> name = wp_name) wps_name in
|
||||
if wp_in_sector then begin
|
||||
(* Build WP array *)
|
||||
let points = List.map (fun n -> let (_, w) = Hashtbl.find yaws n in w#pos) wps_name in
|
||||
let points = Array.of_list points in
|
||||
let segments = Array.of_list segments in
|
||||
let n = Array.length points in
|
||||
(* Update segments *)
|
||||
for i = 0 to n - 1 do
|
||||
let (x1, y1) = geomap#world_of points.(i)
|
||||
and (x2, y2) = geomap#world_of (points.((i+1)mod n)) in
|
||||
segments.(i)#set [`POINTS [|x1; y1; x2; y2 |]]
|
||||
done
|
||||
end
|
||||
) sectors
|
||||
|
||||
initializer (
|
||||
(** Create a graphic waypoint when it is created from the xml editor *)
|
||||
XmlEdit.connect xml_wpts (function XmlEdit.New_child node -> ignore (create_wp node) | _ -> ())
|
||||
)
|
||||
end
|
||||
@@ -1,56 +0,0 @@
|
||||
(*
|
||||
* Displaying and editing a flight plan on a MapCanvas
|
||||
*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
(** [flight_plan geomap color dtd_tile xml] *)
|
||||
class flight_plan :
|
||||
?format_attribs:((string * string) list -> string) ->
|
||||
?editable:bool ->
|
||||
show_moved:bool ->
|
||||
MapCanvas.widget ->
|
||||
string ->
|
||||
string ->
|
||||
Xml.xml ->
|
||||
object
|
||||
method add_waypoint : Latlong.geographic -> MapWaypoints.waypoint
|
||||
method destroy : unit -> unit
|
||||
method georef : Latlong.geographic
|
||||
method hide : unit -> unit
|
||||
method index : XmlEdit.node -> int * MapWaypoints.waypoint
|
||||
method get_wp : int -> MapWaypoints.waypoint (** May raise Not_found *)
|
||||
method show : unit -> unit
|
||||
method window : GObj.widget
|
||||
method waypoints : XmlEdit.node list
|
||||
method xml : Xml.xml
|
||||
method insert_path : (MapWaypoints.waypoint * float) list -> unit
|
||||
method highlight_stage : int -> int -> unit
|
||||
method connect_activated : (XmlEdit.node->unit) -> unit
|
||||
method update_sectors : string -> unit
|
||||
end
|
||||
|
||||
(** Extracts [lat0] and [Lon0] attributes *)
|
||||
val georef_of_xml : Xml.xml -> Latlong.geographic
|
||||
|
||||
(** Display a polygon based on a kml file *)
|
||||
val display_kml : ?group:GnoCanvas.group -> string -> MapCanvas.widget -> Xml.xml -> unit
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
(*
|
||||
* Displaying Google Maps on a MapCanvas object
|
||||
*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
let array_forall = fun f a ->
|
||||
Array.fold_right (fun x r -> f x && r) a true
|
||||
|
||||
open Printf
|
||||
|
||||
|
||||
module LL = Latlong
|
||||
|
||||
(** Quadtreee of displayed tiles *)
|
||||
type tiles_tree =
|
||||
Empty
|
||||
| Tile
|
||||
| Node of tiles_tree array
|
||||
let gm_tiles = Node (Array.make 4 Empty)
|
||||
|
||||
(** Google Maps paths in the quadtree are coded with q,r,s and t*)
|
||||
let index_of = function
|
||||
'q' -> 0 | 'r' -> 1 | 's' -> 2 | 't' -> 3
|
||||
| _ -> invalid_arg "index_of"
|
||||
let char_of = function
|
||||
0 -> 'q' | 1 -> 'r' | 2 -> 's' | 3 -> 't'
|
||||
| _ -> invalid_arg "char_of"
|
||||
|
||||
(** Checking that a tile is already displayed *)
|
||||
let mem_tile = fun tile_key ->
|
||||
let rec loop = fun i tree ->
|
||||
tree = Tile ||
|
||||
i < String.length tile_key &&
|
||||
match tree with
|
||||
Empty -> false
|
||||
| Tile -> true
|
||||
| Node sons -> loop (i+1) sons.(index_of tile_key.[i]) in
|
||||
loop 0 gm_tiles
|
||||
|
||||
(** Adding a tile to the store *)
|
||||
let add_tile = fun tile_key ->
|
||||
let rec loop = fun i tree j ->
|
||||
if i < String.length tile_key then
|
||||
match tree.(j) with
|
||||
Empty ->
|
||||
let sons = Array.make 4 Empty in
|
||||
tree.(j) <- Node sons;
|
||||
loop (i+1) sons (index_of tile_key.[i])
|
||||
| Tile -> () (* Already there *)
|
||||
| Node sons ->
|
||||
loop (i+1) sons (index_of tile_key.[i])
|
||||
else
|
||||
tree.(j) <- Tile in
|
||||
loop 0 [|gm_tiles|] 0
|
||||
|
||||
|
||||
let display_the_tile = fun (geomap:MapCanvas.widget) tile jpg_file level ->
|
||||
let south_lat = tile.Gm.sw_corner.LL.posn_lat
|
||||
and west_long = tile.Gm.sw_corner.LL.posn_long in
|
||||
let north_lat = south_lat +. tile.Gm.height
|
||||
and east_long = west_long +. tile.Gm.width in
|
||||
let ne = LL.make_geo north_lat east_long in
|
||||
|
||||
let (tx, ty) = Gm.tile_size in
|
||||
try
|
||||
let pixbuf = GdkPixbuf.from_file jpg_file in
|
||||
ignore (GMain.Idle.add (fun () ->
|
||||
let map = geomap#display_pixbuf ((0,tx), tile.Gm.sw_corner) ((ty,0),ne) pixbuf ~level in
|
||||
map#raise 1;
|
||||
false));
|
||||
add_tile tile.Gm.key
|
||||
with
|
||||
GdkPixbuf.GdkPixbufError(_, msg) ->
|
||||
match GToolbox.question_box ~title:"Corrupted file" ~buttons:["Erase"; "Cancel"] (sprintf "%s. Erase ?" msg) with
|
||||
1 ->
|
||||
Sys.remove jpg_file
|
||||
| _ -> ()
|
||||
|
||||
|
||||
|
||||
(** Displaying the tile around the given point *)
|
||||
let display_tile = fun (geomap:MapCanvas.widget) wgs84 level ->
|
||||
let desired_tile = Gm.tile_of_geo ~level wgs84 1 in
|
||||
|
||||
let key = desired_tile.Gm.key in
|
||||
if not (mem_tile key) then
|
||||
let (tile, jpg_file) = Gm.get_image key in
|
||||
display_the_tile geomap tile jpg_file (String.length tile.Gm.key)
|
||||
|
||||
|
||||
exception New_displayed of int
|
||||
(** [New_displayed zoom] Raised when a new is loadded *)
|
||||
|
||||
let fill_window = fun (geomap:MapCanvas.widget) zoomlevel ->
|
||||
(** First estimate the coverage of the window *)
|
||||
let width_c, height_c = Gdk.Drawable.get_size geomap#canvas#misc#window
|
||||
and (xc0, yc0) = geomap#canvas#get_scroll_offsets in
|
||||
let (xw0, yw0) = geomap#window_to_world ~winx:(float xc0) ~winy:(float (yc0+height_c))
|
||||
and (xw1, yw1) = geomap#window_to_world ~winx:(float (xc0+width_c)) ~winy:(float yc0) in
|
||||
let sw = geomap#of_world (xw0, yw0)
|
||||
and ne = geomap#of_world (xw1, yw1) in
|
||||
let west = sw.LL.posn_long /. LL.pi
|
||||
and east = ne.LL.posn_long /. LL.pi
|
||||
and north = LL.mercator_lat ne.LL.posn_lat /. LL.pi
|
||||
and south = LL.mercator_lat sw.LL.posn_lat /. LL.pi in
|
||||
|
||||
let east = if east < west then east +. 2. else east in
|
||||
|
||||
(** Get Hashtbl from cache *)
|
||||
let tbl = Gm.get_hashtbl_of_cache () in
|
||||
|
||||
(** Go through the quadtree and look for the holes *)
|
||||
let rec loop = fun twest tsouth tsize trees i zoom key ->
|
||||
(* Check for intersection *)
|
||||
if not (twest > east || (twest+.tsize < west && (east < 1. (* Standard case *) || twest+.2.>east (* Over 180� *))) || tsouth > north || tsouth+.tsize < south) then
|
||||
let tsize2 = tsize /. 2. in
|
||||
try
|
||||
match trees.(i) with
|
||||
Tile -> ()
|
||||
| Empty ->
|
||||
if zoom = 1 then
|
||||
let tile, image = Gm.get_image ~tbl key in
|
||||
let level = String.length tile.Gm.key in
|
||||
display_the_tile geomap tile image level;
|
||||
raise (New_displayed (zoomlevel+1-String.length tile.Gm.key))
|
||||
else begin
|
||||
trees.(i) <- Node (Array.make 4 Empty);
|
||||
loop twest tsouth tsize trees i zoom key
|
||||
end
|
||||
| Node sons ->
|
||||
let continue = fun j tw ts ->
|
||||
loop tw ts tsize2 sons j (zoom-1) (key^String.make 1 (char_of j)) in
|
||||
|
||||
continue 0 twest (tsouth+.tsize2);
|
||||
continue 1 (twest+.tsize2) (tsouth+.tsize2);
|
||||
continue 2 (twest+.tsize2) tsouth;
|
||||
continue 3 twest tsouth;
|
||||
|
||||
(* If the current node is complete, replace it by a Tile *)
|
||||
if array_forall (fun x -> x = Tile) sons then begin
|
||||
trees.(i) <- Tile
|
||||
end
|
||||
with
|
||||
New_displayed z when z = zoom ->
|
||||
trees.(i) <- Tile
|
||||
| Gm.Not_available -> () in
|
||||
loop (-1.) (-1.) 2. [|gm_tiles|] 0 zoomlevel "t"
|
||||
|
||||
|
||||
exception To_copy of int * string
|
||||
|
||||
let gdk_pixbuf_safe_copy_area ~dest ~dest_x ~dest_y ~width ~height ~src_x ~src_y pixbuf =
|
||||
let dest_x, width, src_x =
|
||||
if dest_x < 0 then 0, width+dest_x, src_x-dest_x else dest_x, width, src_x in
|
||||
let dest_y, height, src_y =
|
||||
if dest_y < 0 then 0, height+dest_y, src_y-dest_y else dest_y, height, src_y in
|
||||
let width = min width (GdkPixbuf.get_width dest - dest_x)
|
||||
and height = min height (GdkPixbuf.get_height dest -dest_y) in
|
||||
GdkPixbuf.copy_area ~dest ~dest_x ~dest_y ~width ~height ~src_x ~src_y pixbuf
|
||||
|
||||
let pixbuf = fun sw ne zoomlevel->
|
||||
assert (sw.LL.posn_lat < ne.LL.posn_lat);
|
||||
assert (sw.LL.posn_long < ne.LL.posn_long);
|
||||
let west = sw.LL.posn_long /. LL.pi
|
||||
and east = ne.LL.posn_long /. LL.pi
|
||||
and north = LL.mercator_lat ne.LL.posn_lat /. LL.pi
|
||||
and south = LL.mercator_lat sw.LL.posn_lat /. LL.pi in
|
||||
|
||||
let pixel_size = 1. /. (2. ** 16.) /. 256. in
|
||||
let width = truncate ((east -. west) /. pixel_size)
|
||||
and height = truncate ((north -. south) /. pixel_size) in
|
||||
let dest = GdkPixbuf.create ~width ~height () in
|
||||
let rec loop = fun twest tsouth tsize zoom key ->
|
||||
if not (twest > east || twest+.tsize < west || tsouth > north || tsouth+.tsize < south) then
|
||||
let tsize2 = tsize /. 2. in
|
||||
try
|
||||
if zoom = 1
|
||||
then
|
||||
let tile, image = Gm.get_image key in
|
||||
raise (To_copy (zoomlevel+1-String.length tile.Gm.key, image))
|
||||
else begin
|
||||
let continue = fun j tw ts ->
|
||||
loop tw ts tsize2 (zoom-1) (key^String.make 1 (char_of j)) in
|
||||
continue 0 twest (tsouth+.tsize2);
|
||||
continue 1 (twest+.tsize2) (tsouth+.tsize2);
|
||||
continue 2 (twest+.tsize2) tsouth;
|
||||
continue 3 twest tsouth;
|
||||
end
|
||||
with
|
||||
To_copy (z, image) when z = zoom ->
|
||||
let dest_x = truncate ((twest -. west) /. pixel_size)
|
||||
and dest_y = truncate ((north -. (tsouth+.tsize)) /. pixel_size) in
|
||||
let width = truncate (tsize /. pixel_size) in
|
||||
let src_x = 0
|
||||
and src_y = 0 in
|
||||
let pixbuf = GdkPixbuf.from_file image in
|
||||
gdk_pixbuf_safe_copy_area ~dest ~dest_x ~dest_y ~width ~height:width ~src_x ~src_y pixbuf
|
||||
| Gm.Not_available -> () in
|
||||
loop (-1.) (-1.) 2. zoomlevel "t";
|
||||
dest
|
||||
@@ -1,32 +0,0 @@
|
||||
(*
|
||||
* Displaying Google Maps on a MapCanvas object
|
||||
*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
val display_tile : MapCanvas.widget -> Latlong.geographic -> int -> unit
|
||||
(** Displaying the Google Maps tile around the given point (zoom=1) up to max level *)
|
||||
|
||||
val fill_window : MapCanvas.widget -> int -> unit
|
||||
(** Filling the canvas window with Google Maps tiles at given zoomlevel*)
|
||||
|
||||
val pixbuf : Latlong.geographic -> Latlong.geographic -> int -> GdkPixbuf.pixbuf
|
||||
(** [pixbuf south_west north_east zoomlevel] Returns a map background of the given area *)
|
||||
@@ -1,46 +0,0 @@
|
||||
(*
|
||||
* Displaying IGN Maps on a MapCanvas object
|
||||
*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
module LL = Latlong
|
||||
|
||||
let displayed_tiles = Hashtbl.create 41
|
||||
let mem_tile = fun t -> Hashtbl.mem displayed_tiles t.IGN.key
|
||||
let add_tile = fun t -> Hashtbl.add displayed_tiles t.IGN.key ()
|
||||
|
||||
|
||||
let opacity = 100 (* FIXME *)
|
||||
|
||||
(** Displaying the tile around the given point *)
|
||||
let display_tile = fun (geomap:MapCanvas.widget) wgs84 ->
|
||||
let tile = IGN.tile_of_geo wgs84 in
|
||||
|
||||
if not (mem_tile tile) then
|
||||
let jpg_file = IGN.get_tile tile in
|
||||
|
||||
let (sx,sy) = IGN.tile_size in
|
||||
let pixbuf = GdkPixbuf.from_file jpg_file in
|
||||
|
||||
let map = geomap#display_pixbuf ~opacity ((0,sx), tile.IGN.sw_corner) ((sy,0),tile.IGN.ne_corner) pixbuf in
|
||||
map#raise 1;
|
||||
add_tile tile
|
||||
@@ -1,25 +0,0 @@
|
||||
(*
|
||||
* Displaying IGN Maps on a MapCanvas object
|
||||
*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
val display_tile : MapCanvas.widget -> Latlong.geographic -> unit
|
||||
@@ -1,337 +0,0 @@
|
||||
(*
|
||||
* Track objects
|
||||
*
|
||||
* Copyright (C) 2004 CENA/ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
open Printf
|
||||
module G2d = Geometry_2d
|
||||
module LL = Latlong
|
||||
|
||||
module G = MapCanvas
|
||||
|
||||
module CL = ContrastLabel
|
||||
module ACI = AcIcon
|
||||
|
||||
let affine_pos_and_angle z xw yw angle =
|
||||
let rad_angle = angle /. 180. *. acos(-1.) in
|
||||
let cos_a = cos rad_angle in
|
||||
let sin_a = sin rad_angle in
|
||||
[| cos_a /. z ; sin_a /. z ; ~-. sin_a /. z; cos_a /. z; xw ; yw |]
|
||||
|
||||
let rec norm_angle_360 = fun alpha ->
|
||||
if alpha > 360.0 then norm_angle_360 (alpha -. 360.0)
|
||||
else if alpha < 0.0 then norm_angle_360 (alpha +. 360.0)
|
||||
else alpha
|
||||
|
||||
|
||||
(** variables used for handling cam moves: *)
|
||||
|
||||
let cam_half_aperture = LL.pi /. 6.0
|
||||
let half_pi = LL.pi /. 2.0
|
||||
|
||||
type desired =
|
||||
NoDesired
|
||||
| DesiredCircle of LL.geographic*float*GnoCanvas.ellipse
|
||||
| DesiredSegment of LL.geographic*LL.geographic*GnoCanvas.line
|
||||
|
||||
class track = fun ?(name="Noname") ?(icon="fixedwing") ?(size = 500) ?(color="red") ?(show_carrot=true) (ac_id:string) (geomap:MapCanvas.widget) ->
|
||||
let group = GnoCanvas.group geomap#canvas#root in
|
||||
let empty = ({LL.posn_lat=0.; LL.posn_long=0.}, GnoCanvas.line group) in
|
||||
let v_empty = ({LL.posn_lat=0.; LL.posn_long=0.}, 0.0) in
|
||||
|
||||
let aircraft = GnoCanvas.group group
|
||||
and track = GnoCanvas.group group in
|
||||
let icon_template = match icon with
|
||||
| "home" -> ACI.icon_home_template
|
||||
| "rotorcraft" -> ACI.icon_rotorcraft_template
|
||||
| "quadrotor" -> ACI.icon_quadrotor_template
|
||||
| "hexarotor" -> ACI.icon_hexarotor_template
|
||||
| "octorotor" -> ACI.icon_octorotor_template
|
||||
| "quadrotor_x" -> ACI.icon_quadrotor_x_template
|
||||
| "hexarotor_x" -> ACI.icon_hexarotor_x_template
|
||||
| "octorotor_x" -> ACI.icon_octorotor_x_template
|
||||
| "quadrotor_xi" -> ACI.icon_quadrotor_xi_template
|
||||
| "flyingwing" -> ACI.icon_flyingwing_template
|
||||
| "intruder" -> ACI.icon_intruder_template
|
||||
| "fixedwing" | _ -> ACI.icon_fixedwing_template
|
||||
in
|
||||
let _ac_icon = new ACI.widget ~color ~icon_template aircraft in
|
||||
let ac_label = new CL.widget ~name ~color 25. 25. group in
|
||||
|
||||
let carrot = GnoCanvas.group group in
|
||||
let _ac_carrot =
|
||||
if show_carrot then
|
||||
ignore (GnoCanvas.polygon ~points:[|0.;0.;-5.;-10.;5.;-10.|] ~props:[`WIDTH_UNITS 1.;`FILL_COLOR "orange"; `OUTLINE_COLOR "orange"; `FILL_STIPPLE (Gdk.Bitmap.create_from_data ~width:2 ~height:2 "\002\001")] carrot)
|
||||
else ()
|
||||
in
|
||||
|
||||
let cam = GnoCanvas.group group in
|
||||
|
||||
(** rectangle representing the field covered by the cam *)
|
||||
let _ac_cam_targeted =
|
||||
ignore ( GnoCanvas.ellipse ~x1: (-. 2.5) ~y1: (-. 2.5 ) ~x2: 2.5 ~y2: 2.5 ~fill_color:color ~props:[`WIDTH_UNITS 1.; `OUTLINE_COLOR color; `FILL_STIPPLE (Gdk.Bitmap.create_from_data ~width:2 ~height:2 "\002\001")] cam) in
|
||||
let _ = cam#hide () in
|
||||
|
||||
let mission_target = GnoCanvas.group group in
|
||||
|
||||
(** red circle : target of the mission *)
|
||||
let _ac_mission_target =
|
||||
ignore ( GnoCanvas.ellipse ~x1: (-5.) ~y1: (-5.) ~x2: 5. ~y2: 5. ~fill_color:"red" ~props:[`WIDTH_UNITS 1.; `OUTLINE_COLOR "red"; `FILL_STIPPLE (Gdk.Bitmap.create_from_data ~width:2 ~height:2 "\002\001")] mission_target) in
|
||||
let _ = mission_target#hide () in
|
||||
|
||||
let _desired_circle = GnoCanvas.ellipse group
|
||||
and _desired_segment = GnoCanvas.line group in
|
||||
|
||||
let _ = aircraft#raise_to_top () in
|
||||
|
||||
object (self)
|
||||
val mutable top = 0
|
||||
val mutable color = color
|
||||
val mutable segments = Array.make size empty
|
||||
val mutable v_segments = Array.make size empty
|
||||
val mutable v_top = 0
|
||||
val mutable v_path = Array.make 10 v_empty
|
||||
val mutable last = None
|
||||
val mutable last_heading = 0.0
|
||||
val mutable last_altitude = 0.0
|
||||
val mutable last_speed = 0.0
|
||||
val mutable last_climb = 0.0
|
||||
val mutable last_flight_time = 0.0
|
||||
val mutable last_x_val = 0.0
|
||||
val mutable cam_on = false
|
||||
val mutable params_on = false
|
||||
val mutable v_params_on = false
|
||||
val mutable desired_track = NoDesired
|
||||
val zone = GnoCanvas.rect group
|
||||
val mutable ac_cam_cover = GnoCanvas.polygon ~fill_color:"grey" ~props:[`WIDTH_PIXELS 1 ; `FILL_STIPPLE (Gdk.Bitmap.create_from_data ~width:2 ~height:2 "\002\001")] cam
|
||||
val mutable event_cb = None
|
||||
val mutable destroyed = false
|
||||
method color = color
|
||||
method set_color c = color <- c
|
||||
method track = track
|
||||
method v_path = v_path
|
||||
method aircraft = aircraft
|
||||
method id = ac_id
|
||||
method name = name
|
||||
method set_label = fun s ->
|
||||
ac_label#set_name s
|
||||
method clear_one = fun i ->
|
||||
if segments.(i) != empty then begin
|
||||
(snd segments.(i))#destroy ();
|
||||
segments.(i) <- empty
|
||||
end
|
||||
method incr = fun seg ->
|
||||
let s = Array.length seg in
|
||||
top <- (top + 1) mod s
|
||||
method v_incr = fun path ->
|
||||
let s = Array.length path in
|
||||
v_top <- (v_top + 1) mod s
|
||||
method clear = fun () ->
|
||||
for i = 0 to Array.length segments - 1 do
|
||||
self#clear_one i
|
||||
done;
|
||||
top <- 0
|
||||
method set_cam_state = fun b ->
|
||||
cam_on <- b;
|
||||
if b then begin
|
||||
cam#show ();
|
||||
mission_target#show ()
|
||||
end else begin
|
||||
cam#hide ();
|
||||
mission_target#hide ()
|
||||
end
|
||||
|
||||
method update_ap_status = fun time ->
|
||||
last_flight_time <- time
|
||||
method set_params_state = fun b ->
|
||||
params_on <- b;
|
||||
if not b then (* Reset to the default simple label *)
|
||||
ac_label#set_name name;
|
||||
ac_label#set_y 25.
|
||||
method set_v_params_state = fun b -> v_params_on <- b
|
||||
method set_last = fun x -> last <- x
|
||||
method last = last
|
||||
method pos = match last with Some pos -> pos | None -> failwith "No pos"
|
||||
method last_heading = last_heading
|
||||
method last_altitude = last_altitude
|
||||
method last_speed = last_speed
|
||||
method last_climb = last_climb
|
||||
|
||||
method height = fun () ->
|
||||
match last with
|
||||
None -> last_altitude
|
||||
| Some wgs84 ->
|
||||
let h = try float (Srtm.of_wgs84 wgs84) with _ -> 0. in
|
||||
last_altitude -. h
|
||||
|
||||
(** add track points on map2D, according to the
|
||||
track parameter and store altitude for the vertical path *)
|
||||
method add_point = fun geo alt ->
|
||||
self#clear_one top;
|
||||
let last_geo =
|
||||
match last with
|
||||
None -> geo
|
||||
| Some last_geo -> last_geo in
|
||||
segments.(top) <- (geo, geomap#segment ~group ~fill_color:color last_geo geo);
|
||||
self#incr segments;
|
||||
self#set_last (Some geo);
|
||||
v_path.(v_top) <- (geo, alt);
|
||||
self#v_incr v_path
|
||||
|
||||
method clear_map2D = self#clear ()
|
||||
|
||||
method move_icon = fun wgs84 heading altitude speed climb ->
|
||||
let (xw,yw) = geomap#world_of wgs84 in
|
||||
aircraft#affine_absolute (affine_pos_and_angle geomap#zoom_adj#value xw yw heading);
|
||||
last_heading <- heading;
|
||||
last_altitude <- altitude;
|
||||
last_speed <- speed ;
|
||||
last_climb <- climb;
|
||||
|
||||
if params_on then begin
|
||||
let last_height = self#height () in
|
||||
ac_label#set_name (sprintf "%s\n%+.0f m\n%.1f m/s" name last_height last_speed);
|
||||
ac_label#set_y 70.
|
||||
end;
|
||||
|
||||
ac_label#affine_absolute (affine_pos_and_angle geomap#zoom_adj#value xw yw 0.);
|
||||
self#add_point wgs84 altitude;
|
||||
|
||||
method move_carrot = fun wgs84 ->
|
||||
let (xw,yw) = geomap#world_of wgs84 in
|
||||
carrot#affine_absolute (affine_pos_and_angle geomap#zoom_adj#value xw yw 0.);
|
||||
|
||||
(** draws the circular path to be followed by the aircraft in circle mode *)
|
||||
method draw_circle = fun en radius ->
|
||||
let create = fun () ->
|
||||
desired_track <- DesiredCircle (en, radius, geomap#circle ~color:"#00ff00" en radius) in
|
||||
match desired_track with
|
||||
DesiredCircle (c, r, circle) ->
|
||||
if c <> en || r <> radius then begin
|
||||
circle#destroy ();
|
||||
create ()
|
||||
end
|
||||
| DesiredSegment (p1,p2,s) ->
|
||||
s#destroy ();
|
||||
create ()
|
||||
| NoDesired ->
|
||||
create ()
|
||||
|
||||
(** draws the linear path to be followed by the aircraft between two waypoints *)
|
||||
method draw_segment = fun en1 en2 ->
|
||||
let create = fun () ->
|
||||
desired_track <- DesiredSegment (en1, en2, geomap#segment ~fill_color:"#00ff00" en1 en2) in
|
||||
match desired_track with
|
||||
DesiredCircle (c, r, circle) ->
|
||||
circle#destroy ();
|
||||
create ()
|
||||
| DesiredSegment (p1,p2,s) ->
|
||||
if p1 <> en1 || p2 <> en2 then begin
|
||||
s#destroy ();
|
||||
create ()
|
||||
end
|
||||
| NoDesired ->
|
||||
create ()
|
||||
|
||||
method delete_desired_track = fun () ->
|
||||
begin
|
||||
match desired_track with
|
||||
DesiredCircle (c, r, circle) ->
|
||||
circle#destroy ()
|
||||
| DesiredSegment (p1,p2,s) ->
|
||||
s#destroy ();
|
||||
| NoDesired ->
|
||||
()
|
||||
end;
|
||||
desired_track <- NoDesired
|
||||
|
||||
method draw_zone = fun geo1 geo2 ->
|
||||
let (x1, y1) = geomap#world_of geo1
|
||||
and (x2, y2) = geomap#world_of geo2 in
|
||||
zone#set [`X1 x1; `Y1 y1; `X2 x2; `Y2 y2; `OUTLINE_COLOR "#ffc0c0"; `WIDTH_PIXELS 2]
|
||||
|
||||
(** moves the rectangle representing the field covered by the camera *)
|
||||
method move_cam = fun positions mission_target_wgs84 ->
|
||||
match last, cam_on with
|
||||
Some last_ac, true ->
|
||||
let points = geomap#convert_positions_to_points positions in
|
||||
ac_cam_cover#set [`POINTS points;
|
||||
`OUTLINE_COLOR color];
|
||||
let (mission_target_xw, mission_target_yw) = geomap#world_of mission_target_wgs84 in
|
||||
mission_target#affine_absolute (affine_pos_and_angle geomap#zoom_adj#value mission_target_xw mission_target_yw 0.0)
|
||||
| _ -> ()
|
||||
method zoom = fun z ->
|
||||
let a = aircraft#i2w_affine in
|
||||
let z' = sqrt (a.(0)*.a.(0)+.a.(1)*.a.(1)) in
|
||||
for i = 0 to 3 do a.(i) <- a.(i) /. z' *. 1./.z done;
|
||||
aircraft#affine_absolute a
|
||||
|
||||
method resize = fun new_size ->
|
||||
let a = Array.make new_size empty in
|
||||
let size = Array.length segments in
|
||||
let m = min new_size size in
|
||||
let j = ref ((top - m + size) mod size) in
|
||||
for i = 0 to m - 1 do
|
||||
a.(i) <- segments.(!j);
|
||||
j := (!j + 1) mod size
|
||||
done;
|
||||
for i = 1 to size - new_size do (* Never done if new_size > size *)
|
||||
self#clear_one !j;
|
||||
j := (!j + 1) mod size
|
||||
done;
|
||||
top <- m mod new_size;
|
||||
segments <- a
|
||||
|
||||
method size = Array.length segments
|
||||
|
||||
method event (ev : GnoCanvas.item_event) =
|
||||
begin
|
||||
match ev with
|
||||
| `BUTTON_PRESS ev ->
|
||||
begin
|
||||
match GdkEvent.Button.button ev with
|
||||
| 1 ->
|
||||
begin
|
||||
match event_cb with
|
||||
| Some cb -> cb ac_id
|
||||
| None -> ()
|
||||
end
|
||||
| _ -> ()
|
||||
end
|
||||
| _ -> ()
|
||||
end;
|
||||
true
|
||||
initializer ignore(aircraft#connect#event ~callback:self#event)
|
||||
|
||||
method set_event_cb = fun (cb: string -> unit) -> event_cb <- Some cb
|
||||
|
||||
initializer
|
||||
(* could not properly disconnect adjustment signal, so only calling zoom method if group is still displayed *)
|
||||
ignore(geomap#zoom_adj#connect#value_changed ~callback:(fun () -> if not destroyed then self#zoom geomap#zoom_adj#value));
|
||||
ignore(group#connect#destroy ~callback:(fun () -> destroyed <- true))
|
||||
|
||||
(* destroy method *)
|
||||
method destroy = fun () -> group#destroy ()
|
||||
|
||||
initializer
|
||||
Gc.finalise (fun self -> self#destroy ()) self
|
||||
end
|
||||
@@ -1,74 +0,0 @@
|
||||
(*
|
||||
* Track objects
|
||||
*
|
||||
* Copyright (C) 2004-2010 CENA/ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
class track :
|
||||
?name:string ->
|
||||
?icon:string ->
|
||||
?size:int ->
|
||||
?color:string ->
|
||||
?show_carrot:bool ->
|
||||
string ->
|
||||
MapCanvas.widget ->
|
||||
object
|
||||
method add_point : Latlong.geographic -> float -> unit
|
||||
method aircraft : GnoCanvas.group
|
||||
method id : string
|
||||
method name : string
|
||||
method clear : unit -> unit
|
||||
method clear_map2D : unit
|
||||
method clear_one : int -> unit
|
||||
method color : string
|
||||
method delete_desired_track : unit -> unit
|
||||
method draw_circle : Latlong.geographic -> Latlong.fmeter -> unit
|
||||
method draw_segment : Latlong.geographic -> Latlong.geographic -> unit
|
||||
method draw_zone : Latlong.geographic -> Latlong.geographic -> unit
|
||||
method height : unit -> float
|
||||
method incr : (Latlong.geographic * GnoCanvas.line) array -> unit
|
||||
method last : Latlong.geographic option
|
||||
method last_altitude : float
|
||||
method last_climb : float
|
||||
method last_heading : float
|
||||
method last_speed : float
|
||||
method move_cam : Latlong.geographic array -> Latlong.geographic -> unit
|
||||
method move_carrot : Latlong.geographic -> unit
|
||||
method move_icon :
|
||||
Latlong.geographic -> float -> float -> float -> float -> unit
|
||||
method pos : Latlong.geographic
|
||||
method resize : int -> unit
|
||||
method set_cam_state : bool -> unit
|
||||
method set_color : string -> unit
|
||||
method set_label : string -> unit
|
||||
method set_last : Latlong.geographic option -> unit
|
||||
method set_params_state : bool -> unit
|
||||
method set_v_params_state : bool -> unit
|
||||
method size : int
|
||||
method track : GnoCanvas.group
|
||||
method update_ap_status : float -> unit
|
||||
method v_incr : (Latlong.geographic * float) array -> unit
|
||||
method v_path : (Latlong.geographic * float) array
|
||||
method zoom : float -> unit
|
||||
method event : GnoCanvas.item_event -> bool
|
||||
method set_event_cb : (string -> unit) -> unit
|
||||
method destroy : unit -> unit
|
||||
end
|
||||
@@ -1,309 +0,0 @@
|
||||
(*
|
||||
* Waypoints objects
|
||||
*
|
||||
* Copyright (C) 2004 CENA/ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
module LL = Latlong
|
||||
open Printf
|
||||
open LL
|
||||
|
||||
module CL = ContrastLabel
|
||||
|
||||
(*
|
||||
* Waypoint label offsets
|
||||
*)
|
||||
let s = 6. (* x offset *)
|
||||
|
||||
class group = fun ?(color="red") ?(editable=true) ?(show_moved=false) (geomap:MapCanvas.widget) ->
|
||||
let g = GnoCanvas.group geomap#canvas#root in
|
||||
object
|
||||
method group=g
|
||||
method geomap=geomap
|
||||
method color=color
|
||||
method editable=editable
|
||||
method show_moved = show_moved
|
||||
end
|
||||
|
||||
let rotation_45 =
|
||||
let s = sin (Latlong.pi/.4.) in
|
||||
[|s;s;-.s;s;0.;0.|]
|
||||
|
||||
class waypoint = fun ?(show = true) (wpts_group:group) (name :string) ?(alt=0.) wgs84 ->
|
||||
let geomap=wpts_group#geomap
|
||||
and color = wpts_group#color
|
||||
and editable = wpts_group#editable in
|
||||
let xw, yw = geomap#world_of wgs84 in
|
||||
let callbacks = Hashtbl.create 5 in
|
||||
let updated () =
|
||||
Hashtbl.iter (fun cb _ -> cb ()) callbacks in
|
||||
|
||||
let wpt_group = GnoCanvas.group wpts_group#group in
|
||||
|
||||
let item =
|
||||
GnoCanvas.rect wpt_group ~x1:(-.s) ~y1:(-.s) ~x2:s ~y2:s ~props:[`FILL_COLOR color; `OUTLINE_COLOR "black"] in
|
||||
|
||||
let anim = function
|
||||
None ->
|
||||
Some (Glib.Timeout.add ~ms:500 ~callback:(fun () -> Gdk.X.beep (); item#affine_relative rotation_45; true))
|
||||
| Some x -> Some x in
|
||||
|
||||
|
||||
object (self)
|
||||
val mutable x0 = 0.
|
||||
val mutable y0 = 0.
|
||||
|
||||
val label = new CL.widget ~name:name ~color:"white" s 0. wpt_group
|
||||
val mutable name = name (* FIXME: already in label ! *)
|
||||
val mutable alt = alt
|
||||
val mutable ground_alt = 0.
|
||||
val mutable moved = None
|
||||
val mutable deleted = false
|
||||
val mutable commit_cb = None
|
||||
initializer
|
||||
if not show then wpt_group#hide ()
|
||||
initializer
|
||||
item#affine_absolute rotation_45;
|
||||
self#move xw yw
|
||||
method connect = fun (cb:unit -> unit) ->
|
||||
Hashtbl.add callbacks cb ()
|
||||
method set_commit_callback = fun (cb:unit -> unit) -> commit_cb <- Some cb
|
||||
method name = name
|
||||
method set_name n =
|
||||
if n <> name then begin
|
||||
name <- n;
|
||||
label#set_name name
|
||||
end
|
||||
method geomap = geomap
|
||||
method alt = alt
|
||||
method label = label
|
||||
method xy = let a = wpt_group#i2w_affine in (a.(4), a.(5))
|
||||
method move dx dy =
|
||||
wpt_group#move ~x:dx ~y:dy;
|
||||
wpt_group#raise_to_top ()
|
||||
method edit =
|
||||
let dialog = GWindow.window ~type_hint:`DIALOG ~modal:true ~position:`MOUSE ~border_width:10 ~title:"Waypoint Edit" () in
|
||||
let dvbx = GPack.box `VERTICAL ~packing:dialog#add () in
|
||||
|
||||
let ename = GEdit.entry ~text:name ~editable ~packing:dvbx#add () in
|
||||
let hbox = GPack.hbox ~packing:dvbx#add () in
|
||||
|
||||
let optmenu = GMenu.option_menu ~packing:hbox#add () in
|
||||
let e_pos = GEdit.entry ~width_chars:25 ~packing:hbox#add () in
|
||||
|
||||
(* We would like to share the menu of the map: it does not work ! *)
|
||||
let selected_georef = ref WGS84_dec in
|
||||
let display_coordinates = fun () ->
|
||||
e_pos#set_text (string_of_coordinates !selected_georef self#pos)
|
||||
and set_coordinates = fun () ->
|
||||
self#set (geographic_of_coordinates !selected_georef e_pos#text) in
|
||||
|
||||
display_coordinates ();
|
||||
|
||||
let initial_wgs84 = self#pos in
|
||||
|
||||
let menu = GMenu.menu () in
|
||||
let set = fun kind () ->
|
||||
set_coordinates ();
|
||||
selected_georef := kind;
|
||||
display_coordinates () in
|
||||
let mi = GMenu.menu_item ~label:"WGS84" ~packing:menu#append () in
|
||||
ignore (mi#connect#activate ~callback:(set WGS84_dec));
|
||||
let mi = GMenu.menu_item ~label:"WGS84_dms" ~packing:menu#append () in
|
||||
ignore (mi#connect#activate ~callback:(set WGS84_dms));
|
||||
let mi = GMenu.menu_item ~label:"LambertIIe" ~packing:menu#append () in
|
||||
ignore (mi#connect#activate ~callback:(set LBT2e));
|
||||
List.iter (fun (label, geo) ->
|
||||
let mi = GMenu.menu_item ~label ~packing:menu#append () in
|
||||
ignore (mi#connect#activate ~callback:(set (Bearing geo))))
|
||||
geomap#georefs;
|
||||
optmenu#set_menu menu;
|
||||
|
||||
let ha = GPack.hbox ~packing:dvbx#add () in
|
||||
let minus10= GButton.button ~label:"-10" ~packing:ha#add () in
|
||||
(* let ea = GEdit.entry ~text:(string_of_float alt) ~packing:ha#add () in *)
|
||||
let ea = GEdit.spin_button ~rate:0. ~digits:2 ~width:50 ~packing:ha#add ()
|
||||
and adj = GData.adjustment
|
||||
~value:alt ~lower:(-100.) ~upper:10000.
|
||||
~step_incr:1. ~page_incr:10.0 ~page_size:0. () in
|
||||
ea#set_adjustment adj;
|
||||
ea#set_value alt; (* this should be done by set_adjustment but seems to fail on ubuntu 13.10 (at least) *)
|
||||
|
||||
let agl = alt -. (try float (Srtm.of_wgs84 initial_wgs84) with _ -> ground_alt) in
|
||||
let agl_lab = GMisc.label ~text:(sprintf " AGL: %4.0fm" agl) ~packing:ha#add () in
|
||||
let plus10= GButton.button ~label:"+10" ~packing:ha#add () in
|
||||
let change_alt = fun x ->
|
||||
ea#set_value (ea#value +. x) in
|
||||
ignore(minus10#connect#pressed ~callback:(fun _ -> change_alt (-10.)));
|
||||
ignore(plus10#connect#pressed ~callback:(fun _ -> change_alt (10.)));
|
||||
|
||||
(* called when ok button is clicked in WP Edit dialog *)
|
||||
let callback = fun _ ->
|
||||
geomap#edit_georef_name name ename#text;
|
||||
self#set_name ename#text;
|
||||
alt <- ea#value;
|
||||
label#set_name name;
|
||||
set_coordinates ();
|
||||
updated ();
|
||||
if wpts_group#show_moved then
|
||||
moved <- anim moved;
|
||||
begin
|
||||
match commit_cb with
|
||||
Some cb -> cb ()
|
||||
| None -> ()
|
||||
end;
|
||||
dialog#destroy ()
|
||||
in
|
||||
let dhbx = GPack.box `HORIZONTAL ~packing: dvbx#add () in
|
||||
|
||||
let cancel = GButton.button ~stock:`CANCEL ~packing: dhbx#add () in
|
||||
let destroy = fun () ->
|
||||
self#set initial_wgs84;
|
||||
self#reset_moved ();
|
||||
wpt_group#lower_to_bottom ();
|
||||
dialog#destroy () in
|
||||
ignore(cancel#connect#clicked ~callback:destroy);
|
||||
|
||||
(** Delete button for editable waypoints *)
|
||||
if editable then begin
|
||||
let delete = GButton.button ~stock:`DELETE ~packing: dhbx#add () in
|
||||
let delete_callback = fun () ->
|
||||
dialog#destroy ();
|
||||
self#delete ();
|
||||
geomap#delete_georef name;
|
||||
updated ()
|
||||
in
|
||||
ignore(delete#connect#clicked ~callback:delete_callback)
|
||||
end;
|
||||
|
||||
let ok = GButton.button ~stock:`OK ~packing: dhbx#add () in
|
||||
List.iter
|
||||
(fun e -> ignore (e#connect#activate ~callback))
|
||||
[ename; e_pos];
|
||||
ok#grab_default ();
|
||||
|
||||
ignore(ok#connect#clicked ~callback:(fun _ -> callback (); dialog#destroy ()));
|
||||
|
||||
(* Update AGL on pos or alt change *)
|
||||
let callback = fun _ ->
|
||||
try
|
||||
set_coordinates ();
|
||||
let wgs84 = self#pos in
|
||||
let agl = ea#value -. (try float (Srtm.of_wgs84 wgs84) with _ -> ground_alt) in
|
||||
agl_lab#set_text (sprintf " AGL: %4.0fm" agl)
|
||||
with _ -> ()
|
||||
in
|
||||
ignore (ea#connect#changed ~callback);
|
||||
ignore (e_pos#connect#changed ~callback);
|
||||
dialog#show ()
|
||||
|
||||
val mutable motion = false
|
||||
method event (ev : GnoCanvas.item_event) =
|
||||
begin
|
||||
match ev with
|
||||
| `BUTTON_PRESS ev ->
|
||||
begin
|
||||
match GdkEvent.Button.button ev with
|
||||
| 1 ->
|
||||
motion <- false;
|
||||
let x = GdkEvent.Button.x ev
|
||||
and y = GdkEvent.Button.y ev in
|
||||
x0 <- x; y0 <- y;
|
||||
let curs = Gdk.Cursor.create `FLEUR in
|
||||
item#grab [`POINTER_MOTION; `BUTTON_RELEASE] curs
|
||||
(GdkEvent.Button.time ev)
|
||||
| _ -> ()
|
||||
end
|
||||
| `MOTION_NOTIFY ev ->
|
||||
let state = GdkEvent.Motion.state ev in
|
||||
if Gdk.Convert.test_modifier `BUTTON1 state then begin
|
||||
motion <- true;
|
||||
let x = GdkEvent.Motion.x ev
|
||||
and y = GdkEvent.Motion.y ev in
|
||||
let dx = geomap#current_zoom *. (x-. x0)
|
||||
and dy = geomap#current_zoom *. (y -. y0) in
|
||||
self#move dx dy ;
|
||||
updated ();
|
||||
if wpts_group#show_moved then
|
||||
moved <- anim moved;
|
||||
x0 <- x; y0 <- y
|
||||
end
|
||||
| `BUTTON_RELEASE ev ->
|
||||
if GdkEvent.Button.button ev = 1 then begin
|
||||
item#ungrab (GdkEvent.Button.time ev);
|
||||
self#edit
|
||||
end
|
||||
| _ -> ()
|
||||
end;
|
||||
true
|
||||
initializer ignore(item#connect#event ~callback:self#event)
|
||||
method moved = moved <> None
|
||||
method reset_moved () =
|
||||
match moved with
|
||||
| None -> ()
|
||||
| Some x ->
|
||||
Glib.Timeout.remove x;
|
||||
item#affine_absolute rotation_45;
|
||||
moved <- None
|
||||
|
||||
method deleted = deleted
|
||||
method item = item
|
||||
method pos = geomap#of_world self#xy
|
||||
method set ?altitude ?(update=false) wgs84 =
|
||||
let (xw, yw) = geomap#world_of wgs84
|
||||
and (xw0, yw0) = self#xy
|
||||
and z = geomap#zoom_adj#value in
|
||||
|
||||
let dx = (xw-.xw0)*.z
|
||||
and dy = (yw-.yw0)*.z
|
||||
and dz = match altitude with Some a -> a -. alt | _ -> 0. in
|
||||
|
||||
let current_ecef = ecef_of_geo WGS84 self#pos self#alt
|
||||
and new_ecef = ecef_of_geo WGS84 wgs84 (alt+.dz) in
|
||||
|
||||
let new_pos = ecef_distance current_ecef new_ecef > 2. in
|
||||
match moved, new_pos with
|
||||
| None, _ ->
|
||||
self#move dx dy;
|
||||
alt <- alt+.dz;
|
||||
if update then updated ()
|
||||
| Some _, true -> ()
|
||||
| Some _, false -> self#reset_moved ()
|
||||
method set_ground_alt ga = ground_alt <- ga
|
||||
method delete () =
|
||||
deleted <- true; (* BOF *)
|
||||
geomap#delete_georef name;
|
||||
wpt_group#destroy ()
|
||||
method zoom (z:float) =
|
||||
if List.length wpt_group#get_items > 0 then
|
||||
let a = wpt_group#i2w_affine in
|
||||
a.(0) <- 1./.z; a.(3) <- 1./.z;
|
||||
wpt_group#affine_absolute a
|
||||
initializer wpt_group#raise_to_top ()
|
||||
initializer self#zoom geomap#zoom_adj#value
|
||||
initializer ignore(geomap#zoom_adj#connect#value_changed ~callback:(fun () -> self#zoom geomap#zoom_adj#value))
|
||||
end
|
||||
|
||||
let gensym = let n = ref 0 in fun prefix -> incr n; prefix ^ string_of_int !n
|
||||
|
||||
let waypoint = fun ?show group ?(name = gensym "wp") ?alt en ->
|
||||
new waypoint ?show group name ?alt en
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
(*
|
||||
* Waypoints objects
|
||||
*
|
||||
* Copyright (C) 2004 CENA/ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
class group :
|
||||
?color:string ->
|
||||
?editable:bool ->
|
||||
?show_moved:bool ->
|
||||
MapCanvas.widget ->
|
||||
object
|
||||
method color : string
|
||||
method editable : bool
|
||||
method show_moved : bool
|
||||
method geomap : MapCanvas.widget
|
||||
method group : GnoCanvas.group
|
||||
end
|
||||
|
||||
class waypoint :
|
||||
?show:bool ->
|
||||
group ->
|
||||
string ->
|
||||
?alt:float ->
|
||||
Latlong.geographic ->
|
||||
object
|
||||
method alt : float
|
||||
method geomap : MapCanvas.widget
|
||||
method delete : unit -> unit
|
||||
method edit : unit
|
||||
method pos : Latlong.geographic
|
||||
method event : GnoCanvas.item_event -> bool
|
||||
method item : GnoCanvas.rect
|
||||
method label : ContrastLabel.widget
|
||||
method move : float -> float -> unit
|
||||
method name : string
|
||||
method set : ?altitude:float -> ?update:bool -> Latlong.geographic -> unit
|
||||
method set_ground_alt : float -> unit
|
||||
method set_name : string -> unit
|
||||
method xy : float * float
|
||||
method zoom : float -> unit
|
||||
method moved : bool
|
||||
method reset_moved : unit -> unit
|
||||
method deleted : bool
|
||||
method connect : (unit -> unit) -> unit
|
||||
method set_commit_callback : (unit -> unit) -> unit
|
||||
end
|
||||
|
||||
|
||||
val waypoint : ?show:bool -> group -> ?name:string -> ?alt:float -> Latlong.geographic -> waypoint
|
||||
@@ -1,32 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <caml/mlvalues.h>
|
||||
#include <caml/alloc.h>
|
||||
#include <caml/memory.h>
|
||||
#include <caml/callback.h>
|
||||
#include <caml/fail.h>
|
||||
|
||||
extern value Val_GtkTreePath(GtkTreePath*);
|
||||
|
||||
#define Pointer_val(val) ((void*)Field(val,1))
|
||||
|
||||
#ifdef G_DISABLE_CAST_CHECKS
|
||||
#define check_cast(f,v) f(Pointer_val(v))
|
||||
#else
|
||||
#define check_cast(f,v) (Pointer_val(v) == NULL ? NULL : f(Pointer_val(v)))
|
||||
#endif
|
||||
|
||||
#define GtkTreeView_val(val) check_cast(GTK_TREE_VIEW,val)
|
||||
|
||||
CAMLprim value
|
||||
ml_gtk_tree_view_get_drag_dest_row(value val_tree) {
|
||||
CAMLparam0();
|
||||
CAMLlocal1(ret);
|
||||
GtkTreePath *path;
|
||||
GtkTreeViewDropPosition pos;
|
||||
gtk_tree_view_get_drag_dest_row(GtkTreeView_val(val_tree), &path, &pos);
|
||||
ret = alloc_tuple(2);
|
||||
Store_field(ret,0,Val_GtkTreePath(path));
|
||||
Store_field(ret,1,Val_int(pos));
|
||||
CAMLreturn(ret);
|
||||
}
|
||||
@@ -1,423 +0,0 @@
|
||||
(*
|
||||
* Paparazzi widgets
|
||||
*
|
||||
* Copyright (C) 2008 ENAC
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
open Printf
|
||||
|
||||
module PC = Papget_common
|
||||
module PR = Papget_renderer
|
||||
module E = Expr_syntax
|
||||
let (//) = Filename.concat
|
||||
|
||||
class type item = object
|
||||
method config : unit -> Xml.xml
|
||||
method deleted : bool
|
||||
end
|
||||
|
||||
class type value =
|
||||
object
|
||||
method last_value : string
|
||||
method connect : (string -> unit) -> unit
|
||||
method config : unit -> Xml.xml list
|
||||
method type_ : string
|
||||
end
|
||||
|
||||
|
||||
|
||||
(** [index_of_fields s] Returns i if s matches x[i] else 0. *)
|
||||
let base_and_index =
|
||||
let field_regexp = Str.regexp "\\([^\\.]+\\)\\[\\([0-9]+\\)\\]" in
|
||||
fun field_descr ->
|
||||
if Str.string_match field_regexp field_descr 0 then
|
||||
( Str.matched_group 1 field_descr,
|
||||
int_of_string (Str.matched_group 2 field_descr))
|
||||
else
|
||||
(field_descr, 0)
|
||||
|
||||
|
||||
class message_field = fun ?sender ?(class_name="telemetry") msg_name field_descr ->
|
||||
object
|
||||
val mutable callbacks = []
|
||||
val mutable last_value = "0."
|
||||
|
||||
method last_value = last_value
|
||||
|
||||
method connect = fun cb -> callbacks <- cb :: callbacks
|
||||
method config = fun () ->
|
||||
let field = sprintf "%s:%s" msg_name field_descr in
|
||||
let ac_id = match sender with None -> [] | Some id -> [PC.property "ac_id" id] in
|
||||
[ PC.property "field" field ] @ ac_id
|
||||
method type_ = "message_field"
|
||||
|
||||
initializer
|
||||
let module P = PprzLink.Messages (struct let name = class_name end) in
|
||||
let process_message = fun _sender values ->
|
||||
let (field_name, index) = base_and_index field_descr in
|
||||
let value =
|
||||
match PprzLink.assoc field_name values with
|
||||
PprzLink.Array array -> array.(index)
|
||||
| scalar -> scalar in
|
||||
|
||||
last_value <- PprzLink.string_of_value value;
|
||||
|
||||
List.iter (fun cb -> cb last_value) callbacks in
|
||||
ignore (P.message_bind ?sender msg_name process_message)
|
||||
end
|
||||
|
||||
|
||||
let hash_vars = fun ?sender expr ->
|
||||
let htable = Hashtbl.create 3 in
|
||||
let rec loop = function
|
||||
E.Ident i -> prerr_endline i
|
||||
| E.Int _ | E.Float _ -> ()
|
||||
| E.Call (_id, list) | E.CallOperator (_id, list) -> List.iter loop list
|
||||
| E.Index (_id, e) -> loop e
|
||||
| E.Deref (_e, _f) as deref -> fprintf stderr "Warning: Deref operator is not allowed in Papgets expressions (%s)" (E.sprint deref)
|
||||
| E.Field (i, f) ->
|
||||
if not (Hashtbl.mem htable (i,f)) then
|
||||
let msg_obj = new message_field ?sender i f in
|
||||
Hashtbl.add htable (i, f) msg_obj in
|
||||
loop expr;
|
||||
htable
|
||||
|
||||
|
||||
let wrap = fun f ->
|
||||
fun x y -> string_of_float (f (float_of_string x) (float_of_string y))
|
||||
let eval_bin_op = function
|
||||
| "*" -> wrap ( *. )
|
||||
| "+" -> wrap ( +. )
|
||||
| "-" -> wrap ( -. )
|
||||
| "/" -> wrap ( /. )
|
||||
| "**" -> wrap ( ** )
|
||||
| op -> failwith (sprintf "Papget.eval_expr '%s'" op)
|
||||
|
||||
let eval_expr = fun (extra_functions:(string * (string list -> string)) list) h e ->
|
||||
let rec loop = function
|
||||
E.Ident ident -> failwith (sprintf "Papget.eval_expr '%s'" ident)
|
||||
| E.Int int -> string_of_int int
|
||||
| E.Float float -> string_of_float float
|
||||
| E.CallOperator (ident, [e1; e2]) ->
|
||||
eval_bin_op ident (loop e1) (loop e2)
|
||||
| E.Call (ident, args) when List.mem_assoc ident extra_functions ->
|
||||
(List.assoc ident extra_functions) (List.map loop args)
|
||||
| E.Call (ident, _l) | E.CallOperator (ident, _l) ->
|
||||
failwith (sprintf "Papget.eval_expr '%s(...)'" ident)
|
||||
| E.Index (ident, _e) -> failwith (sprintf "Papget.eval_expr '%s[...]'" ident)
|
||||
| E.Deref (_e, _f) as deref -> failwith (sprintf "Papget.eval_expr Deref operator is not allowed in Papgets expressions (%s)" (E.sprint deref))
|
||||
| E.Field (i, f) ->
|
||||
try
|
||||
(Hashtbl.find h (i,f))#last_value
|
||||
with
|
||||
Not_found -> failwith (sprintf "Papget.eval_expr '%s.%s'" i f)
|
||||
in loop e
|
||||
|
||||
|
||||
|
||||
class expression = fun ?(extra_functions=[]) ?sender expr ->
|
||||
let h = hash_vars ?sender expr in
|
||||
object
|
||||
val mutable callbacks = []
|
||||
val mutable last_value = "0."
|
||||
|
||||
method last_value = last_value
|
||||
|
||||
method connect = fun cb -> callbacks <- cb :: callbacks
|
||||
|
||||
method config = fun () ->
|
||||
let ac_id = match sender with None -> [] | Some id -> [PC.property "ac_id" id] in
|
||||
[ PC.property "expr" (Expr_syntax.sprint expr)] @ ac_id
|
||||
|
||||
method type_ = "expression"
|
||||
|
||||
initializer
|
||||
Hashtbl.iter
|
||||
(fun (i,f) (msg_obj:value) ->
|
||||
let val_updated = fun _new_val ->
|
||||
last_value <- eval_expr extra_functions h expr;
|
||||
List.iter (fun cb -> cb last_value) callbacks
|
||||
in
|
||||
msg_obj#connect val_updated)
|
||||
h
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
class type canvas_item_type =
|
||||
object
|
||||
method connect : unit -> unit
|
||||
method deleted : bool
|
||||
method edit : unit -> unit
|
||||
method event : GnoCanvas.item_event -> bool
|
||||
method renderer : Papget_renderer.t
|
||||
method update : string -> unit
|
||||
method xy : float * float
|
||||
end
|
||||
|
||||
|
||||
class canvas_item = fun ~config canvas_renderer ->
|
||||
let canvas_renderer = (canvas_renderer :> PR.t) in
|
||||
object (self)
|
||||
val mutable motion = false
|
||||
val mutable renderer = canvas_renderer
|
||||
val mutable x_press = 0.
|
||||
val mutable y_press = 0.
|
||||
val mutable deleted = false
|
||||
val mutable dialog_widget = None
|
||||
|
||||
method renderer = renderer
|
||||
|
||||
method xy =
|
||||
let (x0, y0) = renderer#item#i2w ~x:0. ~y:0. in
|
||||
renderer#item#parent#w2i ~x:x0 ~y:y0
|
||||
|
||||
method deleted = deleted
|
||||
|
||||
method update = fun value ->
|
||||
try
|
||||
(renderer#update:string->unit) value
|
||||
with
|
||||
exc -> prerr_endline (Printexc.to_string exc)
|
||||
|
||||
method event = fun (ev : GnoCanvas.item_event) ->
|
||||
let item = (renderer#item :> PR.movable_item) in
|
||||
match ev with
|
||||
`BUTTON_PRESS ev ->
|
||||
begin
|
||||
match GdkEvent.Button.button ev with
|
||||
| 1 ->
|
||||
motion <- false;
|
||||
let x = GdkEvent.Button.x ev and y = GdkEvent.Button.y ev in
|
||||
let (xm, ym) = renderer#item#parent#w2i ~x ~y in
|
||||
let (x0, y0) = renderer#item#i2w ~x:0. ~y:0. in
|
||||
let (xi, yi) = renderer#item#parent#w2i ~x:x0 ~y:y0 in
|
||||
x_press <- xm -. xi; y_press <- ym -. yi;
|
||||
let curs = Gdk.Cursor.create `FLEUR in
|
||||
item#grab [`POINTER_MOTION; `BUTTON_RELEASE] curs
|
||||
(GdkEvent.Button.time ev)
|
||||
| _ -> ()
|
||||
end;
|
||||
true
|
||||
| `MOTION_NOTIFY ev ->
|
||||
let state = GdkEvent.Motion.state ev in
|
||||
if Gdk.Convert.test_modifier `BUTTON1 state then begin
|
||||
motion <- true;
|
||||
let x = GdkEvent.Motion.x ev
|
||||
and y = GdkEvent.Motion.y ev in
|
||||
let (xw, yw) = renderer#item#parent#w2i ~x ~y in
|
||||
item#set [`X (xw-.x_press); `Y (yw-.y_press)];
|
||||
renderer#item#parent#affine_relative [|1.;0.;0.;1.;0.;0.|]
|
||||
end;
|
||||
true
|
||||
| `BUTTON_RELEASE ev ->
|
||||
if GdkEvent.Button.button ev = 1 then begin
|
||||
item#ungrab (GdkEvent.Button.time ev);
|
||||
(* get item and window size *)
|
||||
let bounds = item#get_bounds in
|
||||
let w, h = Gdk.Drawable.get_size item#canvas#misc#window in
|
||||
if not motion then begin
|
||||
self#edit ()
|
||||
end
|
||||
else if (truncate bounds.(0) > w) || (truncate bounds.(2) < 0) || (truncate bounds.(1) > h) || (truncate bounds.(3) < 0) then begin
|
||||
(* delete an item if placed out of the window on the left or top side *)
|
||||
item#destroy ();
|
||||
deleted <- true
|
||||
end;
|
||||
motion <- false
|
||||
end;
|
||||
true
|
||||
| _ -> false
|
||||
|
||||
method edit = fun () ->
|
||||
let file = Env.paparazzi_src // "sw" // "lib" // "ocaml" // "widgets.glade" in
|
||||
let dialog = new Gtk_papget_editor.papget_editor ~file () in
|
||||
|
||||
let ac_id = PC.get_prop "ac_id" config "Any" in
|
||||
dialog#toplevel#set_title ("Papget Editor (A/C: "^ac_id^")");
|
||||
|
||||
let tagged_renderers = Lazy.force PR.lazy_tagged_renderers in
|
||||
let strings = List.map fst tagged_renderers in
|
||||
|
||||
let (combo, (tree, column)) = GEdit.combo_box_text ~packing:dialog#box_item_chooser#add ~strings () in
|
||||
tree#foreach
|
||||
(fun _path row ->
|
||||
if tree#get ~row ~column = renderer#tag then begin
|
||||
combo#set_active_iter (Some row);
|
||||
true
|
||||
end else
|
||||
false);
|
||||
|
||||
let connect_item_editor = fun () ->
|
||||
begin (* Remove the current child ? *)
|
||||
try
|
||||
let child = dialog#box_item_editor#child in
|
||||
dialog#box_item_editor#remove child
|
||||
with
|
||||
Gpointer.Null -> ()
|
||||
end;
|
||||
renderer#edit dialog#box_item_editor#add in
|
||||
|
||||
connect_item_editor ();
|
||||
|
||||
(* Connect the renderer chooser *)
|
||||
ignore (combo#connect#changed
|
||||
~callback:(fun () ->
|
||||
match combo#active_iter with
|
||||
| None -> ()
|
||||
| Some row ->
|
||||
let data = combo#model#get ~row ~column in
|
||||
if data <> renderer#tag then
|
||||
let new_renderer = List.assoc data tagged_renderers in
|
||||
let group = renderer#item#parent in
|
||||
let (x, y) = renderer#item#i2w ~x:0. ~y:0. in
|
||||
let (x, y) = group#w2i ~x ~y in
|
||||
renderer#item#destroy ();
|
||||
renderer <- new_renderer group x y;
|
||||
self#connect ();
|
||||
connect_item_editor ()));
|
||||
|
||||
(* Connect the buttons *)
|
||||
ignore (dialog#button_delete#connect#clicked
|
||||
~callback:(fun () ->
|
||||
dialog#papget_editor#destroy ();
|
||||
renderer#item#destroy ();
|
||||
deleted <- true));
|
||||
ignore (dialog#button_ok#connect#clicked ~callback:(fun () -> dialog#papget_editor#destroy ()));
|
||||
|
||||
dialog_widget <- Some dialog
|
||||
|
||||
val mutable connection =
|
||||
canvas_renderer#item#connect#event ~callback:(fun _ -> false)
|
||||
method connect = fun () ->
|
||||
if PC.get_prop "locked" config "false" = "false" then
|
||||
let item = (renderer#item :> PR.movable_item) in
|
||||
connection <- item#connect#event ~callback:self#event
|
||||
|
||||
initializer
|
||||
self#connect ()
|
||||
end
|
||||
|
||||
class canvas_float_item = fun ~config canvas_renderer ->
|
||||
object
|
||||
inherit canvas_item ~config canvas_renderer as super
|
||||
|
||||
val mutable affine = "1"
|
||||
|
||||
method update = fun value ->
|
||||
let scaled_value =
|
||||
try
|
||||
let (a, b) = Ocaml_tools.affine_transform affine
|
||||
and fvalue = float_of_string value in
|
||||
string_of_float (fvalue *. a +. b)
|
||||
with
|
||||
_ -> value in
|
||||
super#update scaled_value
|
||||
|
||||
method edit = fun () ->
|
||||
super#edit ();
|
||||
match dialog_widget with
|
||||
None -> ()
|
||||
| Some dialog ->
|
||||
(* Set the current value *)
|
||||
dialog#entry_scale#set_text affine;
|
||||
(* Connect the scale entry *)
|
||||
let callback = fun () ->
|
||||
affine <- dialog#entry_scale#text in
|
||||
ignore (dialog#entry_scale#connect#activate ~callback);
|
||||
dialog#hbox_scale#misc#show ()
|
||||
end
|
||||
|
||||
|
||||
class canvas_display_float_item = fun ~config (msg_obj:value) (canvas_renderer:PR.t) ->
|
||||
object (self)
|
||||
inherit canvas_float_item ~config canvas_renderer as item
|
||||
|
||||
initializer
|
||||
affine <- PC.get_prop "scale" config "1";
|
||||
msg_obj#connect self#update_field
|
||||
|
||||
method update_field = fun value ->
|
||||
if not deleted then begin
|
||||
item#update value
|
||||
end
|
||||
|
||||
method config = fun () ->
|
||||
let renderer_props = renderer#config ()
|
||||
and val_props = msg_obj#config ()
|
||||
and scale_prop = PC.property "scale" affine in
|
||||
let (x, y) = item#xy in
|
||||
let attrs =
|
||||
[ "type", msg_obj#type_;
|
||||
"display", String.lowercase_ascii item#renderer#tag;
|
||||
"x", sprintf "%.0f" x; "y", sprintf "%.0f" y ] in
|
||||
Xml.Element ("papget", attrs, scale_prop::val_props@renderer_props)
|
||||
end
|
||||
|
||||
|
||||
(****************************************************************************)
|
||||
(** A clickable item is not editable: The #edit method is overiden with a
|
||||
provided callback *)
|
||||
class canvas_clickable_item = fun type_ properties callback canvas_renderer ->
|
||||
object
|
||||
inherit canvas_item ~config:properties canvas_renderer as item
|
||||
method edit = fun () -> callback ()
|
||||
|
||||
method config = fun () ->
|
||||
let props = renderer#config () in
|
||||
let (x, y) = item#xy in
|
||||
let attrs =
|
||||
[ "type", type_;
|
||||
"display", String.lowercase_ascii item#renderer#tag;
|
||||
"x", sprintf "%.0f" x; "y", sprintf "%.0f" y ] in
|
||||
Xml.Element ("papget", attrs, properties@props)
|
||||
end
|
||||
|
||||
|
||||
class canvas_goto_block_item = fun properties callback (canvas_renderer:PR.t) ->
|
||||
object
|
||||
inherit canvas_clickable_item "goto_block" properties callback canvas_renderer as item
|
||||
end
|
||||
|
||||
class canvas_variable_setting_item = fun properties callback (canvas_renderer:PR.t) ->
|
||||
object
|
||||
inherit canvas_clickable_item "variable_setting" properties callback canvas_renderer
|
||||
end
|
||||
|
||||
|
||||
|
||||
(****************************************************************************)
|
||||
class canvas_video_plugin_item = fun properties (canvas_renderer:PR.t) (adj:GData.adjustment) ->
|
||||
object (self)
|
||||
inherit canvas_item ~config:properties canvas_renderer as item
|
||||
method update_zoom = fun zoom ->
|
||||
item#update zoom
|
||||
method config = fun () ->
|
||||
let props = renderer#config () in
|
||||
let (x, y) = item#xy in
|
||||
let attrs =
|
||||
[ "type", "video_plugin";
|
||||
"display", String.lowercase_ascii item#renderer#tag;
|
||||
"x", sprintf "%.0f" x; "y", sprintf "%.0f" y ] in
|
||||
Xml.Element ("papget", attrs, properties@props)
|
||||
initializer ignore(adj#connect#value_changed ~callback:(fun () -> self#update_zoom (string_of_float adj#value)))
|
||||
end
|
||||
@@ -1,123 +0,0 @@
|
||||
(*
|
||||
* Paparazzi widgets
|
||||
*
|
||||
* Copyright (C) 2008 ENAC
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
class type item =
|
||||
object
|
||||
method config : unit -> Xml.xml
|
||||
method deleted : bool
|
||||
end
|
||||
|
||||
class type value =
|
||||
object
|
||||
method last_value : string
|
||||
method connect : (string -> unit) -> unit
|
||||
method config : unit -> Xml.xml list
|
||||
method type_ : string
|
||||
end
|
||||
|
||||
class message_field :
|
||||
?sender:string ->
|
||||
?class_name:string ->
|
||||
string ->
|
||||
string ->
|
||||
value
|
||||
|
||||
class expression :
|
||||
?extra_functions:(string * (string list -> string)) list ->
|
||||
?sender:string ->
|
||||
Expr_syntax.expression ->
|
||||
value
|
||||
|
||||
class type canvas_item_type =
|
||||
object
|
||||
method connect : unit -> unit
|
||||
method deleted : bool
|
||||
method edit : unit -> unit
|
||||
method event : GnoCanvas.item_event -> bool
|
||||
method renderer : Papget_renderer.t
|
||||
method update : string -> unit
|
||||
method xy : float * float
|
||||
end
|
||||
|
||||
class canvas_display_float_item :
|
||||
config:Xml.xml list ->
|
||||
value ->
|
||||
Papget_renderer.t ->
|
||||
object
|
||||
inherit canvas_item_type
|
||||
|
||||
method config : unit -> Xml.xml
|
||||
method connect : unit -> unit
|
||||
method update_field : string -> unit
|
||||
end
|
||||
|
||||
class canvas_goto_block_item :
|
||||
Xml.xml list ->
|
||||
(unit -> unit) ->
|
||||
Papget_renderer.t ->
|
||||
object
|
||||
method config : unit -> Xml.xml
|
||||
method connect : unit -> unit
|
||||
method deleted : bool
|
||||
method edit : unit -> unit
|
||||
method event : GnoCanvas.item_event -> bool
|
||||
method renderer : Papget_renderer.t
|
||||
method update : string -> unit
|
||||
method xy : float * float
|
||||
end
|
||||
|
||||
class canvas_variable_setting_item :
|
||||
Xml.xml list ->
|
||||
(unit -> unit) ->
|
||||
Papget_renderer.t ->
|
||||
object
|
||||
method config : unit -> Xml.xml
|
||||
method connect : unit -> unit
|
||||
method deleted : bool
|
||||
method edit : unit -> unit
|
||||
method event : GnoCanvas.item_event -> bool
|
||||
method renderer : Papget_renderer.t
|
||||
method update : string -> unit
|
||||
method xy : float * float
|
||||
end
|
||||
|
||||
class canvas_video_plugin_item :
|
||||
Xml.xml list ->
|
||||
Papget_renderer.t ->
|
||||
GData.adjustment ->
|
||||
object
|
||||
inherit canvas_item_type
|
||||
method config : unit -> Xml.xml
|
||||
method update_zoom : string -> unit
|
||||
(*
|
||||
|
||||
method connect : unit -> unit
|
||||
method deleted : bool
|
||||
method edit : unit -> unit
|
||||
method event : GnoCanvas.item_event -> bool
|
||||
method renderer : Papget_renderer.t
|
||||
method xy : float * float
|
||||
*)
|
||||
end
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
(*
|
||||
* Commons for papgets
|
||||
*
|
||||
* Copyright (C) 2008 ENAC
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
let get_property = fun attr_name xml ->
|
||||
let attr = ExtXml.child ~select:(fun x -> ExtXml.attrib x "name" = attr_name) xml "property" in
|
||||
ExtXml.attrib attr "value"
|
||||
|
||||
|
||||
let get_prop = fun name children default ->
|
||||
let xml = Xml.Element ("", [], children) in
|
||||
try get_property name xml with _ -> default
|
||||
|
||||
let property = fun name value ->
|
||||
Xml.Element("property", [ "name", name; "value", value ], [])
|
||||
|
||||
let xml = fun type_ display_ properties ->
|
||||
Xml.Element ("papget", ["type", type_; "display", display_],
|
||||
List.map (fun (x, y) -> property x y) properties)
|
||||
|
||||
let float_property = fun name value ->
|
||||
property name (string_of_float value)
|
||||
|
||||
let dnd_source = fun (widget:GObj.widget) papget_xml ->
|
||||
let dnd_targets = [ { Gtk.target = "STRING"; flags = []; info = 0} ] in
|
||||
widget#drag#source_set dnd_targets ~modi:[`BUTTON1] ~actions:[`COPY];
|
||||
let data_get = fun _ (sel:GObj.selection_context) ~info ~time ->
|
||||
sel#return (Xml.to_string papget_xml) in
|
||||
ignore (widget#drag#connect#data_get ~callback:data_get);
|
||||
@@ -1,34 +0,0 @@
|
||||
(*
|
||||
* Commons for papgets
|
||||
*
|
||||
* Copyright (C) 2008 ENAC
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
val get_property : string -> Xml.xml -> string
|
||||
(** [get_property name config] *)
|
||||
|
||||
val get_prop : string -> Xml.xml list -> string -> string
|
||||
(** [get_prop name config_list default_value] *)
|
||||
|
||||
val property : string -> string -> Xml.xml
|
||||
val xml : string -> string -> (string * string) list -> Xml.xml
|
||||
val float_property : string -> float -> Xml.xml
|
||||
val dnd_source : GObj.widget -> Xml.xml -> unit
|
||||
@@ -1,392 +0,0 @@
|
||||
(*
|
||||
* Paparazzi widget renderers
|
||||
*
|
||||
* Copyright (C) 2008-2009 ENAC, Pascal Brisset
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
open Printf
|
||||
module PC = Papget_common
|
||||
let (//) = Filename.concat
|
||||
|
||||
class type movable_item =
|
||||
object
|
||||
inherit GnoCanvas.base_item
|
||||
method set : GnomeCanvas.group_p list -> unit
|
||||
end
|
||||
|
||||
class type t =
|
||||
object
|
||||
method tag : string
|
||||
method edit : (GObj.widget -> unit) -> unit
|
||||
method item : movable_item
|
||||
method update : string -> unit
|
||||
method config : unit -> Xml.xml list
|
||||
end
|
||||
|
||||
|
||||
(*************************** Text ***********************************)
|
||||
class canvas_text = fun ?(config=[]) canvas_group x y ->
|
||||
let group = GnoCanvas.group ~x ~y canvas_group in
|
||||
let text = GnoCanvas.text ~text:"_" group in
|
||||
object (self)
|
||||
val mutable format = PC.get_prop "format" config "%.2f"
|
||||
val mutable size = float_of_string (PC.get_prop "size" config "15.")
|
||||
val mutable color = PC.get_prop "color" config "#00ff00"
|
||||
|
||||
method tag = "Text"
|
||||
method item = (group :> movable_item)
|
||||
method config = fun () ->
|
||||
[ PC.property "format" format;
|
||||
PC.float_property "size" size;
|
||||
PC.property "color" color ]
|
||||
method update = fun (value : string) ->
|
||||
let renderer = fun x ->
|
||||
try sprintf (Scanf.format_from_string format "%f") (float_of_string x) with _ -> x in
|
||||
text#set [`SIZE_POINTS size; `TEXT (renderer value); `FILL_COLOR color; `ANCHOR `NW]
|
||||
|
||||
|
||||
method edit = fun (pack:GObj.widget -> unit) ->
|
||||
let file = Env.paparazzi_src // "sw" // "lib" // "ocaml" // "widgets.glade" in
|
||||
let text_editor = new Gtk_papget_text_editor.table_text_editor ~file () in
|
||||
pack text_editor#table_text_editor#coerce;
|
||||
|
||||
(* Initialize the entries *)
|
||||
text_editor#entry_format#set_text format;
|
||||
text_editor#spinbutton_size#set_value size;
|
||||
text_editor#comboboxentry_color#set_active 0;
|
||||
|
||||
(* Connect the entries *)
|
||||
let callback = fun () ->
|
||||
format <- text_editor#entry_format#text in
|
||||
ignore (text_editor#entry_format#connect#activate ~callback);
|
||||
let callback = fun () ->
|
||||
size <- text_editor#spinbutton_size#value in
|
||||
ignore (text_editor#spinbutton_size#connect#value_changed ~callback);
|
||||
let callback = fun () ->
|
||||
color <- text_editor#comboboxentry_color#entry#text in
|
||||
ignore (text_editor#comboboxentry_color#connect#changed ~callback);
|
||||
end
|
||||
|
||||
|
||||
(***************************Vertical Ruler ***********************************)
|
||||
let affine_pos_and_angle xw yw angle =
|
||||
let cos_a = cos angle in
|
||||
let sin_a = sin angle in
|
||||
[| cos_a ; sin_a ; ~-. sin_a; cos_a; xw ; yw |]
|
||||
let affine_pos xw yw = affine_pos_and_angle xw yw 0.
|
||||
|
||||
|
||||
class canvas_ruler = fun ?(config=[]) canvas_group x y ->
|
||||
let h = float_of_string (PC.get_prop "height" config "100.")
|
||||
and index_on_right = bool_of_string (PC.get_prop "index_on_right" config "false")
|
||||
and point_per_unit = float_of_string (PC.get_prop "point_per_unit" config "2.")
|
||||
and w = float_of_string (PC.get_prop "width" config "32.")
|
||||
and step = int_of_string (PC.get_prop "step" config "10") in
|
||||
let text_props=[`ANCHOR `CENTER; `FILL_COLOR "white"]
|
||||
and index_width = 10. in
|
||||
|
||||
let root = GnoCanvas.group ~x ~y canvas_group in
|
||||
let r = GnoCanvas.group root in
|
||||
|
||||
let props = (text_props@[`ANCHOR `EAST]) in
|
||||
|
||||
(* One step drawer *)
|
||||
let draw = fun i value ->
|
||||
let i = i * step in
|
||||
let y = -. point_per_unit *. (float i -. value) in
|
||||
if y >= -. h && y <= h then begin
|
||||
let text = Printf.sprintf "%d" i in
|
||||
ignore (GnoCanvas.text ~text ~props ~y ~x:(w*.0.75) r);
|
||||
ignore (GnoCanvas.line ~points:[|w*.0.8;y;w-.1.;y|] ~fill_color:"white" r)
|
||||
end;
|
||||
let y = y -. float step /. 2. *. point_per_unit in
|
||||
if y >= -. h && y <= h then
|
||||
ignore(GnoCanvas.line ~points:[|w*.0.8;y;w-.1.;y|] ~fill_color:"white" r)
|
||||
in
|
||||
|
||||
let drawer = fun value ->
|
||||
(* Remove previous items *)
|
||||
List.iter (fun i -> i#destroy ()) r#get_items;
|
||||
let v = truncate value / step in
|
||||
let k = truncate (h /. point_per_unit) / step in
|
||||
for i = max 0 (v - k) to (v + k) do
|
||||
draw i value
|
||||
done
|
||||
in
|
||||
|
||||
(** Yellow index *)
|
||||
let _ = GnoCanvas.line ~points:[|0.;0.;w-.1.;0.|] ~fill_color:"yellow" root in
|
||||
let s = index_width in
|
||||
let idx = GnoCanvas.polygon ~points:[|0.;0.;-.s;s/.2.;-.s;-.s/.2.|] ~fill_color:"yellow" root in
|
||||
let () =
|
||||
if index_on_right then
|
||||
idx#affine_absolute (affine_pos_and_angle w 0. Latlong.pi) in
|
||||
|
||||
object
|
||||
method tag = "Ruler"
|
||||
method edit = fun (pack:GObj.widget -> unit) -> ()
|
||||
method update = fun value ->
|
||||
let value = float_of_string value in
|
||||
drawer value
|
||||
method item = (root :> movable_item)
|
||||
method config = fun () ->
|
||||
[ PC.float_property "height" h;
|
||||
PC.property "index_on_right" (sprintf "%b" index_on_right);
|
||||
PC.float_property "width" w;
|
||||
PC.float_property "point_per_unit" point_per_unit;
|
||||
PC.property "step" (sprintf "%d" step) ]
|
||||
end
|
||||
|
||||
(*************************** Gauge ***********************************)
|
||||
class canvas_gauge = fun ?(config=[]) canvas_group x y ->
|
||||
let size = PC.get_prop "size" config "50." in
|
||||
(*let text_props = [`ANCHOR `CENTER; `FILL_COLOR "white"] in*)
|
||||
|
||||
let r1 = max 10. ((float_of_string size) /. 2.) in
|
||||
let r2 = r1 +. 3. in
|
||||
let r3 = 3.5 in
|
||||
let max_rot = 2. *. Latlong.pi /. 3. in
|
||||
|
||||
let root = GnoCanvas.group ~x ~y canvas_group in
|
||||
(*let gauge = GnoCanvas.group root in*)
|
||||
|
||||
(*let props = (text_props@[`ANCHOR `EAST]) in*)
|
||||
|
||||
let _ = GnoCanvas.ellipse ~x1:r2 ~y1:r2 ~x2:(-.r2) ~y2:(-.r2)
|
||||
~props:[`NO_FILL_COLOR; `OUTLINE_COLOR "grey"; `WIDTH_PIXELS 6] root in
|
||||
let points = [|0.;-.r1;0.;-.r1+.3.|] in
|
||||
let props = [`WIDTH_PIXELS 2; `FILL_COLOR "red"] in
|
||||
let _ = GnoCanvas.line ~points ~props root in
|
||||
let il = GnoCanvas.line ~points ~props root in
|
||||
let () = il#affine_absolute (affine_pos_and_angle 0. 0. (-. Latlong.pi /. 3.)) in
|
||||
let ill = GnoCanvas.line ~points ~props root in
|
||||
let () = ill#affine_absolute (affine_pos_and_angle 0. 0. (-. 2. *. Latlong.pi /. 3.)) in
|
||||
let ir = GnoCanvas.line ~points ~props root in
|
||||
let () = ir#affine_absolute (affine_pos_and_angle 0. 0. (Latlong.pi /. 3.)) in
|
||||
let irr = GnoCanvas.line ~points ~props root in
|
||||
let () = irr#affine_absolute (affine_pos_and_angle 0. 0. (2. *. Latlong.pi /. 3.)) in
|
||||
|
||||
let idx = GnoCanvas.polygon ~points:[|r3-.0.2;0.;0.;-.r1;-.(r3-.0.2);0.|]
|
||||
~props:[`FILL_COLOR "red"; `OUTLINE_COLOR "white"] root in
|
||||
let _ = GnoCanvas.ellipse ~x1:r3 ~y1:r3 ~x2:(-.r3) ~y2:(-.r3) ~props:[`OUTLINE_COLOR "grey"] ~fill_color:"red" root in
|
||||
let text_min = GnoCanvas.text ~x:(-.r1) ~y:(r1/.2.) ~props:[`ANCHOR `NE; `FILL_COLOR "#00ff00"] root in
|
||||
let text_max = GnoCanvas.text ~x:r1 ~y:(r1/.2.) ~props:[`ANCHOR `NW; `FILL_COLOR "#00ff00"] root in
|
||||
let text_mid = GnoCanvas.text ~x:0. ~y:(-.r2-.3.) ~props:[`ANCHOR `SOUTH; `FILL_COLOR "#00ff00"] root in
|
||||
let text_text = GnoCanvas.text ~x:0. ~y:(r2+.3.) ~props:[`ANCHOR `NORTH; `FILL_COLOR "#00ff00"] root in
|
||||
|
||||
object
|
||||
val mutable min = PC.get_prop "min" config "-50."
|
||||
val mutable max = PC.get_prop "max" config "50."
|
||||
val mutable text = PC.get_prop "text" config ""
|
||||
|
||||
method tag = "Gauge"
|
||||
method edit = fun (pack:GObj.widget -> unit) ->
|
||||
let file = Env.paparazzi_src // "sw" // "lib" // "ocaml" // "widgets.glade" in
|
||||
let gauge_editor = new Gtk_papget_gauge_editor.table_gauge_editor ~file () in
|
||||
pack gauge_editor#table_gauge_editor#coerce;
|
||||
|
||||
(* Initialize the entries *)
|
||||
gauge_editor#entry_min#set_text min;
|
||||
gauge_editor#entry_max#set_text max;
|
||||
gauge_editor#entry_text#set_text text;
|
||||
|
||||
(* Connect the entries *)
|
||||
let callback = fun () ->
|
||||
min <- gauge_editor#entry_min#text in
|
||||
ignore (gauge_editor#entry_min#connect#activate ~callback);
|
||||
let callback = fun () ->
|
||||
max <- gauge_editor#entry_max#text in
|
||||
ignore (gauge_editor#entry_max#connect#activate ~callback);
|
||||
let callback = fun () ->
|
||||
text <- gauge_editor#entry_text#text in
|
||||
ignore (gauge_editor#entry_text#connect#activate ~callback);
|
||||
|
||||
method update = fun value ->
|
||||
let value = float_of_string value in
|
||||
(* Gauge drawer *)
|
||||
let fmin = float_of_string min in
|
||||
let fmax = float_of_string max in
|
||||
let rot = ref (-.max_rot +. 2. *. max_rot *. (value -. fmin) /. (fmax -. fmin)) in
|
||||
if !rot > max_rot then rot := max_rot;
|
||||
if !rot < -.max_rot then rot := -.max_rot;
|
||||
idx#affine_absolute (affine_pos_and_angle 0. 0. !rot);
|
||||
text_min#set [`TEXT min];
|
||||
text_max#set [`TEXT max];
|
||||
text_mid#set [`TEXT (string_of_float ((fmin +. fmax)/.2.))];
|
||||
text_text#set [`TEXT text]
|
||||
|
||||
method item = (root :> movable_item)
|
||||
method config = fun () ->
|
||||
[ PC.property "min" min;
|
||||
PC.property "max" max;
|
||||
PC.property "size" size;
|
||||
PC.property "text" text ]
|
||||
end
|
||||
|
||||
(*************************** Led ***********************************)
|
||||
class canvas_led = fun ?(config=[]) canvas_group x y ->
|
||||
let size = float_of_string (PC.get_prop "size" config "15.") in
|
||||
|
||||
let root = GnoCanvas.group ~x ~y canvas_group in
|
||||
|
||||
let r = (max 2. (size /. 2.)) +. 1. in
|
||||
let led = GnoCanvas.ellipse ~x1:r ~y1:r ~x2:(-.r) ~y2:(-.r)
|
||||
~props:[`NO_FILL_COLOR; `OUTLINE_COLOR "grey"; `WIDTH_UNITS 2.] root in
|
||||
|
||||
let led_text = GnoCanvas.text ~x:(-.r-.3.) ~y:0. ~props:[`ANCHOR `EAST; `FILL_COLOR "#00ff00"] root in
|
||||
|
||||
object
|
||||
val mutable size = float_of_string (PC.get_prop "size" config "15.")
|
||||
val mutable text = PC.get_prop "text" config ""
|
||||
val mutable test_value = float_of_string (PC.get_prop "test_value" config "0.")
|
||||
val mutable test_inv = bool_of_string (PC.get_prop "test_invert" config "false")
|
||||
|
||||
method tag = "Led"
|
||||
method edit = fun (pack:GObj.widget -> unit) ->
|
||||
let file = Env.paparazzi_src // "sw" // "lib" // "ocaml" // "widgets.glade" in
|
||||
let led_editor = new Gtk_papget_led_editor.table_led_editor ~file () in
|
||||
pack led_editor#table_led_editor#coerce;
|
||||
|
||||
(* Initialize the entries *)
|
||||
led_editor#entry_text#set_text text;
|
||||
led_editor#spinbutton_size#set_value size;
|
||||
led_editor#spinbutton_test#set_value test_value;
|
||||
|
||||
(* Connect the entries *)
|
||||
let callback = fun () ->
|
||||
text <- led_editor#entry_text#text in
|
||||
ignore (led_editor#entry_text#connect#activate ~callback);
|
||||
let callback = fun () ->
|
||||
size <- led_editor#spinbutton_size#value in
|
||||
ignore (led_editor#spinbutton_size#connect#activate ~callback);
|
||||
let callback = fun () ->
|
||||
test_value <- led_editor#spinbutton_test#value in
|
||||
ignore (led_editor#spinbutton_test#connect#activate ~callback);
|
||||
let callback = fun () ->
|
||||
test_inv <- led_editor#check_invert#active in
|
||||
ignore (led_editor#check_invert#connect#toggled ~callback);
|
||||
|
||||
method update = fun value ->
|
||||
let value = float_of_string value in
|
||||
let inv = if test_inv then not else (fun x -> x) in
|
||||
(* Led drawer *)
|
||||
if inv (value = test_value) then led#set [`FILL_COLOR "red"]
|
||||
else led#set [`FILL_COLOR "#00ff00"];
|
||||
let r = (max 2. (size /. 2.)) +. 1. in
|
||||
led#set [`X1 r; `Y1 r; `X2 (-.r); `Y2 (-.r)];
|
||||
led_text#set [`TEXT text; `SIZE_POINTS size; `X (-.r-.3.)]
|
||||
|
||||
method item = (root :> movable_item)
|
||||
method config = fun () ->
|
||||
[ PC.float_property "size" size;
|
||||
PC.property "text" text ]
|
||||
end
|
||||
|
||||
(****************************************************************************)
|
||||
class canvas_button = fun ?(config=[]) canvas_group x y ->
|
||||
let icon = PC.get_prop "icon" config "icon_file" in
|
||||
let pixbuf = GdkPixbuf.from_file (Env.gcs_icons_path // icon) in
|
||||
let group = GnoCanvas.group ~x ~y canvas_group in
|
||||
let _item = GnoCanvas.pixbuf ~pixbuf group in
|
||||
object
|
||||
method tag = "Button"
|
||||
method item = (group :> movable_item)
|
||||
method edit = fun (pack:GObj.widget -> unit) -> ()
|
||||
method update = fun (value:string) -> ()
|
||||
method config = fun () ->
|
||||
[ PC.property "icon" icon]
|
||||
initializer
|
||||
group#raise_to_top ();
|
||||
end
|
||||
|
||||
|
||||
(****************************************************************************)
|
||||
class canvas_mplayer = fun ?(config=[]) canvas_group x y ->
|
||||
let video_feed = PC.get_prop "video_feed" config "video_URI" in
|
||||
let width = float_of_string (PC.get_prop "width" config "320.")
|
||||
and height = float_of_string (PC.get_prop "height" config "240.") in
|
||||
let socket = GWindow.socket () in
|
||||
let group = GnoCanvas.group ~x ~y canvas_group in
|
||||
let item = GnoCanvas.widget ~width ~height ~widget:socket group in
|
||||
|
||||
object
|
||||
method tag = "Mplayer"
|
||||
method item = (group :> movable_item)
|
||||
method edit = fun (pack:GObj.widget -> unit) -> ()
|
||||
method update = fun (value:string) ->
|
||||
let zoom = try float_of_string value with _ -> 1. in
|
||||
item#set [`WIDTH (width /. zoom); `HEIGHT (height /. zoom)]
|
||||
method config = fun () ->
|
||||
[ PC.property "video_feed" video_feed;
|
||||
PC.float_property "width" width;
|
||||
PC.float_property "height" height ]
|
||||
initializer
|
||||
group#lower_to_bottom ();
|
||||
let com = sprintf "exec mplayer -vo xv -really-quiet -nomouseinput %s -wid 0x%lx -geometry %.0fx%.0f" video_feed socket#xwindow width height in
|
||||
let dev_null = Unix.descr_of_out_channel (open_out "/dev/null") in
|
||||
ignore (Unix.create_process "/bin/sh" [|"/bin/sh"; "-c"; com|] dev_null dev_null dev_null)
|
||||
end
|
||||
|
||||
|
||||
(****************************************************************************)
|
||||
class canvas_plugin = fun ?(config=[]) canvas_group x y ->
|
||||
let command = PC.get_prop "command" config "missing_plugin_command" in
|
||||
let width = float_of_string (PC.get_prop "width" config "320.")
|
||||
and height = float_of_string (PC.get_prop "height" config "240.") in
|
||||
let socket = GWindow.socket () in
|
||||
let group = GnoCanvas.group ~x ~y canvas_group in
|
||||
let item = GnoCanvas.widget ~width ~height ~widget:socket group in
|
||||
|
||||
object
|
||||
method tag = "Plugin"
|
||||
method item = (group :> movable_item)
|
||||
method edit = fun (pack:GObj.widget -> unit) -> ()
|
||||
method update = fun (value:string) ->
|
||||
let zoom = try float_of_string value with _ -> 1. in
|
||||
item#set [`WIDTH (width /. zoom); `HEIGHT (height /. zoom) ]
|
||||
method config = fun () ->
|
||||
[ PC.property "command" command;
|
||||
PC.float_property "width" width;
|
||||
PC.float_property "height" height ]
|
||||
initializer
|
||||
group#lower_to_bottom ();
|
||||
let com = sprintf "exec %s0x%lx" command socket#xwindow in
|
||||
let dev_null = Unix.descr_of_out_channel (open_out "/dev/null") in
|
||||
ignore (Unix.create_process "/bin/sh" [|"/bin/sh"; "-c"; com|] dev_null dev_null dev_null)
|
||||
end
|
||||
|
||||
|
||||
|
||||
let renderers =
|
||||
[ (new canvas_text :> ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t);
|
||||
(new canvas_ruler :> ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t);
|
||||
(new canvas_gauge :> ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t);
|
||||
(new canvas_led :> ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t) ]
|
||||
|
||||
let lazy_tagged_renderers = lazy
|
||||
(let x = 0. and y = 0.
|
||||
and group = (GnoCanvas.canvas ())#root in
|
||||
List.map
|
||||
(fun constructor ->
|
||||
let o = constructor ?config:None group x y in
|
||||
(o#tag, constructor))
|
||||
renderers)
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
(*
|
||||
* Paparazzi widget renderers
|
||||
*
|
||||
* Copyright (C) 2008 ENAC
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
class type movable_item =
|
||||
object
|
||||
inherit GnoCanvas.base_item
|
||||
method set : GnomeCanvas.group_p list -> unit
|
||||
end
|
||||
|
||||
class type t =
|
||||
object
|
||||
method config : unit -> Xml.xml list
|
||||
method edit : (GObj.widget -> unit) -> unit
|
||||
method item : movable_item
|
||||
method tag : string
|
||||
method update : string -> unit
|
||||
end
|
||||
|
||||
class canvas_text : ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t
|
||||
(** [canvas_text config group x y] *)
|
||||
|
||||
class canvas_ruler : ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t
|
||||
(** [canvas_ruler config group x y] *)
|
||||
|
||||
class canvas_gauge : ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t
|
||||
(** [canvas_gauge config group x y] *)
|
||||
|
||||
class canvas_led : ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t
|
||||
(** [canvas_led config group x y] *)
|
||||
|
||||
class canvas_button : ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t
|
||||
(** [canvas_button config group x y] *)
|
||||
|
||||
class canvas_mplayer : ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t
|
||||
(** [canvas_mplayer config group x y] *)
|
||||
|
||||
class canvas_plugin : ?config:Xml.xml list -> #GnoCanvas.group -> float -> float -> t
|
||||
(** [canvas_plugin config group x y] *)
|
||||
|
||||
val lazy_tagged_renderers :
|
||||
(string * (?config:Xml.xml list -> GnoCanvas.group -> float -> float -> t))
|
||||
list lazy_t
|
||||
(** List of renderers available to display a telemetry field value *)
|
||||
@@ -1,399 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<!-- interface-requires gtk+ 2.6 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkWindow" id="papget_text_editor">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Text Papget Properties</property>
|
||||
<property name="window_position">mouse</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table_text_editor">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label39">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Format</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label40">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Size</property>
|
||||
<property name="justify">right</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label45">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Color</property>
|
||||
<property name="justify">right</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entry_format">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="spinbutton_size">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">1 0 100 1 10 0</property>
|
||||
<property name="climb_rate">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkComboBoxEntry" id="comboboxentry_color">
|
||||
<property name="visible">True</property>
|
||||
<property name="has_tooltip">True</property>
|
||||
<property name="tooltip" translatable="yes">Colors defined in X11 rgb.txt</property>
|
||||
<property name="items" translatable="yes">green
|
||||
red
|
||||
blue
|
||||
yellow
|
||||
orange
|
||||
white</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkWindow" id="papget_editor">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Papget Editor (A/C: Any)</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="default_width">300</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="box_item_chooser">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox_scale">
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label41">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Scale</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entry_scale">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">"a+b" to display value x as a.x+b</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="text" translatable="yes">1+0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="box_item_editor">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox9">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button_delete">
|
||||
<property name="label">gtk-delete</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button_ok">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkWindow" id="papget_gauge_editor">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Gauge Papget Properties</property>
|
||||
<property name="window_position">mouse</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table_gauge_editor">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label42">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Min</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label43">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Max</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entry_min">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entry_max">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entry_text">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label44">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Text</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkWindow" id="papget_led_editor">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Led Papget Properties</property>
|
||||
<property name="window_position">mouse</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table_led_editor">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Text</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Size</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="spinbutton_size">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">15 2 100 1 10 0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entry_text">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Test invert</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="check_invert">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Test value</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="spinbutton_test">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">0 0 100 1 10 0</property>
|
||||
<property name="climb_rate">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
@@ -1,67 +0,0 @@
|
||||
(*
|
||||
* Wind sock
|
||||
*
|
||||
* Copyright (C) 2007 ENAC
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
let flatten = fun s a ->
|
||||
let n = Array.length a in
|
||||
let b = Array.make (2*n) 0. in
|
||||
for i = 0 to n - 1 do
|
||||
let (x, y) = a.(i) in
|
||||
b.(2*i) <- float x *. s;
|
||||
b.(2*i+1) <- float y *. s
|
||||
done;
|
||||
b
|
||||
|
||||
class item = fun ?(show = false) size_unit group ->
|
||||
let texture = `FILL_STIPPLE (Gdk.Bitmap.create_from_data ~width:2 ~height:2 "\002\001") in
|
||||
|
||||
let group = GnoCanvas.group group in
|
||||
|
||||
(* Text *)
|
||||
let t = GnoCanvas.text group ~props:[`TEXT "12.1"; `X 0.; `Y 0.; `ANCHOR `CENTER; `FILL_COLOR "black"] in
|
||||
|
||||
(* Red left and right *)
|
||||
let props = [`FILL_COLOR "red"; texture] in
|
||||
let points = flatten size_unit [|(-6,4); (-2,3); (-2,-3); (-6,-4)|] in
|
||||
let _ = GnoCanvas.polygon group ~props ~points in
|
||||
let points = flatten size_unit [|(2,2); (6,1); (6,-1); (2,-2)|] in
|
||||
let _ = GnoCanvas.polygon group ~props ~points in
|
||||
|
||||
(* White center *)
|
||||
let props = [`FILL_COLOR "white"] in
|
||||
let points = flatten size_unit [|(-2,3); (2,2); (2,-2); (-2,-3)|] in
|
||||
let _ = GnoCanvas.polygon group ~props ~points in
|
||||
|
||||
(* contour *)
|
||||
let points = flatten size_unit [|(-6,4); (6,1); (6,-1); (-6,-4)|] in
|
||||
let props = [`OUTLINE_COLOR "white"; `WIDTH_PIXELS 1] in
|
||||
let contour = GnoCanvas.polygon group ~props ~points in
|
||||
|
||||
object
|
||||
method item = group
|
||||
method label = t
|
||||
initializer
|
||||
t#raise_to_top ();
|
||||
if not show then group#hide ()
|
||||
method set_color = fun color -> contour#set [`OUTLINE_COLOR color]
|
||||
end
|
||||
@@ -1,33 +0,0 @@
|
||||
(*
|
||||
* Wind sock
|
||||
*
|
||||
* Copyright (C) 2007 ENAC
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
(** [item ?show size_unit group] Length of the wind sock is 6 times
|
||||
[size_unit] *)
|
||||
class item : ?show:bool -> float -> #GnoCanvas.group ->
|
||||
object
|
||||
method item : GnoCanvas.group
|
||||
method label : GnoCanvas.text
|
||||
method set_color : string -> unit
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,79 +0,0 @@
|
||||
(*
|
||||
* XML graphics editor
|
||||
*
|
||||
* Copyright (C) 2004 CENA/ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
(** XML types base on the xml-light library *)
|
||||
|
||||
type t
|
||||
(** The whole XML data structure *)
|
||||
|
||||
type node
|
||||
(** One data structure node. Warning: it is not an absolute
|
||||
node designation: it may not remain valid after strucure modifications
|
||||
(reordering, deletion addition, ... *)
|
||||
|
||||
type tag = string
|
||||
type attribute = string * string
|
||||
type attributes = attribute list
|
||||
|
||||
type event = Deleted | Modified of attributes | New_child of node
|
||||
|
||||
val create : ?format_attribs:((string * string) list -> string) -> ?editable:bool -> ?width:int -> Dtd.dtd -> Xml.xml -> (t * GObj.widget)
|
||||
(** [create ?format_attribs ?editable dtd xml] Opens a display of [xml] with contextual right button
|
||||
actions constrained by [dtd]. Returns the corresponding model. *)
|
||||
|
||||
val xml_of_node : node -> Xml.xml
|
||||
val xml_of_view : t -> Xml.xml
|
||||
(** [xml_of_view v] Returns the XML displayed data structure *)
|
||||
|
||||
val root : t -> node
|
||||
|
||||
val child : node -> tag -> node
|
||||
val tag : node -> string
|
||||
val attribs : node -> attributes
|
||||
val attrib : node -> string -> string (* Safe case match *)
|
||||
val children : node -> node list
|
||||
val parent : node -> tag -> node (** May raise Failure *)
|
||||
(** Xml-light like acces functions *)
|
||||
|
||||
val set_attrib : node -> attribute -> unit
|
||||
val set_attribs : node -> attributes -> unit
|
||||
val delete : node -> unit
|
||||
val add_child : node -> tag -> attributes -> node
|
||||
(** Modifications *)
|
||||
|
||||
val connect : node -> (event -> unit) -> unit
|
||||
val connect_activated : t -> (node -> unit) -> unit
|
||||
(** To be kept informed about modifications *)
|
||||
|
||||
val string_of_attribs : attributes -> string
|
||||
(** Default formatter for attributes *)
|
||||
|
||||
val selection : t -> node
|
||||
|
||||
val expand_node : ?all:bool -> t -> node -> unit
|
||||
|
||||
val set_background : ?all:bool -> node -> string -> unit
|
||||
|
||||
type id = int
|
||||
val id : node -> id
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,93 +0,0 @@
|
||||
(*
|
||||
* Real time handling of flying A/Cs
|
||||
*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
|
||||
type color = string
|
||||
type gps_acc_level = GPS_ACC_HIGH | GPS_ACC_LOW | GPS_ACC_VERY_LOW | GPS_NO_ACC
|
||||
|
||||
type aircraft = private {
|
||||
ac_name : string;
|
||||
ac_speech_name : string;
|
||||
config : PprzLink.values;
|
||||
track : MapTrack.track;
|
||||
color: color;
|
||||
fp_group : MapFP.flight_plan;
|
||||
fp_show : GMenu.check_menu_item;
|
||||
wp_HOME : MapWaypoints.waypoint option;
|
||||
fp : Xml.xml;
|
||||
blocks : (int * string) list;
|
||||
mutable last_ap_mode : string;
|
||||
mutable last_stage : int * int;
|
||||
ir_page : Pages.infrared;
|
||||
gps_page : Pages.gps;
|
||||
pfd_page : Horizon.pfd;
|
||||
link_page : Pages.link;
|
||||
misc_page : Pages.misc;
|
||||
dl_settings_page : Page_settings.settings option;
|
||||
rc_settings_page : Pages.rc_settings option;
|
||||
pages : GObj.widget;
|
||||
notebook_label : GMisc.label;
|
||||
strip : Strip.t;
|
||||
rc_max_rate : float;
|
||||
mutable first_pos : bool;
|
||||
mutable last_block_name : string;
|
||||
mutable in_kill_mode : bool;
|
||||
mutable speed : float;
|
||||
mutable alt : float;
|
||||
mutable target_alt : float;
|
||||
mutable flight_time : int;
|
||||
mutable wind_speed : float;
|
||||
mutable wind_dir : float; (* Rad *)
|
||||
mutable ground_prox : bool;
|
||||
mutable got_track_status_timer : int;
|
||||
mutable last_dist_to_wp : float;
|
||||
mutable dl_values : string option array;
|
||||
mutable last_unix_time : float;
|
||||
mutable airspeed : float;
|
||||
mutable version : string;
|
||||
mutable last_gps_acc : gps_acc_level;
|
||||
mutable last_bat_warn_time : float;
|
||||
time_link_lost: (string, float) Hashtbl.t
|
||||
}
|
||||
|
||||
val aircrafts : (string, aircraft) Hashtbl.t
|
||||
|
||||
val safe_bind : string -> (string -> PprzLink.values -> unit) -> unit
|
||||
|
||||
val track_size : int ref
|
||||
(** Default length for A/C tracks on the 2D view *)
|
||||
|
||||
val auto_hide_fp : bool -> unit
|
||||
(** Automatically hide flight plan of not selected ac *)
|
||||
|
||||
val listen_acs_and_msgs : MapCanvas.widget -> GPack.notebook -> GPack.box -> bool -> Pages.alert -> bool -> string -> Gtk_tools.pixmap_in_drawin_area -> bool -> unit
|
||||
(** [listen_acs_and_msgs geomap aircraft_notebook confirm_kill alert_page auto_center_new_ac alt_graph timestamp] *)
|
||||
|
||||
val jump_to_block : string -> int -> unit
|
||||
(** [jump_to_block ac_id block_id] Sends a JUMP_TO_BLOCK message *)
|
||||
|
||||
val dl_setting : string -> int -> float -> unit
|
||||
(** [dl_setting ac_id var_index value] Sends a DL_SETTING message *)
|
||||
|
||||
val filter_ac_ids: string -> unit
|
||||
@@ -1,28 +0,0 @@
|
||||
(*
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*)
|
||||
|
||||
let set_georef_if_none = fun geomap wgs84 ->
|
||||
match geomap#georef with
|
||||
None ->
|
||||
geomap#set_georef wgs84;
|
||||
geomap#center wgs84
|
||||
| Some _ -> ()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user