diff --git a/Tools/ArdupilotMegaPlanner/ArduCopterConfig.xml b/Tools/ArdupilotMegaPlanner/ArduCopterConfig.xml index 2558e46e2c8022bcb52c9e741b1213e441e8bd02..fda38f6780653459242fc80c616f181ad72dfae0 100644 --- a/Tools/ArdupilotMegaPlanner/ArduCopterConfig.xml +++ b/Tools/ArdupilotMegaPlanner/ArduCopterConfig.xml @@ -101,6 +101,70 @@ Too high = slow wobbles <STEP>0.001</STEP> </FIELD> </FIELDS> + + <SUBHEAD>Yaw Angular Rate Control:</SUBHEAD> + <DESC>How much throttle is applied to rotate the copter at the desired speed. + </DESC> + <FIELDS> + <FIELD> + <NAME>P</NAME> + <PARAMNAME>RATE_YAW_P</PARAMNAME> + <RANGEMIN>0.001</RANGEMIN> + <RANGEMAX>5</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>I</NAME> + <PARAMNAME>RATE_YAW_I</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>5</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>D</NAME> + <PARAMNAME>RATE_YAW_D</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>5</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>IMAX</NAME> + <PARAMNAME>RATE_YAW_IMAX</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>50</RANGEMAX> + <STEP>1</STEP> + </FIELD> + </FIELDS> + + <SUBHEAD>Yaw Stabilize Control:</SUBHEAD> + <DESC> + How fast the copter reacts to user or autopilot input. + Higher = more aggressive control. + Too high = slow wobbles + </DESC> + <FIELDS> + <FIELD> + <NAME>P</NAME> + <PARAMNAME>STB_YAW_P</PARAMNAME> + <RANGEMIN>0.001</RANGEMIN> + <RANGEMAX>10</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>I</NAME> + <PARAMNAME>STB_YAW_I</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>5</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>IMAX</NAME> + <PARAMNAME>STB_YAW_IMAX</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>50</RANGEMAX> + <STEP>1</STEP> + </FIELD> + </FIELDS> </Item> <!-- Loiter --> <Item> @@ -140,7 +204,7 @@ How much angle is applied to make the copter accelerate to the desired speed. <PARAMNAME>LOITER_LON_IMAX</PARAMNAME> <RANGEMIN>0</RANGEMIN> <RANGEMAX>50</RANGEMAX> - <STEP>0.1</STEP> + <STEP>1</STEP> </FIELD> </FIELDS> <SUBHEAD>Loiter Speed:</SUBHEAD> diff --git a/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj b/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj index def4fc453c8dbbf8e5a82c6565a9c5da54614943..b318087f83590a47972b034963d31c86a2ccb17a 100644 --- a/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj +++ b/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj @@ -226,6 +226,7 @@ <Compile Include="Attributes\DisplayTextAttribute.cs" /> <Compile Include="Attributes\PrivateAttribute.cs" /> <Compile Include="CodeGen.cs" /> + <Compile Include="Utilities\CollectionExtensions.cs" /> <Compile Include="Utilities\ParameterMetaDataConstants.cs" /> <Compile Include="Controls\BackstageView\BackstageView.cs"> <SubType>UserControl</SubType> diff --git a/Tools/ArdupilotMegaPlanner/MainV2.cs b/Tools/ArdupilotMegaPlanner/MainV2.cs index f04826220bf9cc033b872fd744acb58fa515f155..907bb8c6caea25220150bc06bc8eb722ffd1b578 100644 --- a/Tools/ArdupilotMegaPlanner/MainV2.cs +++ b/Tools/ArdupilotMegaPlanner/MainV2.cs @@ -1733,8 +1733,18 @@ namespace ArdupilotMega static void DoUpdateWorker_DoWork(object sender, Controls.ProgressWorkerEventArgs e) { - ((ProgressReporterDialogue)sender).UpdateProgressAndStatus(-1, "Getting Base URL"); - MainV2.updateCheckMain((ProgressReporterDialogue)sender); + // TODO: Is this the right place? + #region Fetch Parameter Meta Data + + var progressReporterDialogue = ((ProgressReporterDialogue) sender); + progressReporterDialogue.UpdateProgressAndStatus(-1, "Getting Updated Parameters"); + + ParameterMetaDataParser.GetParameterInformation(); + + #endregion Fetch Parameter Meta Data + + progressReporterDialogue.UpdateProgressAndStatus(-1, "Getting Base URL"); + MainV2.updateCheckMain(progressReporterDialogue); } private static bool updateCheck(ProgressReporterDialogue frmProgressReporter, string baseurl, string subdir) diff --git a/Tools/ArdupilotMegaPlanner/Msi/wix.pdb b/Tools/ArdupilotMegaPlanner/Msi/wix.pdb index e2bd4a8c51e6596bf41da25015857ed84be7ef85..a5d459167772c92af2f5da9b7b52010c246af54a 100644 Binary files a/Tools/ArdupilotMegaPlanner/Msi/wix.pdb and b/Tools/ArdupilotMegaPlanner/Msi/wix.pdb differ diff --git a/Tools/ArdupilotMegaPlanner/Utilities/CollectionExtensions.cs b/Tools/ArdupilotMegaPlanner/Utilities/CollectionExtensions.cs new file mode 100644 index 0000000000000000000000000000000000000000..6b435af4025aabf2f92bf0bf975914ca637f78f5 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Utilities/CollectionExtensions.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ArdupilotMega.Utilities +{ + public static class CollectionExtensions + { + /// <summary> + /// Performs the specified <paramref name="action"/> on each element of the <paramref name="enumerable"/>. + /// + /// </summary> + /// <param name="enumerable">An enumerable instance. + /// </param><param name="action"/> + public static void ForEach(this IEnumerable enumerable, Action<object> action) + { + foreach (object obj in enumerable) + action(obj); + } + + /// <summary> + /// Performs the specified <paramref name="action"/> on each element of the <paramref name="enumerable"/>. + /// + /// </summary> + /// <param name="enumerable">An enumerable instance. + /// </param><param name="action"/> + public static void ForEach<T>(this IEnumerable enumerable, Action<T> action) + { + foreach (T obj in enumerable) + action(obj); + } + + /// <summary> + /// Performs the specified <paramref name="action"/> on each element of the <paramref name="enumerable"/>. + /// + /// </summary> + /// <typeparam name="T">The type contained in the <paramref name="enumerable"/>. + /// </typeparam><param name="enumerable"/><param name="action"/> + public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action) + { + foreach (T obj in enumerable) + action(obj); + } + } +} diff --git a/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataConstants.cs b/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataConstants.cs index 7f189aa0666761376bd16e56e1e14095b50b5633..fb29584b08521b229ca8621f0f818c2c149f7732 100644 --- a/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataConstants.cs +++ b/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataConstants.cs @@ -2,11 +2,23 @@ { public sealed class ParameterMetaDataConstants { - public const string Delimeter = "@"; + #region Markers + + public const string ParamDelimeter = "@"; + public const string PathDelimeter = ","; public const string Param = "Param"; + public const string Group = "Group"; + public const string Path = "Path"; + + #endregion + + #region Meta Keys + public const string DisplayName = "DisplayName"; public const string Description = "Description"; public const string Units = "Units"; public const string Range = "Range"; + + #endregion } -} +} \ No newline at end of file diff --git a/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataParser.cs b/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataParser.cs index 2c3d2c0e13df50a56cb8ff3e1fb07398b6f4e77b..d4498f0f5f391ee52658e704194fe03897cc9ab0 100644 --- a/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataParser.cs +++ b/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataParser.cs @@ -7,13 +7,15 @@ using System.Net; using System.Text.RegularExpressions; using System.Windows.Forms; using System.Xml; +using ArdupilotMega.Utilities; using log4net; namespace ArdupilotMega.Utilities { public static class ParameterMetaDataParser { - private static readonly Regex _paramMetaRegex = new Regex(String.Format("{0}(?<MetaKey>[^:]+):(?<MetaValue>.+)", ParameterMetaDataConstants.Delimeter)); + private static readonly Regex _paramMetaRegex = new Regex(String.Format("{0}(?<MetaKey>[^:]+):(?<MetaValue>.+)", ParameterMetaDataConstants.ParamDelimeter)); + private static readonly Regex _parentDirectoryRegex = new Regex("(?<ParentDirectory>[../]*)(?<Path>.+)"); private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); @@ -34,59 +36,85 @@ namespace ArdupilotMega.Utilities foreach (string parameterLocation in parameterLocations) { - log.Info(parameterLocation); + // Write the start element for this parameter location + objXmlTextWriter.WriteStartElement(parameterLocation.ToLower().Contains("arducopter") ? MainV2.Firmwares.ArduCopter2.ToString() : MainV2.Firmwares.ArduPlane.ToString()); - var request = WebRequest.Create(parameterLocation); + // Read and parse the content. + string dataFromAddress = ReadDataFromAddress(parameterLocation); + ParseGroupInformation(dataFromAddress, objXmlTextWriter, parameterLocation); + ParseParameterInformation(dataFromAddress, objXmlTextWriter); - // Plenty of timeout - request.Timeout = 10000; + // Write the end element for this parameter location + objXmlTextWriter.WriteEndElement(); - // Set the Method property of the request to GET. - request.Method = "GET"; - - // Get the response. - using (var response = request.GetResponse()) - { - // Display the status. - log.Info(((HttpWebResponse)response).StatusDescription); + } + + // Clear the stream + objXmlTextWriter.WriteEndDocument(); + objXmlTextWriter.Flush(); + objXmlTextWriter.Close(); + } + } + } - // Get the stream containing content returned by the server. - using (var dataStream = response.GetResponseStream()) - { - if (dataStream != null) + /// <summary> + /// Parses the group parameter information. + /// </summary> + /// <param name="fileContents">The file contents.</param> + /// <param name="objXmlTextWriter">The obj XML text writer.</param> + /// <param name="parameterLocation">The parameter location.</param> + private static void ParseGroupInformation(string fileContents, XmlTextWriter objXmlTextWriter, string parameterLocation) + { + var parsedInformation = ParseKeyValuePairs(fileContents, ParameterMetaDataConstants.Group); + if (parsedInformation != null && parsedInformation.Count > 0) + { + // node is the prefix of the parameter group here + parsedInformation.ForEach(node => + { + // node.Value is a nested dictionary containing the additional meta data + // In this case we are looking for the @Path key + if (node.Value != null && node.Value.Count > 0) + { + // Find the @Path key + node.Value + .Where(meta => meta.Key == ParameterMetaDataConstants.Path) + // We might have multiple paths to inspect, so break them out by the delimeter + .ForEach(path => path.Value.Split(new []{ ParameterMetaDataConstants.PathDelimeter }, StringSplitOptions.None) + .ForEach(separatedPath => { - // Open the stream using a StreamReader for easy access. - using (var reader = new StreamReader(dataStream)) + // Match based on the regex defined at the top of this class + Match pathMatch = _parentDirectoryRegex.Match(separatedPath); + if (pathMatch.Success && pathMatch.Groups["Path"] != null && !String.IsNullOrEmpty(pathMatch.Groups["Path"].Value)) { - // Write the start element for this parameter location - objXmlTextWriter.WriteStartElement(parameterLocation); + if (pathMatch.Groups["ParentDirectory"] != null && !String.IsNullOrEmpty(pathMatch.Groups["ParentDirectory"].Value)) + { + // How many directories from the original path do we have to move + int numberOfParentDirectoryMoves = pathMatch.Groups["ParentDirectory"].Value.Split(new string[] { "../" }, StringSplitOptions.None).Count(); - // Read and parse the content. - ParseParameterInformation(reader.ReadToEnd(), objXmlTextWriter); + // We need to remove the http:// or https:// prefix to build the new URL properly + string httpTest = parameterLocation.Substring(0, 7); + int trimHttpPrefixIdx = httpTest == "http://" ? 7 : 8; - // Write the end element for this parameter location - objXmlTextWriter.WriteEndElement(); + // Get the parts of the original URL + var parameterLocationParts = parameterLocation.Substring(trimHttpPrefixIdx, parameterLocation.Length - trimHttpPrefixIdx).Split(new char[] { '/' }); - // Close the reader - reader.Close(); - } + // Rebuild the new url taking into account the numberOfParentDirectoryMoves + string urlAfterParentDirectory = string.Empty; + for (int i = 0; i < parameterLocationParts.Length && i < parameterLocationParts.Length - numberOfParentDirectoryMoves; i++) + { + urlAfterParentDirectory += parameterLocationParts[i] + "/"; + } - // Close the datastream - dataStream.Close(); - } - } - - // Close the response - response.Close(); - } + // This is the URL of the file we need to parse for comments + string newPath = String.Format("{0}{1}{2}", parameterLocation.Substring(0, trimHttpPrefixIdx), urlAfterParentDirectory, pathMatch.Groups["Path"].Value); + // Parse the param info from the newly constructed URL + ParseParameterInformation(ReadDataFromAddress(newPath), objXmlTextWriter, node.Key); + } + } + })); } - - // Clear the stream - objXmlTextWriter.WriteEndDocument(); - objXmlTextWriter.Flush(); - objXmlTextWriter.Close(); - } + }); } } @@ -97,8 +125,50 @@ namespace ArdupilotMega.Utilities /// <param name="objXmlTextWriter">The obj XML text writer.</param> private static void ParseParameterInformation(string fileContents, XmlTextWriter objXmlTextWriter) { + ParseParameterInformation(fileContents, objXmlTextWriter, string.Empty); + } + + /// <summary> + /// Parses the parameter information. + /// </summary> + /// <param name="fileContents">The file contents.</param> + /// <param name="objXmlTextWriter">The obj XML text writer.</param> + /// <param name="parameterPrefix">The parameter prefix.</param> + private static void ParseParameterInformation(string fileContents, XmlTextWriter objXmlTextWriter, string parameterPrefix) + { + var parsedInformation = ParseKeyValuePairs(fileContents, ParameterMetaDataConstants.Param); + if(parsedInformation != null && parsedInformation.Count > 0) + { + parsedInformation.ForEach(node => + { + objXmlTextWriter.WriteStartElement(String.Format("{0}{1}", parameterPrefix, node.Key)); + if (node.Value != null && node.Value.Count > 0) + { + node.Value.ForEach(meta => + { + // Write the key value pair to XML + objXmlTextWriter.WriteStartElement(meta.Key); + objXmlTextWriter.WriteString(meta.Value); + objXmlTextWriter.WriteEndElement(); + }); + } + objXmlTextWriter.WriteEndElement(); + }); + } + } + + /// <summary> + /// Parses the parameter information. + /// </summary> + /// <param name="fileContents">The file contents.</param> + /// <param name="nodeKey">The node key.</param> + /// <returns></returns> + private static Dictionary<string, Dictionary<string, string>> ParseKeyValuePairs(string fileContents, string nodeKey) + { + var returnDict = new Dictionary<string, Dictionary<string, string>>(); + var indicies = new List<int>(); - GetIndexOfMarkers(ref indicies, fileContents, ParameterMetaDataConstants.Delimeter + ParameterMetaDataConstants.Param, 0); + GetIndexOfMarkers(ref indicies, fileContents, ParameterMetaDataConstants.ParamDelimeter + nodeKey, 0); if(indicies.Count > 0) { @@ -113,7 +183,7 @@ namespace ArdupilotMega.Utilities if(!String.IsNullOrEmpty(subStringToSearch)) { var metaIndicies = new List<int>(); - GetIndexOfMarkers(ref metaIndicies, subStringToSearch, ParameterMetaDataConstants.Delimeter, 0); + GetIndexOfMarkers(ref metaIndicies, subStringToSearch, ParameterMetaDataConstants.ParamDelimeter, 0); if(metaIndicies.Count > 0) { @@ -123,40 +193,43 @@ namespace ArdupilotMega.Utilities // Match based on the regex defined at the top of this class Match paramNameKeyMatch = _paramMetaRegex.Match(paramNameKey); - if (paramNameKeyMatch.Success && paramNameKeyMatch.Groups["MetaKey"].Value == ParameterMetaDataConstants.Param) + if (paramNameKeyMatch.Success && paramNameKeyMatch.Groups["MetaKey"].Value == nodeKey) { - objXmlTextWriter.WriteStartElement(paramNameKeyMatch.Groups["MetaValue"].Value.Trim(new char[] { ' ' })); - - // Loop through the indicies of the meta data found - for (int x = 1; x < metaIndicies.Count; x++) + string key = paramNameKeyMatch.Groups["MetaValue"].Value.Trim(new char[] {' '}); + var metaDict = new Dictionary<string, string>(); + if(!returnDict.ContainsKey(key)) { - // This is the end index for a substring to search for parameter attributes - // If we are on the last index in our collection, we will search to the end of the file - var stopMetaIdx = (x == metaIndicies.Count - 1) ? subStringToSearch.Length : metaIndicies[x + 1]; + // Loop through the indicies of the meta data found + for (int x = 1; x < metaIndicies.Count; x++) + { + // This is the end index for a substring to search for parameter attributes + // If we are on the last index in our collection, we will search to the end of the file + var stopMetaIdx = (x == metaIndicies.Count - 1) ? subStringToSearch.Length : metaIndicies[x + 1]; - // This meta param string - var metaString = subStringToSearch.Substring(metaIndicies[x], (stopMetaIdx - metaIndicies[x])); + // This meta param string + var metaString = subStringToSearch.Substring(metaIndicies[x], (stopMetaIdx - metaIndicies[x])); - // Match based on the regex defined at the top of this class - Match metaMatch = _paramMetaRegex.Match(metaString); + // Match based on the regex defined at the top of this class + Match metaMatch = _paramMetaRegex.Match(metaString); - // Test for success - if (metaMatch.Success) - { - // Write the key value pair to XML - objXmlTextWriter.WriteStartElement(metaMatch.Groups["MetaKey"].Value.Trim(new char[] { ' ' })); - objXmlTextWriter.WriteString(metaMatch.Groups["MetaValue"].Value.Trim(new char[] { ' ' })); - objXmlTextWriter.WriteEndElement(); + // Test for success + if (metaMatch.Success) + { + string metaKey = metaMatch.Groups["MetaKey"].Value.Trim(new char[] {' '}); + if(!metaDict.ContainsKey(metaKey)) + { + metaDict.Add(metaKey, metaMatch.Groups["MetaValue"].Value.Trim(new char[] { ' ' })); + } + } } } - - // End this parameter node - objXmlTextWriter.WriteEndElement(); + returnDict.Add(key, metaDict); } } } } } + return returnDict; } /// <summary> @@ -188,5 +261,67 @@ namespace ArdupilotMega.Utilities } } } + + /// <summary> + /// Reads the data from address. + /// </summary> + /// <param name="address">The address.</param> + /// <returns></returns> + private static string ReadDataFromAddress(string address) + { + string data = string.Empty; + + log.Info(address); + + // Make sure we don't blow up if the user is not connected or the endpoint is not available + try + { + var request = WebRequest.Create(address); + + // Plenty of timeout + request.Timeout = 10000; + + // Set the Method property of the request to GET. + request.Method = "GET"; + + // Get the response. + using (var response = request.GetResponse()) + { + // Display the status. + log.Info(((HttpWebResponse)response).StatusDescription); + + // Get the stream containing content returned by the server. + using (var dataStream = response.GetResponseStream()) + { + if (dataStream != null) + { + // Open the stream using a StreamReader for easy access. + using (var reader = new StreamReader(dataStream)) + { + // Store the data to return + data = reader.ReadToEnd(); + + // Close the reader + reader.Close(); + } + + // Close the datastream + dataStream.Close(); + } + } + + // Close the response + response.Close(); + } + + // Return the data + return data; + } + catch (WebException ex) + { + log.Error(String.Format("The request to {0} failed.", address), ex); + } + return string.Empty; + } } } diff --git a/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataRepository.cs b/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataRepository.cs index 0697a76c07b24d9513124c25584d4c94960ca128..738e684880c718a170d4eafe4c7ca2d9e4139c50 100644 --- a/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataRepository.cs +++ b/Tools/ArdupilotMegaPlanner/Utilities/ParameterMetaDataRepository.cs @@ -3,6 +3,7 @@ using System.Configuration; using System.IO; using System.Windows.Forms; using System.Xml.Linq; +using System.Linq; namespace ArdupilotMega.Utilities { @@ -32,7 +33,19 @@ namespace ArdupilotMega.Utilities { // Use this to find the endpoint node we are looking for // Either it will be pulled from a file in the ArduPlane hierarchy or the ArduCopter hierarchy - string endpointSearchString = (MainV2.cs.firmware == MainV2.Firmwares.ArduPlane) ? "arduplane" : "arducopter"; + var element = _parameterMetaDataXML.Element(MainV2.cs.firmware.ToString()); + if(element != null && element.HasElements) + { + var node = element.Element(nodeKey); + if(node != null && node.HasElements) + { + var metaValue = node.Element(metaKey); + if(metaValue != null) + { + return metaValue.Value; + } + } + } } return string.Empty; } diff --git a/Tools/ArdupilotMegaPlanner/app.config b/Tools/ArdupilotMegaPlanner/app.config index 063dfdef787b8749448af9bda365941162ddbbd3..9bb4229ef3a09b9535adbc50996f8768c806b4cd 100644 --- a/Tools/ArdupilotMegaPlanner/app.config +++ b/Tools/ArdupilotMegaPlanner/app.config @@ -8,6 +8,10 @@ <appSettings> <add key="UpdateLocation" value="http://ardupilot-mega.googlecode.com/git/Tools/ArdupilotMegaPlanner/bin/Release/"/> + <add key="ParameterLocations" + value="http://ardupilot-mega.googlecode.com/git/ArduCopter/Parameters.pde"/> + <add key="ParameterMetaDataXMLFileName" + value="ParameterMetaData.xml"/> </appSettings> <log4net> <appender name="Console" type="log4net.Appender.ConsoleAppender"> diff --git a/Tools/ArdupilotMegaPlanner/bin/Release/ArduCopterConfig.xml b/Tools/ArdupilotMegaPlanner/bin/Release/ArduCopterConfig.xml index 2558e46e2c8022bcb52c9e741b1213e441e8bd02..fda38f6780653459242fc80c616f181ad72dfae0 100644 --- a/Tools/ArdupilotMegaPlanner/bin/Release/ArduCopterConfig.xml +++ b/Tools/ArdupilotMegaPlanner/bin/Release/ArduCopterConfig.xml @@ -101,6 +101,70 @@ Too high = slow wobbles <STEP>0.001</STEP> </FIELD> </FIELDS> + + <SUBHEAD>Yaw Angular Rate Control:</SUBHEAD> + <DESC>How much throttle is applied to rotate the copter at the desired speed. + </DESC> + <FIELDS> + <FIELD> + <NAME>P</NAME> + <PARAMNAME>RATE_YAW_P</PARAMNAME> + <RANGEMIN>0.001</RANGEMIN> + <RANGEMAX>5</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>I</NAME> + <PARAMNAME>RATE_YAW_I</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>5</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>D</NAME> + <PARAMNAME>RATE_YAW_D</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>5</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>IMAX</NAME> + <PARAMNAME>RATE_YAW_IMAX</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>50</RANGEMAX> + <STEP>1</STEP> + </FIELD> + </FIELDS> + + <SUBHEAD>Yaw Stabilize Control:</SUBHEAD> + <DESC> + How fast the copter reacts to user or autopilot input. + Higher = more aggressive control. + Too high = slow wobbles + </DESC> + <FIELDS> + <FIELD> + <NAME>P</NAME> + <PARAMNAME>STB_YAW_P</PARAMNAME> + <RANGEMIN>0.001</RANGEMIN> + <RANGEMAX>10</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>I</NAME> + <PARAMNAME>STB_YAW_I</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>5</RANGEMAX> + <STEP>0.001</STEP> + </FIELD> + <FIELD> + <NAME>IMAX</NAME> + <PARAMNAME>STB_YAW_IMAX</PARAMNAME> + <RANGEMIN>0</RANGEMIN> + <RANGEMAX>50</RANGEMAX> + <STEP>1</STEP> + </FIELD> + </FIELDS> </Item> <!-- Loiter --> <Item> @@ -140,7 +204,7 @@ How much angle is applied to make the copter accelerate to the desired speed. <PARAMNAME>LOITER_LON_IMAX</PARAMNAME> <RANGEMIN>0</RANGEMIN> <RANGEMAX>50</RANGEMAX> - <STEP>0.1</STEP> + <STEP>1</STEP> </FIELD> </FIELDS> <SUBHEAD>Loiter Speed:</SUBHEAD> diff --git a/Tools/ArdupilotMegaPlanner/bin/Release/version.txt b/Tools/ArdupilotMegaPlanner/bin/Release/version.txt index cf279dbac70c778e06cd683e3db7c8535e628f1c..b68b098b7a9eaee2814f060456ed85826ef27c7f 100644 --- a/Tools/ArdupilotMegaPlanner/bin/Release/version.txt +++ b/Tools/ArdupilotMegaPlanner/bin/Release/version.txt @@ -1 +1 @@ -1.1.4498.32482 \ No newline at end of file +1.1.4499.14296 \ No newline at end of file