Beispiel #1
0
        public void Test()
        {
            var simSettings = new SimulationSettings();

            simSettings.RenderMode = RenderModes.Normal;

            var game = new SimulatorGame(simSettings, IntPtr.Zero);

            _collision = new TerrainCollision(game, game);
            _collision.Initialize();
            _collision.TmpBuildScene();

            // Find new position and velocity from a constant acceleration over timestep
            const float dt = 0.017f;

            var a = new Vector3(0, 9.81f, 0);
            var startCondition1 = new TimestepStartingCondition(Vector3.Zero, Vector3.Zero, a,
                                                                Quaternion.Identity, TimeSpan.Zero);
            TimestepStartingCondition startCondition2 = startCondition1;

            var joystickOutput = new JoystickOutput(0.1f, 0.1f, 0, 0.5f);

            for (int i = 0; i < 100; i++)
            {
                TimestepResult jitterResult = ByJitter(startCondition1, joystickOutput,
                                                       startCondition1.StartTime + TimeSpan.FromSeconds(dt), dt);

                TimestepResult physicsResult = ByPhysics(startCondition2, joystickOutput,
                                                         startCondition2.StartTime + TimeSpan.FromSeconds(dt), dt);

                Vector3 dPos = jitterResult.Position - physicsResult.Position;
                Vector3 dVel = jitterResult.Velocity - physicsResult.Velocity;


                if (jitterResult.Orientation != physicsResult.Orientation)
                {
                    float dPitchDeg =
                        MathHelper.ToDegrees(VectorHelper.GetPitchAngle(jitterResult.Orientation) -
                                             VectorHelper.GetPitchAngle(physicsResult.Orientation));

                    float dRollDeg =
                        MathHelper.ToDegrees(VectorHelper.GetRollAngle(jitterResult.Orientation) -
                                             VectorHelper.GetRollAngle(physicsResult.Orientation));

                    float dYawDeg =
                        MathHelper.ToDegrees(VectorHelper.GetHeadingAngle(jitterResult.Orientation) -
                                             VectorHelper.GetHeadingAngle(physicsResult.Orientation));


                    Console.WriteLine("YPR delta " + dPitchDeg + " " + dRollDeg + " " + dYawDeg);
                }

                TimeSpan nextStartTime = physicsResult.EndTime;
                startCondition1 = new TimestepStartingCondition(jitterResult.Position, jitterResult.Velocity,
                                                                a, jitterResult.Orientation, nextStartTime);

                startCondition2 = new TimestepStartingCondition(physicsResult.Position, physicsResult.Velocity,
                                                                a, physicsResult.Orientation, nextStartTime);
            }
        }
        /// <summary>Calculates the input and external forces.</summary>
        /// <returns>The new orientation and the total acceleration for this orientation in this timestep.</returns>
        public SimulationStepResults PerformTimestep(PhysicalHeliState prev, JoystickOutput output, TimeSpan stepDuration,
                                                     TimeSpan stepEndTime)
        {
            if (!_isInitialized)
            {
//                startCondition.Acceleration = CalculateAcceleration(startCondition.Orientation, startCondition.Velocity, input);
                _prevTimestepResult = new TimestepResult(prev.Position, prev.Velocity, prev.Orientation,
                                                         stepEndTime - stepDuration);

                _isInitialized = true;
            }

            // If the number of substeps is 0 then only the state at the end of the timestep will be calculated.
            // If the number is greater than 1, then the timestep will 1 then a substep will be calculated in the middle of the timestep.
            const int substeps = 0;

            if (substeps < 0)
            {
                throw new Exception("The number of substeps is invalid.");
            }

            TimeSpan substepDuration = stepDuration.Divide(1 + substeps);

            Vector3 initialAcceleration = CalculateAcceleration(prev.Orientation, prev.Velocity, output);
            var     initialState        = new TimestepStartingCondition(_prevTimestepResult, initialAcceleration);
            //_prevTimestepResult.Result;
//            var substepResults = new List<SubstepResults> {initialState};

            // We always need to calculate at least the timestep itself, plus any optional substeps.
            // Substeps are used to provide sensors with a higher frequency of data than the simulator is capable of rendering real-time.
//            const int stepsToCalculate = substeps + 1;
//            SubstepResults prevSubstep = initialState;
//            for (int i = 0; i < stepsToCalculate; i++)
//            {
//                prevSubstep.Acceleration = CalculateAcceleration(prevSubstep.Orientation, prevSubstep.Velocity, input);
//                SubstepResults r = SimulateStep(prevSubstep, prevSubstep.Acceleration, input, substepDuration, stepEndTime);
//
//                substepResults.Add(r);
//                prevSubstep = r;
//            }


            TimestepResult result = SimulateStep(initialState, output, substepDuration, stepEndTime);

            //new SimulationStepResults(stepDuration, substepDuration, substepResults);
            _prevTimestepResult = result;

//            DebugInformation.Time1 = stepEndTime;
//            DebugInformation.Q1 = result.Orientation;
//
//            DebugInformation.Vectors["Pos"] = result.Position;
//            DebugInformation.Vectors["Vel"] = result.Velocity;
//            DebugInformation.Vectors["Acc"] = initialAcceleration;

            return(new SimulationStepResults(initialState, result, stepEndTime - stepDuration, stepEndTime));
        }
        private void UpdatePhysicalState(GameTime gameTime, JoystickOutput output, out PhysicalHeliState trueState)
        {
            _simulationState = _physics.PerformTimestep(_physicalState, output, gameTime.ElapsedGameTime,
                                                        gameTime.TotalGameTime);

            TimestepResult final = _simulationState.Result;

            // We need to use the second last simulation substep to obtain the current acceleration used
            // because the entire substep has constant acceleration and it makes no sense
            // to use the acceleration calculated for the state after the timestep because no animation will occur after it.
            // TODO Support substeps
            Vector3 currentAcceleration = _simulationState.StartingCondition.Acceleration;

            trueState = new PhysicalHeliState(final.Orientation, final.Position, final.Velocity, currentAcceleration);
        }
Beispiel #4
0
        public void Update(SimulationStepResults step, JoystickOutput output)
        {
            // TODO Use substeps in physics simulation when sensors require higher frequency than the main-loop runs at
            // Currently we simply use the state at the start of the timestep to feed into the sensors, so they read the state
            // that was before any motion took place in that timestep.
            // Later we may need to update sensors multiple times for each timestep.
            TimestepStartingCondition start = step.StartingCondition;
            TimestepResult            end   = step.Result;

            var startPhysicalState = new PhysicalHeliState(start.Orientation, start.Position, start.Velocity,
                                                           start.Acceleration);

            var endPhysicalState = new PhysicalHeliState(end.Orientation, end.Position, end.Velocity,
                                                         new Vector3(float.NaN));

            // Update all sensors
            foreach (ISensor sensor in _sensors)
            {
                sensor.Update(startPhysicalState, endPhysicalState, output, step.StartTime, step.EndTime);
            }
        }