/// <summary> /// Sends the requested <see cref="DroneCommand"/> to the drone. If the command equals the last command sent, then it won't be sent again. /// </summary> /// <param name="droneCommand">The requested <see cref="DroneCommand"/>.</param> protected void InternalControl(DroneCommand droneCommand) { if (this.lastCommandSentToDrone == null || (droneCommand != null && !this.lastCommandSentToDrone.Equals(droneCommand))) { this.lastCommandSentToDrone = droneCommand.Copy(); this.drone.Control(droneCommand); } }
/// <summary> /// Processes a key input. /// </summary> /// <param name="keyInfo">The key input to evaluate.</param> /// <returns>The evaluation result of the <paramref name="keyInfo"/>.</returns> public InputProcessResult ProcessKeyInput(KeyInfo keyInfo) { DroneCommand keyEvaluated = this.keyInputEvaluator.EvaluateKey(keyInfo); if (keyEvaluated == null) { return(null); } this.LatestKeyInputEvaluated = keyEvaluated; DroneControllerKeyInputProcessResult result = new DroneControllerKeyInputProcessResult(this.LatestKeyInputEvaluated.Copy()); this.Control(); return(result); }
public IEnumerator ExecuteCommand(DroneCommand command) { if (!Flying && command != DroneCommand.On) { Game.PlaySoundEffect(content.audio.drone_failure); yield break; } switch (command) { case DroneCommand.Forward: yield return(Get <Scripts>().GoTo(Forward())); break; case DroneCommand.Left: TurnLeft(); break; case DroneCommand.Right: TurnRight(); break; case DroneCommand.Off: StopFlyingSound(); Game.PlaySoundEffect(content.audio.drone_shutdown); yield return(Get <Scripts>().GoTo(StopEngine())); Game.PlaySoundEffect(content.audio.drone_landing); break; case DroneCommand.On: PlayFlyingSound(); yield return(Get <Scripts>().GoTo(StartEngine())); Get <DroneDisplacement>().Reset(); ReachedCeiling = true; break; } // if collision while (Get <Scripts>().ScriptCollection.Count > 0) { yield return(1); } }
public void ProcessKeyInput_KeyIsSupported_ReturnsEvaluatedDroneCommand() { var moveCommand = new MoveCommand() { Lateral = 0, Longitudinal = 0, Vertical = -1, Yaw = 0, }; this.keyInputEvaluatorMock .Setup(kie => kie.EvaluateKey(It.IsAny <KeyInfo>())) .Returns(moveCommand); var result = this.droneController.ProcessKeyInput(new KeyInfo(Key.W, KeyState.Down)); this.controllableDroneMock.Verify(d => d.Control(moveCommand), Times.Once); Assert.IsType <DroneControllerKeyInputProcessResult>(result); DroneCommand resultDroneCommand = (result as DroneControllerKeyInputProcessResult).Result; MoveCommand resultMoveCommand = resultDroneCommand as MoveCommand; Assert.True(moveCommand.Equals(resultMoveCommand)); }
private DroneCommand EvaluateInputs() { // key input has always priority over the hands input if (this.LatestKeyInputEvaluated != null) { DroneCommand latestKeyInputEvaluatedCopy = this.LatestKeyInputEvaluated.Copy(); // If the evaluated input from the keyboard was executed, then it has to be set to null, // otherwise the evaluated hands input will never have the chance to get executed. // After being evaluated the _latestKeyInputEvaluated is always set to null // unless it's a MoveCommand which represents a moving state. // Why? // Imagine the following scenario: // The hand detector is enabled but we want to control the drone using the keyboard. // We are pressing the left key arrow (nothing else). // We are going to enter the KeyboardDroneController.ProcessKeyInput method only once. // Right after the key is evaluated the _latestKeyInputEvaluated is set to null. // At the same time because of the enabled hand detector we're receiving several input per second from the web camera. // This means that even though the left arrow key is still held down, instead of the _latestKeyInputEvaluated // the _latestHandsInputEvaluated is going to be executed. // (Because the _latestKeyInputEvaluated was set to null before.) if (!(this.LatestKeyInputEvaluated is MoveCommand moveCommand) || moveCommand.Still) { this.LatestKeyInputEvaluated = null; } return(latestKeyInputEvaluatedCopy); } else if (this.LatestHandsInputEvaluated != null) { DroneCommand latestHandsInputEvaluatedCopy = this.LatestHandsInputEvaluated.Copy(); return(latestHandsInputEvaluatedCopy); } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="DroneControllerKeyInputProcessResult"/> class. /// </summary> /// <param name="result">The <see cref="DroneCommand"/> that was evaluated from the hands input.</param> public DroneControllerKeyInputProcessResult(DroneCommand result) { this.Result = result; }
/// <summary> /// Evaluated latest inputs together. /// </summary> protected override void Control() { DroneCommand inputsEvaluated = this.EvaluateInputs(); this.InternalControl(inputsEvaluated); }
/// <summary> /// Initializes a new instance of the <see cref="AbstractDroneController"/> class. /// </summary> /// <param name="drone">The <see cref="AbstractDrone"/> that we would like to control with this controller.</param> public AbstractDroneController(AbstractDrone drone) { this.drone = drone; this.lastCommandSentToDrone = null; }
/// <summary> /// The interface to speak to control the drone. /// </summary> /// <param name="droneCommand">The <see cref="DroneCommand"/> to be executed by the drone.</param> public abstract void Control(DroneCommand droneCommand);