diff --git a/conf/settings/basic.xml b/conf/settings/basic.xml index ff9b296953..85fcb50a6d 100644 --- a/conf/settings/basic.xml +++ b/conf/settings/basic.xml @@ -6,6 +6,7 @@ + diff --git a/conf/settings/tuning.xml b/conf/settings/tuning.xml index 38ee619c9a..e465861ee5 100644 --- a/conf/settings/tuning.xml +++ b/conf/settings/tuning.xml @@ -17,7 +17,6 @@ - @@ -88,9 +87,6 @@ - - - diff --git a/sw/ground_segment/cockpit/Makefile b/sw/ground_segment/cockpit/Makefile index 015789f895..1e59dc4ebc 100644 --- a/sw/ground_segment/cockpit/Makefile +++ b/sw/ground_segment/cockpit/Makefile @@ -28,10 +28,10 @@ OCAMLCFLAGS=-thread OCAMLOPT=ocamlopt OCAMLOPTFLAGS=-thread INCLUDES=-I +lablgtk2 -I ../../lib/ocaml -I +xml-light -LIBS=glibivy-ocaml.cma lablgtk.cma lib-pprz.cma lablgnomecanvas.cma xlib-pprz.cma +LIBS=glibivy-ocaml.cma lablgtk.cma lablglade.cma lib-pprz.cma lablgnomecanvas.cma xlib-pprz.cma CMXA=$(LIBS:.cma=.cmxa) -ML= horizon.ml strip.ml pages.ml speech.ml plugin.ml sectors.ml map2d.ml editFP.ml live.ml particules.ml gcs.ml +ML= gtk_gcs.ml horizon.ml strip.ml pages.ml speech.ml plugin.ml sectors.ml map2d.ml editFP.ml live.ml particules.ml gcs.ml MAIN=gcs CMO=$(ML:.ml=.cmo) CMX=$(ML:.ml=.cmx) @@ -59,9 +59,16 @@ $(MAIN).opt : $(CMX) @echo OOC $< $(Q)$(OCAMLOPT) $(OCAMLCFLAGS) $(INCLUDES) -c $< +gtk_gcs.ml : gcs.glade + lablgladecc2 -root eventbox_strip -hide-default $< | grep -B 1000000 " end" > $@ + + +strip : gtk_gcs.ml test_strip.ml + $(OCAMLC) $(OCAMLCFLAGS) $(INCLUDES) lablgtk.cma lablglade.cma gtkInit.cmo $^ -o $@ + clean: - rm -f *~* *.cm* *.o *.out *.opt map2d gcs .depend + rm -f *~* *.cm* *.o *.out *.opt map2d gcs .depend gtk_gcs.ml diff --git a/sw/ground_segment/cockpit/gcs.glade b/sw/ground_segment/cockpit/gcs.glade index 88fcb4ae8c..b14fd085e5 100644 --- a/sw/ground_segment/cockpit/gcs.glade +++ b/sw/ground_segment/cockpit/gcs.glade @@ -51,745 +51,1310 @@ False - + True - 4 - 8 False - 1 - 1 + 0 - + True - <b>12:10</b> - False - True - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 0 - 1 - fill - - - - - - - 50 - True - Battery - GDK_POINTER_MOTION_MASK - - - 0 - 1 - 1 - 3 - fill - - - - - - True - True - False + False + 0 - + True - 3 - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - True - 0 + 3 + 4 + False + 0 + 0 + + + + 50 + True + Throttle + + + 2 + 3 + 0 + 1 + 1 + fill + fill + + + + + + 50 + True + Ground speed + + + 1 + 2 + 0 + 1 + 2 + fill + fill + + + + + + 50 + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 6 + 0 + + + + 50 + True + Battery + GDK_POINTER_MOTION_MASK + + + + + + + + True + <i>Bat</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + 1 + 1 + 2 + fill + fill + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 6 + 0 + + + + True + False + 2 + + + + True + True + False + + + + True + AUTO2 + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + 0 + True + True + + + + + + True + True + False + + + + True + NO RC + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + 0 + True + True + + + + + + True + True + False + + + + True + 3D + False + True + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + 0 + True + True + + + + + + + + + + True + <i>Status</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 1 + 2 + 1 + 3 + fill + fill + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 6 + 0 + + + + True + + + + + + + + True + <i>AGL</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 2 + 3 + 1 + 2 + fill + fill + + + + + + 27 + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 6 + 0 + + + + True + True + False + + + + True + 0 + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + + + True + <i>Link</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + 1 + 2 + 3 + fill + fill + + + + + + 27 + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 6 + 0 + + + + True + <b>-30m</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + True + <i>/Target</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 2 + 3 + 2 + 3 + fill + fill + + + + + + 27 + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 6 + 0 + + + + True + False + 0 + + + + True + <b>185m</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + / + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + <b>215m</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + True + <i>Alt</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 3 + 4 + 2 + 3 + fill + fill + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 6 + 0 + + + + True + 3 + 2 + False + 0 + 0 + + + + True + <i>ETA</i> + False + True + GTK_JUSTIFY_RIGHT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + <i>N/A</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 1 + 2 + 2 + 3 + fill + + + + + + + True + <i>Stage </i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + <b>1:10</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 1 + 2 + 1 + 2 + fill + + + + + + + True + <i>Time</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + <b>2:20</b> + False + True + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 1 + 2 + 0 + 1 + fill + + + + + + + + + + + True + <i>Block</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 3 + 4 + 1 + 2 + fill + fill + + + + + + 85 + True + <i>N/A</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 3 + 4 + 0 + 1 + fill + + + + + + + True + True + False + + + + True + <b>12:10</b> + False + True + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + 0 + 1 + 0 + 1 + fill + + + + + 0 + False + False + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 6 + 0 + + + + True + 3 + 3 + False + 0 + 0 + + + + True + False + Kill + True + GTK_RELIEF_NORMAL + True + + + + 16 + 16 + True + gtk-stop + 1 + 0.5 + 0.5 + 0 + 0 + + + + + 1 + 2 + 0 + 1 + fill + + + + + + + True + False + Resurrect + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-redo + 2 + 0.5 + 0.5 + 0 + 0 + + + + + 2 + 3 + 0 + 1 + fill + + + + + + + True + False + Altitude -5m + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-goto-bottom + 2 + 0.5 + 0.5 + 0 + 0 + + + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + False + Altitude +5m + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-goto-top + 4 + 0.5 + 0.5 + 0 + 0 + + + + + 1 + 2 + 1 + 2 + fill + + + + + + + True + False + Shift 5m left + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-goto-first + 1 + 0.5 + 0.5 + 0 + 0 + + + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + False + Recenter + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-media-pause + 2 + 0.5 + 0.5 + 0 + 0 + + + + + 1 + 2 + 2 + 3 + fill + + + + + + + True + False + Shift 5m right + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-goto-last + 2 + 0.5 + 0.5 + 0 + 0 + + + + + 2 + 3 + 2 + 3 + fill + + + + + + + True + False + Altitude +30m + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-go-up + 2 + 0.5 + 0.5 + 0 + 0 + + + + + 2 + 3 + 1 + 2 + fill + + + + + + + True + False + Launch + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-apply + 1 + 0.5 + 0.5 + 0 + 0 + + + + + 0 + 1 + 0 + 1 + fill + + + + + + + + + + + True + <i>Nav</i> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + False + - 0 - 1 - 3 - 4 - fill + 0 + True + True - + True - True - GTK_RELIEF_NORMAL - True + False + 0 - - True - gtk-redo - 2 - 0.5 - 0.5 - 0 - 0 - + - 7 - 8 - 1 - 2 - fill - - - - - - - True - True - GTK_RELIEF_NORMAL - True - - - - True - gtk-stop - 2 - 0.5 - 0.5 - 0 - 0 - - - - - 6 - 7 - 1 - 2 - fill - - - - - - - True - Launch - GTK_RELIEF_NORMAL - True - - - - 16 - 16 - True - gtk-apply - 4 - 0.5 - 0.5 - 0 - 0 - - - - - 5 - 6 - 1 - 2 - fill - - - - - - - True - True - GTK_RELIEF_NORMAL - True - - - - True - gtk-go-up - 2 - 0.5 - 0.5 - 0 - 0 - - - - - 7 - 8 - 2 - 3 - fill - - - - - - - True - True - GTK_RELIEF_NORMAL - True - - - - True - gtk-goto-top - 2 - 0.5 - 0.5 - 0 - 0 - - - - - 6 - 7 - 2 - 3 - fill - - - - - - - True - True - GTK_RELIEF_NORMAL - True - - - - True - gtk-goto-bottom - 2 - 0.5 - 0.5 - 0 - 0 - - - - - 5 - 6 - 2 - 3 - fill - - - - - - - True - True - GTK_RELIEF_NORMAL - True - - - - True - gtk-goto-last - 2 - 0.5 - 0.5 - 0 - 0 - - - - - 7 - 8 - 3 - 4 - fill - - - - - - - True - True - GTK_RELIEF_NORMAL - True - - - - True - gtk-media-pause - 2 - 0.5 - 0.5 - 0 - 0 - - - - - 6 - 7 - 3 - 4 - fill - - - - - - - True - True - GTK_RELIEF_NORMAL - True - - - - 16 - True - gtk-goto-first - 2 - 0.5 - 0.5 - 0 - 0 - - - - - 5 - 6 - 3 - 4 - fill - - - - - - - True - <b>2:20</b> - False - True - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 5 - 8 - 0 - 1 - fill - - - - - - - True - <b>Standby</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 3 - 5 - 0 - 1 - fill - - - - - - - True - <b>circle </b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 3 - 4 - 1 - 2 - fill - - - - - - - True - <b>1:10</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 4 - 5 - 1 - 2 - fill - - - - - - - True - ETA - False - False - GTK_JUSTIFY_RIGHT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 3 - 4 - 2 - 3 - fill - - - - - - - True - <b>0:45</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 4 - 5 - 2 - 3 - fill - - - - - - - True - Alt - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 3 - 4 - 3 - 4 - fill - - - - - - - True - <b>185/215</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 4 - 5 - 3 - 4 - fill - - - - - - - True - True - False - - - - True - NO RC - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - 1 - 2 - 2 - 3 - fill - fill - - - - - - True - Ground speed - - - 1 - 2 - 0 - 1 - fill - fill - - - - - - True - - - 2 - 3 - 3 - 4 - fill - fill - - - - - - 50 - True - - - 2 - 3 - 1 - 3 - fill - fill - - - - - - True - Throttle - - - 2 - 3 - 0 - 1 - fill - fill - - - - - - True - True - False - - - - True - AUTO2 - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - 1 - 2 - 1 - 2 - fill - fill - - - - - - True - True - False - - - - True - 3D - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - 1 - 2 - 3 - 4 - fill - fill + 0 + True + True diff --git a/sw/ground_segment/cockpit/live.ml b/sw/ground_segment/cockpit/live.ml index feccc020c6..98778c1515 100644 --- a/sw/ground_segment/cockpit/live.ml +++ b/sw/ground_segment/cockpit/live.ml @@ -85,6 +85,8 @@ type aircraft = { 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 } let aircrafts = Hashtbl.create 3 @@ -291,7 +293,6 @@ let load_mission = fun ?editable color geomap xml -> new MapFP.flight_plan ~format_attribs:attributes_pretty_printer ?editable ~show_moved:true geomap color Env.flight_plan_dtd xml - let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id:string) config -> let color = Pprz.string_assoc "default_gui_color" config and name = Pprz.string_assoc "ac_name" config in @@ -470,7 +471,7 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id Some settings_tab with _ -> None in - let ac = { track = track; color = color; + let ac = { track = track; color = color; last_dist_to_wp = 0.; fp_group = fp ; config = config ; fp = fp_xml; ac_name = name; blocks = blocks; last_ap_mode= ""; @@ -487,7 +488,8 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id wind_dir = 42.; ground_prox = true; wind_speed = 0.; pages = ac_frame#coerce; - notebook_label = _label + notebook_label = _label; + got_track_status_timer = 1000; } in Hashtbl.add aircrafts ac_id ac; select_ac acs_notebook ac_id; @@ -516,19 +518,23 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id ignore (Glib.Timeout.add 10000 send_wind); - (** Connect the shift altitude buttons *) + (** Connect the strip buttons *) begin match dl_settings_page with Some settings_tab -> - begin + let connect = fun setting_name strip_connect -> try - let flight_altitude_id, _flight_altitude_label = - settings_tab#assoc "flight_altitude" in - strip#connect_shift_alt - (fun x ->dl_setting_callback flight_altitude_id (ac.target_alt+.x)) + let id, _label = settings_tab#assoc setting_name in + strip_connect (fun x -> dl_setting_callback id x) with Not_found -> - prerr_endline "Warning: Flight_altitude not setable from GCS strip (i.e. not listed in the xml settings file)" - end + fprintf stderr "Warning: %s not setable from GCS strip (i.e. not listed in the xml settings file)" setting_name in + + connect "flight_altitude" (fun f -> ac.strip#connect_shift_alt (fun x -> f (ac.target_alt+.x))); + connect "launch" ac.strip#connect_launch; + connect "kill_throttle" ac.strip#connect_kill; + connect "nav_shift" ac.strip#connect_shift_lateral; + connect "pprz_mode" ac.strip#connect_mode; + connect "estimator_flight_time" ac.strip#connect_flight_time; | None -> () end; @@ -546,8 +552,15 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id prerr_endline "Warning: GPS reset not setable from GCS (i.e. 'gps_reset' not listed in the xml settings file)" end | None -> () - end + end; + (* Monitor track status *) + let monitor_track_status = fun () -> + ac.got_track_status_timer <- ac.got_track_status_timer + 1; + if ac.got_track_status_timer > 5 then + ac.track#delete_desired_track (); + true in + ignore (Glib.Timeout.add 1000 monitor_track_status);; @@ -605,8 +618,7 @@ let get_fbw_msg = fun _sender vs -> let get_engine_status_msg = fun _sender vs -> let ac = get_ac vs in - ac.strip#set_label "throttle" - (string_of_float (Pprz.float_assoc "throttle" vs)); + ac.strip#set_throttle (Pprz.float_assoc "throttle" vs); ac.strip#set_bat (Pprz.float_assoc "bat" vs) let get_if_calib_msg = fun _sender vs -> @@ -692,14 +704,14 @@ let listen_flight_params = fun geomap auto_center_new_ac alert -> let set_label lbl_name value = let s = if value < 0. - then sprintf "- %.1f" (abs_float value) - else sprintf "%.1f" value + then sprintf "- %.0f" (abs_float value) + else sprintf "%.0f" value in ac.strip#set_label lbl_name s in - set_label "alt" alt; - set_label "speed" speed; - set_label "climb" climb; + set_label "altitude" alt; + ac.strip#set_speed speed; + ac.strip#set_climb climb; let agl = (a "agl") in ac.alt <- alt; ac.strip#set_agl agl; @@ -721,9 +733,8 @@ let listen_flight_params = fun geomap auto_center_new_ac alert -> and cur_stage = Pprz.int_assoc "cur_stage" vs in highlight_fp ac cur_block cur_stage; let set_label = fun l f -> - ac.strip#set_label l (sprintf "%.1f" (Pprz.float_assoc f vs)) in - set_label "->" "target_alt"; - set_label "/" "target_climb"; + ac.strip#set_label l (sprintf "%.0f" (Pprz.float_assoc f vs)) in + set_label "target_altitude" "target_alt"; let target_alt = Pprz.float_assoc "target_alt" vs in ac.strip#set_label "diff_target_alt" (sprintf "%+.0f" (ac.alt -. target_alt)); ac.target_alt <- target_alt; @@ -731,7 +742,6 @@ let listen_flight_params = fun geomap auto_center_new_ac alert -> if b <> ac.last_block_name then begin log_and_say alert ac.ac_name (sprintf "%s, %s" ac.ac_name b); ac.last_block_name <- b; - let b = String.sub b 0 (min 10 (String.length b)) in ac.strip#set_label "block_name" b end; let block_time = Int32.to_int (Pprz.int32_assoc "block_time" vs) @@ -739,7 +749,15 @@ let listen_flight_params = fun geomap auto_center_new_ac alert -> let bt = sprintf "%02d:%02d" (block_time / 60) (block_time mod 60) in ac.strip#set_label "block_time" bt; let st = sprintf "%02d:%02d" (stage_time / 60) (block_time mod 60) in - ac.strip#set_label "stage_time" st + ac.strip#set_label "stage_time" st; + let d = Pprz.float_assoc "dist_to_wp" vs in + let label = + if d = ac.last_dist_to_wp || ac.speed = 0. then + "N/A" + else + sprintf "%.0fs" (d /. ac.speed) in + ac.strip#set_label "eta_time" label; + ac.last_dist_to_wp <- d in safe_bind "NAV_STATUS" get_ns; @@ -755,6 +773,7 @@ let listen_flight_params = fun geomap auto_center_new_ac alert -> let get_circle_status = fun _sender vs -> let ac = get_ac vs in + ac.got_track_status_timer <- 0; let a = fun s -> Pprz.float_assoc s vs in let wgs84 = { posn_lat = (Deg>>Rad)(a "circle_lat"); posn_long = (Deg>>Rad)(a "circle_long") } in ac.track#draw_circle wgs84 (float_of_string (Pprz.string_assoc "radius" vs)) @@ -763,6 +782,7 @@ let listen_flight_params = fun geomap auto_center_new_ac alert -> let get_segment_status = fun _sender vs -> let ac = get_ac vs in + ac.got_track_status_timer <- 0; let a = fun s -> Pprz.float_assoc s vs in let geo1 = { posn_lat = (Deg>>Rad)(a "segment1_lat"); posn_long = (Deg>>Rad)(a "segment1_long") } and geo2 = { posn_lat = (Deg>>Rad)(a "segment2_lat"); posn_long = (Deg>>Rad)(a "segment2_long") } in @@ -794,7 +814,13 @@ let listen_flight_params = fun geomap auto_center_new_ac alert -> log_and_say alert ac.ac_name (sprintf "%s, %s" ac.ac_name ap_mode); ac.last_ap_mode <- ap_mode; ac.strip#set_label "AP" (Pprz.string_assoc "ap_mode" vs); - ac.strip#set_color "AP" (if List.mem ap_mode ok_modes then ok_color else alert_color); + let color = + match ap_mode with + "AUTO2" -> ok_color + | "AUTO1" -> "#10F0E0" + | "MANUAL" -> warning_color + | _ -> alert_color in + ac.strip#set_color "AP" color; end; let gps_mode = Pprz.string_assoc "gps_mode" vs in ac.strip#set_label "GPS" gps_mode; @@ -816,7 +842,7 @@ let listen_flight_params = fun geomap auto_center_new_ac alert -> in safe_bind "AP_STATUS" get_ap_status; - listen_dl_value () + listen_dl_value ();; let listen_waypoint_moved = fun () -> let get_values = fun _sender vs -> diff --git a/sw/ground_segment/cockpit/live.mli b/sw/ground_segment/cockpit/live.mli index 8a73b6a0de..6a54d470f3 100644 --- a/sw/ground_segment/cockpit/live.mli +++ b/sw/ground_segment/cockpit/live.mli @@ -55,6 +55,8 @@ type aircraft = { 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 } val aircrafts : (string, aircraft) Hashtbl.t diff --git a/sw/ground_segment/cockpit/strip.ml b/sw/ground_segment/cockpit/strip.ml index 31e3e4ea47..5e032e519d 100644 --- a/sw/ground_segment/cockpit/strip.ml +++ b/sw/ground_segment/cockpit/strip.ml @@ -24,16 +24,26 @@ * *) +let (//) = Filename.concat + type t = < add_widget : GObj.widget -> unit; connect_shift_alt : (float -> unit) -> unit; - set_agl : float -> unit; - set_bat : float -> unit; - set_color : string -> string -> unit; - set_label : string -> string -> unit; - connect : (unit -> unit) -> unit; - hide_buttons : unit -> unit; - show_buttons : unit -> unit > + connect_shift_lateral : (float -> unit) -> unit; + connect_launch : (float -> unit) -> unit; + connect_kill : (float -> unit) -> unit; + connect_mode : (float -> unit) -> unit; + connect_flight_time : (float -> unit) -> unit; + set_agl : float -> unit; + set_bat : float -> unit; + set_throttle : float -> unit; + set_speed : float -> unit; + set_climb : float -> unit; + set_color : string -> string -> unit; + set_label : string -> string -> unit; + connect : (unit -> unit) -> unit; + hide_buttons : unit -> unit; + show_buttons : unit -> unit > let bat_max = 12.5 let bat_min = 9. @@ -50,6 +60,7 @@ let strips_table = GPack.vbox ~spacing:5 ~packing:scrolled#add_with_viewport () let set_label labels name value = try let _eb, l = List.assoc (name^"_value") labels in + let value = Printf.sprintf "%s" value in if l#text <> value then l#set_label value with @@ -66,7 +77,7 @@ class gauge = fun ?(color="green") ?(history_len=50) gauge v_min v_max -> object val history = Array.create history_len 0 val mutable history_index = -1 - method set = fun value string -> + method set = fun ?arrow value strings -> let {Gtk.width=width; height=height} = gauge#misc#allocation in if height > 1 then (* Else the drawing area is not allocated already *) let dr = GDraw.pixmap ~width ~height ~window:gauge () in @@ -99,9 +110,57 @@ class gauge = fun ?(color="green") ?(history_len=50) gauge v_min v_max -> done; polygon := (width,height-h):: !polygon; dr#polygon ~filled:true !polygon; + + (* Arrow for the variation *) + begin + match arrow with + None -> () + | Some angle_rad -> + let w = width and h = height in + let fh = 0.8 *. float w in + let x = truncate (cos angle_rad *. fh) + and y = - truncate (sin angle_rad *. fh) in + let l = [w/10, h/2; w/10+x,h/2+y] in + dr#set_foreground `BLACK; + dr#lines l + end; + + let context = gauge#misc#create_pango_context in + List.iter (fun (vpos, 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; + Pango.Layout.set_text layout string; + let (w,h) = Pango.Layout.get_pixel_size layout in + let y = truncate (vpos *. float height) - h / 2 in + dr#put_layout ~x:((width-w)/2) ~y ~fore:`BLACK layout) + strings; + + (new GDraw.drawable gauge#misc#window)#put_pixmap ~x:0 ~y:0 dr#pixmap + end + +class hgauge = fun ?(color="green") gauge v_min v_max -> + object + method set = fun value string -> + let {Gtk.width=width; height=height} = gauge#misc#allocation in + if height > 1 then (* Else the drawing area is not allocated already *) + let dr = GDraw.pixmap ~width ~height ~window:gauge () in + dr#set_foreground (`NAME "orange"); + dr#rectangle ~x:0 ~y:0 ~width ~height ~filled:true (); + + let f = (value -. v_min) /. (v_max -. v_min) in + let f = max 0. (min 1. f) in + let w = truncate (float width *. f) in + + dr#set_foreground (`NAME color); + dr#rectangle ~x:0 ~y:0 ~width:w ~height ~filled:true (); let context = gauge#misc#create_pango_context in 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; Pango.Layout.set_text layout string; let (w,h) = Pango.Layout.get_pixel_size layout in dr#put_layout ~x:((width-w)/2) ~y:((height-h)/2) ~fore:`BLACK layout; @@ -109,148 +168,126 @@ class gauge = fun ?(color="green") ?(history_len=50) gauge v_min v_max -> (new GDraw.drawable gauge#misc#window)#put_pixmap ~x:0 ~y:0 dr#pixmap end - - -(** set the battery *) -let set_bat bat value = - bat#set value (string_of_float value) - - -(** set the AGL *) -let set_agl agl value = - agl#set value (Printf.sprintf "%3.0f" value) - - -let add_widget = fun buttons_box widget -> - buttons_box#add widget - -let labels_name = [| - [| "AP" ; "alt" ; "->" |]; [| "RC"; "climb"; "/" |]; [| "GPS"; "speed"; "throttle" |] -|] - -let labels_print = [| - [| "AP" ; "alt" ; "->" |]; [| "RC"; "climb"; "->" |]; [| "GPS"; "speed"; "throtl" |] -|] -let gen_int = let i = ref (-1) in fun () -> incr i; !i - -(** Number of rows: colored line + labels + buttons + user buttons *) -let rows = 1 + Array.length labels_name + 2 - -(** Numnber of columns: battey gauge + labels & values + AGL gauge *) -let columns = 1 + 2 * Array.length labels_name.(0) + 1 - - (** add a strip to the panel *) -let add config color center_ac mark = +let add = fun config color center_ac mark -> let strip_labels = ref [] in let add_label = fun name value -> strip_labels := (name, value) :: !strip_labels in let ac_name = Pprz.string_assoc "ac_name" config in - let tooltips = GData.tooltips () in + let file = Env.paparazzi_src // "sw" // "ground_segment" // "cockpit" // "gcs.glade" in + let strip = new Gtk_gcs.eventbox_strip ~file () in - (* frame of the strip *) - let strip_ebox = GBin.event_box ~packing:strips_table#pack () in - let frame = GBin.frame ~shadow_type: `IN ~packing:strip_ebox#add () in - let framevb = GPack.vbox ~packing:frame#add () in + let eventbox_dummy = GBin.event_box () in - (** Table (everything except the user buttons) *) - let strip = GPack.table ~rows ~columns ~col_spacings:3 ~row_spacings:2 ~packing:framevb#pack () in + strips_table#pack strip#toplevel#coerce; (* Name in top left *) - let name = (GMisc.label ~text: (ac_name) ~packing: (strip#attach ~top: 0 ~left: 0) ()) in - name#set_width_chars 5; - - - let plane_color = GBin.event_box ~packing:(strip#attach ~top:0 ~left:1 ~right:columns) () in + strip#label_ac_name#set_label (Printf.sprintf "%s" ac_name); + + (* Color *) + let plane_color = strip#eventbox_strip in plane_color#coerce#misc#modify_bg [`NORMAL, `NAME color]; - let h = GPack.hbox ~packing:plane_color#add () in - let ft = GMisc.label ~text: "00:00:00" ~packing:h#add () in - ft#set_width_chars 8; - add_label "flight_time_value" (plane_color, ft); - let block_time = GMisc.label ~text: "00:00" ~packing:h#add () in - add_label "block_time_value" (plane_color, block_time); - - let stage_time = GMisc.label ~text: "00:00" ~packing:h#add () in - add_label "stage_time_value" (plane_color, stage_time); - - let block_name = GMisc.label ~text: "______" ~packing:h#add () in - add_label "block_name_value" (plane_color, block_name); - - tooltips#set_tip plane_color#coerce ~text:"Flight time - Block time - Stage time - Block name"; + add_label "flight_time_value" (eventbox_dummy, strip#label_flight_time); + add_label "block_time_value" (eventbox_dummy, strip#label_block_time); + add_label "stage_time_value" (eventbox_dummy, strip#label_stage_time); + add_label "block_name_value" (eventbox_dummy, strip#label_block_name); (* battery gauge *) - let bat_da = GMisc.drawing_area ~show:true ~packing:(strip#attach ~top:1 ~bottom:3 ~left:0) () in + let bat_da = strip#drawingarea_battery in bat_da#misc#realize (); let bat = new gauge bat_da bat_min bat_max in (* AGL gauge *) - let agl_box = GBin.event_box ~packing:(strip#attach ~top:1 ~bottom:3 ~left:(columns-1)) () in - let agl_da = GMisc.drawing_area ~width:40 ~show:true ~packing:agl_box#add () in + let agl_da = strip#drawingarea_agl in agl_da#misc#realize (); - tooltips#set_tip agl_box#coerce ~text:"AGL (m)"; let agl = new gauge agl_da 0. agl_max in - + + (* Speed gauge *) + strip#drawingarea_speed#misc#realize (); + let speed = new hgauge strip#drawingarea_speed 0. 10. in (* FIXME *) + + (* Throttle gauge *) + strip#drawingarea_throttle#misc#realize (); + let throttle = new hgauge strip#drawingarea_throttle 0. 100. in (* Diff to target altitude *) - let dta_box = GBin.event_box ~packing:(strip#attach ~top:3 ~left:(columns-1)) () in - let diff_target_alt = GMisc.label ~text: "+0" ~packing:dta_box#add () in - add_label "diff_target_alt_value" (plane_color, diff_target_alt); - tooltips#set_tip dta_box#coerce ~text:"Height to target (m)"; + let diff_target_alt = strip#label_diff_target_alt in + add_label "diff_target_alt_value" (eventbox_dummy, diff_target_alt); (* Telemetry *) - let eb = GBin.event_box ~packing:(strip#attach ~top:3 ~left:0) () in - let ts = GMisc.label ~text:"N/A" ~packing:eb#add () in + let eb = strip#eventbox_telemetry in + let ts = strip#label_telemetry in add_label "telemetry_status_value" (eb, ts); ts#set_width_chars 3; - tooltips#set_tip eb#coerce ~text:"Telemetry status\nGreen if time since last bat message < 5s"; (* Labels *) - Array.iteri - (fun i a -> - Array.iteri - (fun j s -> - ignore (GMisc.label ~text: labels_print.(i).(j) ~justify:`RIGHT ~packing: (strip#attach ~top:(1+i) ~left: (1+2*j)) ()); - let eb = GBin.event_box ~packing: (strip#attach ~top:(i+1) ~left: (1+2*j+1)) () in - let lvalue = (GMisc.label ~text: "" ~justify: `RIGHT ~packing:eb#add ()) in - lvalue#set_width_chars 6; - add_label (s^"_value") (eb, lvalue); - ) a - ) labels_name; + add_label "RC_value" (strip#eventbox_rc, strip#label_rc); + add_label "AP_value" (strip#eventbox_mode, strip#label_mode); + add_label "GPS_value" (strip#eventbox_gps, strip#label_gps); + + add_label "altitude_value" (eventbox_dummy, strip#label_altitude); + add_label "target_altitude_value" (eventbox_dummy, strip#label_target_altitude); + + add_label "eta_time_value" (eventbox_dummy, strip#label_eta_time); + + let connect_buttons = fun callback -> + List.iter (fun ((button:GButton.button), value) -> + ignore (button#connect#clicked (fun () -> callback value)); + button#misc#set_sensitive true) in (* Buttons *) - let hbox = GPack.hbox ~width:300 ~spacing:2 ~packing:(strip#attach ~top:4 ~left:0 ~right:columns) () in - let b = GButton.button ~label:"Center A/C" ~packing:hbox#add () in - ignore(b#connect#clicked ~callback:center_ac); - let b = GButton.button ~label:"Mark" ~packing:hbox#add () in - ignore (b#connect#clicked ~callback:mark); - - let minus5 = GButton.button ~label:"-5m" ~packing:hbox#add ~show:false () - and plus5 = GButton.button ~label:"+5m" ~packing:hbox#add ~show:false () - and plus30 = GButton.button ~label:"+30m" ~packing:hbox#add ~show:false () in - ignore (b#connect#clicked ~callback:mark); - - (* User buttons *) - let user_hbox = GPack.hbox ~spacing:2 ~packing:(strip#attach ~top:5 ~left:0 ~right:columns) () in - - object - method set_agl value = set_agl agl value - method set_bat value = set_bat bat value + object + val mutable climb = 0. + method set_climb = fun v -> climb <- v + method set_agl value = + let arrow = max (min 0.5 (climb /. 5.)) (-0.5) in + agl#set ~arrow value [0.2, (Printf.sprintf "%3.0f" value); 0.8, Printf.sprintf "%+.1f" climb] + method set_bat value = bat#set value [0.5, (string_of_float value)] + method set_throttle value = throttle#set value (Printf.sprintf "%.0f%%" value) + method set_speed value = speed#set value (Printf.sprintf "%.1fm/s" value) method set_label name value = set_label !strip_labels name value method set_color name value = set_color !strip_labels name value - method add_widget w = add_widget user_hbox w + method add_widget w = strip#hbox_user#pack ~fill:false w method connect_shift_alt callback = - ignore (plus5#connect#clicked (fun () -> callback 5.)); - ignore (plus30#connect#clicked (fun () -> callback 30.)); - ignore (minus5#connect#clicked (fun () -> callback (-5.))); - minus5#misc#show (); - plus5#misc#show (); - plus30#misc#show (); - method hide_buttons () = hbox#misc#hide (); user_hbox#misc#hide () - method show_buttons () = hbox#misc#show (); user_hbox#misc#show () + connect_buttons callback + [ strip#button_minus_five, -5.; + strip#button_plus_five, 5.; + strip#button_plus_thirty, 30.] + + method connect_shift_lateral callback = + connect_buttons callback + [ strip#button_left, -5.; + strip#button_right, 5.; + strip#button_center, 0.] + + method connect_kill callback = + connect_buttons callback + [ strip#button_kill, 1.; + strip#button_resurrect, 0.] + + method connect_launch = fun callback -> + connect_buttons callback + [ strip#button_launch, 1. ] + + method connect_mode = fun callback -> + let callback = fun _ -> + callback 2.; (* Back in AUTO2 *) + true in + ignore(strip#eventbox_mode#event#connect#button_press ~callback) + + (* Reset the flight time *) + method connect_flight_time = fun callback -> + let callback = fun _ -> + callback 0.; + true in + ignore(strip#eventbox_flight_time#event#connect#button_press ~callback) + + method hide_buttons () = strip#hbox_user#misc#hide (); strip#frame_nav#misc#set_sensitive false + method show_buttons () = strip#hbox_user#misc#show (); strip#frame_nav#misc#set_sensitive true method connect = fun (select: unit -> unit) -> let callback = fun _ -> select (); true in - ignore (strip_ebox#event#connect#button_press ~callback) + ignore (strip#eventbox_strip#event#connect#button_press ~callback) end diff --git a/sw/ground_segment/cockpit/strip.mli b/sw/ground_segment/cockpit/strip.mli index d59d04a30b..afb2602b08 100644 --- a/sw/ground_segment/cockpit/strip.mli +++ b/sw/ground_segment/cockpit/strip.mli @@ -1,8 +1,16 @@ type t = < add_widget : GObj.widget -> unit; connect_shift_alt : (float -> unit) -> unit; + connect_shift_lateral : (float -> unit) -> unit; + connect_launch : (float -> unit) -> unit; + connect_kill : (float -> unit) -> unit; + connect_mode : (float -> unit) -> unit; + connect_flight_time : (float -> unit) -> unit; set_agl : float -> unit; set_bat : float -> unit; + set_throttle : float -> unit; + set_speed : float -> unit; + set_climb : float -> unit; set_color : string -> string -> unit; set_label : string -> string -> unit; hide_buttons : unit -> unit;