public void Calculate_WithAircraftStateAndSpeedHigherThanRotationSpeedAndPitch_ReturnsExpectedPitchRate(AircraftData aircraftData) { // Setup var random = new Random(21); double rotationSpeed = GetRotationSpeed(aircraftData); double pitchAngle = aircraftData.MaximumPitchAngle.Degrees - random.NextDouble(); var aircraftState = new AircraftState(Angle.FromDegrees(pitchAngle), random.NextAngle(), rotationSpeed + random.NextDouble(), random.NextDouble(), random.NextDouble()); var calculator = new TestTakeOffDynamicsCalculator(aircraftData, airDensity, random.NextDouble()); // Call AircraftAccelerations accelerations = calculator.Calculate(aircraftState); // Assert Angle expectedPitchRate = aircraftData.PitchAngleGradient; Assert.AreEqual(expectedPitchRate, accelerations.PitchRate); }
public static void Calculate_WithAircraftStateAlways_ReturnsExpectedClimbRate() { // Setup var random = new Random(21); AircraftData aircraftData = AircraftDataTestFactory.CreateRandomAircraftData(); Angle angleOfAttack = AerodynamicsDataTestHelper.GetValidAngleOfAttack(aircraftData.AerodynamicsData); var aircraftState = new AircraftState(angleOfAttack, new Angle(), random.NextDouble(), random.NextDouble(), random.NextDouble()); var calculator = new TestTakeOffDynamicsCalculator(aircraftData, random.NextDouble(), random.NextDouble()); // Call AircraftAccelerations accelerations = calculator.Calculate(aircraftState); // Assert double expectedClimbRate = aircraftState.TrueAirspeed * Math.Sin(aircraftState.FlightPathAngle.Radians); Assert.AreEqual(expectedClimbRate, accelerations.ClimbRate, tolerance); }
public void Integrate_Always_PerformsExpectedIntegration() { // Setup var random = new Random(21); AircraftState state = CreateAircraftState(); AircraftAccelerations accelerations = CreateAircraftAccelerations(); double timeStep = random.NextDouble(); // Call AircraftState resultingState = new EulerIntegrator().Integrate(state, accelerations, timeStep); // Assert Assert.AreEqual(ExpectedIntegratedValue(state.Height, accelerations.ClimbRate, timeStep), resultingState.Height); Assert.AreEqual(ExpectedIntegratedValue(state.TrueAirspeed, accelerations.TrueAirSpeedRate, timeStep), resultingState.TrueAirspeed); Assert.AreEqual(ExpectedIntegratedValue(state.Distance, state.TrueAirspeed, timeStep), resultingState.Distance); Assert.AreEqual(ExpectedIntegratedValue(state.FlightPathAngle, accelerations.FlightPathRate, timeStep), resultingState.FlightPathAngle); Assert.AreEqual(ExpectedIntegratedValue(state.PitchAngle, accelerations.PitchRate, timeStep), resultingState.PitchAngle); }
public static void Calculate_WithAirspeedLowerThanThreshold_ReturnsExpectedZeroRate() { // Setup var random = new Random(21); AircraftData aircraftData = AircraftDataTestFactory.CreateRandomAircraftData(); Angle angleOfAttack = AerodynamicsDataTestHelper.GetValidAngleOfAttack(aircraftData.AerodynamicsData); var aircraftState = new AircraftState(angleOfAttack, new Angle(), random.NextDouble(), random.NextDouble(), random.NextDouble()); // Precondition Assert.IsTrue(aircraftState.TrueAirspeed < 1); var calculator = new TestTakeOffDynamicsCalculator(aircraftData, random.NextDouble(), random.NextDouble()); // Call AircraftAccelerations accelerations = calculator.Calculate(aircraftState); // Assert Assert.Zero(accelerations.FlightPathRate.Degrees); }
public string ToString(AircraftState state) { return("Position: " + state.u + "," + state.v + "\t Speed: " + state.speed + "\t Heading: " + state.heading + "\t Altitude: " + state.altitude + "\t HP:" + state.hp); }
private static void A_StateChanged(object sender, AircraftState e) { Console.WriteLine($"Самолет {sender} находится в состоянии {e.GetDescription()}"); }
public void GivenCalculator_WhenCalculatingAndSolutionConvergesWithScreenHeightAfterFailureDynamics_ThenCallsInExpectedOrderAndOutputReturned() { // Given var random = new Random(21); const double screenHeight = 10.7; int nrOfTimeSteps = random.Next(3, int.MaxValue); double timeStep = random.NextDouble(); int failureSpeed = random.Next(); var failureState = new AircraftState(random.NextAngle(), random.NextAngle(), failureSpeed + 0.1, random.NextDouble(), random.NextDouble()); AircraftState[] states = { failureState, CreateAircraftStateWithHeight(screenHeight - 0.2), CreateAircraftStateWithHeight(screenHeight) }; AircraftAccelerations[] accelerations = { CreateAircraftAccelerations(), CreateAircraftAccelerations(), CreateAircraftAccelerations() }; var normalTakeOffDynamicsCalculator = Substitute.For <INormalTakeOffDynamicsCalculator>(); normalTakeOffDynamicsCalculator.Calculate(Arg.Any <AircraftState>()) .Returns(accelerations[0]); var failureTakeOffDynamicsCalculator = Substitute.For <IFailureTakeOffDynamicsCalculator>(); failureTakeOffDynamicsCalculator.Calculate(Arg.Any <AircraftState>()) .Returns(accelerations[1], accelerations[2]); var integrator = Substitute.For <IIntegrator>(); integrator.Integrate(Arg.Any <AircraftState>(), Arg.Any <AircraftAccelerations>(), timeStep) .Returns(states[0], states[1], states[2]); var calculatorSettings = new CalculationSettings(failureSpeed, nrOfTimeSteps, timeStep); var calculator = new DistanceCalculator(normalTakeOffDynamicsCalculator, failureTakeOffDynamicsCalculator, integrator, calculatorSettings); // Call DistanceCalculatorOutput output = calculator.Calculate(); // Assert normalTakeOffDynamicsCalculator.Received(1).Calculate(Arg.Any <AircraftState>()); failureTakeOffDynamicsCalculator.Received(2).Calculate(Arg.Any <AircraftState>()); integrator.Received(3).Integrate(Arg.Any <AircraftState>(), Arg.Any <AircraftAccelerations>(), timeStep); Received.InOrder(() => { normalTakeOffDynamicsCalculator.Calculate(Arg.Is <AircraftState>(state => IsZeroAircraftState(state))); integrator.Integrate(Arg.Is <AircraftState>(state => IsZeroAircraftState(state)), accelerations[0], timeStep); failureTakeOffDynamicsCalculator.Calculate(states[0]); integrator.Integrate(states[0], accelerations[1], timeStep); failureTakeOffDynamicsCalculator.Calculate(states[1]); integrator.Integrate(states[1], accelerations[2], timeStep); }); Assert.AreEqual(states.Last().Distance, output.Distance); Assert.AreEqual(failureSpeed, output.FailureSpeed); }
protected override Angle CalculatePitchRate(AircraftState state) { return(new Angle()); }
public override void Update(float fDeltaTime) { if (this.Flaps) { this.m_linDragModule.setCoefficient(LINEAR_DRAG_COEFFICIENT * 1.5f); this.m_liftModule.setCoefficient(LIFT_COEFFICIENT * 1.5f); } else { this.m_linDragModule.setCoefficient(LINEAR_DRAG_COEFFICIENT); this.m_liftModule.setCoefficient(LIFT_COEFFICIENT); } this.LastPosition = this.Position; base.Update(fDeltaTime); Vector3 antigravity = GameState.GRAVITY * -1; Vector3 appliedLift = Vector3.Zero; Vector3 appliedThrust = Vector3.Zero; Vector3 appliedLinearDrag = Vector3.Zero; Vector3 appliedAngularDrag = Vector3.Zero; Vector3 appliedDamage = Vector3.Zero; Vector3 appliedPitchDirectional = Vector3.Zero; switch (this.state) { case AircraftState.ON_DECK: this.SetWorld(STARTING_POSITION); this.SetVelocity(Vector3.Zero, Vector3.Zero); if (this.thrust == 100) { this.state = AircraftState.CATAPULTING; this.catapultTimer = CATAPULT_LAUNCH_TIME; } break; case AircraftState.CATAPULTING: this.catapultTimer -= fDeltaTime; Vector3 launch = this.Forward * CATAPULT_GAIN_FORWARD * fDeltaTime + this.Up * CATAPULT_GAIN_UP * fDeltaTime; this.ApplyForce(ref launch); //System.Diagnostics.Debug.WriteLine(launch.Length()+""); if (this.catapultTimer <= 0) this.state = AircraftState.IN_FLIGHT; break; case AircraftState.STALLED: Quaternion quat = Quaternion.CreateFromAxisAngle(this.Left, (float)Math.PI / 2) - this.Orientation; Vector3 stallforce = new Vector3(quat.X, quat.Y, quat.Z); stallforce = stallforce * STALL_GAIN * fDeltaTime; this.ApplyTorque(ref stallforce); if (!this.isStalled()) { this.state = AircraftState.IN_FLIGHT; HUD.Get().setStall(false); } break; case AircraftState.IN_FLIGHT: appliedAngularDrag = this.m_angDragModule.tick(fDeltaTime); appliedLinearDrag = this.m_linDragModule.tick(fDeltaTime); appliedLift = this.m_liftModule.tick(fDeltaTime); appliedPitchDirectional = this.m_pitchDirModule.tick(fDeltaTime); if (this.isStalled()) { this.state = AircraftState.STALLED; HUD.Get().setStall(true); } break; } //System.Diagnostics.Debug.WriteLine(this.state); appliedThrust = this.m_thrustModule.tick(fDeltaTime); appliedDamage = this.m_dmgModule.tick(fDeltaTime); //this.ApplyForce(ref antigravity); HUD.Get().formatStrings(this.LinearVelocity.Length(),this.m_thrustModule.getFuelAsPercent()); HUD.Get().setFuel(this.m_thrustModule.getFuelAsPercent()); HUD.Get().setVelocity(this.LinearVelocity.Length()); HUD.Get().setDebugMessage(String.Format( "X={0} Y={1} Z={2} VX: {7:F2} VY: {8:F2} VZ: {9:F2}\nLDrag: {3:F2} ADrag: {6:F2} Thrust: {4:F2} Lift: {5:F2}\nPitDir: {11:F2} Damage: {10:F2}", this.Position.X, this.Position.Y, this.Position.Z, appliedLinearDrag.Length(), appliedThrust.Length(), appliedLift.Length(), appliedAngularDrag.Length(), this.LinearVelocity.X, this.LinearVelocity.Y, this.LinearVelocity.Z, appliedDamage.Length(), appliedPitchDirectional.Length())); }
private void SetControllerValues() { try { AircraftState aircraftState = AircraftRadioLogic.Instance.GetCurrentAircraftStateThreadSafe(); RadioConfigurations radioConfig = AircraftRadioLogic.Instance.RadioConfig; if (aircraftState.elevatorValueRaw != this.lastAircraftState.elevatorValueRaw) { joyRight.YValue = aircraftState.elevatorValueRaw; plotElevator1.PointX = aircraftState.elevatorValueRaw; plotElevator1.PointY = aircraftState.elevatorValue1; plotElevator2.PointX = aircraftState.elevatorValueRaw; plotElevator2.PointY = aircraftState.elevatorValue2; } if (aircraftState.aileronValue != this.lastAircraftState.aileronValue) { joyRight.XValue = aircraftState.aileronValue - radioConfig.Aileron_MinValue; } if (aircraftState.rudderValue != this.lastAircraftState.rudderValue) { joyLeft.XValue = aircraftState.rudderValue - radioConfig.Rudder_MinValue; } if (aircraftState.throtleValue != this.lastAircraftState.throtleValue) { if (radioConfig.Throtle_ReverseJoystick) { joyLeft.YValue = radioConfig.Throtle_MaxValue - (aircraftState.throtleValue - radioConfig.Throtle_MinValue); } else { joyLeft.YValue = (aircraftState.throtleValue - radioConfig.Throtle_MinValue); } } this.lastAircraftState = aircraftState; this.textBox.Text = Math.Round(AircraftRadioLogic.Instance.GetRadioConnectionFPS(), 1).ToString(); this.txtTotalSendPackages.Text = AircraftRadioLogic.Instance.GetRadioTotalSends().ToString(); vtailViewer.LeftValue = (double)aircraftState.elevatorValue1; vtailViewer.RightValue = (double)aircraftState.elevatorValue2; //if (AircraftRadioLogic.Instance.COMInitialized) { txtChan1Value.Text = aircraftState.throtleValue.ToString(); txtChan2Value.Text = aircraftState.aileronValue.ToString(); txtChan3Value1.Text = aircraftState.elevatorValue1.ToString(); txtChan3Value2.Text = aircraftState.elevatorValue2.ToString(); txtChan4Value.Text = aircraftState.rudderValue.ToString(); } } catch (Exception ex) { //AddLogItem("ERR", "Error in SetControllerValues" + ex.ToString()); } }
/// <summary> /// Calculates the aerodynamic drag force that is acting on the aircraft. [N] /// </summary> /// <param name="state">The <see cref="AircraftState"/> /// the aircraft is currently in.</param> /// <returns>The drag force.</returns> protected abstract double CalculateAerodynamicDragForce(AircraftState state);
protected override double CalculateAerodynamicDragForce(AircraftState state) { CalculateDragInput = state; return(Drag); }
/// <summary> /// Создать новый экземпляр самолета. /// </summary> /// <param name="name">Имя самолета.</param> public Aircraft(string name) { Name = name; State = AircraftState.Sleep; }
private double CalculateRollDragForce(AircraftState aircraftState) { return(GetFrictionCoefficient() * CalculateNormalForce(aircraftState)); }
private static double CalculateClimbRate(AircraftState aircraftState) { return(aircraftState.TrueAirspeed * Math.Sin(aircraftState.FlightPathAngle.Radians)); }
/// <summary> /// Calculates the pitch rate based on <paramref name="state"/>. /// </summary> /// <param name="state">The <see cref="AircraftState"/> the aircraft /// is currently in.</param> /// <returns>The pitch rate.</returns> protected virtual Angle CalculatePitchRate(AircraftState state) { return(ShouldRotate(state) ? AircraftData.PitchAngleGradient : new Angle()); }
/// <summary> /// Calculates the angle of attack based on <paramref name="state"/>. /// </summary> /// <param name="state">The <see cref="AircraftState"/> the aircraft /// is currently in.</param> /// <returns>The angle of attack.</returns> protected static Angle CalculateAngleOfAttack(AircraftState state) { return(state.PitchAngle - state.FlightPathAngle); }