From 39e23d69a6fe2c531c0bf7f0f8ebddc0aa84151b Mon Sep 17 00:00:00 2001 From: David Date: Sun, 24 Jun 2018 01:16:40 +0200 Subject: [PATCH] Set heading and VS --- README.md | 6 ++ .../Commands/HeadingMCPControl.cs | 80 +++++++++++++++++ .../Commands/VerticalSpeedMCPControl.cs | 88 +++++++++++++++++++ X-Plane Voice Control/Constants.cs | 14 ++- X-Plane Voice Control/MainForm.Designer.cs | 20 ++++- X-Plane Voice Control/MainForm.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../X-Plane Voice Control.csproj | 2 + 8 files changed, 210 insertions(+), 8 deletions(-) create mode 100644 X-Plane Voice Control/Commands/HeadingMCPControl.cs create mode 100644 X-Plane Voice Control/Commands/VerticalSpeedMCPControl.cs diff --git a/README.md b/README.md index 94a1ee3..1613fa5 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,11 @@ You need ExtPlane Plugin installed ([Download](https://github.com/vranki/ExtPlan * __[select / engage / turn on / arm / de-select / disengage / turn off / disarm / toggle] auto throttle__ * __[select / egnage / turn on / de-select / disengage / turn off] / toggle] v-nav__ * __[select / engage / turn on / de-select / disengage / turn off] / toggle] l-nav__ +* Heading set + * set __heading__ to __XXX__ +* Vertical speed set + * set __vertical speed__ to negative V thousand /& X hundred [fifty] [fpm / feet per minute / feet] + * __eg: set vertical speed to six thousand five hundred fifty; set vertical speed to six hundred; set vertical speed fifty__ __Cheat sheet:__ @@ -83,6 +88,7 @@ __Cheat sheet:__ * Normal text is Optional * __X => [zero / one / two / three / four / fiver / six / seven / eight / niner]__ * __T => [zero / one / two / three / four / fiver / six / seven]__ +* __V => [zero / one / two / three / four / five / six]__ ## Hard time speaking - train Windows to understand you better? * Open Speech Recognition by clicking the Start button, clicking Control Panel, clicking Ease of Access, and then clicking Speech Recognition. diff --git a/X-Plane Voice Control/Commands/HeadingMCPControl.cs b/X-Plane Voice Control/Commands/HeadingMCPControl.cs new file mode 100644 index 0000000..c54e04f --- /dev/null +++ b/X-Plane Voice Control/Commands/HeadingMCPControl.cs @@ -0,0 +1,80 @@ +using System; +using System.Linq; +using System.Speech.Recognition; +using System.Speech.Synthesis; +using System.Threading; +using System.Threading.Tasks; +using ExtPlaneNet; + +namespace X_Plane_Voice_Control.Commands +{ + class HeadingMCPControl : ControlTemplate + { + + public HeadingMCPControl(ExtPlaneInterface interface_, SpeechSynthesizer synthesizer) : base(interface_, synthesizer) + { + var headingGrammar = new GrammarBuilder(); + headingGrammar.Append("please", 0, 1); + headingGrammar.Append("set", 0, 1); + headingGrammar.Append("heading"); + headingGrammar.Append("to", 0, 1); + headingGrammar.Append(Constants.NumberChoices, 3, 3); + headingGrammar.Append("please", 0, 1); + Grammar = new Grammar(headingGrammar); + RecognitionPattern = Constants.DeserializeRecognitionPattern(headingGrammar.DebugShowPhrases); + } + public sealed override Grammar Grammar { get; } + public override string RecognitionPattern { get; } + + public override void DataRefSubscribe() + { + XPlaneInterface.Subscribe("laminar/B738/autopilot/mcp_hdg_dial"); + } + + public override void OnTrigger(RecognitionResult rResult, string phrase) + { + var presentHeading = (int)XPlaneInterface.GetDataRef("laminar/B738/autopilot/mcp_hdg_dial").Value; + var stringHeading = Constants.StringNumbersToDigits(phrase); + stringHeading = stringHeading.Substring(stringHeading.Length - 5, 5); + var requestedHeading = int.Parse(stringHeading.Replace(" ", "")); + if (requestedHeading > 360) + { + SpeechSynthesizer.SpeakAsync("Cannot set heading bigger than 360"); + return; + } + + if (requestedHeading == 360) + requestedHeading = 0; + + int wayToRotate; + if (presentHeading < requestedHeading) + { + var x = requestedHeading - presentHeading; + var y = presentHeading + (360 - requestedHeading); + wayToRotate = x <= y ? 1 : -1; + } + else + { + var x = (360 - presentHeading) + requestedHeading; + var y = presentHeading - requestedHeading; + wayToRotate = x <= y ? 1 : -1; + } + + Task.Run(() => + { + while (presentHeading != requestedHeading) + { + presentHeading += wayToRotate; + if (presentHeading == 360) + presentHeading = 0; + if (presentHeading == -1) + presentHeading = 359; + XPlaneInterface.SetDataRef("laminar/B738/autopilot/mcp_hdg_dial", presentHeading); + Thread.Sleep(2); + } + }); + SpeechSynthesizer.SpeakAsync($"Setting heading to {stringHeading}"); + } + + } +} diff --git a/X-Plane Voice Control/Commands/VerticalSpeedMCPControl.cs b/X-Plane Voice Control/Commands/VerticalSpeedMCPControl.cs new file mode 100644 index 0000000..02f8585 --- /dev/null +++ b/X-Plane Voice Control/Commands/VerticalSpeedMCPControl.cs @@ -0,0 +1,88 @@ +using System; +using System.Linq; +using System.Speech.Recognition; +using System.Speech.Synthesis; +using System.Threading; +using System.Threading.Tasks; +using ExtPlaneNet; + +namespace X_Plane_Voice_Control.Commands +{ + class VerticalSpeedMCPControl : ControlTemplate + { + + public VerticalSpeedMCPControl(ExtPlaneInterface interface_, SpeechSynthesizer synthesizer) : base(interface_, synthesizer) + { + var headingGrammar = new GrammarBuilder(); + + var thousandGrammar = new GrammarBuilder(); + thousandGrammar.Append(Constants.VerticalSpeedNumberChoices); + thousandGrammar.Append("thousand"); + + var hundredGrammar = new GrammarBuilder(); + hundredGrammar.Append(Constants.ClassicNumberChoices); + hundredGrammar.Append("hundred"); + + var altitudeGrammar = new GrammarBuilder(); + altitudeGrammar.Append(thousandGrammar, 0, 1); + altitudeGrammar.Append(hundredGrammar, 0, 1); + headingGrammar.Append("please", 0, 1); + headingGrammar.Append("set", 0, 1); + headingGrammar.Append("vertical speed"); + headingGrammar.Append("to", 0, 1); + headingGrammar.Append("negative", 0, 1); + headingGrammar.Append(altitudeGrammar); + headingGrammar.Append("fifty", 0, 1); + headingGrammar.Append(new Choices("fpm", "feet per minute", "feet"), 0, 1); + headingGrammar.Append("please", 0, 1); + Grammar = new Grammar(headingGrammar); + RecognitionPattern = Constants.DeserializeRecognitionPattern(headingGrammar.DebugShowPhrases); + } + public sealed override Grammar Grammar { get; } + public override string RecognitionPattern { get; } + + public override void DataRefSubscribe() + { + XPlaneInterface.Subscribe("sim/cockpit/autopilot/vertical_velocity"); + } + + public override void OnTrigger(RecognitionResult rResult, string phrase) + { + var stringHeading = Constants.StringNumbersToDigits(phrase); + try + { + var startingIndexNumber = Constants.NumbersInDigits.First(stringHeading.Contains); + var startingIndex = stringHeading.IndexOf(startingIndexNumber, StringComparison.Ordinal); + stringHeading = stringHeading.Substring(startingIndex, stringHeading.Length - startingIndex); + } + catch { } + + var splittedString = stringHeading.Split(' '); + float verticalSpeedToSet = 0; + for (var i = 0; i < splittedString.Length; i += 2) + { + var nextIndex = i + 1; + if (nextIndex > splittedString.Length - 1) + break; + if (splittedString[i + 1] == "thousand") + { + verticalSpeedToSet += int.Parse(splittedString[i]) * 1000; + } + if (splittedString[i + 1] == "hundred") + { + verticalSpeedToSet += int.Parse(splittedString[i]) * 100; + } + } + + if (phrase.Contains("fifty") && verticalSpeedToSet < 1000 && verticalSpeedToSet > -1000) + verticalSpeedToSet += 50; + + if (phrase.Contains("negative")) + verticalSpeedToSet *= -1; + XPlaneInterface.SetDataRef("sim/cockpit/autopilot/vertical_velocity", verticalSpeedToSet); + + + } + + } +} diff --git a/X-Plane Voice Control/Constants.cs b/X-Plane Voice Control/Constants.cs index 4a4bb06..977ed65 100644 --- a/X-Plane Voice Control/Constants.cs +++ b/X-Plane Voice Control/Constants.cs @@ -4,14 +4,24 @@ namespace X_Plane_Voice_Control { internal static class Constants { + private static readonly string[] ClassicNumbers = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; + private static readonly string[] Numbers = { "zero", "one", "two", "three", "four", "fiver", "six", "seven", "eight", "niner" }; - private static readonly string[] TransponderNumbers = { "zero", "one", "two", "three", "four", "fiver", "six", "seven"}; + private static readonly string[] TransponderNumbers = { "zero", "one", "two", "three", "four", "fiver", "six", "seven" }; + + private static readonly string[] VerticalSpeedNumbers = { "zero", "one", "two", "three", "four", "five", "six" }; + + public static readonly string[] NumbersInDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; public static readonly Choices NumberChoices = new Choices(Numbers); + public static readonly Choices ClassicNumberChoices = new Choices(ClassicNumbers); + public static readonly Choices TransponderNumberChoices = new Choices(TransponderNumbers); + public static readonly Choices VerticalSpeedNumberChoices = new Choices(VerticalSpeedNumbers); + public const int ButtonReleaseDelay = 700; public const int PushButtonReleaseDelay = 300; @@ -20,7 +30,7 @@ public static string StringNumbersToDigits(string input) { return input.Replace("zero", "0").Replace("one", "1").Replace("two", "2").Replace("three", "3") .Replace("four", "4").Replace("fiver", "5").Replace("six", "6").Replace("seven", "7") - .Replace("eight", "8").Replace("niner", "9").Replace("decimal", "").Replace("point", "").Trim(); + .Replace("eight", "8").Replace("niner", "9").Replace("decimal", "").Replace("point", "").Replace("five", "5").Replace("nine", "9").Trim(); } public static bool IsValidComFreq(int input) diff --git a/X-Plane Voice Control/MainForm.Designer.cs b/X-Plane Voice Control/MainForm.Designer.cs index d1a2e44..ef05443 100644 --- a/X-Plane Voice Control/MainForm.Designer.cs +++ b/X-Plane Voice Control/MainForm.Designer.cs @@ -34,13 +34,14 @@ private void InitializeComponent() this.comboBoxVoices = new System.Windows.Forms.ComboBox(); this.comboBoxRecognizer = new System.Windows.Forms.ComboBox(); this.labelRecognizer = new System.Windows.Forms.Label(); + this.labelConnectionStatus = new System.Windows.Forms.Label(); this.SuspendLayout(); // // buttonListen // this.buttonListen.AutoSize = true; this.buttonListen.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.buttonListen.Location = new System.Drawing.Point(263, 105); + this.buttonListen.Location = new System.Drawing.Point(264, 105); this.buttonListen.Margin = new System.Windows.Forms.Padding(4); this.buttonListen.Name = "buttonListen"; this.buttonListen.Size = new System.Drawing.Size(67, 26); @@ -61,7 +62,7 @@ private void InitializeComponent() // labelVoice // this.labelVoice.AutoSize = true; - this.labelVoice.Location = new System.Drawing.Point(13, 10); + this.labelVoice.Location = new System.Drawing.Point(14, 10); this.labelVoice.Name = "labelVoice"; this.labelVoice.Size = new System.Drawing.Size(85, 16); this.labelVoice.TabIndex = 2; @@ -71,7 +72,7 @@ private void InitializeComponent() // this.comboBoxVoices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxVoices.FormattingEnabled = true; - this.comboBoxVoices.Location = new System.Drawing.Point(104, 7); + this.comboBoxVoices.Location = new System.Drawing.Point(105, 7); this.comboBoxVoices.Name = "comboBoxVoices"; this.comboBoxVoices.Size = new System.Drawing.Size(226, 24); this.comboBoxVoices.TabIndex = 3; @@ -96,11 +97,23 @@ private void InitializeComponent() this.labelRecognizer.TabIndex = 4; this.labelRecognizer.Text = "Select recognizer:"; // + // labelConnectionStatus + // + this.labelConnectionStatus.AutoSize = true; + this.labelConnectionStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelConnectionStatus.ForeColor = System.Drawing.Color.Red; + this.labelConnectionStatus.Location = new System.Drawing.Point(14, 74); + this.labelConnectionStatus.Name = "labelConnectionStatus"; + this.labelConnectionStatus.Size = new System.Drawing.Size(110, 16); + this.labelConnectionStatus.TabIndex = 6; + this.labelConnectionStatus.Text = "Not Connected"; + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(344, 145); + this.Controls.Add(this.labelConnectionStatus); this.Controls.Add(this.comboBoxRecognizer); this.Controls.Add(this.labelRecognizer); this.Controls.Add(this.comboBoxVoices); @@ -128,6 +141,7 @@ private void InitializeComponent() private System.Windows.Forms.ComboBox comboBoxVoices; private System.Windows.Forms.ComboBox comboBoxRecognizer; private System.Windows.Forms.Label labelRecognizer; + private System.Windows.Forms.Label labelConnectionStatus; } } diff --git a/X-Plane Voice Control/MainForm.cs b/X-Plane Voice Control/MainForm.cs index f5caed4..b2c5d53 100644 --- a/X-Plane Voice Control/MainForm.cs +++ b/X-Plane Voice Control/MainForm.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Globalization; using System.Linq; using System.Reflection; @@ -36,7 +37,8 @@ private void ButtonListen_Click(object sender, EventArgs e) try { _extPlaneInterface.Connect(); - MessageBox.Show("Successfully connected! You can now speak after clicking OK", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); + labelConnectionStatus.Text = "Connected"; + labelConnectionStatus.ForeColor = Color.Green; } catch (Exception) { diff --git a/X-Plane Voice Control/Properties/AssemblyInfo.cs b/X-Plane Voice Control/Properties/AssemblyInfo.cs index f9b4fe1..4582b41 100644 --- a/X-Plane Voice Control/Properties/AssemblyInfo.cs +++ b/X-Plane Voice Control/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.7.0.0")] -[assembly: AssemblyFileVersion("0.7.0.0")] +[assembly: AssemblyVersion("0.8.0.0")] +[assembly: AssemblyFileVersion("0.8.0.0")] diff --git a/X-Plane Voice Control/X-Plane Voice Control.csproj b/X-Plane Voice Control/X-Plane Voice Control.csproj index b55eae8..421a995 100644 --- a/X-Plane Voice Control/X-Plane Voice Control.csproj +++ b/X-Plane Voice Control/X-Plane Voice Control.csproj @@ -54,8 +54,10 @@ + +