#if UNITY_5_3_OR_NEWER using UnityEngine; namespace RoboidControl.Unity { public class DifferentialDrive : Thing { public Wheel leftWheel; public Wheel rightWheel; public SphereCollider casterWheel; protected RoboidControl.DifferentialDrive coreDrive => core as RoboidControl.DifferentialDrive; /// /// Create the Unity representation /// /// The core touch sensor /// The Unity representation of the touch sensor public static DifferentialDrive Create(RoboidControl.DifferentialDrive core) { DifferentialDrive component = null; Rigidbody rb = null; GameObject prefab = (GameObject)Resources.Load("DifferentialDrive"); if (prefab != null) { // Use resource prefab when available GameObject gameObj = Instantiate(prefab); component = gameObj.GetComponent(); if (component != null) component.core = core; rb = component.GetComponent(); } else { // Fallback implementation GameObject gameObj = new(core.name); component = gameObj.AddComponent(); component.Init(core); rb = gameObj.AddComponent(); rb.isKinematic = false; rb.mass = 0.5f; } return component; } private Rigidbody rb = null; protected virtual void Awake() { rb = GetComponent(); } protected override void HandleBinary() { Debug.Log("Diff drive handle Binary"); if (coreDrive.wheelRadius <= 0 || coreDrive.wheelSeparation <= 0) return; // if (leftWheel == null) { // motors = GetComponentsInChildren(); // foreach (var motor in motors) { // if (motor.core.id == coreDrive.leftWheel.id) // leftWheel = motor; // } // if (leftWheel == null) // // Create placeholder wheel // leftWheel = Wheel.Create(this.GetComponent(), coreDrive.leftWheel.id); // } if (leftWheel != null) { leftWheel.core ??= coreDrive.leftWheel; SphereCollider leftWheelCollider = leftWheel.GetComponent(); leftWheelCollider.radius = coreDrive.wheelRadius; // leftWheelCollider.center = new Vector3(-coreDrive.wheelSeparation / 2, 0, 0); } // if (rightWheel == null) { // if (motors == null) // motors = GetComponentsInChildren(); // foreach (var motor in motors) { // if (motor.core.id == coreDrive.rightWheel.id) // rightWheel = motor; // } // if (rightWheel == null) // rightWheel = Wheel.Create(this.GetComponent(), coreDrive.rightWheel.id); // } if (rightWheel != null) { rightWheel.core ??= coreDrive.rightWheel; SphereCollider rightWheelCollider = rightWheel.GetComponent(); rightWheelCollider.radius = coreDrive.wheelRadius; // rightWheelCollider.center = new Vector3(coreDrive.wheelSeparation / 2, 0, 0); } if (casterWheel == null) { // Create it } if (casterWheel != null) { casterWheel.radius = coreDrive.wheelRadius; // Put it in the middle of the back casterWheel.center = new Vector3(0, 0, -coreDrive.wheelSeparation); } } protected override void FixedUpdate() { base.FixedUpdate(); float leftWheelVelocity = leftWheel.rotationSpeed * (2 * Mathf.PI) * coreDrive.wheelRadius; float rightWheelVelocity = rightWheel.rotationSpeed * (2 * Mathf.PI) * coreDrive.wheelRadius; float forwardSpeed = (leftWheelVelocity + rightWheelVelocity) / 2f; float turningSpeed = (leftWheelVelocity - rightWheelVelocity) / coreDrive.wheelSeparation; // Use smoothing to emulate motor inertia rb.velocity = 0.9f * rb.velocity + 0.1f * forwardSpeed * transform.forward; rb.angularVelocity = 0.9f * rb.angularVelocity + 0.1f * turningSpeed * Vector3.up; } } } #endif