Version 2.1.2: Python bindings, OBJ assets support, bugfixes.
PiperOrigin-RevId: 434731612 Change-Id: I0cfda3e7a3d1c72036764986efc252ffa1b8c6b0
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mujoco {
|
||||
|
||||
// The component represents a joint with 1 degree of translational freedom.
|
||||
public class MjBallJoint : MjBaseJoint {
|
||||
[Tooltip("In radians.")]
|
||||
public float RangeUpper;
|
||||
|
||||
[Tooltip("Joint settings.")]
|
||||
public MjJointSettings Settings = MjJointSettings.Default;
|
||||
|
||||
protected override void OnParseMjcf(XmlElement mjcf) {
|
||||
// Transform.
|
||||
transform.localPosition =
|
||||
MjEngineTool.UnityVector3(mjcf.GetVector3Attribute("pos", defaultValue: Vector3.zero));
|
||||
|
||||
Settings.FromMjcf(mjcf);
|
||||
var rangeValues = mjcf.GetFloatArrayAttribute("range", defaultValue: new float[] { 0, 0 });
|
||||
// rangeValues[0] is always 0 for ball joints.
|
||||
RangeUpper = rangeValues[1];
|
||||
}
|
||||
|
||||
protected override XmlElement OnGenerateMjcf(XmlDocument doc) {
|
||||
var mjcf = (XmlElement)doc.CreateElement("joint");
|
||||
mjcf.SetAttribute("type", "ball");
|
||||
|
||||
MjEngineTool.PositionToMjcf(mjcf, this);
|
||||
|
||||
Settings.ToMjcf(mjcf);
|
||||
mjcf.SetAttribute("range", MjEngineTool.MakeLocaleInvariant($"0 {RangeUpper}"));
|
||||
|
||||
return mjcf;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc71be844486c4586ba729c1ab4d914a
|
||||
timeCreated: 1552056297
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mujoco {
|
||||
|
||||
public abstract class MjBaseJoint : MjComponent {
|
||||
public override MujocoLib.mjtObj ObjectType => MujocoLib.mjtObj.mjOBJ_JOINT;
|
||||
|
||||
public int QposAddress { get; private set; } = -1;
|
||||
public int DofAddress { get; private set; } = -1;
|
||||
// Joint will add Degrees of Freedom to this MjBaseBody.
|
||||
// It's the MjBaseBody located immediately above this joint in the scene tree.
|
||||
// NOTE: This property won't be initialized until runtime.
|
||||
public MjBaseBody ParentBody { get; private set; }
|
||||
|
||||
// Joint will constrain the ParentBody to this MjBaseBody.
|
||||
// It's the MjBaseBody located two levels above this joint in the scene tree.
|
||||
// For some joints, such as MjFreeJoint, this can be null.
|
||||
// NOTE: This property won't be initialized until runtime.
|
||||
public MjBaseBody GrandParentBody { get; private set; }
|
||||
|
||||
// Return the bodies connected by this joint.
|
||||
public void GetConnectedBodies(out MjBaseBody grandParent, out MjBaseBody parent) {
|
||||
parent = MjHierarchyTool.FindParentComponent<MjBaseBody>(this);
|
||||
if (parent != null) {
|
||||
grandParent = MjHierarchyTool.FindParentComponent<MjBaseBody>(parent);
|
||||
} else {
|
||||
grandParent = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override unsafe void OnBindToRuntime(MujocoLib.mjModel_* model, MujocoLib.mjData_* data) {
|
||||
QposAddress = model->jnt_qposadr[MujocoId];
|
||||
DofAddress = model->jnt_dofadr[MujocoId];
|
||||
}
|
||||
|
||||
protected override void Start() {
|
||||
base.Start();
|
||||
MjBaseBody grandparentBody, parentBody;
|
||||
GetConnectedBodies(out grandparentBody, out parentBody);
|
||||
GrandParentBody = grandparentBody;
|
||||
ParentBody = parentBody;
|
||||
if (ParentBody == null) {
|
||||
throw new Exception("The joint doesn't have a ParentBody.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07bd997db28964e5daf6af0ff47e157f
|
||||
timeCreated: 1538399740
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mujoco {
|
||||
|
||||
// The component represents a joint with 6 degrees of freedom.
|
||||
public class MjFreeJoint : MjBaseJoint {
|
||||
protected override void OnParseMjcf(XmlElement mjcf) {}
|
||||
|
||||
protected override XmlElement OnGenerateMjcf(XmlDocument doc) {
|
||||
return (XmlElement)doc.CreateElement("freejoint");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ef627bd3075d42d886135a149a187a2
|
||||
timeCreated: 1537540954
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,88 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mujoco {
|
||||
|
||||
public class MjHingeJoint : MjBaseJoint {
|
||||
[Tooltip("In degrees.")]
|
||||
public float RangeLower;
|
||||
[Tooltip("In degrees.")]
|
||||
public float RangeUpper;
|
||||
|
||||
[Tooltip("The current joint angle, in degrees. Read-only at play time.")]
|
||||
public float Configuration;
|
||||
|
||||
[Tooltip("Joint movement, in rad/sec. Read-only at play time.")]
|
||||
public float Velocity;
|
||||
|
||||
[Tooltip("Joint settings.")]
|
||||
public MjJointSettings Settings = MjJointSettings.Default;
|
||||
|
||||
// World space rotation axis.
|
||||
public Vector3 RotationAxis => transform.rotation * Vector3.right;
|
||||
|
||||
protected override unsafe void OnBindToRuntime(MujocoLib.mjModel_* model, MujocoLib.mjData_* data) {
|
||||
base.OnBindToRuntime(model, data);
|
||||
data->qvel[DofAddress] = Velocity;
|
||||
}
|
||||
|
||||
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
|
||||
var qpos = (float)data->qpos[QposAddress];
|
||||
Configuration = (qpos % (2 * Mathf.PI)) * Mathf.Rad2Deg;
|
||||
Velocity = (float)data->qvel[DofAddress];
|
||||
}
|
||||
|
||||
protected override void OnParseMjcf(XmlElement mjcf) {
|
||||
transform.localPosition =
|
||||
MjEngineTool.UnityVector3(mjcf.GetVector3Attribute("pos", defaultValue: Vector3.zero));
|
||||
|
||||
var rotationAxis =
|
||||
MjEngineTool.UnityVector3(mjcf.GetVector3Attribute("axis", defaultValue: Vector3.right));
|
||||
transform.localRotation = Quaternion.FromToRotation(Vector3.right, rotationAxis);
|
||||
|
||||
var rangeValues = mjcf.GetFloatArrayAttribute("range", defaultValue: new float[] { 0, 0 });
|
||||
RangeLower = rangeValues[0];
|
||||
RangeUpper = rangeValues[1];
|
||||
|
||||
if (!MjSceneImportSettings.AnglesInDegrees) {
|
||||
RangeLower *= Mathf.Rad2Deg;
|
||||
RangeUpper *= Mathf.Rad2Deg;
|
||||
}
|
||||
|
||||
Configuration = mjcf.GetFloatAttribute("ref", 0.0f);
|
||||
|
||||
Settings.FromMjcf(mjcf);
|
||||
}
|
||||
|
||||
protected override XmlElement OnGenerateMjcf(XmlDocument doc) {
|
||||
var mjcf = (XmlElement)doc.CreateElement("joint");
|
||||
mjcf.SetAttribute("type", "hinge");
|
||||
|
||||
MjEngineTool.PositionAxisToMjcf(mjcf, this);
|
||||
|
||||
Settings.ToMjcf(mjcf);
|
||||
if (RangeLower > RangeUpper) {
|
||||
throw new ArgumentException("Lower range value can't be bigger than Higher");
|
||||
}
|
||||
mjcf.SetAttribute("range", $"{RangeLower} {RangeUpper}");
|
||||
mjcf.SetAttribute("ref", $"{Configuration}");
|
||||
|
||||
return mjcf;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 517cde9d618b143a19f0ad61355a7f31
|
||||
timeCreated: 1537542636
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,171 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mujoco {
|
||||
|
||||
[Serializable]
|
||||
public struct MjJointSettings {
|
||||
[Tooltip("Added inertia of all DoFs created by this joint.")]
|
||||
public float Armature;
|
||||
|
||||
[Tooltip("Joint spring settings.")]
|
||||
public SpringSettings Spring;
|
||||
|
||||
[Tooltip("Joint solver settings.")]
|
||||
public SolverSettings Solver;
|
||||
|
||||
// Default joint settings.
|
||||
public static MjJointSettings Default = new MjJointSettings() {
|
||||
Solver = SolverSettings.Default,
|
||||
};
|
||||
|
||||
public void FromMjcf(XmlElement mjcf) {
|
||||
Armature = mjcf.GetFloatAttribute("armature", 0.0f);
|
||||
Spring.FromMjcf(mjcf);
|
||||
Solver.FromMjcf(mjcf);
|
||||
}
|
||||
|
||||
public void ToMjcf(XmlElement mjcf) {
|
||||
mjcf.SetAttribute("armature", MjEngineTool.MakeLocaleInvariant($"{Armature}"));
|
||||
Spring.ToMjcf(mjcf);
|
||||
Solver.ToMjcf(mjcf);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SpringSettings {
|
||||
public float TimeConstant;
|
||||
public float DampingRatio;
|
||||
|
||||
[Tooltip("Joint stiffness. If this value is positive, a spring will be created.")]
|
||||
public float Stiffness;
|
||||
[Tooltip("Damping applied to all degrees of freedom created by this joint.")]
|
||||
public float Damping;
|
||||
|
||||
[Tooltip("Spring equilibrium pose.")]
|
||||
public float EquilibriumPose;
|
||||
|
||||
public void ToMjcf(XmlElement mjcf) {
|
||||
// Spring settings.
|
||||
mjcf.SetAttribute("springref", MjEngineTool.MakeLocaleInvariant($"{EquilibriumPose}"));
|
||||
mjcf.SetAttribute("springdamper", MjEngineTool.MakeLocaleInvariant($"{TimeConstant} {DampingRatio}"));
|
||||
mjcf.SetAttribute("damping", MjEngineTool.MakeLocaleInvariant($"{Damping}"));
|
||||
mjcf.SetAttribute("stiffness", MjEngineTool.MakeLocaleInvariant($"{Stiffness}"));
|
||||
}
|
||||
|
||||
public void FromMjcf(XmlElement mjcf) {
|
||||
var springDamper = mjcf.GetVector2Attribute("springdamper", Vector2.zero);
|
||||
TimeConstant = springDamper.x;
|
||||
DampingRatio = springDamper.y;
|
||||
EquilibriumPose = mjcf.GetFloatAttribute("springref", 0.0f);
|
||||
Damping = mjcf.GetFloatAttribute("damping", 0.0f);
|
||||
Stiffness = mjcf.GetFloatAttribute("stiffness", 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SolverImpedance {
|
||||
public float DMin;
|
||||
public float DMax;
|
||||
public float Width;
|
||||
public float Midpoint;
|
||||
public float Power;
|
||||
|
||||
public static SolverImpedance Default =
|
||||
new SolverImpedance() { DMin = 0.9f, DMax = 0.95f, Width = 0.001f, Midpoint = 0.5f,
|
||||
Power = 2.0f };
|
||||
|
||||
public void FromMjcf(XmlElement element, string attributeName) {
|
||||
var values = element.GetFloatArrayAttribute(
|
||||
attributeName, new float[] { Default.DMin, Default.DMax, Default.Width, Default.Midpoint,
|
||||
Default.Power });
|
||||
DMin = values[0];
|
||||
DMax = values[1];
|
||||
Width = values[2];
|
||||
Midpoint = values[3];
|
||||
Power = values[4];
|
||||
}
|
||||
|
||||
public void ToMjcf(XmlElement element, string attributeName) {
|
||||
element.SetAttribute(attributeName, MjEngineTool.MakeLocaleInvariant($"{DMin} {DMax} {Width} {Midpoint} {Power}"));
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SolverReference {
|
||||
public float TimeConst;
|
||||
public float DampRatio;
|
||||
|
||||
public static SolverReference Default =
|
||||
new SolverReference() { TimeConst = 0.02f, DampRatio = 1.0f };
|
||||
|
||||
public void FromMjcf(XmlElement element, string attributeName) {
|
||||
var values = element.GetFloatArrayAttribute(
|
||||
attributeName, new float[] { Default.TimeConst, Default.DampRatio });
|
||||
TimeConst = values[0];
|
||||
DampRatio = values[1];
|
||||
}
|
||||
|
||||
public void ToMjcf(XmlElement element, string attributeName) {
|
||||
element.SetAttribute(attributeName, MjEngineTool.MakeLocaleInvariant($"{TimeConst} {DampRatio}"));
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SolverSettings {
|
||||
[Tooltip("Does the joint have limits.")]
|
||||
public bool Limited;
|
||||
|
||||
[Tooltip("Limit margin - always in radians/meters.")]
|
||||
public float Margin;
|
||||
public SolverReference RefLimit;
|
||||
public SolverImpedance ImpLimit;
|
||||
|
||||
[Tooltip("Friction loss due to dry friction.")]
|
||||
public float FrictionLoss;
|
||||
public SolverImpedance ImpFriction;
|
||||
public SolverReference RefFriction;
|
||||
|
||||
public static SolverSettings Default = new SolverSettings() {
|
||||
ImpFriction = SolverImpedance.Default,
|
||||
ImpLimit = SolverImpedance.Default,
|
||||
RefFriction = SolverReference.Default,
|
||||
RefLimit = SolverReference.Default,
|
||||
};
|
||||
|
||||
public void ToMjcf(XmlElement mjcf) {
|
||||
RefLimit.ToMjcf(mjcf, "solreflimit");
|
||||
ImpLimit.ToMjcf(mjcf, "solimplimit");
|
||||
RefFriction.ToMjcf(mjcf, "solreffriction");
|
||||
ImpFriction.ToMjcf(mjcf, "solimpfriction");
|
||||
mjcf.SetAttribute("frictionloss", MjEngineTool.MakeLocaleInvariant($"{FrictionLoss}"));
|
||||
mjcf.SetAttribute("limited", $"{Limited}".ToLower());
|
||||
mjcf.SetAttribute("margin", MjEngineTool.MakeLocaleInvariant($"{Margin}"));
|
||||
}
|
||||
|
||||
public void FromMjcf(XmlElement mjcf) {
|
||||
RefLimit.FromMjcf(mjcf, "solreflimit");
|
||||
ImpLimit.FromMjcf(mjcf, "solimplimit");
|
||||
RefFriction.FromMjcf(mjcf, "solreffriction");
|
||||
ImpFriction.FromMjcf(mjcf, "solimpfriction");
|
||||
FrictionLoss = mjcf.GetFloatAttribute("frictionloss", 0.0f);
|
||||
Limited = mjcf.GetBoolAttribute("limited", false);
|
||||
Margin = mjcf.GetFloatAttribute("margin", defaultValue: 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c02a22208190149a6a949f4247c77155
|
||||
timeCreated: 1537542636
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mujoco {
|
||||
|
||||
// The component represents a joint with 1 degree of translational freedom.
|
||||
public class MjSlideJoint : MjBaseJoint {
|
||||
[Tooltip("In meters.")]
|
||||
public float RangeLower;
|
||||
[Tooltip("In meters.")]
|
||||
public float RangeUpper;
|
||||
|
||||
[Tooltip("The current joint angle, in degrees. Read-only at play time.")]
|
||||
public float Configuration;
|
||||
|
||||
[Tooltip("Joint movement, in rad/sec. Read-only at play time.")]
|
||||
public float Velocity;
|
||||
|
||||
[Tooltip("Joint settings.")]
|
||||
public MjJointSettings Settings = MjJointSettings.Default;
|
||||
|
||||
// World space slide axis.
|
||||
public Vector3 SlideAxis => transform.rotation * Vector3.right;
|
||||
|
||||
protected override unsafe void OnBindToRuntime(MujocoLib.mjModel_* model, MujocoLib.mjData_* data) {
|
||||
base.OnBindToRuntime(model, data);
|
||||
data->qvel[DofAddress] = Velocity;
|
||||
}
|
||||
|
||||
public override unsafe void OnSyncState(MujocoLib.mjData_* data) {
|
||||
var qpos = (float)data->qpos[QposAddress];
|
||||
Configuration = (qpos % (2 * Mathf.PI)) * Mathf.Rad2Deg;
|
||||
Velocity = (float)data->qvel[DofAddress];
|
||||
}
|
||||
|
||||
protected override void OnParseMjcf(XmlElement mjcf) {
|
||||
// Transform.
|
||||
transform.localPosition =
|
||||
MjEngineTool.UnityVector3(mjcf.GetVector3Attribute("pos", defaultValue: Vector3.zero));
|
||||
|
||||
var rotationAxis =
|
||||
MjEngineTool.UnityVector3(mjcf.GetVector3Attribute("axis", defaultValue: Vector3.right));
|
||||
transform.localRotation = Quaternion.FromToRotation(Vector3.right, rotationAxis);
|
||||
|
||||
var rangeValues = mjcf.GetFloatArrayAttribute("range", defaultValue: new float[] { 0, 0 });
|
||||
RangeLower = rangeValues[0];
|
||||
RangeUpper = rangeValues[1];
|
||||
|
||||
Configuration = mjcf.GetFloatAttribute("ref", 0.0f);
|
||||
|
||||
Settings.FromMjcf(mjcf);
|
||||
}
|
||||
|
||||
protected override XmlElement OnGenerateMjcf(XmlDocument doc) {
|
||||
var mjcf = (XmlElement)doc.CreateElement("joint");
|
||||
mjcf.SetAttribute("type", "slide");
|
||||
|
||||
MjEngineTool.PositionAxisToMjcf(mjcf, this);
|
||||
|
||||
Settings.ToMjcf(mjcf);
|
||||
if (RangeLower > RangeUpper) {
|
||||
throw new ArgumentException("Lower range value can't be bigger than Higher");
|
||||
}
|
||||
mjcf.SetAttribute("range", MjEngineTool.MakeLocaleInvariant($"{RangeLower} {RangeUpper}"));
|
||||
mjcf.SetAttribute("ref", MjEngineTool.MakeLocaleInvariant($"{Configuration}"));
|
||||
|
||||
return mjcf;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f0920b38d2fe4e21bb645eff3f73be4
|
||||
timeCreated: 1537527115
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user