USD : Adopt newton-usd-schemas & deprecate MjcPhysics equivalents

This commit is contained in:
Andrew Kaufman
2026-03-04 12:27:04 -08:00
parent facebe5aa1
commit 792f53c823
5 changed files with 457 additions and 105 deletions
@@ -4,6 +4,7 @@
)
class "MjcSceneAPI" (
apiSchemas = ["NewtonSceneAPI"]
doc = "API providing global simulation options for MuJoCo."
)
{
@@ -120,7 +121,9 @@ class "MjcSceneAPI" (
)
uniform bool mjc:flag:gravity = 1 (
displayName = "Gravity Toggle"
doc = "Enables the application of gravitational acceleration as defined in mjOption."
doc = """DEPRECATED: Use newton:gravityEnabled instead.
Enables the application of gravitational acceleration as defined in mjOption."""
)
uniform bool mjc:flag:invdiscrete = 0 (
displayName = "Discrete-Time Inverse Dynamics Toggle"
@@ -200,7 +203,9 @@ class "MjcSceneAPI" (
)
uniform int mjc:option:iterations = 100 (
displayName = "Solver Iterations"
doc = "Maximum number of iterations of the constraint solver."
doc = """DEPRECATED: Use newton:maxSolverIterations instead.
Maximum number of iterations of the constraint solver."""
)
uniform token mjc:option:jacobian = "auto" (
allowedTokens = ["auto", "dense", "sparse"]
@@ -265,7 +270,9 @@ class "MjcSceneAPI" (
)
uniform double mjc:option:timestep = 0.002 (
displayName = "Timestep"
doc = "Controls the timestep in seconds used by MuJoCo."
doc = """DEPRECATED: Use newton:timeStepsPerSecond instead.
Controls the timestep in seconds used by MuJoCo."""
)
uniform double mjc:option:tolerance = 1e-8 (
displayName = "Solver Tolerance"
@@ -303,6 +310,7 @@ class "MjcImageableAPI" (
}
class "MjcCollisionAPI" (
apiSchemas = ["NewtonCollisionAPI"]
doc = "API describing a MuJoCo collider."
)
{
@@ -312,7 +320,9 @@ class "MjcCollisionAPI" (
)
uniform double mjc:gap = 0 (
displayName = "Gap"
doc = "This attribute is used to enable the generation of inactive contacts, i.e., contacts that are ignored by the constraint solver but are included in mjData.contact for the purpose of custom computations. When this value is positive, geom distances between margin and margin-gap correspond to such inactive contacts."
doc = """DEPRECATED: Use newton:contactGap instead.
This attribute is used to enable the generation of inactive contacts, i.e., contacts that are ignored by the constraint solver but are included in mjData.contact for the purpose of custom computations. When this value is positive, geom distances between margin and margin-gap correspond to such inactive contacts."""
)
uniform int mjc:group = 0 (
displayName = "Group"
@@ -320,7 +330,9 @@ class "MjcCollisionAPI" (
)
uniform double mjc:margin = 0 (
displayName = "Margin"
doc = "Distance threshold below which contacts are detected and included in the global array mjData.contact."
doc = """DEPRECATED: Use newton:contactMargin and newton:contactGap instead.
Distance threshold below which contacts are detected and included in the global array mjData.contact."""
)
uniform int mjc:priority = 0 (
displayName = "Priority"
@@ -345,6 +357,7 @@ class "MjcCollisionAPI" (
}
class "MjcMeshCollisionAPI" (
apiSchemas = ["NewtonMeshCollisionAPI"]
doc = "API describing a MuJoCo mesh collider."
)
{
@@ -355,7 +368,9 @@ class "MjcMeshCollisionAPI" (
)
uniform int mjc:maxhullvert = -1 (
displayName = "Maximum Hull Vertices"
doc = "Sets an upper limit on the number of vertices in the meshes convex hull. The default value of -1 means unlimited."
doc = """DEPRECATED: Use newton:maxHullVertices instead.
Sets an upper limit on the number of vertices in the meshes convex hull. The default value of -1 means unlimited."""
)
}
@@ -537,16 +552,23 @@ class "MjcJointAPI" (
}
class "MjcMaterialAPI" (
doc = "API providing extension attributes to represent physical MuJoCo materials."
apiSchemas = ["NewtonMaterialAPI"]
doc = """DEPRECATED: Use NewtonMaterialAPI instead. All attributes on this API have been superseded by Newton equivalents.
API providing extension attributes to represent physical MuJoCo materials."""
)
{
uniform double mjc:rollingfriction = 0.0001 (
displayName = "Rolling Friction"
doc = "Friction value acting around both axes on the contact tangent plane."
doc = """DEPRECATED: Use newton:rollingFriction instead.
Friction value acting around both axes on the contact tangent plane."""
)
uniform double mjc:torsionalfriction = 0.005 (
displayName = "Torsional Friction"
doc = "Friction value acting around contact normal."
doc = """DEPRECATED: Use newton:torsionalFriction instead.
Friction value acting around contact normal."""
)
}
@@ -586,23 +608,36 @@ class "MjcEqualityWeldAPI" (
}
class "MjcEqualityJointAPI" (
apiSchemas = ["MjcEqualityAPI"]
apiSchemas = ["NewtonMimicAPI"]
doc = """API providing extension attributes to represent equality/joint constraints.
This API is applied to a joint prim which acts as the constrained joint (joint1 in
MuJoCo terminology). The target relationship points to another joint prim which is
the reference joint (joint2 in MuJoCo terminology). The constrained joint's position
or angle is constrained to be a quartic polynomial of the reference joint's position
or angle. Only scalar joint types (slide and hinge) can be used."""
This API is applied to a joint prim which acts as the follower (joint0). The leader
joint (joint1) is specified via the newton:mimicJoint relationship inherited from
NewtonMimicAPI.
The follower's position or angle is constrained to be a quartic polynomial of the
leader's position or angle:
joint0 = coef0 + coef1*(joint1) + coef2*(joint1)^2 + coef3*(joint1)^3 + coef4*(joint1)^4
The constant (coef0) and linear (coef1) coefficients are provided by NewtonMimicAPI
as newton:mimicCoef0 and newton:mimicCoef1. The higher-order coefficients (coef2-coef4)
are provided by this API.
Only scalar joint types (slide and hinge) can be used."""
)
{
uniform double mjc:coef0 = 0 (
displayName = "Coefficient 0"
doc = """Constant coefficient a0 of the quartic polynomial. The constraint is:
doc = """DEPRECATED: Use newton:mimicCoef0 instead.
Constant coefficient a0 of the quartic polynomial. The constraint is:
y = y0 + a0 + a1*(x-x0) + a2*(x-x0)^2 + a3*(x-x0)^3 + a4*(x-x0)^4."""
)
uniform double mjc:coef1 = 1 (
displayName = "Coefficient 1"
doc = "Linear coefficient a1 of the quartic polynomial."
doc = """DEPRECATED: Use newton:mimicCoef1 instead.
Linear coefficient a1 of the quartic polynomial."""
)
uniform double mjc:coef2 = 0 (
displayName = "Coefficient 2"
@@ -616,6 +651,19 @@ class "MjcEqualityJointAPI" (
displayName = "Coefficient 4"
doc = "Quartic coefficient a4 of the quartic polynomial."
)
uniform double[] mjc:solimp = [0.9, 0.95, 0.001, 0.5, 2] (
displayName = "SolImp"
doc = "Constraint solver parameter for equality constraint simulation."
)
uniform double[] mjc:solref = [0.02, 1] (
displayName = "SolRef"
doc = "Constraint solver parameter for equality constraint simulation."
)
rel mjc:target (
doc = """DEPRECATED: Use newton:mimicJoint instead.
Secondary target of the equality constraint (the leader/reference joint)."""
)
}
class MjcTendon "MjcTendon" (
+77 -17
View File
@@ -100,6 +100,7 @@ class "MjcSceneAPI"
}
doc = """API providing global simulation options for MuJoCo."""
prepend apiSchemas = ["NewtonSceneAPI"]
inherits = </APISchemaBase>
)
{
@@ -108,7 +109,9 @@ class "MjcSceneAPI"
string apiName = "Timestep"
}
displayName = "Timestep"
doc = """Controls the timestep in seconds used by MuJoCo."""
doc = """DEPRECATED: Use newton:timeStepsPerSecond instead.
Controls the timestep in seconds used by MuJoCo."""
)
uniform double mjc:option:impratio = 1.0 (
@@ -229,7 +232,9 @@ class "MjcSceneAPI"
string apiName = "Iterations"
}
displayName = "Solver Iterations"
doc = """Maximum number of iterations of the constraint solver."""
doc = """DEPRECATED: Use newton:maxSolverIterations instead.
Maximum number of iterations of the constraint solver."""
)
uniform double mjc:option:tolerance = 1e-08 (
@@ -378,7 +383,9 @@ class "MjcSceneAPI"
string apiName = "GravityFlag"
}
displayName = "Gravity Toggle"
doc = """Enables the application of gravitational acceleration as defined in mjOption."""
doc = """DEPRECATED: Use newton:gravityEnabled instead.
Enables the application of gravitational acceleration as defined in mjOption."""
)
uniform bool mjc:flag:clampctrl = True (
@@ -674,6 +681,7 @@ class "MjcCollisionAPI"
}
doc = """API describing a MuJoCo collider."""
prepend apiSchemas = ["NewtonCollisionAPI"]
inherits = </APISchemaBase>
)
{
@@ -738,7 +746,9 @@ class "MjcCollisionAPI"
string apiName = "Margin"
}
displayName = "Margin"
doc = """Distance threshold below which contacts are detected and included in the global array mjData.contact."""
doc = """DEPRECATED: Use newton:contactMargin and newton:contactGap instead.
Distance threshold below which contacts are detected and included in the global array mjData.contact."""
)
uniform double mjc:gap = 0.0 (
@@ -746,7 +756,9 @@ class "MjcCollisionAPI"
string apiName = "Gap"
}
displayName = "Gap"
doc = """This attribute is used to enable the generation of inactive contacts, i.e., contacts that are ignored by the constraint solver but are included in mjData.contact for the purpose of custom computations. When this value is positive, geom distances between margin and margin-gap correspond to such inactive contacts."""
doc = """DEPRECATED: Use newton:contactGap instead.
This attribute is used to enable the generation of inactive contacts, i.e., contacts that are ignored by the constraint solver but are included in mjData.contact for the purpose of custom computations. When this value is positive, geom distances between margin and margin-gap correspond to such inactive contacts."""
)
}
@@ -757,6 +769,7 @@ class "MjcMeshCollisionAPI"
}
doc = """API describing a MuJoCo mesh collider."""
prepend apiSchemas = ["NewtonMeshCollisionAPI"]
inherits = </APISchemaBase>
)
{
@@ -774,7 +787,9 @@ class "MjcMeshCollisionAPI"
string apiName = "MaxHullVert"
}
displayName = "Maximum Hull Vertices"
doc = """Sets an upper limit on the number of vertices in the meshes convex hull. The default value of -1 means unlimited."""
doc = """DEPRECATED: Use newton:maxHullVertices instead.
Sets an upper limit on the number of vertices in the meshes convex hull. The default value of -1 means unlimited."""
)
}
@@ -1035,8 +1050,11 @@ class "MjcMaterialAPI"
customData = {
string className = "MaterialAPI"
}
doc = """API providing extension attributes to represent physical MuJoCo materials."""
doc = """DEPRECATED: Use NewtonMaterialAPI instead. All attributes on this API have been superseded by Newton equivalents.
API providing extension attributes to represent physical MuJoCo materials."""
prepend apiSchemas = ["NewtonMaterialAPI"]
inherits = </APISchemaBase>
)
{
@@ -1045,7 +1063,9 @@ class "MjcMaterialAPI"
string apiName = "TorsionalFriction"
}
displayName = "Torsional Friction"
doc = """Friction value acting around contact normal."""
doc = """DEPRECATED: Use newton:torsionalFriction instead.
Friction value acting around contact normal."""
)
uniform double mjc:rollingfriction = 0.0001 (
@@ -1053,7 +1073,9 @@ class "MjcMaterialAPI"
string apiName = "RollingFriction"
}
displayName = "Rolling Friction"
doc = """Friction value acting around both axes on the contact tangent plane."""
doc = """DEPRECATED: Use newton:rollingFriction instead.
Friction value acting around both axes on the contact tangent plane."""
)
}
@@ -1121,22 +1143,58 @@ class "MjcEqualityJointAPI" (
string className = "EqualityJointAPI"
}
doc = """API providing extension attributes to represent equality/joint constraints.
This API is applied to a joint prim which acts as the constrained joint (joint1 in
MuJoCo terminology). The target relationship points to another joint prim which is
the reference joint (joint2 in MuJoCo terminology). The constrained joint's position
or angle is constrained to be a quartic polynomial of the reference joint's position
or angle. Only scalar joint types (slide and hinge) can be used."""
prepend apiSchemas = ["MjcEqualityAPI"]
This API is applied to a joint prim which acts as the follower (joint0). The leader
joint (joint1) is specified via the newton:mimicJoint relationship inherited from
NewtonMimicAPI.
The follower's position or angle is constrained to be a quartic polynomial of the
leader's position or angle:
joint0 = coef0 + coef1*(joint1) + coef2*(joint1)^2 + coef3*(joint1)^3 + coef4*(joint1)^4
The constant (coef0) and linear (coef1) coefficients are provided by NewtonMimicAPI
as newton:mimicCoef0 and newton:mimicCoef1. The higher-order coefficients (coef2-coef4)
are provided by this API.
Only scalar joint types (slide and hinge) can be used."""
prepend apiSchemas = ["NewtonMimicAPI"]
inherits = </APISchemaBase>
)
{
uniform double[] mjc:solimp = [0.9, 0.95, 0.001, 0.5, 2] (
customData = {
string apiName = "SolImp"
}
displayName = "SolImp"
doc = """Constraint solver parameter for equality constraint simulation."""
)
uniform double[] mjc:solref = [0.02, 1] (
customData = {
string apiName = "SolRef"
}
displayName = "SolRef"
doc = """Constraint solver parameter for equality constraint simulation."""
)
rel mjc:target (
customData = {
string apiName = "MjcTarget"
}
doc = """DEPRECATED: Use newton:mimicJoint instead.
Secondary target of the equality constraint (the leader/reference joint)."""
)
uniform double mjc:coef0 = 0 (
customData = {
string apiName = "Coef0"
}
displayName = "Coefficient 0"
doc = """Constant coefficient a0 of the quartic polynomial. The constraint is:
doc = """DEPRECATED: Use newton:mimicCoef0 instead.
Constant coefficient a0 of the quartic polynomial. The constraint is:
y = y0 + a0 + a1*(x-x0) + a2*(x-x0)^2 + a3*(x-x0)^3 + a4*(x-x0)^4."""
)
@@ -1145,7 +1203,9 @@ class "MjcEqualityJointAPI" (
string apiName = "Coef1"
}
displayName = "Coefficient 1"
doc = """Linear coefficient a1 of the quartic polynomial."""
doc = """DEPRECATED: Use newton:mimicCoef1 instead.
Linear coefficient a1 of the quartic polynomial."""
)
uniform double mjc:coef2 = 0 (
@@ -15,6 +15,7 @@
#include "mjcf/mujoco_to_usd.h"
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <numbers>
#include <string>
@@ -119,6 +120,16 @@ TF_DEFINE_PRIVATE_TOKENS(kTokens,
(UsdPrimvarReader_float2)
(UsdUVTexture)
(UsdPreviewSurface)
((NewtonMaterialAPI, "NewtonMaterialAPI"))
((NewtonMeshCollisionAPI, "NewtonMeshCollisionAPI"))
((newtonTorsionalFriction, "newton:torsionalFriction"))
((newtonRollingFriction, "newton:rollingFriction"))
((newtonMaxHullVertices, "newton:maxHullVertices"))
((newtonMaxSolverIterations, "newton:maxSolverIterations"))
((newtonTimeStepsPerSecond, "newton:timeStepsPerSecond"))
((newtonGravityEnabled, "newton:gravityEnabled"))
((newtonContactMargin, "newton:contactMargin"))
((newtonContactGap, "newton:contactGap"))
);
// Using to satisfy TF_REGISTRY_FUNCTION macro below and avoid operating in PXR_NS.
@@ -393,8 +404,11 @@ class ModelWriter {
WriteUniformAttribute(mesh_spec, pxr::SdfValueTypeNames->Token,
MjcPhysicsTokens->mjcInertia, inertia);
WriteUniformAttribute(mesh_spec, pxr::SdfValueTypeNames->Int,
MjcPhysicsTokens->mjcMaxhullvert, mesh->maxhullvert);
// Newton mesh attribute (replaces deprecated mjc:maxhullvert)
if (mesh->maxhullvert != -1) {
WriteUniformAttribute(mesh_spec, pxr::SdfValueTypeNames->Int,
kTokens->newtonMaxHullVertices, mesh->maxhullvert);
}
// NOTE: The geometry data taken from the spec is the post-compilation
// data after it has been mjCMesh::Compile'd. So don't be surprised if
@@ -500,7 +514,7 @@ class ModelWriter {
const std::vector<std::pair<pxr::TfToken, double>>
option_double_attributes = {
{MjcPhysicsTokens->mjcOptionTimestep, spec_->option.timestep},
// mjc:option:timestep deprecated in favor of newton:timeStepsPerSecond
{MjcPhysicsTokens->mjcOptionTolerance, spec_->option.tolerance},
{MjcPhysicsTokens->mjcOptionLs_tolerance,
spec_->option.ls_tolerance},
@@ -519,7 +533,7 @@ class ModelWriter {
}
const std::vector<std::pair<pxr::TfToken, int>> option_int_attributes = {
{MjcPhysicsTokens->mjcOptionIterations, spec_->option.iterations},
// mjc:option:iterations deprecated in favor of newton:maxSolverIterations
{MjcPhysicsTokens->mjcOptionLs_iterations, spec_->option.ls_iterations},
{MjcPhysicsTokens->mjcOptionNoslip_iterations,
spec_->option.noslip_iterations},
@@ -666,7 +680,7 @@ class ModelWriter {
{MjcPhysicsTokens->mjcFlagContact, mjDSBL_CONTACT},
{MjcPhysicsTokens->mjcFlagSpring, mjDSBL_SPRING},
{MjcPhysicsTokens->mjcFlagDamper, mjDSBL_DAMPER},
{MjcPhysicsTokens->mjcFlagGravity, mjDSBL_GRAVITY},
// mjc:flag:gravity deprecated in favor of newton:gravityEnabled
{MjcPhysicsTokens->mjcFlagClampctrl, mjDSBL_CLAMPCTRL},
{MjcPhysicsTokens->mjcFlagWarmstart, mjDSBL_WARMSTART},
{MjcPhysicsTokens->mjcFlagFilterparent, mjDSBL_FILTERPARENT},
@@ -747,6 +761,19 @@ class ModelWriter {
WriteUniformAttribute(physics_scene_spec, pxr::SdfValueTypeNames->Bool,
MjcPhysicsTokens->mjcCompilerSaveInertial,
(bool)spec_->compiler.saveinertial);
// Newton scene attributes (auto-applied via MjcSceneAPI -> NewtonSceneAPI)
WriteUniformAttribute(physics_scene_spec, pxr::SdfValueTypeNames->Int,
kTokens->newtonMaxSolverIterations,
spec_->option.iterations);
if (spec_->option.timestep > 0) {
WriteUniformAttribute(physics_scene_spec, pxr::SdfValueTypeNames->Int,
kTokens->newtonTimeStepsPerSecond,
static_cast<int>(std::round(1.0 / spec_->option.timestep)));
}
bool gravity_disabled = spec_->option.disableflags & mjDSBL_GRAVITY;
WriteUniformAttribute(physics_scene_spec, pxr::SdfValueTypeNames->Bool,
kTokens->newtonGravityEnabled, !gravity_disabled);
}
void WriteMeshes() {
@@ -868,16 +895,13 @@ class ModelWriter {
pxr::UsdPhysicsTokens->physicsDynamicFriction,
(float)geom->friction[0]);
}
if (geom->friction[1] != geom_default->friction[1]) {
WriteUniformAttribute(material_spec, pxr::SdfValueTypeNames->Double,
MjcPhysicsTokens->mjcTorsionalfriction,
geom->friction[1]);
}
if (geom->friction[2] != geom_default->friction[2]) {
WriteUniformAttribute(material_spec, pxr::SdfValueTypeNames->Double,
MjcPhysicsTokens->mjcRollingfriction,
geom->friction[2]);
}
// Newton material attributes (replaces deprecated mjc:torsionalfriction / mjc:rollingfriction)
WriteUniformAttribute(material_spec, pxr::SdfValueTypeNames->Float,
kTokens->newtonTorsionalFriction,
(float)geom->friction[1]);
WriteUniformAttribute(material_spec, pxr::SdfValueTypeNames->Float,
kTokens->newtonRollingFriction,
(float)geom->friction[2]);
return material_spec;
}
@@ -1706,11 +1730,13 @@ class ModelWriter {
MjcPhysicsTokens->mjcSolimp,
pxr::VtArray<double>(geom->solimp, geom->solimp + mjNIMP));
WriteUniformAttribute(geom_spec, pxr::SdfValueTypeNames->Double,
MjcPhysicsTokens->mjcMargin, geom->margin);
WriteUniformAttribute(geom_spec, pxr::SdfValueTypeNames->Double,
MjcPhysicsTokens->mjcGap, geom->gap);
// Newton collision attributes (replaces deprecated mjc:margin / mjc:gap)
WriteUniformAttribute(geom_spec, pxr::SdfValueTypeNames->Float,
kTokens->newtonContactMargin,
static_cast<float>(geom->margin - geom->gap));
WriteUniformAttribute(geom_spec, pxr::SdfValueTypeNames->Float,
kTokens->newtonContactGap,
static_cast<float>(geom->gap));
if (geom->mass >= mjMINVAL || geom->density >= mjMINVAL) {
ApplyApiSchema(layer_, geom_spec, pxr::UsdPhysicsTokens->PhysicsMassAPI);