private async Task LoadBinaryFile(string file) { try { AppendMessage("Loading " + file); ShowStatus("Loading " + file); Px4DataLog data = new Px4DataLog(); await data.Load(file, progress); logs.Add(data); ShowSchema(); Debug.WriteLine(data.StartTime.ToString()); UiDispatcher.RunOnUIThread(() => { // add flight for Flight entireLog = new Flight() { Name = "Log " + logs.Count, StartTime = data.StartTime, Duration = data.Duration }; allFlights.Add(entireLog); foreach (var flight in data.GetFlights()) { flight.Name = "Flight " + allFlights.Count; allFlights.Add(flight); AppendMessage("Motor started at {0} and ran for {1} ", flight.StartTime, flight.Duration); } if (myMap.Visibility == Visibility.Visible) { ShowMap(); } }); // remember successfully loaded log file. Settings settings = await ((App)App.Current).LoadSettings(); settings.LastLogFile = file; await settings.SaveAsync(); } catch (Exception ex) { AppendMessage("### Error loading log: " + ex.Message); } ShowStatus("Done Loading " + file); UpdateButtons(); }
public IEnumerable <Flight> GetFlights() { if (flights == null) { flights = new List <Model.Flight>(); int min = int.MaxValue; int max = int.MinValue; // mavlink_servo_output_raw_t is an actual PWM signal, so it toggles between RC0_TRIM (usually 1500) and the // values it is sending to the motor, so we have to weed out the trim values in order to see the actual // values. int trim = 1500; // should get this from the parameter values. // compute the min/max servo settings. foreach (var msg in this.data) { if (msg.TypedValue is MAVLink.mavlink_servo_output_raw_t) { MAVLink.mavlink_servo_output_raw_t servo = (MAVLink.mavlink_servo_output_raw_t)msg.TypedValue; if (servo.servo1_raw != 0 && servo.servo1_raw != trim) { min = Math.Min(min, servo.servo1_raw); max = Math.Max(max, servo.servo1_raw); } } } // find flights DateTime start = this.startTime; DateTime endTime = start; Flight current = null; int offCount = 0; // compute the min/max servo settings. foreach (var msg in this.data) { if (msg.TypedValue is MAVLink.mavlink_servo_output_raw_t) { MAVLink.mavlink_servo_output_raw_t servo = (MAVLink.mavlink_servo_output_raw_t)msg.TypedValue; endTime = start.AddMilliseconds(servo.time_usec / 1000); if (servo.servo1_raw != trim) { if (servo.servo1_raw > min) { if (current == null) { current = new Flight() { Log = this, StartTime = start.AddMilliseconds(servo.time_usec / 1000) }; flights.Add(current); offCount = 0; } } else if (servo.servo1_raw == min && offCount++ > 10) { if (current != null) { current.Duration = endTime - current.StartTime; current = null; } } } } } if (current != null) { current.Duration = endTime - current.StartTime; } } return(flights); }
public async Task Load(string fileName, ProgressUtility progress) { flights.Clear(); // CSV doesn't have realtime clock, so go with the file date instead. this.startTime = File.GetLastWriteTime(fileName); // time (us) int min = int.MaxValue; int max = int.MinValue; await Task.Run(() => { using (Stream s = File.OpenRead(fileName)) { XmlNameTable nametable = new NameTable(); using (XmlCsvReader reader = new XmlCsvReader(s, System.Text.Encoding.UTF8, new Uri(fileName), nametable)) { progress.ShowProgress(0, s.Length, s.Position); reader.FirstRowHasColumnNames = true; data = XDocument.Load(reader); this.schema = new LogItemSchema() { Name = "CsvDataLog", Type = "Root" }; // create the schema List<LogItemSchema> children = new List<Model.LogItemSchema>(); foreach (String name in reader.ColumnNames) { children.Add(new LogItemSchema() { Name = name, Parent = this.schema }); } this.schema.ChildItems = children; progress.ShowProgress(0, s.Length, s.Position); } } foreach (var e in data.Root.Elements()) { int? i = GetTimeMicroseconds(e); if (i.HasValue) { if (i.Value < min) { min = i.Value; } if (i > max) { max = i.Value; } } } }); // this log has no absolute UTC time, only ticks since board was booted, so we make up a start time. DateTime end = this.startTime.AddMilliseconds((max - min) / 1000); var flight = new Flight() { Log = this, StartTime = this.startTime, Duration = end - this.startTime }; this.duration = end - this.startTime; this.flights.Add(flight); }
public async Task Load(string fileName, ProgressUtility progress) { flights.Clear(); // CSV doesn't have realtime clock, so go with the file date instead. this.startTime = File.GetLastWriteTime(fileName); // time (ms) long min = long.MaxValue; long max = long.MinValue; await Task.Run(() => { timeElementName = null; using (Stream s = File.OpenRead(fileName)) { Dictionary <string, LogItemSchema> map = new Dictionary <string, LogItemSchema>(); XmlNameTable nametable = new NameTable(); using (XmlCsvReader reader = new XmlCsvReader(s, System.Text.Encoding.UTF8, new Uri(fileName), nametable)) { reader.FirstRowHasColumnNames = true; reader.ColumnsAsAttributes = true; while (reader.Read()) { progress.ShowProgress(0, s.Length, s.Position); if (this.schema == null) { // create the schema this.schema = new LogItemSchema() { Name = "CsvLog", Type = "Root" }; List <LogItemSchema> children = new List <Model.LogItemSchema>(); LogItemSchema row = null; foreach (String name in reader.ColumnNames) { if (timeElementName == null && (name.ToLower().Contains("time") || name.ToLower().Contains("ticks"))) { timeElementName = name; } if (name.Contains(":")) { // then we have sub-parts. int pos = name.IndexOf(":"); string key = name.Substring(0, pos); string field = name.Substring(pos + 1); LogItemSchema group = null; if (!map.ContainsKey(key)) { group = new LogItemSchema() { Name = key, Parent = this.schema, Type = key, ChildItems = new List <LogItemSchema>() }; children.Add(group); map[key] = group; } else { group = map[key]; } var leaf = new LogItemSchema() { Name = field, Parent = group, Type = "Double" }; group.ChildItems.Add(leaf); map[name] = leaf; } else { if (row == null) { row = new LogItemSchema() { Name = "Other", Parent = this.schema, Type = "Other", ChildItems = new List <LogItemSchema>() }; children.Add(row); } var leaf = new LogItemSchema() { Name = name, Parent = row, Type = "Double" }; row.ChildItems.Add(leaf); map[name] = leaf; } } this.schema.ChildItems = children; } if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "row") { // read a row long time = GetTicks(reader); min = Math.Min(min, time); max = Math.Max(max, time); LogEntry row = new Model.LogEntry() { Name = "Other", Timestamp = (ulong)time }; log.Add(row); Dictionary <string, LogEntry> groups = new Dictionary <string, LogEntry>(); if (reader.MoveToFirstAttribute()) { do { string name = XmlConvert.DecodeName(reader.LocalName); LogItemSchema itemSchema = map[name]; LogEntry e = row; if (name.Contains(":")) { // then we have sub-parts. int pos = name.IndexOf(":"); string key = name.Substring(0, pos); string field = name.Substring(pos + 1); if (!groups.ContainsKey(key)) { e = new LogEntry() { Name = key, Timestamp = (ulong)time }; groups[key] = e; log.Add(e); } else { e = groups[key]; } name = field; } string value = reader.Value; double d = 0; if (double.TryParse(value, out d)) { e.SetField(name, d); } else { if (!string.IsNullOrEmpty(value)) { // not a number. itemSchema.Type = "String"; e.SetField(name, value); } } }while (reader.MoveToNextAttribute()); reader.MoveToElement(); } } } } } }); // this log has no absolute UTC time, only ticks since board was booted, so we make up a start time. DateTime end = this.startTime.AddMilliseconds((max - min) / 1000); var flight = new Flight() { Log = this, StartTime = this.startTime, Duration = end - this.startTime }; this.duration = end - this.startTime; this.flights.Add(flight); }