Esempio n. 1
0
            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);
            }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
            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);
            }
Esempio n. 5
0
 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);
 }
Esempio n. 6
0
 private static void A_StateChanged(object sender, AircraftState e)
 {
     Console.WriteLine($"Самолет {sender} находится в состоянии {e.GetDescription()}");
 }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
 protected override Angle CalculatePitchRate(AircraftState state)
 {
     return(new Angle());
 }
Esempio n. 9
0
        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()));
        }
Esempio n. 10
0
        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());
            }
        }
Esempio n. 11
0
 /// <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);
Esempio n. 12
0
 protected override double CalculateAerodynamicDragForce(AircraftState state)
 {
     CalculateDragInput = state;
     return(Drag);
 }
Esempio n. 13
0
 /// <summary>
 /// Создать новый экземпляр самолета.
 /// </summary>
 /// <param name="name">Имя самолета.</param>
 public Aircraft(string name)
 {
     Name  = name;
     State = AircraftState.Sleep;
 }
Esempio n. 14
0
 private double CalculateRollDragForce(AircraftState aircraftState)
 {
     return(GetFrictionCoefficient() * CalculateNormalForce(aircraftState));
 }
Esempio n. 15
0
 private static double CalculateClimbRate(AircraftState aircraftState)
 {
     return(aircraftState.TrueAirspeed * Math.Sin(aircraftState.FlightPathAngle.Radians));
 }
Esempio n. 16
0
 /// <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());
 }
Esempio n. 17
0
 /// <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);
 }