#if UNITY_5_3_OR_NEWER using System.Collections; using UnityEngine; using LinearAlgebra; namespace RoboidControl.Unity { public class RelativeEncoder : Thing { /// /// Create the Unity representation /// /// The core motor /// The Unity representation of a motor public static RelativeEncoder Create(RoboidControl.RelativeEncoder core) { GameObject prefab = (GameObject)Resources.Load("IncrementalEncoder"); if (prefab != null) { // Use resource prefab when available GameObject gameObj = Instantiate(prefab); RelativeEncoder component = gameObj.GetComponent(); if (component != null) component.core = core; return component; } else { // Fallback implementation GameObject gameObj = new(core.name); RelativeEncoder component = gameObj.AddComponent(); component.Init(core); Rigidbody rb = gameObj.AddComponent(); rb.isKinematic = true; return component; } } RoboidControl.RelativeEncoder coreEncoder => this.core as RoboidControl.RelativeEncoder; /// /// The rotation speed in degrees per second /// public float rotationSpeed = 0.0f; protected override void HandleBinary() { this.rotationSpeed = coreEncoder.angularSpeed; } private Quaternion lastRotation; protected override void Update() { base.Update(); if (this.transform.childCount == 0) return; Transform child = this.transform.GetChild(0); // Get the delta rotation since last frame Quaternion deltaRotation = Quaternion.Inverse(lastRotation) * child.localRotation; // Normalize angles to range [-180..180) // Note: it is not possible to track rotation speeds higher than 180 degrees per frame because of representation limitations of Quaternions float deltaAngle = Angle.Normalize(deltaRotation.eulerAngles.x); this.rotationSpeed = deltaAngle / Time.deltaTime; } IEnumerator UpdateCore() { WaitForSeconds wait = new(0.1f); while (true) { this.coreEncoder.angularSpeed = this.rotationSpeed; yield return wait; } } } } #endif