FrontWheelTracker.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEngine;
  6. using Valve.VR;
  7. namespace Tracking
  8. {
  9. public class FrontWheelTracker : CalibratableTracker, IViveTracker
  10. {
  11. protected override string KeyPrefix => "fw";
  12. public float trackerDistanceToWheelCenterPoint;
  13. public KineticLegTracker legTracker;
  14. public int framesToConsider = 10;
  15. public bool useTrackerRotationInsteadOfPosition;
  16. public string id;
  17. public string Id => id;
  18. public SteamVR_TrackedObject TrackedObject => GetComponent<SteamVR_TrackedObject>();
  19. public float SteerRotation => framesToConsider > 1
  20. ? CalculateSteerRotationMultiFrame()
  21. : CalculateSteerRotationSingleFrame();
  22. public Vector3 DebugPosOnBikePlane { private set; get; }
  23. private Queue<float> previousValues;
  24. private void OnEnable()
  25. {
  26. if (framesToConsider > 1)
  27. {
  28. previousValues = new Queue<float>(framesToConsider);
  29. }
  30. }
  31. private float CalculateSteerRotationSingleFrame()
  32. {
  33. if (useTrackerRotationInsteadOfPosition) return RelativeRotation.y;
  34. var posOnBikePlane = GetPosOnBikePlane();
  35. return TrackerPositionToAngle(posOnBikePlane);
  36. }
  37. private float CalculateSteerRotationMultiFrame()
  38. {
  39. var angleThisFrame = CalculateSteerRotationSingleFrame();
  40. if (previousValues.Count > framesToConsider)
  41. {
  42. previousValues.Dequeue();
  43. }
  44. previousValues.Enqueue(angleThisFrame);
  45. //easiest way -> avg; TODO maybe in future, remove outliers
  46. return previousValues.Average();
  47. }
  48. private Vector3 GetPosOnBikePlane()
  49. {
  50. //legTracker position is added to compensate movements of the whole installation
  51. Vector3 legTrackerPos = Vector3.zero;
  52. if (legTracker.isActiveAndEnabled)
  53. {
  54. legTrackerPos = legTracker.RelativePosition;
  55. }
  56. var posOnBikePlane = Vector3.ProjectOnPlane(RelativePosition + legTrackerPos, bicycleTransform.up);
  57. DebugPosOnBikePlane = posOnBikePlane;
  58. /*if (Mathf.Abs(posOnBikePlane.x / trackerDistanceToWheelCenterPoint) >= 1f)
  59. {
  60. Debug.LogError("Strange behaviour!");
  61. //EditorApplication.isPaused = true;
  62. }*/
  63. return posOnBikePlane;
  64. }
  65. private float TrackerPositionToAngle(Vector3 posOnBikePlane)
  66. {
  67. var theta = Mathf.Acos(Mathf.Clamp(posOnBikePlane.x / trackerDistanceToWheelCenterPoint, -1f, 1f));
  68. return 90f - theta * Mathf.Rad2Deg;
  69. }
  70. }
  71. }