FrontWheelTracker.cs 2.6 KB

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