/// <summary> /// This methode is the complement of previous methode DisplayOnForm. /// </summary> /// <param name="cm"></param> private void GetFromForm(ChangeMarker cm) { if (Settings.MachineType == MachineTypes.StreetWasher) { cm.SpreadingOnOff = chkPump.Checked; cm.Hopper1OnOff = chkLeftJetOnOff.Checked; cm.Hopper2OnOff = chkRightJetOnOff.Checked; cm.Dosage = (double)numPressure.Value; cm.SpreadingWidthLeft = (double)numPositionLeftJet.Value; cm.SpreadingWidthRight = (double)numPositionRightJet.Value; } else { // Row 1 cm.SpreadingOnOff = chkSpreading.Checked; cm.DualWidthOnOff = chkDualWidth.Checked; cm.SprayingOnOff = chkSpraying.Checked; // Row 2 cm.Dosage = (double)numDosage.Value; cm.MaxOnOff = chkMaxOnOff.Checked; cm.SecMatOnOff = chkSecMatOnOff.Checked; cm.PersentageLiquid = (double)numPersentageLiquid.Value; cm.DosageLiquid = (double)numDosageLiquid.Value; cm.Hopper1OnOff = chkHopper1OnOff.Checked; cm.Hopper2OnOff = chkHopper2OnOff.Checked; // Row 3 cm.SpreadingWidthLeft = (double)numSpreadingWidthLeft.Value; cm.SpreadingWidthRight = (double)numSpreadingWidthRight.Value; cm.SprayingWidthLeft = (double)numSprayingWidthLeft.Value; cm.SprayingWidthRight = (double)numSprayingWidthRight.Value; } }
/// <summary> /// This methode displays the Changemarker class content (=xml) onto the form. /// If this methode changes then also update methode GetFromForm! /// </summary> /// <param name="cm"></param> private void DisplayOnForm(ChangeMarker cm) { if (Settings.MachineType == MachineTypes.StreetWasher) { chkPump.Checked = cm.SpreadingOnOff; chkLeftJetOnOff.Checked = cm.Hopper1OnOff; chkRightJetOnOff.Checked = cm.Hopper2OnOff; Set(numPressure, cm.Dosage); Set(numPositionRightJet, cm.SpreadingWidthRight); Set(numPositionLeftJet, cm.SpreadingWidthLeft); } else { // Row 1 chkSpreading.Checked = cm.SpreadingOnOff; chkDualWidth.Checked = cm.DualWidthOnOff; chkSpraying.Checked = cm.SprayingOnOff; // Row 2 Set(numDosage, cm.Dosage); chkMaxOnOff.Checked = cm.MaxOnOff; chkSecMatOnOff.Checked = cm.SecMatOnOff; Set(numPersentageLiquid, cm.PersentageLiquid); Set(numDosageLiquid, cm.DosageLiquid); chkHopper1OnOff.Checked = cm.Hopper1OnOff; chkHopper2OnOff.Checked = cm.Hopper2OnOff; // Row 3 Set(numSpreadingWidthLeft, cm.SpreadingWidthLeft); Set(numSpreadingWidthRight, cm.SpreadingWidthRight); Set(numSprayingWidthLeft, cm.SprayingWidthLeft); Set(numSprayingWidthRight, cm.SprayingWidthRight); } }
/// <summary> /// Read AR3 file. See http://confluence.ash.ads.org/display/EHP/Autologic+ar3+route+file+format.+V2 /// </summary> /// <param name="filename">ar3 filename</param> /// <returns>ar3 route</returns> public static Route ReadAr3(string filename) { #region FIELDS // // The distance table contains the relation between LatLng and distance. // Filled during Read Gps markers. Filled with unique latlng and sorted distance. // var distanceTable = new Dictionary <PointLatLng, int>(); var line = string.Empty; var version = string.Empty; var startPoint = new PointLatLng(); var lastDistance = -1; var route = new Route() { FileName = filename }; var random = new Random(); var previousChangeMarker = new ChangeMarker(); errors = new int[5]; // used in unittesting. #endregion using (TextReader reader = new StreamReader(filename)) { while ((line = reader.ReadLine()) != null) { try { var s = line.Split(':', ','); // #region READ HEADER // if (line.StartsWith("Ar3")) { version = s[1]; } else if (line.StartsWith("MachineType")) { route.MachineType = My.GetEnum <MachineTypes>(s[1]); } #endregion // #region READ GPS MARKERS // else if (line.StartsWith("WayPoint[")) { var distance = (int)My.Val(s[3]); if (distance < lastDistance) { My.Log($"{++errors[0]} {line} has descending distance and will be ignored."); } else if (distance == lastDistance) { My.Log($"{++errors[1]} Duplicated line {line}"); } else { var point = Unique(new PointLatLng(My.Val(s[2]), My.Val(s[1])), distance); route.GpsMarkers.Add(new GpsMarker(point)); if (startPoint.IsEmpty) { startPoint = point; latLngFirstNav = Unique(startPoint, 20); // Sort dictionary 4 holten_cityjet.ar3 } } lastDistance = distance; } #endregion // #region READ NAVIGATION MARKERS // else if (line.StartsWith("Instruction[")) { PointLatLng latlng; if (s[1] == "0") // Set first Navigation marker not at distance zero. This is reserved for Change marker. { latlng = latLngFirstNav; route.GpsMarkers.Insert(1, new GpsMarker(latlng)); } else { latlng = FindLatLng(s[1]); } var marker = new NavigationMarker(latlng); if (s[2] == "1007") // Get custom message. { marker.Message = (s[6] != "") ? s[6] : Path.GetFileNameWithoutExtension(s[5]); } else { marker.Message = NavigationMessage(s[2]); } // // Get roundabout index. // marker.RoundAboutIndex = Math.Max((int)My.Val(s[3]), 0); if (marker.Message == "-") { My.Log($"{++errors[2]} {line} Unkown navigation type {s[2]}"); } marker.SoundFile = My.ValidateFilename((s[5] != "") ? s[5] : (marker.Message + ".wav")); // Todo create soundfile. route.NavigationMarkers.Add(marker); } #endregion // #region READ CHANGE MARKERS // else if (line.StartsWith("ChangePoint[")) { var marker = new ChangeMarker(FindLatLng(s[1])); if (route.MachineType == MachineTypes.StreetWasher) { // 1=DistanceFromStart, ActivityState, LeftNozzleIsActive, LeftNozzlePosition, RightNozzleIsActive, RightNozzlePosition, waterpressure,Marked, Message // If this code is changed then modify also methode DisplayOnForm. // // Handle empty strings; use previous marker value. marker.SpreadingOnOff = My.Bool(s[2], previousChangeMarker.SpreadingOnOff); marker.Hopper1OnOff = My.Bool(s[3], previousChangeMarker.Hopper1OnOff); marker.SpreadingWidthLeft = My.Val(s[4], previousChangeMarker.SpreadingWidthLeft); marker.Hopper2OnOff = My.Bool(s[5], previousChangeMarker.Hopper2OnOff); marker.SpreadingWidthRight = My.Val(s[6], previousChangeMarker.SpreadingWidthRight); marker.Dosage = My.Val(s[7], previousChangeMarker.Dosage); // // Set default pressure according spec. // if (marker.Dosage < 5) { marker.Dosage = 5; } } else { // 1=DistanceFromStartInCm, SpreadSprayOnOff, SprayModeOnOff, Max, SecMat,Dosage, WidthLeft, WidthRight, SecDos, WidthLeftSpraying, WidthRightSpraying, CombiPercentage, HopperSelection, Marked, Message marker.SpreadingOnOff = My.Bool(s[2], previousChangeMarker.SpreadingOnOff); marker.SprayingOnOff = My.Bool(s[3], previousChangeMarker.SprayingOnOff); marker.MaxOnOff = My.Bool(s[4], previousChangeMarker.MaxOnOff); marker.SecMatOnOff = My.Bool(s[5], previousChangeMarker.SecMatOnOff); marker.Dosage = My.Val(s[6], previousChangeMarker.Dosage * 100) / 100; marker.SpreadingWidthLeft = My.Val(s[7], previousChangeMarker.SpreadingWidthLeft * 100) / 100; marker.SpreadingWidthRight = My.Val(s[8], previousChangeMarker.SpreadingWidthRight * 100) / 100; marker.DosageLiquid = My.Val(s[9], previousChangeMarker.DosageLiquid * 100) / 100; marker.SprayingWidthLeft = My.Val(s[10], previousChangeMarker.SprayingWidthLeft * 100) / 100; marker.SprayingWidthRight = My.Val(s[11], previousChangeMarker.SprayingWidthRight * 100) / 100; marker.PersentageLiquid = My.Val(s[12], previousChangeMarker.PersentageLiquid); } // // First change marker should have distance 0. // if (route.ChangeMarkers.Count == 0 && s[1] != "0") { route.ChangeMarkers.Add(new ChangeMarker(startPoint)); } route.ChangeMarkers.Add(marker); previousChangeMarker = marker; } #endregion } catch (Exception ee) { Log($"{++errors[3]} Error in {line} {ee.Message} {ee.StackTrace}"); } } // // First change marker should have distance 0. // if (route.ChangeMarkers.Count == 0) { route.ChangeMarkers.Add(new ChangeMarker(startPoint)); } } My.Log("End of requirement analyze."); return(route); // // Make unique LatLng point. See Software Design Document. // PointLatLng Unique(PointLatLng point, int distance) { while (distanceTable.ContainsKey(point)) { var r = random.NextDouble() / 100000; point = new PointLatLng(point.Lat + r, point.Lng + r); } distanceTable.Add(point, distance); return(point); } PointLatLng FindLatLng(string sdistance) { var distance = (int)My.Val(sdistance); var last = default(KeyValuePair <PointLatLng, int>); var idx = 0; foreach (var item in distanceTable) { ++idx; if (item.Value < distance) { last = item; } else if (item.Value == distance) { last = item; break; } else if (item.Value > distance) // No corresponding Gps marker (orphan). { if (last.Key.IsEmpty) { last = item; } if (item.Value - distance < distance - last.Value) { last = item; } if (distance - last.Value < 200) { break; // Don't mark as orphan when marker is within 200 cm of current or previous marker. } if (item.Value - distance < 200) { break; } ++errors[4]; break; } } distanceTable.Remove(last.Key); // Use distance only one's so that both Navigation- and Change marker can't be added to one gps marker. return(last.Key); } }