| using System; |
| using UnityEngine; |
| using NUnit.Framework; |
| using Unity.MLAgents.Sensors; |
|
|
| namespace Unity.MLAgents.Tests |
| { |
| public class PoseExtractorTests |
| { |
| class BasicPoseExtractor : PoseExtractor |
| { |
| protected internal override Pose GetPoseAt(int index) |
| { |
| return Pose.identity; |
| } |
|
|
| protected internal override Vector3 GetLinearVelocityAt(int index) |
| { |
| return Vector3.zero; |
| } |
| } |
|
|
| class UselessPoseExtractor : BasicPoseExtractor |
| { |
| public void Init(int[] parentIndices) |
| { |
| Setup(parentIndices); |
| } |
| } |
|
|
| [Test] |
| public void TestEmptyExtractor() |
| { |
| var poseExtractor = new UselessPoseExtractor(); |
|
|
| |
| poseExtractor.UpdateLocalSpacePoses(); |
| poseExtractor.UpdateModelSpacePoses(); |
|
|
| Assert.AreEqual(0, poseExtractor.NumPoses); |
|
|
| |
| foreach (var pose in poseExtractor.GetEnabledModelSpacePoses()) |
| { |
| throw new UnityAgentsException("This shouldn't happen"); |
| } |
|
|
| foreach (var pose in poseExtractor.GetEnabledLocalSpacePoses()) |
| { |
| throw new UnityAgentsException("This shouldn't happen"); |
| } |
|
|
| foreach (var vel in poseExtractor.GetEnabledModelSpaceVelocities()) |
| { |
| throw new UnityAgentsException("This shouldn't happen"); |
| } |
|
|
| foreach (var vel in poseExtractor.GetEnabledLocalSpaceVelocities()) |
| { |
| throw new UnityAgentsException("This shouldn't happen"); |
| } |
|
|
| |
| Assert.Throws<NullReferenceException>( |
| () => poseExtractor.GetParentIndex(0) |
| ); |
|
|
| |
| var displayNodes = poseExtractor.GetDisplayNodes(); |
| Assert.AreEqual(0, displayNodes.Count); |
| } |
|
|
| [Test] |
| public void TestSimpleExtractor() |
| { |
| var poseExtractor = new UselessPoseExtractor(); |
| var parentIndices = new[] { -1, 0 }; |
| poseExtractor.Init(parentIndices); |
| Assert.AreEqual(2, poseExtractor.NumPoses); |
| } |
|
|
| |
| |
| |
| |
| class ChainPoseExtractor : PoseExtractor |
| { |
| public Vector3 offset; |
| public ChainPoseExtractor(int size) |
| { |
| var parents = new int[size]; |
| for (var i = 0; i < size; i++) |
| { |
| parents[i] = i - 1; |
| } |
| Setup(parents); |
| } |
|
|
| protected internal override Pose GetPoseAt(int index) |
| { |
| var rotation = Quaternion.identity; |
| var translation = offset + new Vector3(index, index, index); |
| return new Pose |
| { |
| rotation = rotation, |
| position = translation |
| }; |
| } |
|
|
| protected internal override Vector3 GetLinearVelocityAt(int index) |
| { |
| return Vector3.zero; |
| } |
| } |
|
|
| [Test] |
| public void TestChain() |
| { |
| var size = 4; |
| var chain = new ChainPoseExtractor(size); |
| chain.offset = new Vector3(.5f, .75f, .333f); |
|
|
| chain.UpdateModelSpacePoses(); |
| chain.UpdateLocalSpacePoses(); |
|
|
|
|
| var modelPoseIndex = 0; |
| foreach (var modelSpace in chain.GetEnabledModelSpacePoses()) |
| { |
| if (modelPoseIndex == 0) |
| { |
| |
| Assert.IsTrue(modelSpace == Pose.identity); |
| } |
| else |
| { |
| var expectedModelTranslation = new Vector3(modelPoseIndex, modelPoseIndex, modelPoseIndex); |
| Assert.IsTrue(expectedModelTranslation == modelSpace.position); |
| } |
| modelPoseIndex++; |
| } |
| Assert.AreEqual(size, modelPoseIndex); |
|
|
| var localPoseIndex = 0; |
| foreach (var localSpace in chain.GetEnabledLocalSpacePoses()) |
| { |
| if (localPoseIndex == 0) |
| { |
| |
| Assert.IsTrue(localSpace == Pose.identity); |
| } |
| else |
| { |
| var expectedLocalTranslation = new Vector3(1, 1, 1); |
| Assert.IsTrue(expectedLocalTranslation == localSpace.position, $"{expectedLocalTranslation} != {localSpace.position}"); |
| } |
|
|
| localPoseIndex++; |
| } |
| Assert.AreEqual(size, localPoseIndex); |
| } |
|
|
| [Test] |
| public void TestChainDisplayNodes() |
| { |
| var size = 4; |
| var chain = new ChainPoseExtractor(size); |
|
|
| var displayNodes = chain.GetDisplayNodes(); |
| Assert.AreEqual(size, displayNodes.Count); |
|
|
| for (var i = 0; i < size; i++) |
| { |
| var displayNode = displayNodes[i]; |
| Assert.AreEqual(i, displayNode.OriginalIndex); |
| Assert.AreEqual(null, displayNode.NodeObject); |
| Assert.AreEqual(i, displayNode.Depth); |
| Assert.AreEqual(true, displayNode.Enabled); |
| } |
| } |
|
|
| [Test] |
| public void TestDisplayNodesLoop() |
| { |
| |
| var poseExtractor = new UselessPoseExtractor(); |
| poseExtractor.Init(new[] { -1, 2, 1 }); |
|
|
| |
| poseExtractor.GetDisplayNodes(); |
|
|
| |
| poseExtractor.Init(new[] { -1, 1 }); |
|
|
| |
| poseExtractor.GetDisplayNodes(); |
| } |
|
|
| class BadPoseExtractor : BasicPoseExtractor |
| { |
| public BadPoseExtractor() |
| { |
| var size = 2; |
| var parents = new int[size]; |
| |
| for (var i = 0; i < size; i++) |
| { |
| parents[i] = i; |
| } |
| Setup(parents); |
| } |
| } |
|
|
| [Test] |
| public void TestExpectedRoot() |
| { |
| Assert.Throws<UnityAgentsException>(() => |
| { |
| var unused = new BadPoseExtractor(); |
| }); |
| } |
| } |
|
|
| public class PoseExtensionTests |
| { |
| [Test] |
| public void TestInverse() |
| { |
| Pose t = new Pose |
| { |
| rotation = Quaternion.AngleAxis(23.0f, new Vector3(1, 1, 1).normalized), |
| position = new Vector3(-1.0f, 2.0f, 3.0f) |
| }; |
|
|
| var inverseT = t.Inverse(); |
| var product = inverseT.Multiply(t); |
| Assert.IsTrue(Vector3.zero == product.position); |
| Assert.IsTrue(Quaternion.identity == product.rotation); |
| } |
| } |
| } |
|
|