Revert "redid the global settings according to suggested guidelines"

This reverts commit 655b961c89.
This commit is contained in:
Joan Llobera
2025-10-17 09:42:40 +02:00
parent 655b961c89
commit 0001fe221c
+373 -415
View File
@@ -13,424 +13,382 @@
// limitations under the License. // limitations under the License.
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml; using System.Xml;
using UnityEngine; using UnityEngine;
using UnityEngine.Profiling;
namespace Mujoco namespace Mujoco {
{
// The MuJoCo parser is case-sensitive. The case format of the entries in the enums below is // The MuJoCo parser is case-sensitive. The case format of the entries in the enums below is
// exactly what the documentation specifies: http://mujoco.org/book/XMLreference.html#option . // exactly what the documentation specifies: http://mujoco.org/book/XMLreference.html#option .
public enum IntegratorType public enum IntegratorType {
{ Euler,
Euler, RK4,
RK4, @implicit,
@implicit, @implicitfast
@implicitfast }
}
public enum FrictionConeType {
public enum FrictionConeType pyramidal,
{ elliptic
pyramidal, }
elliptic
} public enum JacobianType {
dense,
public enum JacobianType sparse,
{ auto
dense, }
sparse,
auto public enum ConstraintSolverType {
} PGS,
CG,
public enum ConstraintSolverType Newton
{ }
PGS,
CG, public enum EnableDisableFlag {
Newton enable,
} disable
}
public enum EnableDisableFlag
{ [Serializable]
enable, public struct MjcfOptionFlag {
disable public EnableDisableFlag Constraint;
} public EnableDisableFlag Equality;
public EnableDisableFlag FrictionLoss;
[Serializable] public EnableDisableFlag Limit;
public struct MjcfOptionFlag public EnableDisableFlag Contact;
{ public EnableDisableFlag Passive;
public EnableDisableFlag Constraint; public EnableDisableFlag Gravity;
public EnableDisableFlag Equality; public EnableDisableFlag ClampCtrl;
public EnableDisableFlag FrictionLoss; public EnableDisableFlag WarmStart;
public EnableDisableFlag Limit; public EnableDisableFlag FilterParent;
public EnableDisableFlag Contact; public EnableDisableFlag Actuation;
public EnableDisableFlag Spring; public EnableDisableFlag RefSafe;
public EnableDisableFlag Damper; public EnableDisableFlag Override;
public EnableDisableFlag Gravity; public EnableDisableFlag Energy;
public EnableDisableFlag ClampCtrl; public EnableDisableFlag FwdInv;
public EnableDisableFlag WarmStart; public EnableDisableFlag MultiCCD;
public EnableDisableFlag FilterParent; public static MjcfOptionFlag Default = new MjcfOptionFlag() {
public EnableDisableFlag Actuation; Constraint = EnableDisableFlag.enable,
public EnableDisableFlag RefSafe; Equality = EnableDisableFlag.enable,
public EnableDisableFlag Override; FrictionLoss = EnableDisableFlag.enable,
public EnableDisableFlag Energy; Limit = EnableDisableFlag.enable,
public EnableDisableFlag FwdInv; Contact = EnableDisableFlag.enable,
public EnableDisableFlag MultiCCD; Passive = EnableDisableFlag.enable,
public static MjcfOptionFlag Default = new MjcfOptionFlag() Gravity = EnableDisableFlag.enable,
{ ClampCtrl = EnableDisableFlag.enable,
Constraint = EnableDisableFlag.enable, WarmStart = EnableDisableFlag.enable,
Equality = EnableDisableFlag.enable, FilterParent = EnableDisableFlag.enable,
FrictionLoss = EnableDisableFlag.enable, Actuation = EnableDisableFlag.enable,
Limit = EnableDisableFlag.enable, RefSafe = EnableDisableFlag.enable,
Contact = EnableDisableFlag.enable, Override = EnableDisableFlag.disable,
Spring = EnableDisableFlag.enable, Energy = EnableDisableFlag.disable,
Damper = EnableDisableFlag.enable, FwdInv = EnableDisableFlag.disable,
Gravity = EnableDisableFlag.enable, MultiCCD = EnableDisableFlag.disable
ClampCtrl = EnableDisableFlag.enable, };
WarmStart = EnableDisableFlag.enable,
FilterParent = EnableDisableFlag.enable, public void FromMjcf(XmlElement mjcf) {
Actuation = EnableDisableFlag.enable, var localDefault = MjcfOptionFlag.Default;
RefSafe = EnableDisableFlag.enable, Constraint = mjcf.GetEnumAttribute<EnableDisableFlag>("constraint", localDefault.Constraint);
Override = EnableDisableFlag.disable, Equality = mjcf.GetEnumAttribute<EnableDisableFlag>("equality", localDefault.Equality);
Energy = EnableDisableFlag.disable, FrictionLoss = mjcf.GetEnumAttribute<EnableDisableFlag>("frictionloss",
FwdInv = EnableDisableFlag.disable, localDefault.FrictionLoss);
MultiCCD = EnableDisableFlag.disable Limit = mjcf.GetEnumAttribute<EnableDisableFlag>("limit", localDefault.Limit);
}; Contact = mjcf.GetEnumAttribute<EnableDisableFlag>("contact", localDefault.Contact);
Passive = mjcf.GetEnumAttribute<EnableDisableFlag>("passive", localDefault.Passive);
public void FromMjcf(XmlElement mjcf) Gravity = mjcf.GetEnumAttribute<EnableDisableFlag>("gravity", localDefault.Gravity);
{ ClampCtrl = mjcf.GetEnumAttribute<EnableDisableFlag>("clampctrl", localDefault.ClampCtrl);
var localDefault = MjcfOptionFlag.Default; WarmStart = mjcf.GetEnumAttribute<EnableDisableFlag>("warmstart", localDefault.WarmStart);
Constraint = mjcf.GetEnumAttribute<EnableDisableFlag>("constraint", localDefault.Constraint); FilterParent = mjcf.GetEnumAttribute<EnableDisableFlag>("filterparent",
Equality = mjcf.GetEnumAttribute<EnableDisableFlag>("equality", localDefault.Equality); localDefault.FilterParent);
FrictionLoss = mjcf.GetEnumAttribute<EnableDisableFlag>("frictionloss", Actuation = mjcf.GetEnumAttribute<EnableDisableFlag>("actuation", localDefault.Actuation);
localDefault.FrictionLoss); RefSafe = mjcf.GetEnumAttribute<EnableDisableFlag>("refsafe", localDefault.RefSafe);
Limit = mjcf.GetEnumAttribute<EnableDisableFlag>("limit", localDefault.Limit); Override = mjcf.GetEnumAttribute<EnableDisableFlag>("override", localDefault.Override);
Contact = mjcf.GetEnumAttribute<EnableDisableFlag>("contact", localDefault.Contact); Energy = mjcf.GetEnumAttribute<EnableDisableFlag>("energy", localDefault.Energy);
Spring = mjcf.GetEnumAttribute<EnableDisableFlag>("spring", localDefault.Spring); FwdInv = mjcf.GetEnumAttribute<EnableDisableFlag>("fwdinv", localDefault.FwdInv);
Damper = mjcf.GetEnumAttribute<EnableDisableFlag>("damper", localDefault.Damper); MultiCCD = mjcf.GetEnumAttribute<EnableDisableFlag>("multiccd", localDefault.MultiCCD);
Gravity = mjcf.GetEnumAttribute<EnableDisableFlag>("gravity", localDefault.Gravity); }
ClampCtrl = mjcf.GetEnumAttribute<EnableDisableFlag>("clampctrl", localDefault.ClampCtrl);
WarmStart = mjcf.GetEnumAttribute<EnableDisableFlag>("warmstart", localDefault.WarmStart); public void ToMjcf(XmlElement mjcf) {
FilterParent = mjcf.GetEnumAttribute<EnableDisableFlag>("filterparent", mjcf.SetAttribute("constraint", Constraint.ToString());
localDefault.FilterParent); mjcf.SetAttribute("equality", Equality.ToString());
Actuation = mjcf.GetEnumAttribute<EnableDisableFlag>("actuation", localDefault.Actuation); mjcf.SetAttribute("frictionloss", FrictionLoss.ToString());
RefSafe = mjcf.GetEnumAttribute<EnableDisableFlag>("refsafe", localDefault.RefSafe); mjcf.SetAttribute("limit", Limit.ToString());
Override = mjcf.GetEnumAttribute<EnableDisableFlag>("override", localDefault.Override); mjcf.SetAttribute("contact", Contact.ToString());
Energy = mjcf.GetEnumAttribute<EnableDisableFlag>("energy", localDefault.Energy); // mjcf.SetAttribute("passive", Passive.ToString());
FwdInv = mjcf.GetEnumAttribute<EnableDisableFlag>("fwdinv", localDefault.FwdInv); mjcf.SetAttribute("gravity", Gravity.ToString());
MultiCCD = mjcf.GetEnumAttribute<EnableDisableFlag>("multiccd", localDefault.MultiCCD); mjcf.SetAttribute("clampctrl", ClampCtrl.ToString());
} mjcf.SetAttribute("warmstart", WarmStart.ToString());
mjcf.SetAttribute("filterparent", FilterParent.ToString());
public void ToMjcf(XmlElement mjcf) mjcf.SetAttribute("actuation", Actuation.ToString());
{ mjcf.SetAttribute("refsafe", RefSafe.ToString());
mjcf.SetAttribute("constraint", Constraint.ToString()); mjcf.SetAttribute("override", Override.ToString());
mjcf.SetAttribute("equality", Equality.ToString()); mjcf.SetAttribute("energy", Energy.ToString());
mjcf.SetAttribute("frictionloss", FrictionLoss.ToString()); mjcf.SetAttribute("fwdinv", FwdInv.ToString());
mjcf.SetAttribute("limit", Limit.ToString()); mjcf.SetAttribute("multiccd", MultiCCD.ToString());
mjcf.SetAttribute("contact", Contact.ToString()); }
mjcf.SetAttribute("spring", Spring.ToString()); }
mjcf.SetAttribute("damper", Damper.ToString());
mjcf.SetAttribute("gravity", Gravity.ToString()); [Serializable]
mjcf.SetAttribute("clampctrl", ClampCtrl.ToString()); public struct MjSizeStruct {
mjcf.SetAttribute("warmstart", WarmStart.ToString()); public String Memory;
mjcf.SetAttribute("filterparent", FilterParent.ToString()); public static MjSizeStruct Default = new MjSizeStruct() {
mjcf.SetAttribute("actuation", Actuation.ToString()); Memory = "-1"
mjcf.SetAttribute("refsafe", RefSafe.ToString()); };
mjcf.SetAttribute("override", Override.ToString());
mjcf.SetAttribute("energy", Energy.ToString()); public void ParseMjcf(XmlElement mjcf) {
mjcf.SetAttribute("fwdinv", FwdInv.ToString()); Memory = mjcf.GetStringAttribute("memory", "-1");
mjcf.SetAttribute("multiccd", MultiCCD.ToString()); }
}
} public XmlElement ToMjcf(XmlElement mjcf) {
mjcf.SetAttribute("memory", $"{Memory}");
[Serializable] return mjcf;
public struct MjSizeStruct }
{ }
public String Memory;
public static MjSizeStruct Default = new MjSizeStruct() [Serializable]
{ public struct MjOptionStruct {
Memory = "-1"
}; // "timestep" and "gravity" come from global settings.
// "apirate" is only relevant to HAPTIX.
public void ParseMjcf(XmlElement mjcf) [Tooltip("Ratio of frictional-to-normal constraint impedance.")]
{ public float ImpRatio;
Memory = mjcf.GetStringAttribute("memory", "-1"); [Tooltip("Global magnetic flux used by magnetometer sensors.")]
} public Vector3 Magnetic;
[Tooltip("Velocity vector of the medium, scales with the values of Density and Viscosity below.")]
public XmlElement ToMjcf(XmlElement mjcf) public Vector3 Wind;
{ [Tooltip("Density of the medium for lift and drag forces. 0 disables lift and drag forces.")]
mjcf.SetAttribute("memory", $"{Memory}"); public float Density;
return mjcf; [Tooltip("Viscosity of the medium for viscous forces. 0 disables viscous forces.")]
} public float Viscosity;
} [Tooltip("Contact pair margin used when ContactOverride flag is set.")]
public float OverrideMargin;
[Serializable] [Tooltip("Contact pair solref used when ContactOverride flag is set.")]
public struct MjOptionStruct public SolverReference OverrideSolRef;
{ [Tooltip("Contact pair solimp used when ContactOverride flag is set.")]
public SolverImpedance OverrideSolImp;
// "timestep" and "gravity" come from global settings. [Tooltip("Numerical integrator.")]
[Tooltip("Ratio of frictional-to-normal constraint impedance.")] public IntegratorType Integrator;
public float ImpRatio; [Tooltip("How to model the friction cone.")]
[Tooltip("Global magnetic flux used by magnetometer sensors.")] public FrictionConeType Cone;
public Vector3 Magnetic; [Tooltip("How to represent the constraint Jacobian.")]
[Tooltip("Velocity vector of the medium, scales with the values of Density and Viscosity below.")] public JacobianType Jacobian;
public Vector3 Wind; [Tooltip("Constraint solver algorithm.")]
[Tooltip("Density of the medium for lift and drag forces. 0 disables lift and drag forces.")] public ConstraintSolverType Solver;
public float Density; [Tooltip("Maximum iterations for the constraint solver.")]
[Tooltip("Viscosity of the medium for viscous forces. 0 disables viscous forces.")] public int Iterations;
public float Viscosity; [Tooltip("Threshold used for early termination of the constraint solver.")]
[Tooltip("Contact pair margin used when ContactOverride flag is set.")] public float Tolerance;
public float OverrideMargin; [Tooltip("Maximum iterations for the no-slip phase of the constraint solver.")]
[Tooltip("Contact pair solref used when ContactOverride flag is set.")] public int NoSlipIterations;
public SolverReference OverrideSolRef; [Tooltip("Threshold used for early termination of the Noslip solver.")]
[Tooltip("Contact pair solimp used when ContactOverride flag is set.")] public float NoSlipTolerance;
public SolverImpedance OverrideSolImp; [Tooltip("Maximum iterations for convex mesh collisions.")]
[Tooltip("Numerical integrator.")] public int CcdIterations;
public IntegratorType Integrator; [Tooltip("Threshold used for early termination of the MPR algorithm.")]
[Tooltip("How to model the friction cone.")] public float CcdTolerance;
public FrictionConeType Cone;
[Tooltip("How to represent the constraint Jacobian.")] public MjcfOptionFlag Flag;
public JacobianType Jacobian;
[Tooltip("Constraint solver algorithm.")] // Default values copied from the "XML reference" page in the MuJoCo documentation.
public ConstraintSolverType Solver; public static MjOptionStruct Default = new MjOptionStruct() {
[Tooltip("Maximum iterations for the constraint solver.")] ImpRatio = 1.0f,
public int Iterations; Magnetic = Vector3.zero,
[Tooltip("Threshold used for early termination of the constraint solver.")] Wind = new Vector3(0.0f, 0.0f, 0.0f),
public float Tolerance; Density = 0.0f,
[Tooltip("Maximum iterations for the no-slip phase of the constraint solver.")] Viscosity = 0.0f,
public int NoSlipIterations; OverrideMargin = 0.0f,
[Tooltip("Threshold used for early termination of the Noslip solver.")] OverrideSolRef = SolverReference.Default,
public float NoSlipTolerance; OverrideSolImp = SolverImpedance.Default,
[Tooltip("Maximum iterations for convex mesh collisions.")] Integrator = IntegratorType.Euler,
public int CcdIterations; Cone = FrictionConeType.pyramidal,
[Tooltip("Threshold used for early termination of the MPR algorithm.")] Jacobian = JacobianType.auto,
public float CcdTolerance; Solver = ConstraintSolverType.Newton,
Iterations = 100,
public MjcfOptionFlag Flag; Tolerance = 1e-8f,
NoSlipIterations = 0,
// Default values copied from the "XML reference" page in the MuJoCo documentation. NoSlipTolerance = 1e-6f,
public static MjOptionStruct Default = new MjOptionStruct() CcdIterations = 50,
{ CcdTolerance = 1e-6f,
ImpRatio = 1.0f, Flag = MjcfOptionFlag.Default
Magnetic = Vector3.zero, };
Wind = new Vector3(0.0f, 0.0f, 0.0f),
Density = 0.0f, public void ParseMjcf(XmlElement mjcf) {
Viscosity = 0.0f, if (mjcf.HasAttribute("timestep")) {
OverrideMargin = 0.0f, var mjTimestep = mjcf.GetFloatAttribute("timestep", Time.fixedDeltaTime);
OverrideSolRef = SolverReference.Default, if (mjTimestep != Time.fixedDeltaTime) {
OverrideSolImp = SolverImpedance.Default, Debug.unityLogger.LogWarning(
Integrator = IntegratorType.Euler, "MuJoCo",
Cone = FrictionConeType.pyramidal, $"MuJoCo's timestep ({mjTimestep}s) ignored, please set fixedDeltaTime manually.",
Jacobian = JacobianType.auto, null);
Solver = ConstraintSolverType.Newton, }
Iterations = 100, }
Tolerance = 1e-8f, if (mjcf.HasAttribute("gravity")) {
NoSlipIterations = 0, var mjGravity = mjcf.GetVector3Attribute("gravity", Vector3.zero);
NoSlipTolerance = 1e-6f, Debug.unityLogger.LogWarning(
CcdIterations = 50, "MuJoCo",
CcdTolerance = 1e-6f, $"MuJoCo's gravity ({mjGravity.x} {mjGravity.z} {mjGravity.y}) ignored, " +
Flag = MjcfOptionFlag.Default "please set gravity in the Physics Manager.",
}; null);
}
public void ParseMjcf(XmlElement mjcf) var localDefault = MjOptionStruct.Default;
{ ImpRatio = mjcf.GetFloatAttribute("impratio", localDefault.ImpRatio);
if (mjcf.HasAttribute("timestep")) Magnetic = mjcf.GetVector3Attribute("magnetic", localDefault.Magnetic);
{ Wind = mjcf.GetVector3Attribute("wind", localDefault.Wind);
var mjTimestep = mjcf.GetFloatAttribute("timestep", Time.fixedDeltaTime); Density = mjcf.GetFloatAttribute("density", localDefault.Density);
if (mjTimestep != Time.fixedDeltaTime) Viscosity = mjcf.GetFloatAttribute("viscosity", localDefault.Viscosity);
{ OverrideMargin = mjcf.GetFloatAttribute("o_margin", localDefault.OverrideMargin);
Debug.unityLogger.LogWarning(
"MuJoCo", OverrideSolRef.FromMjcf(mjcf, "o_solref");
$"MuJoCo's timestep ({mjTimestep}s) ignored, please set fixedDeltaTime manually.", OverrideSolImp.FromMjcf(mjcf, "o_solimp");
null);
} Integrator = mjcf.GetEnumAttribute<IntegratorType>("integrator", localDefault.Integrator);
} Cone = mjcf.GetEnumAttribute<FrictionConeType>("cone", localDefault.Cone);
if (mjcf.HasAttribute("gravity")) Jacobian = mjcf.GetEnumAttribute<JacobianType>("jacobian", localDefault.Jacobian);
{ Solver = mjcf.GetEnumAttribute<ConstraintSolverType>("solver", localDefault.Solver);
var mjGravity = mjcf.GetVector3Attribute("gravity", Vector3.zero);
Debug.unityLogger.LogWarning( Iterations = (int)mjcf.GetFloatAttribute("iterations", localDefault.Iterations);
"MuJoCo", Tolerance = mjcf.GetFloatAttribute("tolerance", localDefault.Tolerance);
$"MuJoCo's gravity ({mjGravity.x} {mjGravity.z} {mjGravity.y}) ignored, " + NoSlipIterations = (int)mjcf.GetFloatAttribute(
"please set gravity in the Physics Manager.", "noslip_iterations", localDefault.NoSlipIterations);
null); NoSlipTolerance = mjcf.GetFloatAttribute("noslip_tolerance", localDefault.NoSlipTolerance);
} CcdIterations = (int)mjcf.GetFloatAttribute("ccd_iterations", localDefault.CcdIterations);
var localDefault = MjOptionStruct.Default; CcdTolerance = mjcf.GetFloatAttribute("ccd_tolerance", localDefault.CcdTolerance);
ImpRatio = mjcf.GetFloatAttribute("impratio", localDefault.ImpRatio);
Magnetic = mjcf.GetVector3Attribute("magnetic", localDefault.Magnetic); var flagElements = mjcf.GetElementsByTagName("flag");
Wind = mjcf.GetVector3Attribute("wind", localDefault.Wind); if (flagElements.Count == 1) {
Density = mjcf.GetFloatAttribute("density", localDefault.Density); Flag.FromMjcf(flagElements[0] as XmlElement);
Viscosity = mjcf.GetFloatAttribute("viscosity", localDefault.Viscosity); } else if (flagElements.Count > 1) {
OverrideMargin = mjcf.GetFloatAttribute("o_margin", localDefault.OverrideMargin); throw new ArgumentException("More than one <flag> node is not supported.");
}
OverrideSolRef.FromMjcf(mjcf, "o_solref"); }
OverrideSolImp.FromMjcf(mjcf, "o_solimp");
public XmlElement ToMjcf(XmlElement mjcf) {
Integrator = mjcf.GetEnumAttribute<IntegratorType>("integrator", localDefault.Integrator); mjcf.SetAttribute("impratio", MjEngineTool.MakeLocaleInvariant($"{ImpRatio}"));
Cone = mjcf.GetEnumAttribute<FrictionConeType>("cone", localDefault.Cone);
Jacobian = mjcf.GetEnumAttribute<JacobianType>("jacobian", localDefault.Jacobian); mjcf.SetAttribute("magnetic", MjEngineTool.MakeLocaleInvariant($"{Magnetic.x} {Magnetic.y} {Magnetic.z}"));
Solver = mjcf.GetEnumAttribute<ConstraintSolverType>("solver", localDefault.Solver); mjcf.SetAttribute("wind", MjEngineTool.MakeLocaleInvariant($"{Wind.x} {Wind.y} {Wind.z}"));
Iterations = (int)mjcf.GetFloatAttribute("iterations", localDefault.Iterations); mjcf.SetAttribute("density", MjEngineTool.MakeLocaleInvariant($"{Density}"));
Tolerance = mjcf.GetFloatAttribute("tolerance", localDefault.Tolerance); mjcf.SetAttribute("viscosity", MjEngineTool.MakeLocaleInvariant($"{Viscosity}"));
NoSlipIterations = (int)mjcf.GetFloatAttribute( mjcf.SetAttribute("o_margin", MjEngineTool.MakeLocaleInvariant($"{OverrideMargin}"));
"noslip_iterations", localDefault.NoSlipIterations);
NoSlipTolerance = mjcf.GetFloatAttribute("noslip_tolerance", localDefault.NoSlipTolerance); OverrideSolRef.ToMjcf(mjcf, "o_solref");
CcdIterations = (int)mjcf.GetFloatAttribute("ccd_iterations", localDefault.CcdIterations); OverrideSolImp.ToMjcf(mjcf, "o_solimp");
CcdTolerance = mjcf.GetFloatAttribute("ccd_tolerance", localDefault.CcdTolerance);
mjcf.SetAttribute("integrator", Integrator.ToString());
var flagElements = mjcf.GetElementsByTagName("flag"); mjcf.SetAttribute("cone", Cone.ToString());
if (flagElements.Count == 1) mjcf.SetAttribute("jacobian", Jacobian.ToString());
{ mjcf.SetAttribute("solver", Solver.ToString());
Flag.FromMjcf(flagElements[0] as XmlElement);
} mjcf.SetAttribute("iterations", MjEngineTool.MakeLocaleInvariant($"{Iterations}"));
else if (flagElements.Count > 1) mjcf.SetAttribute("tolerance", MjEngineTool.MakeLocaleInvariant($"{Tolerance}"));
{ mjcf.SetAttribute("noslip_iterations", MjEngineTool.MakeLocaleInvariant($"{NoSlipIterations}"));
throw new ArgumentException("More than one <flag> node is not supported."); mjcf.SetAttribute("noslip_tolerance", MjEngineTool.MakeLocaleInvariant($"{NoSlipTolerance}"));
} mjcf.SetAttribute("ccd_iterations", MjEngineTool.MakeLocaleInvariant($"{CcdIterations}"));
} mjcf.SetAttribute("ccd_tolerance", MjEngineTool.MakeLocaleInvariant($"{CcdTolerance}"));
public XmlElement ToMjcf(XmlElement mjcf) var flags = (XmlElement)mjcf.AppendChild(
{ mjcf.OwnerDocument.CreateElement("flag"));
mjcf.SetAttribute("impratio", MjEngineTool.MakeLocaleInvariant($"{ImpRatio}")); Flag.ToMjcf(flags);
return mjcf;
mjcf.SetAttribute("magnetic", }
MjEngineTool.MakeLocaleInvariant($"{Magnetic.x} {Magnetic.y} {Magnetic.z}")); }
mjcf.SetAttribute("wind", MjEngineTool.MakeLocaleInvariant($"{Wind.x} {Wind.y} {Wind.z}"));
[Serializable]
mjcf.SetAttribute("density", MjEngineTool.MakeLocaleInvariant($"{Density}")); public class NumericEntry {
mjcf.SetAttribute("viscosity", MjEngineTool.MakeLocaleInvariant($"{Viscosity}")); public String Name;
mjcf.SetAttribute("o_margin", MjEngineTool.MakeLocaleInvariant($"{OverrideMargin}")); [Tooltip("Space-separated list of floats.")]
public String Data;
OverrideSolRef.ToMjcf(mjcf, "o_solref"); }
OverrideSolImp.ToMjcf(mjcf, "o_solimp");
public class MjGlobalSettings : MonoBehaviour {
mjcf.SetAttribute("integrator", Integrator.ToString());
mjcf.SetAttribute("cone", Cone.ToString()); [Tooltip("Filename for the generated scene XML.")]
mjcf.SetAttribute("jacobian", Jacobian.ToString()); public string DebugFileName;
mjcf.SetAttribute("solver", Solver.ToString());
[Tooltip("Scales the force applied by the mouse spring.")]
mjcf.SetAttribute("iterations", MjEngineTool.MakeLocaleInvariant($"{Iterations}")); public float MouseSpringStiffness = 100;
mjcf.SetAttribute("tolerance", MjEngineTool.MakeLocaleInvariant($"{Tolerance}"));
mjcf.SetAttribute("noslip_iterations", MjEngineTool.MakeLocaleInvariant($"{NoSlipIterations}")); [Tooltip("If false, numerical suffixes will be aded to ensure name uniqueness.")]
mjcf.SetAttribute("noslip_tolerance", MjEngineTool.MakeLocaleInvariant($"{NoSlipTolerance}")); public bool UseRawGameObjectNames;
mjcf.SetAttribute("ccd_iterations", MjEngineTool.MakeLocaleInvariant($"{CcdIterations}"));
mjcf.SetAttribute("ccd_tolerance", MjEngineTool.MakeLocaleInvariant($"{CcdTolerance}")); public MjOptionStruct GlobalOptions = MjOptionStruct.Default;
var flags = (XmlElement)mjcf.AppendChild( public MjSizeStruct GlobalSizes = MjSizeStruct.Default;
mjcf.OwnerDocument.CreateElement("flag"));
Flag.ToMjcf(flags); public List<NumericEntry> CustomNumeric = new List<NumericEntry>() {};
return mjcf;
} public static MjGlobalSettings Instance {
} get {
if (_instance == null) {
[Serializable] var instances = FindObjectsOfType<MjGlobalSettings>();
public class NumericEntry if (instances.Length > 1) {
{ throw new InvalidOperationException(
public String Name; "Only one MjGlobalSettings instance is allowed - please resolve manually.");
[Tooltip("Space-separated list of floats.")] } else if (instances.Length == 1) {
public String Data; _instance = instances[0];
} }
}
public class MjGlobalSettings : MonoBehaviour return _instance;
{ }
}
[Tooltip("Filename for the generated scene XML.")]
public string DebugFileName; private static MjGlobalSettings _instance = null;
[Tooltip("Scales the force applied by the mouse spring.")] public void Awake() {
public float MouseSpringStiffness = 100; if (_instance == null) {
_instance = this;
[Tooltip("If false, numerical suffixes will be aded to ensure name uniqueness.")] } else if (_instance != this) {
public bool UseRawGameObjectNames; throw new InvalidOperationException(
"At most one MjGlobalSettings should be present.");
public MjOptionStruct GlobalOptions = MjOptionStruct.Default; }
}
public MjSizeStruct GlobalSizes = MjSizeStruct.Default;
public void ParseGlobalMjcfSections(XmlElement mujocoNode) {
public List<NumericEntry> CustomNumeric = new List<NumericEntry>() { };
var optionNode = mujocoNode.SelectSingleNode("option") as XmlElement;
public static MjGlobalSettings Instance var sizeNode = mujocoNode.SelectSingleNode("size") as XmlElement;
{ var customNode = mujocoNode.SelectSingleNode("custom") as XmlElement;
get
{ if (optionNode != null) {
if (_instance == null) GlobalOptions.ParseMjcf(optionNode);
{ }
var instances = FindObjectsOfType<MjGlobalSettings>(); if (sizeNode != null) {
if (instances.Length > 1) GlobalSizes.ParseMjcf(sizeNode);
{ }
throw new InvalidOperationException( if (customNode != null) {
"Only one MjGlobalSettings instance is allowed - please resolve manually."); foreach (var childNode in customNode.ChildNodes) {
} var child = childNode as XmlElement;
else if (instances.Length == 1) if (child.Name == "numeric") {
{ var numeric = new NumericEntry();
_instance = instances[0]; numeric.Name = child.GetAttribute("name");
} numeric.Data = child.GetAttribute("data");
} CustomNumeric.Add(numeric);
return _instance; }
} }
} }
}
private static MjGlobalSettings _instance = null;
public void GlobalsToMjcf(XmlElement mjcf) {
public void Awake() var doc = mjcf.OwnerDocument;
{ var optionMjcf = (XmlElement)mjcf.AppendChild(doc.CreateElement("option"));
if (_instance == null) GlobalOptions.ToMjcf(optionMjcf);
{ var sizeMjcf = (XmlElement)mjcf.AppendChild(doc.CreateElement("size"));
_instance = this; GlobalSizes.ToMjcf(sizeMjcf);
} var customMjcf = (XmlElement)mjcf.AppendChild(doc.CreateElement("custom"));
else if (_instance != this) foreach (var numeric in CustomNumeric) {
{ var numericMjcf = (XmlElement)customMjcf.AppendChild(doc.CreateElement("numeric"));
throw new InvalidOperationException( numericMjcf.SetAttribute("name", numeric.Name);
"At most one MjGlobalSettings should be present."); // TODO: add validation that data is a space-separated list of floating numbers?
} numericMjcf.SetAttribute("data", numeric.Data);
} }
}
public void ParseGlobalMjcfSections(XmlElement mujocoNode) }
{
var optionNode = mujocoNode.SelectSingleNode("option") as XmlElement;
var sizeNode = mujocoNode.SelectSingleNode("size") as XmlElement;
var customNode = mujocoNode.SelectSingleNode("custom") as XmlElement;
if (optionNode != null)
{
GlobalOptions.ParseMjcf(optionNode);
}
if (sizeNode != null)
{
GlobalSizes.ParseMjcf(sizeNode);
}
if (customNode != null)
{
foreach (var childNode in customNode.ChildNodes)
{
var child = childNode as XmlElement;
if (child.Name == "numeric")
{
var numeric = new NumericEntry();
numeric.Name = child.GetAttribute("name");
numeric.Data = child.GetAttribute("data");
CustomNumeric.Add(numeric);
}
}
}
}
public void GlobalsToMjcf(XmlElement mjcf)
{
var doc = mjcf.OwnerDocument;
var optionMjcf = (XmlElement)mjcf.AppendChild(doc.CreateElement("option"));
GlobalOptions.ToMjcf(optionMjcf);
var sizeMjcf = (XmlElement)mjcf.AppendChild(doc.CreateElement("size"));
GlobalSizes.ToMjcf(sizeMjcf);
var customMjcf = (XmlElement)mjcf.AppendChild(doc.CreateElement("custom"));
foreach (var numeric in CustomNumeric)
{
var numericMjcf = (XmlElement)customMjcf.AppendChild(doc.CreateElement("numeric"));
numericMjcf.SetAttribute("name", numeric.Name);
// TODO: add validation that data is a space-separated list of floating numbers?
numericMjcf.SetAttribute("data", numeric.Data);
}
}
}
} }