Refactor: separate buffer indexing and swizzling.

This also fixes a sensor data reading bug: previously, _sensorIndex was multiplied by 3 by MjEngineTool.

PiperOrigin-RevId: 451699887
Change-Id: I864bcbf8159857764854b25311a26ec5672125d9
This commit is contained in:
Tom Erez
2022-05-29 00:23:57 -07:00
committed by Copybara-Service
parent 5cc73c30bf
commit 02f300c762
16 changed files with 213 additions and 86 deletions
+8 -23
View File
@@ -47,7 +47,8 @@ namespace Mujoco {
var MjVec = MjEngineTool.MjVector3(vec);
var MjVecAsArray = new double[] { 10, 11, 12, MjVec.x, MjVec.y, MjVec.z };
fixed (double* MjArrPtr = MjVecAsArray) {
var recreatedVec = MjEngineTool.UnityVector3(MjArrPtr, 1);
var recreatedVec = MjEngineTool.UnityVector3(
MjEngineTool.MjVector3AtEntry(MjArrPtr, 1));
Assert.That(recreatedVec, Is.EqualTo(vec));
}
}
@@ -64,23 +65,6 @@ namespace Mujoco {
Assert.That(unityVec, Is.EqualTo(vec));
}
[TestCase(0.1f, 0.2f, 0.3f, 0.4f)]
[TestCase(-0.1f, -0.2f, -0.3f, -0.4f)]
[TestCase(-0.1f, 0.2f, 0.3f, 0.4f)]
[TestCase(0.1f, -0.2f, 0.3f, 0.4f)]
[TestCase(0.1f, 0.2f, -0.3f, 0.4f)]
[TestCase(0.1f, 0.2f, 0.3f, -0.4f)]
public unsafe void RoundrobinConversionOfQuaternion(float x, float y, float z, float w) {
var quat = new Quaternion(x, y, z, w);
var MjQuat = MjEngineTool.MjQuaternion(quat);
var MjQuatAsArray =
new double[] { 10, 20, 30, 40, MjQuat.w, MjQuat.x, MjQuat.y, MjQuat.z };
var recreatedQuat = MjEngineTool.UnityQuaternion(MjQuatAsArray, 1);
var q1 = new Vector4(quat.x, quat.y, quat.z, quat.w);
var q2 = new Vector4(recreatedQuat.x, recreatedQuat.y, recreatedQuat.z, recreatedQuat.w);
Assert.That(q1, Is.EqualTo(q2));
}
[TestCase(0.1f, 0.2f, 0.3f, 0.4f)]
[TestCase(-0.1f, -0.2f, -0.3f, -0.4f)]
[TestCase(-0.1f, 0.2f, 0.3f, 0.4f)]
@@ -94,7 +78,8 @@ namespace Mujoco {
var MjQuatAsArray =
new double[] { 10, 20, 30, 40, MjQuat.w, MjQuat.x, MjQuat.y, MjQuat.z };
fixed (double* MjArrPtr = MjQuatAsArray) {
var recreatedQuat = MjEngineTool.UnityQuaternion(MjArrPtr, 1);
var recreatedQuat = MjEngineTool.UnityQuaternion(
MjEngineTool.MjQuaternionAtEntry(MjArrPtr, 1));
var q1 = new Vector4(quat.x, quat.y, quat.z, quat.w);
var q2 = new Vector4(recreatedQuat.x, recreatedQuat.y, recreatedQuat.z, recreatedQuat.w);
Assert.That(q1, Is.EqualTo(q2));
@@ -138,8 +123,8 @@ namespace Mujoco {
var result = Quaternion.identity;
var buffer = new double[4];
fixed (double* unsafeBuffer = buffer) {
MjEngineTool.SetMjQuaternion(unsafeBuffer, quat, entryIndex: 0);
result = MjEngineTool.UnityQuaternion(unsafeBuffer, entryIndex: 0);
MjEngineTool.SetMjQuaternion(unsafeBuffer, quat);
result = MjEngineTool.UnityQuaternion(unsafeBuffer);
}
Assert.That(quat, Is.EqualTo(result));
}
@@ -154,8 +139,8 @@ namespace Mujoco {
var result = Vector3.zero;
double[] buffer = new double[3];
fixed (double* unsafeBuffer = buffer) {
MjEngineTool.SetMjVector3(unsafeBuffer, vec, entryIndex: 0);
result = MjEngineTool.UnityVector3(unsafeBuffer, entryIndex: 0);
MjEngineTool.SetMjVector3(unsafeBuffer, vec);
result = MjEngineTool.UnityVector3(unsafeBuffer);
}
Assert.That(vec, Is.EqualTo(result));
}
+123
View File
@@ -0,0 +1,123 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.TestTools.Utils;
namespace Mujoco {
[TestFixture]
public class MjSensorPlayTests {
private MjBody _body;
private MjSite _site;
private MjGeom _geom;
private MjHingeJoint _joint;
private MjSiteQuaternionSensor _siteQuatSensor0;
private MjSiteQuaternionSensor _siteQuatSensor;
private MjSiteVectorSensor _siteVectorSensor;
private MjGeomQuaternionSensor _geomQuatSensor;
private MjGeomVectorSensor _geomVectorSensor;
private MjBodyQuaternionSensor _bodyQuatSensor;
private MjBodyVectorSensor _bodyVectorSensor;
private MjScene _scene;
[SetUp]
public void SetUp() {
_scene = MjScene.Instance;
_body = new GameObject("body").AddComponent<MjBody>();
_site = new GameObject("site").AddComponent<MjSite>();
_geom = new GameObject("geom").AddComponent<MjGeom>();
_siteQuatSensor0 = new GameObject("sq0").AddComponent<MjSiteQuaternionSensor>();
_siteQuatSensor0.Site = _site;
_siteQuatSensor = new GameObject("sq").AddComponent<MjSiteQuaternionSensor>();
_siteQuatSensor.Site = _site;
_siteVectorSensor = new GameObject("sv").AddComponent<MjSiteVectorSensor>();
_siteVectorSensor.Site = _site;
_siteVectorSensor.SensorType = MjSiteVectorSensor.AvailableSensors.FramePos;
_geomQuatSensor = new GameObject("gq").AddComponent<MjGeomQuaternionSensor>();
_geomQuatSensor.Geom = _geom;
_geomVectorSensor = new GameObject("gv").AddComponent<MjGeomVectorSensor>();
_geomVectorSensor.Geom = _geom;
_geomVectorSensor.SensorType = MjGeomVectorSensor.AvailableSensors.FramePos;
_bodyQuatSensor = new GameObject("bq").AddComponent<MjBodyQuaternionSensor>();
_bodyQuatSensor.Body = _body;
_bodyVectorSensor = new GameObject("bv").AddComponent<MjBodyVectorSensor>();
_bodyVectorSensor.Body = _body;
_bodyVectorSensor.SensorType = MjBodyVectorSensor.AvailableSensors.FramePos;
_site.transform.position = new Vector3(1, 2, 3);
_site.transform.rotation = new Quaternion(0, 1, 2, 3);
_geom.transform.position = new Vector3(4, 5, 6);
_geom.transform.rotation = new Quaternion(4, 5, 6, 7);
_body.transform.position = new Vector3(7, 8, 9);
_body.transform.rotation = new Quaternion(7, 8, 9, 9);
_scene.CreateScene(); // compilation happens here
}
[TearDown]
public void TearDown() {
GameObject.DestroyImmediate(_site.gameObject);
GameObject.DestroyImmediate(_body.gameObject);
GameObject.DestroyImmediate(_geom.gameObject);
GameObject.DestroyImmediate(_siteQuatSensor0.gameObject);
GameObject.DestroyImmediate(_siteQuatSensor.gameObject);
GameObject.DestroyImmediate(_siteVectorSensor.gameObject);
GameObject.DestroyImmediate(_geomQuatSensor.gameObject);
GameObject.DestroyImmediate(_geomVectorSensor.gameObject);
GameObject.DestroyImmediate(_bodyQuatSensor.gameObject);
GameObject.DestroyImmediate(_bodyVectorSensor.gameObject);
GameObject.DestroyImmediate(_scene.gameObject);
GameObject.DestroyImmediate(MjScene.Instance);
}
[UnityTest]
public IEnumerator CheckSensorData() {
yield return new WaitForFixedUpdate(); // updating the transform
yield return new WaitForFixedUpdate(); // updating the transform
var vecComparer = new Vector3EqualityComparer(1e-4f);
var quatComparer = new Vector4EqualityComparer(1e-4f);
Assert.That(
_siteVectorSensor.SensorReading,
Is.EqualTo(_site.transform.position).Using(vecComparer));
Assert.That(
_geomVectorSensor.SensorReading,
Is.EqualTo(_geom.transform.position).Using(vecComparer));
Assert.That(
_bodyVectorSensor.SensorReading,
Is.EqualTo(_body.transform.position).Using(vecComparer));
Assert.That(
_siteQuatSensor0.SensorReading,
Is.EqualTo(_site.transform.rotation.normalized).Using(quatComparer));
Assert.That(
_siteQuatSensor.SensorReading,
Is.EqualTo(_site.transform.rotation.normalized).Using(quatComparer));
Assert.That(
_geomQuatSensor.SensorReading,
Is.EqualTo(_geom.transform.rotation.normalized).Using(quatComparer));
Assert.That(
_bodyQuatSensor.SensorReading,
Is.EqualTo(_body.transform.rotation.normalized).Using(quatComparer));
}
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 62bfed53c131e77cfa2845ad38c35a4e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: