|
| 1 | +using System.Collections; |
| 2 | +using System.Collections.Generic; |
| 3 | +using UnityEngine; |
| 4 | + |
| 5 | +public class Gyro_Accel : MonoBehaviour |
| 6 | +{ |
| 7 | + public enum UpdateType { FixedUpdate, Update } |
| 8 | + |
| 9 | + [Header("=== SETTINGS ===")] |
| 10 | + public UpdateType update_type = UpdateType.FixedUpdate; |
| 11 | + |
| 12 | + [Header("=== OUTCOMES ===")] |
| 13 | + [ReadOnlyInsp] public Vector3 gyroscope; |
| 14 | + [ReadOnlyInsp] public Vector3 local_gyroscope; |
| 15 | + [ReadOnlyInsp] public Vector3 acceleration; |
| 16 | + [ReadOnlyInsp] public Vector3 local_acceleration; |
| 17 | + |
| 18 | + private Quaternion prev_rotation; |
| 19 | + private Vector3 prev_position; |
| 20 | + private Vector3 prev_velocity; |
| 21 | + |
| 22 | + void Start() { |
| 23 | + prev_rotation = transform.rotation; |
| 24 | + prev_position = transform.position; |
| 25 | + prev_velocity = Vector3.zero; |
| 26 | + } |
| 27 | + |
| 28 | + void Update() { |
| 29 | + if (update_type == UpdateType.Update) Calculate(Time.deltaTime); |
| 30 | + } |
| 31 | + |
| 32 | + // Update is called once per frame |
| 33 | + void FixedUpdate() { |
| 34 | + if (update_type == UpdateType.FixedUpdate) Calculate(Time.fixedDeltaTime); |
| 35 | + } |
| 36 | + |
| 37 | + private void Calculate(float dt) { |
| 38 | + // Cache current stats |
| 39 | + Quaternion current_rotation = transform.rotation; |
| 40 | + Vector3 current_position = transform.position; |
| 41 | + |
| 42 | + // Calculate gyroscope and acceleration |
| 43 | + gyroscope = ComputeGyro(prev_rotation, current_rotation, dt); |
| 44 | + Vector3 vel = (current_position - prev_position) / dt; |
| 45 | + acceleration = ((vel - prev_velocity) / dt) - Physics.gravity; |
| 46 | + |
| 47 | + // Calculate local |
| 48 | + local_gyroscope = Quaternion.Inverse(current_rotation) * gyroscope; |
| 49 | + local_acceleration = Quaternion.Inverse(current_rotation) * acceleration; |
| 50 | + |
| 51 | + // Cache previous |
| 52 | + prev_rotation = current_rotation; |
| 53 | + prev_position = current_position; |
| 54 | + prev_velocity = vel; |
| 55 | + } |
| 56 | + |
| 57 | + public static Vector3 ComputeGyro(Quaternion prev, Quaternion current, float dt) { |
| 58 | + // Measure change in rotation from the previous rotation |
| 59 | + Quaternion dq = current * Quaternion.Inverse(prev); |
| 60 | + |
| 61 | + // Ensure shortest path |
| 62 | + if (dq.w < 0) { |
| 63 | + dq = new Quaternion(-dq.x, -dq.y, -dq.z, -dq.w); |
| 64 | + } |
| 65 | + |
| 66 | + // Get angle axis |
| 67 | + dq.ToAngleAxis(out float angleDeg, out Vector3 axis); |
| 68 | + |
| 69 | + // Consider when angle diff is greater than 180 degrees. We basically want to contain rotations between -180 and 180 degrees |
| 70 | + if (angleDeg > 180f) { |
| 71 | + angleDeg -= 360f; |
| 72 | + } |
| 73 | + |
| 74 | + // Calculate output gyroscope |
| 75 | + float angleRad = angleDeg * Mathf.Deg2Rad; |
| 76 | + return axis * (angleRad / dt); // Radians per second |
| 77 | + } |
| 78 | +} |
0 commit comments