From 92d68d7cf8c3b936a4d4318f7fc2a100e2937a46 Mon Sep 17 00:00:00 2001 From: Pascal Brisset Date: Fri, 8 May 2009 20:35:58 +0000 Subject: [PATCH] * CSV export now possible in batch * Choice for the separator --- sw/logalizer/export.glade | 36 +++++++++++++++++---- sw/logalizer/export.ml | 68 ++++++++++++++++++++++++++++----------- sw/logalizer/plot.ml | 53 ++++++++++++++++-------------- 3 files changed, 108 insertions(+), 49 deletions(-) diff --git a/sw/logalizer/export.glade b/sw/logalizer/export.glade index 608320e348..5681ac570b 100644 --- a/sw/logalizer/export.glade +++ b/sw/logalizer/export.glade @@ -4,7 +4,6 @@ - True Save CSV GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE @@ -14,7 +13,7 @@ True False False - GDK_WINDOW_TYPE_HINT_DIALOG + GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False @@ -29,9 +28,9 @@ True True - GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC GTK_POLICY_ALWAYS - GTK_SHADOW_IN + GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT @@ -142,6 +141,31 @@ False 0 + + 3 + False + False + + + + + + True + Sep: + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + 0 False @@ -150,7 +174,7 @@ - + True True False @@ -203,7 +227,7 @@ True True - gtk-cancel + gtk-close True GTK_RELIEF_NORMAL True diff --git a/sw/logalizer/export.ml b/sw/logalizer/export.ml index 51cc8c5963..3acae12236 100644 --- a/sw/logalizer/export.ml +++ b/sw/logalizer/export.ml @@ -26,7 +26,7 @@ open Printf open Latlong - + let (//) = Filename.concat let class_name="telemetry" @@ -85,7 +85,8 @@ type timestamp = (*****************************************************************************) -let export_values = fun ?(export_geo_pos=true) (model:GTree.tree_store) data timestamp filename -> +let export_values = fun ?(sep="tab") ?(export_geo_pos=true) (model:GTree.tree_store) data timestamp filename -> + let sep = if sep = "tab" then "\t" else sep in let fields_to_export = ref [] in model#foreach (fun _path row -> if model#get ~row ~column:col_to_export then begin @@ -108,8 +109,8 @@ let export_values = fun ?(export_geo_pos=true) (model:GTree.tree_store) data tim (* Print the header *) fprintf f "Time"; if export_geo_pos then - fprintf f ";GPS lat(deg);GPS long(deg)"; - List.iter (fun (m,field) -> fprintf f ";%s:%s" m field) !fields_to_export; + fprintf f "%sGPS lat(deg)%sGPS long(deg)" sep sep; + List.iter (fun (m,field) -> fprintf f "%s%s:%s" sep m field) !fields_to_export; fprintf f "\n%!"; (* Store for the current values *) @@ -117,25 +118,35 @@ let export_values = fun ?(export_geo_pos=true) (model:GTree.tree_store) data tim and time = ref (match data with (t, _, _)::_ -> t | _ -> 0.) in let print_last_values = fun t -> - fprintf f "%.3f" t; + let all_values = ref true in + let lookup = fun m field -> - try Pprz.string_of_value (Hashtbl.find last_values (m,field)) with Not_found -> "" in + try Pprz.string_of_value (Hashtbl.find last_values (m,field)) with Not_found -> all_values := false; "" in + + let buf = Buffer.create 64 in + + bprintf buf "%.3f" t; + if export_geo_pos then begin try let utm_east = float_of_string (lookup "GPS" "utm_east") /. 100. and utm_north = float_of_string (lookup "GPS" "utm_north") /. 100. and utm_zone = int_of_string (lookup "GPS" "utm_zone") in let wgs84 = Latlong.of_utm WGS84 {utm_x=utm_east; utm_y=utm_north; utm_zone=utm_zone} in - fprintf f ";%.6f;%.6f" ((Rad>>Deg) wgs84.posn_lat) ((Rad>>Deg) wgs84.posn_long) + bprintf buf "%s%.6f%s%.6f" sep ((Rad>>Deg) wgs84.posn_lat) sep ((Rad>>Deg) wgs84.posn_long) with - exc -> fprintf stderr "%s\n%!" (Printexc.to_string exc) + Failure "float_of_string" -> () + | exc -> fprintf stderr "%s\n%!" (Printexc.to_string exc) end; + List.iter (fun (m,field) -> let v = lookup m field in - fprintf f ";%s" v) + bprintf buf "%s%s" sep v) !fields_to_export; - fprintf f "\n%!" in + + if !all_values then + fprintf f "%s\n" (Buffer.contents buf) in (* Write one line per time stamp. *) List.iter (fun (t, msg, fields) -> @@ -185,8 +196,7 @@ let read_preferences = fun () -> (** The save file dialog box *) -let save_values = fun w log_filename save -> - let filename = Env.paparazzi_home // "var" // "logs" // log_filename ^ ".csv" in +let save_values = fun w filename save -> match GToolbox.select_file ~title:"Save Values" ~filename () with None -> () | Some file -> @@ -196,7 +206,7 @@ let save_values = fun w log_filename save -> (*****************************************************************************) (** The popup window displaying values to export *) -let popup = fun xml log_filename data -> +let popup = fun ?(no_gui = false) xml log_filename data -> (* Build the list window *) let file = Env.paparazzi_src // "sw" // "logalizer" // "export.glade" in let w = new Gtk_export.export ~file () in @@ -236,11 +246,15 @@ let popup = fun xml log_filename data -> - (* The combo box for the extrapolation FIXME - let strings = ["Last Value"; "Linear Extrapolation"] in - let (combo, (tree, column)) = GEdit.combo_box_text ~packing:w#box_choose_interpol#add ~strings () in + (* The combo box for the separator *) + let strings = ["tab"; ";"; ","] in + let (combo, (tree, column)) = GEdit.combo_box_text ~packing:w#box_choose_sep#add ~strings () in tree#foreach (fun _path row -> combo#set_active_iter (Some row); true); (* Select the first *) - *) + let get_separator = fun () -> + match combo#active_iter with + | None -> failwith "get_timestamp" + | Some row -> + combo#model#get ~row ~column in ignore (w#button_cancel#connect#clicked (fun () -> w#export#destroy ())); @@ -252,5 +266,21 @@ let popup = fun xml log_filename data -> Period (float_of_string w#entry_period#text) else Msg combo_value in - save_values w log_filename (fun x -> export_values ~export_geo_pos:w#checkbutton_LL#active model data timestamp x) in - ignore (w#button_save#connect#clicked callback) + let sep = get_separator () in + + let do_export = fun x -> export_values ~sep ~export_geo_pos:w#checkbutton_LL#active model data timestamp x in + + let default_filename = Env.paparazzi_home // "var" // "logs" // log_filename ^ ".csv" in + + if no_gui then + do_export default_filename + else + save_values w default_filename do_export in + ignore (w#button_save#connect#clicked callback); + + if no_gui then begin + callback (); + w#export#destroy () + end else + w#export#show () + diff --git a/sw/logalizer/plot.ml b/sw/logalizer/plot.ml index e0a5c3992c..bf5b9a9305 100644 --- a/sw/logalizer/plot.ml +++ b/sw/logalizer/plot.ml @@ -24,14 +24,13 @@ * *) -module LL = Latlong -open LL - +open Latlong open Printf let (//) = Filename.concat let logs_dir = Env.paparazzi_home // "var" // "logs" let sample_kml = Env.paparazzi_home // "data/maps/sample_path.kml" +let verbose = ref false class type text_value = object method text : string end @@ -284,9 +283,9 @@ let write_kml = fun plot log_name values -> and y = snd ys.(i) /. 100. and z = truncate (snd zs.(i)) and a = snd alts.(i) /. 100. in - let utm = { LL.utm_x = x; LL.utm_y = y; LL.utm_zone = z } in + let utm = { utm_x = x; utm_y = y; utm_zone = z } in if z <> 0 then - l := (LL.of_utm LL.WGS84 utm, a) :: !l + l := (of_utm WGS84 utm, a) :: !l done; let l = List.rev !l in let xml = Xml.parse_file sample_kml in @@ -326,7 +325,7 @@ let write_kml = fun plot log_name values -> -let add_ac_submenu = fun protocol ?(factor=object method text="1" end) plot menubar (curves_menu_fact: GMenu.menu GMenu.factory) ac menu_name l raw_msgs -> +let add_ac_submenu = fun ?(export=false) protocol ?(factor=object method text="1" end) plot menubar (curves_menu_fact: GMenu.menu GMenu.factory) ac menu_name l raw_msgs -> let menu = GMenu.menu () in let menuitem = GMenu.menu_item ~label:menu_name () in menuitem#set_submenu menu; @@ -370,13 +369,14 @@ let add_ac_submenu = fun protocol ?(factor=object method text="1" end) plot menu snd (List.find (fun (m, _) -> m.Pprz.name = "GPS") l) in write_kml plot menu_name gps_values in ignore (menu_fact#add_item ~callback "Export KML path"); - let callback = fun () -> - Export.popup protocol menu_name raw_msgs in - ignore (menu_fact#add_item ~callback "Export CSV") - + let callback = fun ?no_gui () -> + Export.popup ?no_gui protocol menu_name raw_msgs in + ignore (menu_fact#add_item ~callback "Export CSV"); + if export then + callback ~no_gui:true () -let load_log = fun ?factor (plot:plot) (menubar:GMenu.menu_shell GMenu.factory) curves_fact xml_file -> +let load_log = fun ?export ?factor (plot:plot) (menubar:GMenu.menu_shell GMenu.factory) curves_fact xml_file -> Debug.call 'p' (fun f -> fprintf f "load_log: %s\n" xml_file); let xml = Xml.parse_file xml_file in let data_file = ExtXml.attrib xml "data_file" in @@ -436,7 +436,9 @@ let load_log = fun ?factor (plot:plot) (menubar:GMenu.menu_shell GMenu.factory) raw_msgs := (t, msg_name, vs) :: !raw_msgs ) with - exc -> prerr_endline (Printexc.to_string exc) + exc -> + if !verbose then + prerr_endline (Printexc.to_string exc) done with End_of_file -> @@ -475,7 +477,7 @@ let load_log = fun ?factor (plot:plot) (menubar:GMenu.menu_shell GMenu.factory) (* Store data for other windows *) logs_menus := (ac, menu_name, (msgs, raw_msgs), protocol) :: !logs_menus; - add_ac_submenu protocol ?factor plot menubar curves_fact ac menu_name msgs raw_msgs; + add_ac_submenu ?export protocol ?factor plot menubar curves_fact ac menu_name msgs raw_msgs; ) acs @@ -518,7 +520,7 @@ let screenshot = fun frame -> (*****************************************************************************) -let rec plot_window = fun init -> +let rec plot_window = fun ?export init -> let plotter = GWindow.window ~allow_shrink:true ~title:"Log Plotter" () in plotter#set_icon (Some (GdkPixbuf.from_file Env.icon_file)); let vbox = GPack.vbox ~packing:plotter#add () in @@ -606,24 +608,27 @@ let rec plot_window = fun init -> ignore(open_log_item#connect#activate ~callback:(fun () -> let factor = (factor:>text_value) in open_log ~factor plot factory curves_menu_fact ())); - List.iter (fun f -> load_log ~factor:(factor:>text_value) plot factory curves_menu_fact f) init; + List.iter (fun f -> load_log ?export ~factor:(factor:>text_value) plot factory curves_menu_fact f) init; plotter#add_accel_group accel_group; plotter#show () - -let _ = - let logs = ref [] in +(***************************** Main ****************************************) +let () = + let logs = ref [] + and export = ref false in Arg.parse - [] + [ ("-export_csv", Arg.Set export, "Export in CSV in batch mode according to saved preferences (conf/%gconf.xml)"); + ("-v", Arg.Set verbose, "Verbose")] (fun x -> logs := x :: !logs) "Usage: plot "; - plot_window !logs; + plot_window ~export: !export !logs; - let loop = Glib.Main.create true in - while Glib.Main.is_running loop do - ignore (Glib.Main.iteration true) - done + if not !export then + let loop = Glib.Main.create true in + while Glib.Main.is_running loop do + ignore (Glib.Main.iteration true) + done