Introduce mjPreContact, a minimal struct passed into the collision functions.

PiperOrigin-RevId: 918533795
Change-Id: I2b5af05c1479b25d5c2cfdc690321a26fce6ede6
This commit is contained in:
Kyle Bayes
2026-05-20 10:47:11 -07:00
committed by Copybara-Service
parent 53b3137a12
commit 7174d33f08
25 changed files with 709 additions and 406 deletions
+36
View File
@@ -5140,6 +5140,42 @@ STRUCTS: Mapping[str, StructDecl] = dict([
),
),
)),
('mjPreContact',
StructDecl(
name='mjPreContact',
declname='struct mjPreContact_',
fields=(
StructFieldDecl(
name='dist',
type=ValueType(name='mjtNum'),
doc='',
),
StructFieldDecl(
name='pos',
type=ArrayType(
inner_type=ValueType(name='mjtNum'),
extents=(3,),
),
doc='',
),
StructFieldDecl(
name='normal',
type=ArrayType(
inner_type=ValueType(name='mjtNum'),
extents=(3,),
),
doc='contact normal of the collision',
),
StructFieldDecl(
name='tangent',
type=ArrayType(
inner_type=ValueType(name='mjtNum'),
extents=(3,),
),
doc='first tangent direction',
),
),
)),
('mjContact',
StructDecl(
name='mjContact',
+1
View File
@@ -25,6 +25,7 @@
// to them under the "raw" namespace.
namespace mujoco::raw {
using MjPreContact = ::mjPreContact;
using MjContact = ::mjContact;
using MjData = ::mjData;
using MjLROpt = ::mjLROpt;
+26
View File
@@ -615,6 +615,32 @@ This is useful for example when the MJB is not available as a file on disk.)"));
X(int, nupdate);
#undef X
// ==================== MJPRECONTACT ==========================================
py::class_<MjPreContactWrapper> mjPreContact(m, "MjPreContact");
mjPreContact.def(py::init<>());
mjPreContact.def("__copy__", [](const MjPreContactWrapper& self) {
return MjPreContactWrapper(self);
});
mjPreContact.def("__deepcopy__", [](const MjPreContactWrapper& self, py::dict) {
return MjPreContactWrapper(self);
});
DefineStructFunctions(mjPreContact);
#define X(var) \
mjPreContact.def_property( \
#var, [](const MjPreContactWrapper& c) { return c.get()->var; }, \
[](MjPreContactWrapper& c, decltype(raw::MjPreContact::var) rhs) { \
c.get()->var = rhs; \
})
X(dist);
#undef X
#define X(var) DefinePyArray(mjPreContact, #var, &MjPreContactWrapper::var)
X(pos);
X(normal);
X(tangent);
#undef X
// ==================== MJCONTACT ============================================
py::class_<MjContactWrapper> mjContact(m, "MjContact");
mjContact.def(py::init<>());
+22
View File
@@ -547,6 +547,27 @@ template <>
struct enable_if_mj_struct<raw::MjModel> { using type = void; };
// ==================== MJCONTACT ==============================================
template <>
class MjWrapper<raw::MjPreContact> : public WrapperBase<raw::MjPreContact> {
public:
MjWrapper();
MjWrapper(const MjWrapper&);
MjWrapper(MjWrapper&&) = default;
MjWrapper(raw::MjPreContact* ptr, pybind11::handle owner);
~MjWrapper() = default;
#define X(var) \
py_array_or_tuple_t< \
std::remove_all_extents_t<decltype(raw::MjPreContact::var)>> \
var
X(pos);
X(normal);
X(tangent);
#undef X
};
using MjPreContactWrapper = MjWrapper<raw::MjPreContact>;
template <>
class MjWrapper<raw::MjContact> : public WrapperBase<raw::MjContact> {
public:
@@ -961,6 +982,7 @@ using _impl::MjSolverStatWrapper;
using _impl::MjModelWrapper;
using _impl::MjDataWrapper;
using _impl::MjContactWrapper;
using _impl::MjPreContactWrapper;
using _impl::MjvPerturbWrapper;
using _impl::MjvCameraWrapper;
using _impl::MjvGLCameraWrapper;
+20
View File
@@ -535,6 +535,26 @@ std::unique_ptr<MjModelWrapper> MjModelWrapper::Deserialize(
return std::unique_ptr<MjModelWrapper>(new MjModelWrapper(model));
}
// ==================== MJPRECONTACT ==========================================
#define X(var) var(InitPyArray(ptr_->var, owner_))
MjPreContactWrapper::MjWrapper()
: WrapperBase(new raw::MjPreContact{}),
X(pos),
X(normal),
X(tangent) {}
MjPreContactWrapper::MjWrapper(raw::MjPreContact* ptr, py::handle owner)
: WrapperBase(ptr, owner),
X(pos),
X(normal),
X(tangent) {}
#undef X
MjPreContactWrapper::MjWrapper(const MjPreContactWrapper& other)
: MjPreContactWrapper() {
*this->ptr_ = *other.ptr_;
}
// ==================== MJCONTACT ==============================================
#define X(var) var(InitPyArray(ptr_->var, owner_))
MjContactWrapper::MjWrapper()