public ClockState Tick(TimeSpan time) { TimeSpan previousTick; TimeSpan nextTick; ClockProgressState progressState; double progress; if (time < TimeSpan.Zero) { previousTick = Granular.Compatibility.TimeSpan.MinValue; nextTick = TimeSpan.Zero; progress = 0; progressState = ClockProgressState.BeforeStarted; } else if (time < Duration) { previousTick = time; nextTick = time; progress = time.Divide(Duration); progressState = ClockProgressState.Active; } else { previousTick = Duration; nextTick = Granular.Compatibility.TimeSpan.MaxValue; progress = 1; progressState = ClockProgressState.AfterEnded; } return new ClockState(progressState, progress, 0, previousTick, nextTick); }
/// <summary> /// Start this callback timer /// </summary> /// <param name="time">Timeout time</param> public void StartTimer(TimeSpan time) { if (time < TimeSpan.Zero) throw new ArgumentOutOfRangeException("time", "The timeout parameter is negative."); timeout = time; if (StatisticsCollector.CollectApplicationRequestsStats) { timeSinceIssued = TimeIntervalFactory.CreateTimeInterval(true); timeSinceIssued.Start(); } TimeSpan firstPeriod = timeout; TimeSpan repeatPeriod = Constants.INFINITE_TIMESPAN; // Single timeout period --> No repeat if (config.ResendOnTimeout && config.MaxResendCount > 0) { firstPeriod = repeatPeriod = timeout.Divide(config.MaxResendCount + 1); } // Start time running DisposeTimer(); timer = new SafeTimer(TimeoutCallback, null, firstPeriod, repeatPeriod); }
private static bool EqualMaxResponseTime(TimeSpan value1, TimeSpan value2) { return value1.Divide(2) <= value2 && value1.Multiply(2) >= value2; }
public ClockState Tick(TimeSpan time) { double iteration = time.Divide(iterationDuration); ClockProgressState progressState = time < FirstTick ? ClockProgressState.BeforeStarted : (time >= LastTick ? ClockProgressState.AfterEnded : ClockProgressState.Active); iteration = Math.Min(Math.Max(iteration, 0), iterationsCount); double iterationRemainder = iteration - Math.Floor(iteration); TimeSpan currentIterationStart; TimeSpan currentIterationTime; if (progressState == ClockProgressState.AfterEnded && iterationRemainder == 0) { currentIterationStart = iterationDuration.Scale(iteration - 1); currentIterationTime = iterationDuration; } else { currentIterationStart = iterationDuration.Scale(iteration - iterationRemainder); currentIterationTime = iterationDuration.Scale(iterationRemainder); } ClockState state = clock.Tick(currentIterationTime); TimeSpan previousTick; TimeSpan nextTick; if (time < FirstTick) { previousTick = Granular.Compatibility.TimeSpan.MinValue; nextTick = FirstTick; } else if (time >= LastTick) { previousTick = LastTick; nextTick = Granular.Compatibility.TimeSpan.MaxValue; } else { if (currentIterationTime > clock.FirstTick || Math.Floor(iteration) == 0) { previousTick = (currentIterationStart + state.PreviousTick).Max(FirstTick); } else { previousTick = (currentIterationStart - iterationDuration + clock.LastTick).Max(FirstTick); } if (currentIterationTime < clock.LastTick || Math.Floor(iteration) == Math.Floor(iterationsCount)) { nextTick = (currentIterationStart + state.NextTick).Min(LastTick); } else { nextTick = (currentIterationStart + iterationDuration + clock.FirstTick).Min(LastTick); } } if (progressState == ClockProgressState.Active) { progressState = state.ProgressState; } return new ClockState(progressState, state.Progress, iteration, previousTick, nextTick); }
/// <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); }