public override void Update(GameTime gameTime)
        {
            if (_playEngineSound && _engineSoundInst != null && _engineSoundInst.State != SoundState.Playing)
            {
                _engineSoundInst.Play();
            }


            long           totalTicks = gameTime.TotalGameTime.Ticks;
            JoystickOutput output     = GetJoystickInput(totalTicks);

            // Invert yaw because we want yaw rotation positive as clockwise seen from above
            output.Yaw *= -1;

            // Update physics and sensors + state estimators
            PhysicalHeliState trueState, observedState, estimatedState, blindEstimatedState;

            UpdatePhysicalState(gameTime, output, out trueState);
            UpdateStateEstimators(_simulationState, gameTime, output, out estimatedState, out blindEstimatedState, out observedState);

            float trueGroundAltitude           = GetGroundAltitude(trueState.Position);
            float estimatedGroundAltitude      = GetGroundAltitude(trueState.Position);
            float trueHeightAboveGround        = GetHeightAboveGround(trueState.Position);
            float gpsinsHeightAboveGround      = GetHeightAboveGround(estimatedState.Position);
            float rangefinderHeightAboveGround = _sensors.GroundRangeFinder.FlatGroundHeight;



            float estimatedHeightAboveGround;

            if (!_testConfiguration.UseGPS)
            {
                throw new NotImplementedException();
            }
            else if (!_testConfiguration.UseINS)
            {
                throw new NotImplementedException();
            }

            if (_testConfiguration.UseGPS && _testConfiguration.UseINS)
            {
                if (!_testConfiguration.UseRangeFinder)
                {
                    estimatedHeightAboveGround = gpsinsHeightAboveGround;
                }
                else
                {
                    // The range finder may be out of range (NaN) and typically requires <10 meters.
                    // In this case we need to fully trust INS/GPS estimate.
                    // Note GPS is easily out-bested by range finder, so no need to weight
                    estimatedHeightAboveGround = float.IsNaN(rangefinderHeightAboveGround)
                                                     ? gpsinsHeightAboveGround
                                                     : rangefinderHeightAboveGround;
                    //                                                   : 0.2f*gpsinsHeightAboveGround + 0.8f*rangefinderHeightAboveGround;
                }
            }
            else
            {
                throw new NotImplementedException();
            }


            // Override Kalman Filter estimate of altitude by the more accurate range finder.
            // However, there is a problem that the estimated map altitude depends on the estimated horizontal position; which is inaccurate.
            estimatedState.Position.Y = estimatedHeightAboveGround + estimatedGroundAltitude;

            _physicalState  = trueState;
            _trueState      = StateHelper.ToHeliState(trueState, trueHeightAboveGround, Autopilot.CurrentWaypoint, output);
            _estimatedState = StateHelper.ToHeliState(estimatedState, estimatedHeightAboveGround, Autopilot.CurrentWaypoint, output);



            // _observedState = observedState;

            // Calculate current error in estimated state
            _estimatedStateError = StateHelper.GetError(_physicalState, StateHelper.ToPhysical(_estimatedState));

            // Add current simulation step to log
            ForwardRightUp accelerometerData = _sensors.IMU.AccelerationLocal;

            Log.Add(new HelicopterLogSnapshot(trueState, observedState, estimatedState, blindEstimatedState, accelerometerData, trueGroundAltitude, gameTime.TotalGameTime));


            // Update visual appearances
            UpdateEffects();

            UpdateSound(output);

            // If we have disabled Jitter we must detect collisions ourselves for test scenarios
            if (!UseTerrainCollision)
            {
                if (IsCollidedWithTerrain())
                {
                    if (Crashed != null)
                    {
                        Crashed(gameTime);
                    }
                }
            }

            // Handle crashes, user input etc.. that cause the helicopter to reset
            HandleResetting(gameTime);

            base.Update(gameTime);
        }