using UnityEngine; namespace URDF { /// /// Utility class for converting between URDF coordinate system (right-handed, Z-up) /// and Unity coordinate system (left-handed, Y-up) /// public static class URDFCoordinateConverter { /// /// Convert URDF position (right-handed, Z-up) to Unity position (left-handed, Y-up) /// Conversion: (x, y, z) -> (x, -z, y) /// public static Vector3 ConvertPosition(Vector3 urdfPosition) { return new Vector3(urdfPosition.x, -urdfPosition.z, urdfPosition.y); } /// /// Convert URDF rotation (RPY in right-handed, Z-up) to Unity rotation (left-handed, Y-up) /// public static Quaternion ConvertRotation(Vector3 rpy) { // Convert RPY to Euler angles in Unity coordinate system // RPY: Roll (around X), Pitch (around Y), Yaw (around Z) // Unity: X, Y, Z rotations in left-handed system // First convert RPY to quaternion in URDF system, then convert to Unity Quaternion roll = Quaternion.AngleAxis(rpy.x * Mathf.Rad2Deg, Vector3.right); Quaternion pitch = Quaternion.AngleAxis(rpy.y * Mathf.Rad2Deg, Vector3.up); Quaternion yaw = Quaternion.AngleAxis(rpy.z * Mathf.Rad2Deg, Vector3.forward); // In URDF: rotation order is typically Roll-Pitch-Yaw Quaternion urdfRotation = yaw * pitch * roll; // Convert from URDF (right-handed, Z-up) to Unity (left-handed, Y-up) // This is a coordinate system transformation Matrix4x4 urdfToUnity = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one); urdfToUnity.m00 = 1; urdfToUnity.m01 = 0; urdfToUnity.m02 = 0; urdfToUnity.m10 = 0; urdfToUnity.m11 = 0; urdfToUnity.m12 = -1; urdfToUnity.m20 = 0; urdfToUnity.m21 = 1; urdfToUnity.m22 = 0; // Alternative approach: directly convert Euler angles // URDF: X=right, Y=forward, Z=up // Unity: X=right, Y=up, Z=forward // So: Unity X = URDF X, Unity Y = URDF Z, Unity Z = -URDF Y float unityX = rpy.x * Mathf.Rad2Deg; // Roll stays the same float unityY = rpy.z * Mathf.Rad2Deg; // Yaw becomes Y rotation float unityZ = -rpy.y * Mathf.Rad2Deg; // Pitch becomes -Z rotation return Quaternion.Euler(unityX, unityY, unityZ); } /// /// Convert URDF axis (right-handed, Z-up) to Unity axis (left-handed, Y-up) /// public static Vector3 ConvertAxis(Vector3 urdfAxis) { return new Vector3(urdfAxis.x, -urdfAxis.z, urdfAxis.y); } } }