public RotationEventArgs(Direction movementDirection, AccumulationStatus rotationAccumulation, uint halfTurns, uint peakHalfTurns, Direction rotationSide, double yaw) { MovementDirection = movementDirection; RotationAccumulationStatus = rotationAccumulation; HalfTurns = halfTurns; PeakHalfTurns = peakHalfTurns; RotationSide = rotationSide; Yaw = yaw; }
public void LoadFromXml(XElement xCondition) { if (xCondition != null) { if (Enum.TryParse(xCondition.GetElementValueTrimmed("TargetRotationSide"), out Direction d)) { TargetRotationSide = d; } else { TargetRotationSide = Direction.Either; } if (Enum.TryParse(xCondition.GetElementValueTrimmed("CompOperator"), out CompareOperator op)) { CompOperator = op; } else { CompOperator = CompareOperator.EqualOrGreaterThan; } if (xCondition.GetElementValueOrNull("TargetHalfTurns") != null) { TargetHalfTurns = (uint)xCondition.GetElementValueInt("TargetHalfTurns"); } else { TargetHalfTurns = (uint)xCondition.GetElementValueInt("TargetFullRotations") * 2; // backwards compatibility if (TargetHalfTurns > 99) { TargetHalfTurns = 99; } } if (xCondition.GetElementValueOrNull("TargetHalfTurnsMax") != null) { TargetHalfTurnsMax = (uint)xCondition.GetElementValueInt("TargetHalfTurnsMax"); } else { TargetHalfTurnsMax = (uint)xCondition.GetElementValueInt("TargetFullRotationsMax") * 2; // backwards compatibility if (TargetHalfTurnsMax > 99) { TargetHalfTurnsMax = 99; } } if (Enum.TryParse(xCondition.GetElementValueTrimmed("TargetAccumulation"), out AccumulationStatus s)) { TargetAccumulation = s; } else { TargetAccumulation = AccumulationStatus.Either; } if (xCondition.GetElementValueOrNull("TargetPeakHalfTurns") != null) { TargetPeakHalfTurns = (uint)xCondition.GetElementValueInt("TargetPeakHalfTurns"); } else { TargetPeakHalfTurns = (uint)xCondition.GetElementValueInt("TargetPeakFullRotations") * 2; // backwards compatibility if (TargetPeakHalfTurns > 99) { TargetPeakHalfTurns = 99; } } } }
/// <summary> /// Checks the difference of the last two Yaw values and determines if either 0 or 180 degree position was crossed. /// Invokes rotation events and updates the lap counter (which in turn is used for counting the half-turns). /// NOTE, the angular difference between the last two Yaw values must always be below 180 degrees for this to work! /// </summary> /// <param name="newYawValue"></param> void UpdateRotation(double newYawValue) { // Oculus rotation axis range is in radians from -pi to +pi. // Zero is the middle point (facing forward). Rotation is positive when turning left. // ***************** // only once at startup IF starting from a saved point of rotation (turn count memory) if (InitialHalfTurn != 0) { _YawValue = newYawValue; CurrentHalfTurn = GetCorrectedInitialHalfTurn(newYawValue); InitialHalfTurn = 0; } // ***************** if (_YawValue != null) // null = first time (or after reset) { if (Math.Abs((double)(_YawValue - newYawValue)) < Threshold180Abs) { bool resetPos = false; Direction moveDir = Direction.Either; if (_YawValue < 0 && newYawValue >= 0) // Zero crossed from negative to positive (right side to left side, moving left) { CurrentHalfTurn += (CurrentHalfTurn == -1) ? 2 : 1; resetPos = (CurrentHalfTurn == 1); moveDir = Direction.Left; AccumulationStatus acc = (resetPos) ? AccumulationStatus.Either : ((RotationSide == Direction.Left) ? AccumulationStatus.Increasing : AccumulationStatus.Decreasing); InvokeYaw0(new RotationEventArgs(moveDir, acc, CompletedHalfTurns, PeakHalfTurns, RotationSide, newYawValue)); } else if (_YawValue >= 0 && newYawValue < 0) // Zero crossed from positive to negative (left side to right side, moving right) { CurrentHalfTurn -= (CurrentHalfTurn == 1) ? 2 : 1; resetPos = (CurrentHalfTurn == -1); moveDir = Direction.Right; AccumulationStatus acc = (resetPos) ? AccumulationStatus.Either : ((RotationSide == Direction.Right) ? AccumulationStatus.Increasing : AccumulationStatus.Decreasing); InvokeYaw0(new RotationEventArgs(moveDir, acc, CompletedHalfTurns, PeakHalfTurns, RotationSide, newYawValue)); } if (resetPos) { InvokeResetPosition(new RotationEventArgs(moveDir, AccumulationStatus.Either, CompletedHalfTurns, PeakHalfTurns, RotationSide, newYawValue)); PeakHalfTurns = 0; // this must NOT be reset before invoking the Yaw0 & ResetPosition events! } } else // 180 degree position was crossed (or sample rate is too low --> incorrect result) { if (_YawValue < newYawValue) // 180 crossed from negative to positive (right side to left side, moving right) { CurrentHalfTurn -= 1; AccumulationStatus acc = (RotationSide == Direction.Right) ? AccumulationStatus.Increasing : AccumulationStatus.Decreasing; InvokeYaw180(new RotationEventArgs(Direction.Right, acc, CompletedHalfTurns, PeakHalfTurns, RotationSide, newYawValue)); } else // 180 crossed from positive to negative (left side to right side, moving left) { CurrentHalfTurn += 1; AccumulationStatus acc = (RotationSide == Direction.Left) ? AccumulationStatus.Increasing : AccumulationStatus.Decreasing; InvokeYaw180(new RotationEventArgs(Direction.Left, acc, CompletedHalfTurns, PeakHalfTurns, RotationSide, newYawValue)); } } } else // first time (or after reset) { // to detect initial orientation CurrentHalfTurn = (newYawValue < 0) ? -1 : 1; } _YawValue = newYawValue; }