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
+4 -2
View File
@@ -35,8 +35,10 @@ namespace Mujoco {
}
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
transform.position = MjEngineTool.UnityVector3(data->xpos, MujocoId);
transform.rotation = MjEngineTool.UnityQuaternion(data->xquat, MujocoId);
transform.position = MjEngineTool.UnityVector3(
MjEngineTool.MjVector3AtEntry(data->xpos, MujocoId));
transform.rotation = MjEngineTool.UnityQuaternion(
MjEngineTool.MjQuaternionAtEntry(data->xquat, MujocoId));
}
}
}
@@ -35,8 +35,10 @@ namespace Mujoco {
}
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
MjEngineTool.SetMjVector3(data->mocap_pos, transform.position, MujocoId);
MjEngineTool.SetMjQuaternion(data->mocap_quat, transform.rotation, MujocoId);
MjEngineTool.SetMjVector3(
MjEngineTool.MjVector3AtEntry(data->mocap_pos, MujocoId), transform.position);
MjEngineTool.SetMjQuaternion(
MjEngineTool.MjQuaternionAtEntry(data->mocap_quat, MujocoId), transform.rotation);
}
}
}
@@ -46,7 +46,7 @@ public class MjBodyQuaternionSensor : MjBaseSensor {
}
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
SensorReading = MjEngineTool.UnityQuaternion(data->sensordata, _sensorAddress);
SensorReading = MjEngineTool.UnityQuaternion(data->sensordata + _sensorAddress);
}
}
}
@@ -71,7 +71,7 @@ public class MjBodyVectorSensor : MjBaseSensor {
}
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
SensorReading = MjEngineTool.UnityVector3(data->sensordata, _sensorAddress);
SensorReading = MjEngineTool.UnityVector3(data->sensordata + _sensorAddress);
}
}
}
@@ -41,7 +41,7 @@ public class MjGeomQuaternionSensor : MjBaseSensor {
}
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
SensorReading = MjEngineTool.UnityQuaternion(data->sensordata, _sensorAddress);
SensorReading = MjEngineTool.UnityQuaternion(data->sensordata + _sensorAddress);
}
}
}
@@ -57,7 +57,7 @@ public class MjGeomVectorSensor : MjBaseSensor {
}
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
SensorReading = MjEngineTool.UnityVector3(data->sensordata, _sensorAddress);
SensorReading = MjEngineTool.UnityVector3(data->sensordata + _sensorAddress);
}
}
}
@@ -43,7 +43,7 @@ public class MjSiteQuaternionSensor : MjBaseSensor {
}
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
SensorReading = MjEngineTool.UnityQuaternion(data->sensordata, _sensorAddress);
SensorReading = MjEngineTool.UnityQuaternion(data->sensordata + _sensorAddress);
}
}
}
@@ -69,8 +69,7 @@ public class MjSiteVectorSensor : MjBaseSensor {
}
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
Vector3 mjReading = new Vector3((float)data->sensordata[_sensorAddress], (float)data->sensordata[_sensorAddress + 1], (float)data->sensordata[_sensorAddress + 2]);
SensorReading = MjEngineTool.UnityVector3(mjReading);
SensorReading = MjEngineTool.UnityVector3(data->sensordata + _sensorAddress);
}
}
}
+12 -6
View File
@@ -48,8 +48,10 @@ public class MjGeom : MjShapeComponent {
var MjParent = MjHierarchyTool.FindParentComponent<MjBaseBody>(this);
if (MjParent != null) {
var comInParentFrame = new MjTransformation(
translation: MjEngineTool.UnityVector3(model->geom_pos, MujocoId),
rotation: MjEngineTool.UnityQuaternion(model->geom_quat, MujocoId));
translation: MjEngineTool.UnityVector3(
MjEngineTool.MjVector3AtEntry(model->geom_pos, MujocoId)),
rotation: MjEngineTool.UnityQuaternion(
MjEngineTool.MjQuaternionAtEntry(model->geom_quat, MujocoId)));
// We don't want to bother calculating global transform in mujoco from mjModel,
// so we'll assume it's the same as the Unity transfor (it's the beginning of simulation after
@@ -78,13 +80,17 @@ public class MjGeom : MjShapeComponent {
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
if (ShapeType == ShapeTypes.Mesh) {
_geomInGlobalFrame.Set(
translation: MjEngineTool.UnityVector3(data->geom_xpos, MujocoId),
rotation: MjEngineTool.UnityQuaternionFromMatrix(data->geom_xmat, MujocoId));
translation: MjEngineTool.UnityVector3(
MjEngineTool.MjVector3AtEntry(data->geom_xpos, MujocoId)),
rotation: MjEngineTool.UnityQuaternionFromMatrix(
MjEngineTool.MjMatrixAtEntry(data->geom_xmat, MujocoId)));
var comInGlobalFrame = _geomInGlobalFrame * _comTransform;
comInGlobalFrame.StoreGlobal(transform);
} else {
transform.position = MjEngineTool.UnityVector3(data->geom_xpos, MujocoId);
transform.rotation = MjEngineTool.UnityQuaternionFromMatrix(data->geom_xmat, MujocoId);
transform.position = MjEngineTool.UnityVector3(
MjEngineTool.MjVector3AtEntry(data->geom_xpos, MujocoId));
transform.rotation = MjEngineTool.UnityQuaternionFromMatrix(
MjEngineTool.MjMatrixAtEntry(data->geom_xmat, MujocoId));
}
}
+4 -2
View File
@@ -40,8 +40,10 @@ public class MjSite : MjShapeComponent {
// Synchronize the state of the component.
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
transform.position = MjEngineTool.UnityVector3(data->site_xpos, MujocoId);
transform.rotation = MjEngineTool.UnityQuaternionFromMatrix(data->site_xmat, MujocoId);
transform.position = MjEngineTool.UnityVector3(
MjEngineTool.MjVector3AtEntry(data->site_xpos, MujocoId));
transform.rotation = MjEngineTool.UnityQuaternionFromMatrix(
MjEngineTool.MjMatrixAtEntry(data->site_xmat, MujocoId));
}
public void OnDrawGizmosSelected() {
@@ -115,8 +115,10 @@ public class MjSpatialTendon : MjBaseTendon {
if (data->wrap_obj[readHead] == -2 || data->wrap_obj[readHead + 1] == -2) {
readHead += 1;
} else {
Vector3 start = MjEngineTool.UnityVector3(data->wrap_xpos, readHead);
Vector3 end = MjEngineTool.UnityVector3(data->wrap_xpos, readHead + 1);
Vector3 start = MjEngineTool.UnityVector3(
MjEngineTool.MjVector3AtEntry(data->wrap_xpos, readHead));
Vector3 end = MjEngineTool.UnityVector3(
MjEngineTool.MjVector3AtEntry(data->wrap_xpos, readHead + 1));
Gizmos.DrawLine(start, end);
if (data->wrap_obj[readHead + 1] >= 0) { // a wrap geom
readHead += 2;
+35 -41
View File
@@ -29,7 +29,6 @@ public static class MjEngineTool {
private const int _elementsPerTransform = 7;
private static double[] _mjQuat = new double[4];
private static double[] _mjMat = new double[9];
private const int _MjSuccess = 1;
public static string Sanitize(string name) {
return name.Replace('/', '_');
@@ -71,25 +70,30 @@ public static class MjEngineTool {
}
// Stores a unity vector in a Mujoco target buffer.
// The vector coordinates will be stored at the 'entryIndex * 3' of the 'mjTarget' array.
public static unsafe void SetMjVector3(double* mjTarget, Vector3 unityVec, int entryIndex) {
var startOffset = entryIndex * _elementsPerPosition;
public static unsafe void SetMjVector3(double* mjTarget, Vector3 unityVec) {
var mjVec = MjVector3(unityVec);
mjTarget[startOffset] = mjVec[0];
mjTarget[startOffset + 1] = mjVec[1];
mjTarget[startOffset + 2] = mjVec[2];
mjTarget[0] = mjVec[0];
mjTarget[1] = mjVec[1];
mjTarget[2] = mjVec[2];
}
// Stores a unity quaternion in a Mujoco target buffer.
// The vector coordinates will be stored at the 'entryIndex * 4' of the 'mjTarget' array.
public static unsafe void SetMjQuaternion(
double* mjTarget, Quaternion unityQuat, int entryIndex) {
var startOffset = entryIndex * _elementsPerRotation;
public static unsafe void SetMjQuaternion(double* mjTarget, Quaternion unityQuat) {
var mjQuat = MjQuaternion(unityQuat);
mjTarget[startOffset] = mjQuat.w;
mjTarget[startOffset + 1] = mjQuat.x;
mjTarget[startOffset + 2] = mjQuat.y;
mjTarget[startOffset + 3] = mjQuat.z;
mjTarget[0] = mjQuat.w;
mjTarget[1] = mjQuat.x;
mjTarget[2] = mjQuat.y;
mjTarget[3] = mjQuat.z;
}
// Returns a pointer to an entry in the MuJoCo field that's 3*offsetEntry down the buffer.
public static unsafe double* MjVector3AtEntry(double* mjTarget, int offsetEntry) {
return mjTarget + offsetEntry * _elementsPerPosition;
}
// Returns a pointer to an entry in the MuJoCo field that's 4*offsetEntry down the buffer.
public static unsafe double* MjQuaternionAtEntry(double* mjTarget, int offsetEntry) {
return mjTarget + offsetEntry * _elementsPerRotation;
}
// Returns a pointer to an entry in the MuJoCo field that's 7*offsetEntry down the buffer.
@@ -97,6 +101,11 @@ public static class MjEngineTool {
return mjTarget + offsetEntry * _elementsPerTransform;
}
// Returns a pointer to an entry in the MuJoCo field that's 9*offsetEntry down the buffer.
public static unsafe double* MjMatrixAtEntry(double* mjTarget, int offsetEntry) {
return mjTarget + offsetEntry * _mjMat.Length;
}
// Stores a unity transform (position+rotation) in a Mujoco target buffer.
public static unsafe void SetMjTransform(
double* mjTarget, Vector3 unityVec, Quaternion unityQuat) {
@@ -117,10 +126,8 @@ public static class MjEngineTool {
}
// Converts a Mujoco vector to a Unity vector.
public static unsafe Vector3 UnityVector3(double* coords, int entryIndex) {
var startOffset = entryIndex * _elementsPerPosition;
return new Vector3(
(float)coords[startOffset], (float)coords[startOffset + 2], (float)coords[startOffset + 1]);
public static unsafe Vector3 UnityVector3(double* mjVector) {
return new Vector3((float)mjVector[0], (float)mjVector[2], (float)mjVector[1]);
}
// Converts a Mujoco vector to a Unity vector.
@@ -142,21 +149,9 @@ public static class MjEngineTool {
}
// Converts a Mujoco quaternion to a Unity quaternion.
// The quaternions is read starting at 'entryIndex * 4' of the 'coords' array.
public static Quaternion UnityQuaternion(double[] coords, int entryIndex) {
var startOffset = entryIndex * _elementsPerRotation;
public static unsafe Quaternion UnityQuaternion(double* mjQuat) {
return new Quaternion(
x:(float)coords[startOffset + 1], y:(float)coords[startOffset + 3],
z:(float)coords[startOffset + 2], w:(float)-coords[startOffset]);
}
// Converts a Mujoco quaternion to a Unity quaternion.
// The quaternion is read starting at 'entryIndex * 4' of the 'coords' array.
public static unsafe Quaternion UnityQuaternion(double* coords, int entryIndex) {
var startOffset = entryIndex * _elementsPerRotation;
return new Quaternion(
x:(float)coords[startOffset + 1], y:(float)coords[startOffset + 3],
z:(float)coords[startOffset + 2], w:(float)-coords[startOffset]);
x:(float)mjQuat[1], y:(float)mjQuat[3], z:(float)mjQuat[2], w:(float)-mjQuat[0]);
}
// Converts a Mujoco quaternion to a Unity quaternion.
@@ -166,17 +161,16 @@ public static class MjEngineTool {
}
// Converts a Mujoco matrix to a Unity quaternion.
// The matrix coordinates are at the 'entryIndex * 9' of the 'coords' array.
public static unsafe Quaternion UnityQuaternionFromMatrix(double* coords, int entryIndex) {
var startOffset = entryIndex * _mjMat.Length;
// The matrix coordinates are at the 'entryIndex * 9' of the 'mjMat' array.
public static unsafe Quaternion UnityQuaternionFromMatrix(double* mjMat) {
for (var j = 0; j < _mjMat.Length; ++j) {
_mjMat[j] = coords[startOffset + j];
_mjMat[j] = mjMat[j];
}
fixed (double* a = _mjQuat)
fixed (double* b = _mjMat) {
MujocoLib.mju_mat2Quat(a, b);
fixed (double* q_out = _mjQuat)
fixed (double* m_in = _mjMat) {
MujocoLib.mju_mat2Quat(q_out, m_in);
return UnityQuaternion(q_out);
}
return UnityQuaternion(_mjQuat, 0);
}
// Converts a Unity extents Vector3 to a Mujoco extents vector.