Add missing attributes to MjcCollisionAPI USD schema.

PiperOrigin-RevId: 783006362
Change-Id: I02d51190d62bb9460863025cd16360427afc70c4
This commit is contained in:
Sam Haves
2025-07-14 12:44:54 -07:00
committed by Copybara-Service
parent ef013a0633
commit e441868dad
9 changed files with 502 additions and 18 deletions
@@ -191,6 +191,185 @@ class MjcPhysicsCollisionAPI : public UsdAPISchemaBase {
UsdAttribute CreateShellInertiaAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// --------------------------------------------------------------------- //
// PRIORITY
// --------------------------------------------------------------------- //
/// Priority determining how the properties of two colliders are combined to
/// form the properties of the contact.
///
/// | ||
/// | -- | -- |
/// | Declaration | `uniform int mjc:priority = 0` |
/// | C++ Type | int |
/// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Int |
/// | \ref SdfVariability "Variability" | SdfVariabilityUniform |
MJCPHYSICS_API
UsdAttribute GetPriorityAttr() const;
/// See GetPriorityAttr(), and also
/// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
/// If specified, author \p defaultValue as the attribute's default,
/// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
/// the default for \p writeSparsely is \c false.
MJCPHYSICS_API
UsdAttribute CreatePriorityAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// --------------------------------------------------------------------- //
// CONDIM
// --------------------------------------------------------------------- //
/// The dimensionality of the contact space for a dynamically generated
/// contact pair is set to the maximum of the condim values of the two
/// participating geoms.
///
/// | ||
/// | -- | -- |
/// | Declaration | `uniform int mjc:condim = 3` |
/// | C++ Type | int |
/// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Int |
/// | \ref SdfVariability "Variability" | SdfVariabilityUniform |
MJCPHYSICS_API
UsdAttribute GetConDimAttr() const;
/// See GetConDimAttr(), and also
/// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
/// If specified, author \p defaultValue as the attribute's default,
/// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
/// the default for \p writeSparsely is \c false.
MJCPHYSICS_API
UsdAttribute CreateConDimAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// --------------------------------------------------------------------- //
// SOLMIX
// --------------------------------------------------------------------- //
/// Specifies the weight used for averaging of contact parameters, and
/// interacts with the priority attribute.
///
/// | ||
/// | -- | -- |
/// | Declaration | `uniform double mjc:solmix = 1` |
/// | C++ Type | double |
/// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Double |
/// | \ref SdfVariability "Variability" | SdfVariabilityUniform |
MJCPHYSICS_API
UsdAttribute GetSolMixAttr() const;
/// See GetSolMixAttr(), and also
/// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
/// If specified, author \p defaultValue as the attribute's default,
/// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
/// the default for \p writeSparsely is \c false.
MJCPHYSICS_API
UsdAttribute CreateSolMixAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// --------------------------------------------------------------------- //
// SOLREF
// --------------------------------------------------------------------- //
/// Specifies the weight used for averaging of contact parameters, and
/// interacts with the priority attribute.
///
/// | ||
/// | -- | -- |
/// | Declaration | `uniform double[] mjc:solref = [0.02, 1]` |
/// | C++ Type | VtArray<double> |
/// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->DoubleArray |
/// | \ref SdfVariability "Variability" | SdfVariabilityUniform |
MJCPHYSICS_API
UsdAttribute GetSolRefAttr() const;
/// See GetSolRefAttr(), and also
/// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
/// If specified, author \p defaultValue as the attribute's default,
/// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
/// the default for \p writeSparsely is \c false.
MJCPHYSICS_API
UsdAttribute CreateSolRefAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// --------------------------------------------------------------------- //
// SOLIMP
// --------------------------------------------------------------------- //
/// Specifies the weight used for averaging of contact parameters, and
/// interacts with the priority attribute.
///
/// | ||
/// | -- | -- |
/// | Declaration | `uniform double[] mjc:solimp = [0.9, 0.95, 0.001, 0.5, 2]`
/// | | C++ Type | VtArray<double> | | \ref Usd_Datatypes "Usd Type" |
/// SdfValueTypeNames->DoubleArray | | \ref SdfVariability "Variability" |
/// SdfVariabilityUniform |
MJCPHYSICS_API
UsdAttribute GetSolImpAttr() const;
/// See GetSolImpAttr(), and also
/// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
/// If specified, author \p defaultValue as the attribute's default,
/// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
/// the default for \p writeSparsely is \c false.
MJCPHYSICS_API
UsdAttribute CreateSolImpAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// --------------------------------------------------------------------- //
// MARGIN
// --------------------------------------------------------------------- //
/// Distance threshold below which contacts are detected and included in the
/// global array mjData.contact.
///
/// | ||
/// | -- | -- |
/// | Declaration | `uniform double mjc:margin = 0` |
/// | C++ Type | double |
/// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Double |
/// | \ref SdfVariability "Variability" | SdfVariabilityUniform |
MJCPHYSICS_API
UsdAttribute GetMarginAttr() const;
/// See GetMarginAttr(), and also
/// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
/// If specified, author \p defaultValue as the attribute's default,
/// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
/// the default for \p writeSparsely is \c false.
MJCPHYSICS_API
UsdAttribute CreateMarginAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// --------------------------------------------------------------------- //
// GAP
// --------------------------------------------------------------------- //
/// 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.
///
/// | ||
/// | -- | -- |
/// | Declaration | `uniform double mjc:gap = 0` |
/// | C++ Type | double |
/// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Double |
/// | \ref SdfVariability "Variability" | SdfVariabilityUniform |
MJCPHYSICS_API
UsdAttribute GetGapAttr() const;
/// See GetGapAttr(), and also
/// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
/// If specified, author \p defaultValue as the attribute's default,
/// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
/// the default for \p writeSparsely is \c false.
MJCPHYSICS_API
UsdAttribute CreateGapAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// ===================================================================== //
// Feel free to add custom code below this line, it will be preserved by
@@ -184,6 +184,10 @@ struct MjcPhysicsTokensType {
///
/// MjcPhysicsActuator
const TfToken mjcBiasType;
/// \brief "mjc:condim"
///
/// MjcPhysicsCollisionAPI
const TfToken mjcCondim;
/// \brief "mjc:crankLength"
///
/// MjcPhysicsActuator
@@ -332,6 +336,10 @@ struct MjcPhysicsTokensType {
///
/// MjcPhysicsActuator
const TfToken mjcGainType;
/// \brief "mjc:gap"
///
/// MjcPhysicsCollisionAPI
const TfToken mjcGap;
/// \brief "mjc:gear"
///
/// MjcPhysicsActuator
@@ -359,7 +367,7 @@ struct MjcPhysicsTokensType {
const TfToken mjcLengthRangeMin;
/// \brief "mjc:margin"
///
/// MjcPhysicsJointAPI
/// MjcPhysicsCollisionAPI, MjcPhysicsJointAPI
const TfToken mjcMargin;
/// \brief "mjc:maxhullvert"
///
@@ -477,6 +485,10 @@ struct MjcPhysicsTokensType {
///
/// MjcPhysicsSceneAPI
const TfToken mjcOptionWind;
/// \brief "mjc:priority"
///
/// MjcPhysicsCollisionAPI
const TfToken mjcPriority;
/// \brief "mjc:qpos"
///
/// MjcPhysicsKeyframe
@@ -505,6 +517,10 @@ struct MjcPhysicsTokensType {
///
/// MjcPhysicsActuator
const TfToken mjcSliderSite;
/// \brief "mjc:solimp"
///
/// MjcPhysicsCollisionAPI
const TfToken mjcSolimp;
/// \brief "mjc:solimpfriction"
///
/// MjcPhysicsJointAPI
@@ -513,6 +529,14 @@ struct MjcPhysicsTokensType {
///
/// MjcPhysicsJointAPI
const TfToken mjcSolimplimit;
/// \brief "mjc:solmix"
///
/// MjcPhysicsCollisionAPI
const TfToken mjcSolmix;
/// \brief "mjc:solref"
///
/// MjcPhysicsCollisionAPI
const TfToken mjcSolref;
/// \brief "mjc:solreffriction"
///
/// MjcPhysicsJointAPI
@@ -97,6 +97,83 @@ UsdAttribute MjcPhysicsCollisionAPI::CreateShellInertiaAttr(
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
UsdAttribute MjcPhysicsCollisionAPI::GetPriorityAttr() const {
return GetPrim().GetAttribute(MjcPhysicsTokens->mjcPriority);
}
UsdAttribute MjcPhysicsCollisionAPI::CreatePriorityAttr(
VtValue const &defaultValue, bool writeSparsely) const {
return UsdSchemaBase::_CreateAttr(
MjcPhysicsTokens->mjcPriority, SdfValueTypeNames->Int,
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
UsdAttribute MjcPhysicsCollisionAPI::GetConDimAttr() const {
return GetPrim().GetAttribute(MjcPhysicsTokens->mjcCondim);
}
UsdAttribute MjcPhysicsCollisionAPI::CreateConDimAttr(
VtValue const &defaultValue, bool writeSparsely) const {
return UsdSchemaBase::_CreateAttr(
MjcPhysicsTokens->mjcCondim, SdfValueTypeNames->Int,
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
UsdAttribute MjcPhysicsCollisionAPI::GetSolMixAttr() const {
return GetPrim().GetAttribute(MjcPhysicsTokens->mjcSolmix);
}
UsdAttribute MjcPhysicsCollisionAPI::CreateSolMixAttr(
VtValue const &defaultValue, bool writeSparsely) const {
return UsdSchemaBase::_CreateAttr(
MjcPhysicsTokens->mjcSolmix, SdfValueTypeNames->Double,
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
UsdAttribute MjcPhysicsCollisionAPI::GetSolRefAttr() const {
return GetPrim().GetAttribute(MjcPhysicsTokens->mjcSolref);
}
UsdAttribute MjcPhysicsCollisionAPI::CreateSolRefAttr(
VtValue const &defaultValue, bool writeSparsely) const {
return UsdSchemaBase::_CreateAttr(
MjcPhysicsTokens->mjcSolref, SdfValueTypeNames->DoubleArray,
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
UsdAttribute MjcPhysicsCollisionAPI::GetSolImpAttr() const {
return GetPrim().GetAttribute(MjcPhysicsTokens->mjcSolimp);
}
UsdAttribute MjcPhysicsCollisionAPI::CreateSolImpAttr(
VtValue const &defaultValue, bool writeSparsely) const {
return UsdSchemaBase::_CreateAttr(
MjcPhysicsTokens->mjcSolimp, SdfValueTypeNames->DoubleArray,
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
UsdAttribute MjcPhysicsCollisionAPI::GetMarginAttr() const {
return GetPrim().GetAttribute(MjcPhysicsTokens->mjcMargin);
}
UsdAttribute MjcPhysicsCollisionAPI::CreateMarginAttr(
VtValue const &defaultValue, bool writeSparsely) const {
return UsdSchemaBase::_CreateAttr(
MjcPhysicsTokens->mjcMargin, SdfValueTypeNames->Double,
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
UsdAttribute MjcPhysicsCollisionAPI::GetGapAttr() const {
return GetPrim().GetAttribute(MjcPhysicsTokens->mjcGap);
}
UsdAttribute MjcPhysicsCollisionAPI::CreateGapAttr(VtValue const &defaultValue,
bool writeSparsely) const {
return UsdSchemaBase::_CreateAttr(
MjcPhysicsTokens->mjcGap, SdfValueTypeNames->Double,
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
namespace {
static inline TfTokenVector _ConcatenateAttributeNames(
const TfTokenVector &left, const TfTokenVector &right) {
@@ -112,8 +189,11 @@ static inline TfTokenVector _ConcatenateAttributeNames(
const TfTokenVector &MjcPhysicsCollisionAPI::GetSchemaAttributeNames(
bool includeInherited) {
static TfTokenVector localNames = {
MjcPhysicsTokens->mjcGroup,
MjcPhysicsTokens->mjcShellinertia,
MjcPhysicsTokens->mjcGroup, MjcPhysicsTokens->mjcShellinertia,
MjcPhysicsTokens->mjcPriority, MjcPhysicsTokens->mjcCondim,
MjcPhysicsTokens->mjcSolmix, MjcPhysicsTokens->mjcSolref,
MjcPhysicsTokens->mjcSolimp, MjcPhysicsTokens->mjcMargin,
MjcPhysicsTokens->mjcGap,
};
static TfTokenVector allNames = _ConcatenateAttributeNames(
UsdAPISchemaBase::GetSchemaAttributeNames(true), localNames);
@@ -234,14 +234,42 @@ class "MjcCollisionAPI" (
doc = "API describing a MuJoCo collider."
)
{
uniform int mjc:condim = 3 (
displayName = "ConDim"
doc = "The dimensionality of the contact space for a dynamically generated contact pair is set to the maximum of the condim values of the two participating geoms."
)
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."
)
uniform int mjc:group = 0 (
displayName = "Group"
doc = "Integer MuJoCo group to which the collider belongs."
)
uniform double mjc:margin = 0 (
displayName = "Margin"
doc = "Distance threshold below which contacts are detected and included in the global array mjData.contact."
)
uniform int mjc:priority = 0 (
displayName = "Priority"
doc = "Priority determining how the properties of two colliders are combined to form the properties of the contact."
)
uniform bool mjc:shellinertia = 0 (
displayName = "Shell Inertia"
doc = "Enables handling of the inertia assuming mass is concentrated on the surface."
)
uniform double[] mjc:solimp = [0.9, 0.95, 0.001, 0.5, 2] (
displayName = "SolImp"
doc = "Specifies the weight used for averaging of contact parameters, and interacts with the priority attribute."
)
uniform double mjc:solmix = 1 (
displayName = "SolMix"
doc = "Specifies the weight used for averaging of contact parameters, and interacts with the priority attribute."
)
uniform double[] mjc:solref = [0.02, 1] (
displayName = "SolMix"
doc = "Specifies the weight used for averaging of contact parameters, and interacts with the priority attribute."
)
}
class "MjcMeshCollisionAPI" (
@@ -547,6 +547,7 @@ class "MjcCollisionAPI"
displayName = "Group"
doc = """Integer MuJoCo group to which the collider belongs."""
)
uniform bool mjc:shellinertia = False (
customData = {
string apiName = "ShellInertia"
@@ -554,6 +555,62 @@ class "MjcCollisionAPI"
displayName = "Shell Inertia"
doc = """Enables handling of the inertia assuming mass is concentrated on the surface."""
)
uniform int mjc:priority = 0 (
customData = {
string apiName = "Priority"
}
displayName = "Priority"
doc = """Priority determining how the properties of two colliders are combined to form the properties of the contact."""
)
uniform int mjc:condim = 3 (
customData = {
string apiName = "ConDim"
}
displayName = "ConDim"
doc = """The dimensionality of the contact space for a dynamically generated contact pair is set to the maximum of the condim values of the two participating geoms."""
)
uniform double mjc:solmix = 1.0 (
customData = {
string apiName = "SolMix"
}
displayName = "SolMix"
doc = """Specifies the weight used for averaging of contact parameters, and interacts with the priority attribute."""
)
uniform double[] mjc:solref = [0.02, 1.0] (
customData = {
string apiName = "SolRef"
}
displayName = "SolMix"
doc = """Specifies the weight used for averaging of contact parameters, and interacts with the priority attribute."""
)
uniform double[] mjc:solimp = [0.9, 0.95, 0.001, 0.5, 2.0] (
customData = {
string apiName = "SolImp"
}
displayName = "SolImp"
doc = """Specifies the weight used for averaging of contact parameters, and interacts with the priority attribute."""
)
uniform double mjc:margin = 0.0 (
customData = {
string apiName = "Margin"
}
displayName = "Margin"
doc = """Distance threshold below which contacts are detected and included in the global array mjData.contact."""
)
uniform double mjc:gap = 0.0 (
customData = {
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."""
)
}
class "MjcMeshCollisionAPI"
@@ -46,6 +46,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcArmature("mjc:armature", TfToken::Immortal),
mjcBiasPrm("mjc:biasPrm", TfToken::Immortal),
mjcBiasType("mjc:biasType", TfToken::Immortal),
mjcCondim("mjc:condim", TfToken::Immortal),
mjcCrankLength("mjc:crankLength", TfToken::Immortal),
mjcCtrl("mjc:ctrl", TfToken::Immortal),
mjcCtrlLimited("mjc:ctrlLimited", TfToken::Immortal),
@@ -83,6 +84,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcFrictionloss("mjc:frictionloss", TfToken::Immortal),
mjcGainPrm("mjc:gainPrm", TfToken::Immortal),
mjcGainType("mjc:gainType", TfToken::Immortal),
mjcGap("mjc:gap", TfToken::Immortal),
mjcGear("mjc:gear", TfToken::Immortal),
mjcGroup("mjc:group", TfToken::Immortal),
mjcInertia("mjc:inertia", TfToken::Immortal),
@@ -122,6 +124,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcOptionTolerance("mjc:option:tolerance", TfToken::Immortal),
mjcOptionViscosity("mjc:option:viscosity", TfToken::Immortal),
mjcOptionWind("mjc:option:wind", TfToken::Immortal),
mjcPriority("mjc:priority", TfToken::Immortal),
mjcQpos("mjc:qpos", TfToken::Immortal),
mjcQvel("mjc:qvel", TfToken::Immortal),
mjcRef("mjc:ref", TfToken::Immortal),
@@ -129,8 +132,11 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcRollingfriction("mjc:rollingfriction", TfToken::Immortal),
mjcShellinertia("mjc:shellinertia", TfToken::Immortal),
mjcSliderSite("mjc:sliderSite", TfToken::Immortal),
mjcSolimp("mjc:solimp", TfToken::Immortal),
mjcSolimpfriction("mjc:solimpfriction", TfToken::Immortal),
mjcSolimplimit("mjc:solimplimit", TfToken::Immortal),
mjcSolmix("mjc:solmix", TfToken::Immortal),
mjcSolref("mjc:solref", TfToken::Immortal),
mjcSolreffriction("mjc:solreffriction", TfToken::Immortal),
mjcSolreflimit("mjc:solreflimit", TfToken::Immortal),
mjcSpringdamper("mjc:springdamper", TfToken::Immortal),
@@ -185,6 +191,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcArmature,
mjcBiasPrm,
mjcBiasType,
mjcCondim,
mjcCrankLength,
mjcCtrl,
mjcCtrlLimited,
@@ -222,6 +229,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcFrictionloss,
mjcGainPrm,
mjcGainType,
mjcGap,
mjcGear,
mjcGroup,
mjcInertia,
@@ -258,6 +266,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcOptionTolerance,
mjcOptionViscosity,
mjcOptionWind,
mjcPriority,
mjcQpos,
mjcQvel,
mjcRef,
@@ -265,8 +274,11 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcRollingfriction,
mjcShellinertia,
mjcSliderSite,
mjcSolimp,
mjcSolimpfriction,
mjcSolimplimit,
mjcSolmix,
mjcSolref,
mjcSolreffriction,
mjcSolreflimit,
mjcSpringdamper,
@@ -761,8 +761,7 @@ class ModelWriter {
ApplyApiSchema(data_, material_path,
pxr::UsdPhysicsTokens->PhysicsMaterialAPI);
ApplyApiSchema(data_, material_path,
MjcPhysicsTokens->MjcMaterialAPI);
ApplyApiSchema(data_, material_path, MjcPhysicsTokens->MjcMaterialAPI);
mjsGeom *geom_default = mjs_getDefault(geom->element)->geom;
if (geom->friction[0] != geom_default->friction[0]) {
@@ -1094,8 +1093,7 @@ class ModelWriter {
}
}
void WriteActuator(mjsActuator *actuator,
const pxr::SdfPath &parent_path) {
void WriteActuator(mjsActuator *actuator, const pxr::SdfPath &parent_path) {
pxr::TfToken valid_name = GetValidPrimName(*mjs_getName(actuator->element));
pxr::SdfPath actuator_path = parent_path.AppendChild(valid_name);
if (!data_->HasSpec(actuator_path)) {
@@ -1121,9 +1119,8 @@ class ModelWriter {
return;
}
CreateRelationshipSpec(data_, actuator_path,
MjcPhysicsTokens->mjcTarget, target_path,
pxr::SdfVariabilityUniform);
CreateRelationshipSpec(data_, actuator_path, MjcPhysicsTokens->mjcTarget,
target_path, pxr::SdfVariabilityUniform);
WriteUniformAttribute(actuator_path, pxr::SdfValueTypeNames->Int,
MjcPhysicsTokens->mjcGroup, actuator->group);
@@ -1132,9 +1129,8 @@ class ModelWriter {
int refsite_id =
mj_name2id(model_, mjOBJ_SITE, actuator->refsite->c_str());
pxr::SdfPath refsite_path = site_paths_[refsite_id];
CreateRelationshipSpec(data_, actuator_path,
MjcPhysicsTokens->mjcRefSite, refsite_path,
pxr::SdfVariabilityUniform);
CreateRelationshipSpec(data_, actuator_path, MjcPhysicsTokens->mjcRefSite,
refsite_path, pxr::SdfVariabilityUniform);
}
if (!actuator->slidersite->empty()) {
@@ -1158,8 +1154,8 @@ class ModelWriter {
} else if (value == mjLIMITED_FALSE) {
limited_token = pxr::MjcPhysicsTokens->false_;
}
WriteUniformAttribute(actuator_path, pxr::SdfValueTypeNames->Token,
token, limited_token);
WriteUniformAttribute(actuator_path, pxr::SdfValueTypeNames->Token, token,
limited_token);
}
const std::vector<std::pair<pxr::TfToken, double>>
@@ -1248,8 +1244,8 @@ class ModelWriter {
void WriteActuators() {
pxr::SdfPath scope_path =
CreatePrimSpec(data_, body_paths_[kWorldIndex],
kTokens->actuatorsScope, pxr::UsdGeomTokens->Scope);
CreatePrimSpec(data_, body_paths_[kWorldIndex], kTokens->actuatorsScope,
pxr::UsdGeomTokens->Scope);
mjsActuator *actuator =
mjs_asActuator(mjs_firstElement(spec_, mjOBJ_ACTUATOR));
while (actuator) {
@@ -1570,6 +1566,34 @@ class ModelWriter {
MjcPhysicsTokens->mjcShellinertia,
geom->typeinertia == mjtGeomInertia::mjINERTIA_SHELL);
WriteUniformAttribute(geom_path, pxr::SdfValueTypeNames->Int,
MjcPhysicsTokens->mjcPriority, geom->priority);
WriteUniformAttribute(geom_path, pxr::SdfValueTypeNames->Int,
MjcPhysicsTokens->mjcCondim, geom->condim);
WriteUniformAttribute(geom_path, pxr::SdfValueTypeNames->Double,
MjcPhysicsTokens->mjcSolmix, geom->solmix);
WriteUniformAttribute(geom_path, pxr::SdfValueTypeNames->Double,
MjcPhysicsTokens->mjcSolmix, geom->solmix);
WriteUniformAttribute(
geom_path, pxr::SdfValueTypeNames->DoubleArray,
MjcPhysicsTokens->mjcSolref,
pxr::VtArray<double>(geom->solref, geom->solref + mjNREF));
WriteUniformAttribute(
geom_path, pxr::SdfValueTypeNames->DoubleArray,
MjcPhysicsTokens->mjcSolimp,
pxr::VtArray<double>(geom->solimp, geom->solimp + mjNIMP));
WriteUniformAttribute(geom_path, pxr::SdfValueTypeNames->Double,
MjcPhysicsTokens->mjcMargin, geom->margin);
WriteUniformAttribute(geom_path, pxr::SdfValueTypeNames->Double,
MjcPhysicsTokens->mjcGap, geom->gap);
if (geom->mass >= mjMINVAL || geom->density >= mjMINVAL) {
ApplyApiSchema(data_, geom_path, pxr::UsdPhysicsTokens->PhysicsMassAPI);
}
+57
View File
@@ -584,6 +584,63 @@ void ParseMjcPhysicsCollisionAPI(
if (group_attr.HasAuthoredValue()) {
group_attr.Get(&geom->group);
}
auto priority_attr = collision_api.GetPriorityAttr();
if (priority_attr.HasAuthoredValue()) {
priority_attr.Get(&geom->priority);
}
auto condim_attr = collision_api.GetConDimAttr();
if (condim_attr.HasAuthoredValue()) {
condim_attr.Get(&geom->condim);
}
auto solmix_attr = collision_api.GetSolMixAttr();
if (solmix_attr.HasAuthoredValue()) {
solmix_attr.Get(&geom->solmix);
}
auto solref_attr = collision_api.GetSolRefAttr();
if (solref_attr.HasAuthoredValue()) {
pxr::VtDoubleArray solref;
solref_attr.Get(&solref);
if (solref.size() == mjNREF) {
for (int i = 0; i < mjNREF; ++i) {
geom->solref[i] = solref[i];
}
} else {
mju_warning(
"solref attribute for geom %s has incorrect size %zu, "
"expected %d.",
mjs_getName(geom->element)->c_str(), solref.size(), mjNREF);
}
}
auto solimp_attr = collision_api.GetSolImpAttr();
if (solimp_attr.HasAuthoredValue()) {
pxr::VtDoubleArray solimp;
solimp_attr.Get(&solimp);
if (solimp.size() == mjNIMP) {
for (int i = 0; i < mjNIMP; ++i) {
geom->solimp[i] = solimp[i];
}
} else {
mju_warning(
"solimp attribute for geom %s has incorrect size %zu, "
"expected %d.",
mjs_getName(geom->element)->c_str(), solimp.size(), mjNIMP);
}
}
auto margin_attr = collision_api.GetMarginAttr();
if (margin_attr.HasAuthoredValue()) {
margin_attr.Get(&geom->margin);
}
auto gap_attr = collision_api.GetGapAttr();
if (gap_attr.HasAuthoredValue()) {
gap_attr.Get(&geom->gap);
}
}
void ParseMjcPhysicsMeshCollisionAPI(
@@ -1463,13 +1463,36 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestMjcPhysicsCollisionAPI) {
<mujoco model="test">
<worldbody>
<body name="body">
<geom name="box" type="box" size=".05 .05 .05" mass="0.1" shellinertia="true"/>
<geom
name="box"
type="box"
size=".05 .05 .05"
mass="0.1"
group="4"
priority="2"
condim="4"
solmix="0.5"
solref="0.1 0.2"
solimp="0.3 0.4 0.5 0.6 0.7"
margin="0.8"
gap="0.9"
shellinertia="true"/>
</body>
</worldbody>
</mujoco>
)";
auto stage = OpenStageWithPhysics(xml);
ExpectAttributeEqual(stage, "/test/body/box.mjc:group", 4);
ExpectAttributeEqual(stage, "/test/body/box.mjc:priority", 2);
ExpectAttributeEqual(stage, "/test/body/box.mjc:condim", 4);
ExpectAttributeEqual(stage, "/test/body/box.mjc:solmix", 0.5);
ExpectAttributeEqual(stage, "/test/body/box.mjc:solref",
pxr::VtArray<double>({0.1, 0.2}));
ExpectAttributeEqual(stage, "/test/body/box.mjc:solimp",
pxr::VtArray<double>({0.3, 0.4, 0.5, 0.6, 0.7}));
ExpectAttributeEqual(stage, "/test/body/box.mjc:margin", 0.8);
ExpectAttributeEqual(stage, "/test/body/box.mjc:gap", 0.9);
ExpectAttributeEqual(stage, "/test/body/box.mjc:shellinertia", true);
}