From af5747c0882595298aa6663aae3dc08032e0fcf2 Mon Sep 17 00:00:00 2001 From: Adam M Rivera Date: Tue, 17 Apr 2012 10:02:39 -0500 Subject: [PATCH] ArdupilotMegaPlanner: Added new APPROACH flight mode and added infrastructure necessary to make it private (ie. not a user selectable mode). --- .../ArdupilotMegaPlanner/ArdupilotMega.csproj | 3 + .../Attributes/DisplayTextAttribute.cs | 44 +++++++ .../Attributes/PrivateAttribute.cs | 35 +++++ Tools/ArdupilotMegaPlanner/Common.cs | 23 +++- Tools/ArdupilotMegaPlanner/CurrentState.cs | 24 ++-- .../ConfigurationView/ConfigFlightModes.cs | 63 +++++++-- .../Utilities/EnumTranslator.cs | 120 ++++++++++++++++++ 7 files changed, 289 insertions(+), 23 deletions(-) create mode 100644 Tools/ArdupilotMegaPlanner/Attributes/DisplayTextAttribute.cs create mode 100644 Tools/ArdupilotMegaPlanner/Attributes/PrivateAttribute.cs create mode 100644 Tools/ArdupilotMegaPlanner/Utilities/EnumTranslator.cs diff --git a/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj b/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj index e781b8cbac..8a91b148d9 100644 --- a/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj +++ b/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj @@ -222,6 +222,8 @@ Tracker.cs + + UserControl @@ -540,6 +542,7 @@ + Tracker.cs diff --git a/Tools/ArdupilotMegaPlanner/Attributes/DisplayTextAttribute.cs b/Tools/ArdupilotMegaPlanner/Attributes/DisplayTextAttribute.cs new file mode 100644 index 0000000000..8b34715b0a --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Attributes/DisplayTextAttribute.cs @@ -0,0 +1,44 @@ +#region Using Statements + +using System; + +#endregion + +namespace ArdupilotMega.Attributes +{ + /// + /// Used to decorate a type or type member with display text. + /// + [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] + public sealed class DisplayTextAttribute : Attribute + { + + private readonly string _text; + + /// + /// Initializes a new instance of the class. + /// + /// The text. + /// + /// Thrown when is null or empty. + /// + public DisplayTextAttribute(string text) + { + if (String.IsNullOrEmpty(text)) + { + throw new ArgumentException("\"text\" is required."); + } + _text = text; + } + + /// + /// Gets the text. + /// + /// The text. + public string Text + { + get { return _text; } + } + + } +} diff --git a/Tools/ArdupilotMegaPlanner/Attributes/PrivateAttribute.cs b/Tools/ArdupilotMegaPlanner/Attributes/PrivateAttribute.cs new file mode 100644 index 0000000000..129d81ac4d --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Attributes/PrivateAttribute.cs @@ -0,0 +1,35 @@ +#region Using Statements + +using System; + +#endregion + +namespace ArdupilotMega.Attributes +{ + [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] + public sealed class PrivateAttribute : Attribute + { + private readonly bool _isPrivate; + + /// + /// Initializes a new instance of the class. + /// + /// if set to true [is private]. + public PrivateAttribute(bool isPrivate) + { + _isPrivate = isPrivate; + } + + /// + /// Gets a value indicating whether this instance is private. + /// + /// + /// true if this instance is private; otherwise, false. + /// + public bool IsPrivate + { + get { return _isPrivate; } + } + + } +} diff --git a/Tools/ArdupilotMegaPlanner/Common.cs b/Tools/ArdupilotMegaPlanner/Common.cs index 4a596aeca5..a18051f967 100644 --- a/Tools/ArdupilotMegaPlanner/Common.cs +++ b/Tools/ArdupilotMegaPlanner/Common.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using AGaugeApp; using System.IO.Ports; using System.Threading; +using ArdupilotMega.Attributes; using GMap.NET; using GMap.NET.WindowsForms; using GMap.NET.WindowsForms.Markers; @@ -319,28 +320,48 @@ namespace ArdupilotMega public enum ac2modes { + [DisplayText("Stabilize")] STABILIZE = 0, // hold level position + [DisplayText("Acro")] ACRO = 1, // rate control + [DisplayText("Altitude Hold")] ALT_HOLD = 2, // AUTO control + [DisplayText("Auto")] AUTO = 3, // AUTO control + [DisplayText("Guided")] GUIDED = 4, // AUTO control + [DisplayText("Loiter")] LOITER = 5, // Hold a single location + [DisplayText("Return to Launch")] RTL = 6, // AUTO control + [DisplayText("Circle")] CIRCLE = 7, + [DisplayText("Position Hold")] POSITION = 8, + [DisplayText("Land")] LAND = 9, // AUTO control - OF_LOITER = 10 + [Private(true)] + APPROACH = 10, + OF_LOITER = 11 } public enum ac2ch7modes { + [DisplayText("Do Nothing")] CH7_DO_NOTHING = 0, + [DisplayText("Set Hover")] CH7_SET_HOVER = 1, + [DisplayText("Flip")] CH7_FLIP = 2, + [DisplayText("Simple Mode")] CH7_SIMPLE_MODE = 3, + [DisplayText("Return to Launch")] CH7_RTL = 4, + [DisplayText("Automatic Trim")] CH7_AUTO_TRIM = 5, + [DisplayText("ADC Filter")] CH7_ADC_FILTER = 6, + [DisplayText("Save Waypoint")] CH7_SAVE_WP = 7 } diff --git a/Tools/ArdupilotMegaPlanner/CurrentState.cs b/Tools/ArdupilotMegaPlanner/CurrentState.cs index 5549044d61..e4d083d322 100644 --- a/Tools/ArdupilotMegaPlanner/CurrentState.cs +++ b/Tools/ArdupilotMegaPlanner/CurrentState.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Reflection; using System.Text; using System.ComponentModel; +using ArdupilotMega.Utilities; using log4net; namespace ArdupilotMega @@ -503,34 +504,37 @@ namespace ArdupilotMega } break; case (byte)(100 + Common.ac2modes.STABILIZE): - mode = "Stabilize"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.STABILIZE); break; case (byte)(100 + Common.ac2modes.ACRO): - mode = "Acro"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.ACRO); break; case (byte)(100 + Common.ac2modes.ALT_HOLD): - mode = "Alt Hold"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.ALT_HOLD); break; case (byte)(100 + Common.ac2modes.AUTO): - mode = "Auto"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.AUTO); break; case (byte)(100 + Common.ac2modes.GUIDED): - mode = "Guided"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.GUIDED); break; case (byte)(100 + Common.ac2modes.LOITER): - mode = "Loiter"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.LOITER); break; case (byte)(100 + Common.ac2modes.RTL): - mode = "RTL"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.RTL); break; case (byte)(100 + Common.ac2modes.CIRCLE): - mode = "Circle"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.CIRCLE); break; case (byte)(100 + Common.ac2modes.LAND): - mode = "Land"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.LAND); + break; + case (byte)(100 + Common.ac2modes.APPROACH): + mode = EnumTranslator.GetDisplayText(Common.ac2modes.APPROACH); break; case (byte)(100 + Common.ac2modes.POSITION): - mode = "Position"; + mode = EnumTranslator.GetDisplayText(Common.ac2modes.POSITION); break; case (byte)ArdupilotMega.MAVLink.MAV_MODE.MAV_MODE_MANUAL: mode = "Manual"; diff --git a/Tools/ArdupilotMegaPlanner/GCSViews/ConfigurationView/ConfigFlightModes.cs b/Tools/ArdupilotMegaPlanner/GCSViews/ConfigurationView/ConfigFlightModes.cs index 58994c233e..863b3b9964 100644 --- a/Tools/ArdupilotMegaPlanner/GCSViews/ConfigurationView/ConfigFlightModes.cs +++ b/Tools/ArdupilotMegaPlanner/GCSViews/ConfigurationView/ConfigFlightModes.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using System.Windows.Forms; using ArdupilotMega.Controls.BackstageView; +using ArdupilotMega.Utilities; namespace ArdupilotMega.GCSViews.ConfigurationView { @@ -165,12 +166,31 @@ namespace ArdupilotMega.GCSViews.ConfigurationView CMB_fmode5.Items.Clear(); CMB_fmode6.Items.Clear(); - CMB_fmode1.Items.AddRange(Enum.GetNames(typeof(Common.apmmodes))); - CMB_fmode2.Items.AddRange(Enum.GetNames(typeof(Common.apmmodes))); - CMB_fmode3.Items.AddRange(Enum.GetNames(typeof(Common.apmmodes))); - CMB_fmode4.Items.AddRange(Enum.GetNames(typeof(Common.apmmodes))); - CMB_fmode5.Items.AddRange(Enum.GetNames(typeof(Common.apmmodes))); - CMB_fmode6.Items.AddRange(Enum.GetNames(typeof(Common.apmmodes))); + var flightModes = EnumTranslator.Translate(); + + CMB_fmode1.DataSource = flightModes; + CMB_fmode1.ValueMember = "Value"; + CMB_fmode1.DisplayMember = "Value"; + + CMB_fmode2.DataSource = flightModes; + CMB_fmode2.ValueMember = "Value"; + CMB_fmode2.DisplayMember = "Value"; + + CMB_fmode3.DataSource = flightModes; + CMB_fmode3.ValueMember = "Value"; + CMB_fmode3.DisplayMember = "Value"; + + CMB_fmode4.DataSource = flightModes; + CMB_fmode4.ValueMember = "Value"; + CMB_fmode4.DisplayMember = "Value"; + + CMB_fmode5.DataSource = flightModes; + CMB_fmode5.ValueMember = "Value"; + CMB_fmode5.DisplayMember = "Value"; + + CMB_fmode6.DataSource = flightModes; + CMB_fmode6.ValueMember = "Value"; + CMB_fmode6.DisplayMember = "Value"; try { @@ -193,12 +213,31 @@ namespace ArdupilotMega.GCSViews.ConfigurationView CMB_fmode5.Items.Clear(); CMB_fmode6.Items.Clear(); - CMB_fmode1.Items.AddRange(Enum.GetNames(typeof(Common.ac2modes))); - CMB_fmode2.Items.AddRange(Enum.GetNames(typeof(Common.ac2modes))); - CMB_fmode3.Items.AddRange(Enum.GetNames(typeof(Common.ac2modes))); - CMB_fmode4.Items.AddRange(Enum.GetNames(typeof(Common.ac2modes))); - CMB_fmode5.Items.AddRange(Enum.GetNames(typeof(Common.ac2modes))); - CMB_fmode6.Items.AddRange(Enum.GetNames(typeof(Common.ac2modes))); + var flightModes = EnumTranslator.Translate(); + + CMB_fmode1.DataSource = flightModes; + CMB_fmode1.ValueMember = "Value"; + CMB_fmode1.DisplayMember = "Value"; + + CMB_fmode2.DataSource = flightModes; + CMB_fmode2.ValueMember = "Value"; + CMB_fmode2.DisplayMember = "Value"; + + CMB_fmode3.DataSource = flightModes; + CMB_fmode3.ValueMember = "Value"; + CMB_fmode3.DisplayMember = "Value"; + + CMB_fmode4.DataSource = flightModes; + CMB_fmode4.ValueMember = "Value"; + CMB_fmode4.DisplayMember = "Value"; + + CMB_fmode5.DataSource = flightModes; + CMB_fmode5.ValueMember = "Value"; + CMB_fmode5.DisplayMember = "Value"; + + CMB_fmode6.DataSource = flightModes; + CMB_fmode6.ValueMember = "Value"; + CMB_fmode6.DisplayMember = "Value"; try { diff --git a/Tools/ArdupilotMegaPlanner/Utilities/EnumTranslator.cs b/Tools/ArdupilotMegaPlanner/Utilities/EnumTranslator.cs new file mode 100644 index 0000000000..e1901aadf1 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Utilities/EnumTranslator.cs @@ -0,0 +1,120 @@ +#region Using Statements + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using ArdupilotMega.Attributes; + +#endregion + +namespace ArdupilotMega.Utilities +{ + public static class EnumTranslator + { + /// + /// Translates this instance. + /// + /// + /// + public static Dictionary Translate() + { + return Translate(true); + } + + /// + /// Translates the specified check private. + /// + /// + /// if set to true [check private]. + /// + public static Dictionary Translate(bool checkPrivate) + { + return Translate(string.Empty, checkPrivate); + } + + /// + /// Translates the specified default text. + /// + /// + /// The default text. + /// if set to true [check private]. + /// + public static Dictionary Translate(string defaultText, bool checkPrivate) + { + return Translate(defaultText, checkPrivate, true); + } + + /// + /// Translates the specified default text. + /// + /// + /// The default text. + /// if set to true [check private]. + /// if set to true [sorting]. + /// + public static Dictionary Translate(string defaultText, bool checkPrivate, bool sorting) + { + var types = new Dictionary(); + var tempTypes = new Dictionary(); + if (!String.IsNullOrEmpty(defaultText)) types.Add(-1, defaultText); + foreach (FieldInfo fieldInfo in typeof(T).GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public)) + { + bool add = true; + string displayText = string.Empty; + T type = (T)fieldInfo.GetValue(typeof(T)); + object[] displayTextObjectArr = fieldInfo.GetCustomAttributes(typeof(DisplayTextAttribute), true); + displayText = (displayTextObjectArr.Length > 0) + ? ((DisplayTextAttribute)displayTextObjectArr[0]).Text + : type.ToString(); + if (checkPrivate) + { + object[] privateAttributeObjectArr = fieldInfo.GetCustomAttributes(typeof(PrivateAttribute), true); + if (privateAttributeObjectArr.Length > 0) + { + add = !((PrivateAttribute)privateAttributeObjectArr[0]).IsPrivate; + } + } + if (add) + { + tempTypes.Add(Convert.ToInt32(type), displayText); + } + } + if (sorting) + { + foreach(var x in tempTypes.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value)){ types.Add(x.Key, x.Value); } + } + else + { + foreach (var x in tempTypes.ToDictionary(x => x.Key, x => x.Value)) { types.Add(x.Key, x.Value); } + } + return types; + } + + /// + /// Gets the display text. + /// + /// + /// The value. + /// + public static string GetDisplayText(T value) + { + var displayText = string.Empty; + var fieldInfo = value.GetType().GetField(value.ToString()); + if(fieldInfo != null) + { + T type = (T)fieldInfo.GetValue(typeof(T)); + if(type != null) + { + object[] displayTextObjectArr = fieldInfo.GetCustomAttributes(typeof(DisplayTextAttribute), true); + displayText = (displayTextObjectArr.Length > 0) + ? ((DisplayTextAttribute)displayTextObjectArr[0]).Text + : type.ToString(); + } + } + return displayText; + } + + } + +}