public static void Build() { var progressTitle = "Building unit database..."; lock (@lock) { using (ProfilingUtility.SampleBlock("Update Unit Database")) { using (NativeUtility.Module("sqlite3.dll")) { SQLiteConnection database = null; try { ProgressUtility.DisplayProgressBar(progressTitle, "Creating database...", 0); if (File.Exists(BoltFlow.Paths.unitOptions)) { VersionControlUtility.Unlock(BoltFlow.Paths.unitOptions); File.Delete(BoltFlow.Paths.unitOptions); } PathUtility.CreateParentDirectoryIfNeeded(BoltFlow.Paths.unitOptions); database = new SQLiteConnection(BoltFlow.Paths.unitOptions); database.CreateTable <UnitOptionRow>(); ProgressUtility.DisplayProgressBar(progressTitle, "Updating codebase...", 0); UpdateCodebase(); ProgressUtility.DisplayProgressBar(progressTitle, "Updating type mappings...", 0); UpdateTypeMappings(); ProgressUtility.DisplayProgressBar(progressTitle, "Converting codebase to unit options...", 0); options = new HashSet <IUnitOption>(GetStaticOptions()); var rows = new HashSet <UnitOptionRow>(); var progress = 0; var lastShownProgress = 0f; foreach (var option in options) { try { var shownProgress = (float)progress / options.Count; if (shownProgress > lastShownProgress + 0.01f) { ProgressUtility.DisplayProgressBar(progressTitle, "Converting codebase to unit options...", shownProgress); lastShownProgress = shownProgress; } rows.Add(option.Serialize()); } catch (Exception ex) { Debug.LogError($"Failed to save option '{option.GetType()}'.\n{ex}"); } progress++; } ProgressUtility.DisplayProgressBar(progressTitle, "Writing to database...", 1); try { database.CreateTable <UnitOptionRow>(); database.InsertAll(rows); } catch (Exception ex) { Debug.LogError($"Failed to write options to database.\n{ex}"); } } finally { database?.Close(); ProgressUtility.ClearProgressBar(); AssetDatabase.Refresh(); //ConsoleProfiler.Dump(); } } } } }
public async Task Load(string file, ProgressUtility progress) { this.file = file; this.startTime = DateTime.MinValue; this.duration = TimeSpan.Zero; bool first = true; // QT time is milliseconds from the following epoch. byte[] msgBuf = new byte[256]; GCHandle handle = GCHandle.Alloc(msgBuf, GCHandleType.Pinned); IntPtr ptr = handle.AddrOfPinnedObject(); DateTime lastTime = DateTime.MinValue; await Task.Run(() => { // MAVLINK_MSG_ID using (Stream s = File.OpenRead(file)) { BinaryReader reader = new BinaryReader(s); while (s.Position < s.Length) { progress.ShowProgress(0, s.Length, s.Position); try { MavLinkMessage header = new MavLinkMessage(); header.ReadHeader(reader); while (!header.IsValid()) { // hmm. looks like a bad record, so now what? header.ShiftHeader(reader); } int read = s.Read(msgBuf, 0, header.Length); if (read == header.Length) { header.Crc = reader.ReadUInt16(); if (!header.IsValidCrc(msgBuf, read)) { continue; } Type msgType = MAVLink.MAVLINK_MESSAGE_INFO[(int)header.MsgId]; if (msgType != null) { // convert to proper mavlink structure. header.TypedPayload = Marshal.PtrToStructure(ptr, msgType); } Message message = AddMessage(header); if (first) { startTime = message.Timestamp; first = false; } } } catch { // try and continue... } } } handle.Free(); }); this.duration = lastTime - startTime; }
public async Task Load(string file, ProgressUtility progress) { this.file = file; string ext = System.IO.Path.GetExtension(file).ToLowerInvariant(); if (ext == ".bin") { this.logType = LogType.binFile; } else if (ext == ".px4log") { this.logType = LogType.px4logFile; } bool hasStartTime = false; this.startTime = DateTime.MinValue; List <LogEntry> rows = new List <LogEntry>(); await Task.Run(() => { using (Stream s = File.OpenRead(file)) { BinaryReader reader = new BinaryReader(s); PX4BinaryLog log = new PX4BinaryLog(this.logType); log.GenerateParser = false; DateTime?gpsStartTime = null; ulong gpsAbsoluteOffset = 0; ulong logStartTime = 0; while (s.Position < s.Length) { progress.ShowProgress(0, s.Length, s.Position); LogEntry row = log.ReadMessageObjects(s) as LogEntry; if (row == null) { // has no system clock value yet, so skip it. continue; } if (!hasStartTime && log.CurrentTime != 0) { hasStartTime = true; logStartTime = log.CurrentTime; this.startTime = GetTime(log.CurrentTime); } if (!gpsStartTime.HasValue && row.Name == "GPS") { ulong time = row.GetField <ulong>("GPSTime"); if (time > 0) { // ok, we got a real GPS time gpsStartTime = GetTime(time); // backtrack and fix up initial rows. if (hasStartTime) { // compute offset from PX4 boot time (which is the log.CurrentTime) and the absolute GPS real time clock // so we can add this offset to PX4 log.CurrentTime so all our times from here on out are in real time. gpsStartTime = gpsStartTime.Value.AddMilliseconds((double)logStartTime - (double)log.CurrentTime); } ulong linuxEpochMicroseconds = ((ulong)(gpsStartTime.Value.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalMilliseconds * 1000); gpsAbsoluteOffset = linuxEpochMicroseconds - logStartTime; this.startTime = gpsStartTime.Value; // and fix existing log entries foreach (LogEntry e in rows) { // add GPS absolute offset to the timestamp. e.Timestamp += gpsAbsoluteOffset; } hasStartTime = true; } } if (gpsStartTime.HasValue) { // add GPS absolute offset to the timestamp. row.Timestamp += gpsAbsoluteOffset; } rows.Add(row); if (row.Format.Name == "PARM") { string name = row.GetField <string>("Name"); float value = row.GetField <float>("Value"); Debug.WriteLine("{0}={1}", name, value); } } if (log.CurrentTime != 0) { DateTime endTime = GetTime(log.CurrentTime + gpsAbsoluteOffset); this.duration = endTime - startTime; Debug.WriteLine("StartTime={0}, EndTime={1}, Duration={2}", startTime.ToString(), endTime.ToString(), duration.ToString()); } CreateSchema(log); } }); this.data = rows; }
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); }
protected override void HandleViewDidAppear(bool animated) { base.HandleViewDidAppear(animated); //UIApplication.SharedApplication.KeyWindow.AddSubview(ReconnectingOverlay.Instance); //LocationUtility.DistanceInMetersFrom(13.736717, 100.523186); if (_attemptAutoLogin) { var deviceListVc = DeviceListViewController.CreateInstance(); if (User.Current == null || !User.Current.HasConfig) { //redirect to Config VC //this.NavigationController.PushViewController(ViewControllerFactory.GetViewController<UserConfigViewController>(), true); NavigateUserConfig(); } else { ProgressUtility.SafeShow("Connecting", async() => { var userConfigVc = UserConfigViewController.CreateInstance(); var response = await ServiceContainer.UserService.RequestConnection( User.Current.Username, User.Current.Password); MainThreadUtility.InvokeOnMain(() => { ProgressUtility.Dismiss(); //on connection error, redirect to config if (response != null && response.IsSuccessful) { //redirect to device list this.NavigateTo(deviceListVc, inCurrentNavController: false); //this.PresentViewController(new AquamonixNavController(deviceListVc), true, null); } else { //this.NavigateTo(userConfigVc, inCurrentNavController: false); if (response?.ErrorBody != null && response.ErrorBody.ErrorType == Aquamonix.Mobile.Lib.Domain.Responses.ErrorResponseType.AuthFailure) { Caches.ClearCachesForAuthFailure(); } //is device cache valid? if (DataCache.HasDevices) { //redirect to device list deviceListVc.ShowConnectionError = true; this.NavigateTo(deviceListVc, inCurrentNavController: false); } else { //redirect to user config userConfigVc.ShowConnectionError = true; this.NavigateTo(userConfigVc, inCurrentNavController: false); } } }); }); } } else { this.PresentViewController(new StartViewController(true), false, null); } }