Introduce new logging API, fixes #858

PiperOrigin-RevId: 930744288
Change-Id: I6ec1203b55c031390f3eef23192e2337508ce886
This commit is contained in:
Yuval Tassa
2026-06-11 14:36:17 -07:00
committed by Copybara-Service
parent a2abaf7aef
commit 58f6d52491
45 changed files with 2586 additions and 422 deletions
+99 -5
View File
@@ -539,6 +539,96 @@ This is useful for example when the MJB is not available as a file on disk.)"));
X(int, number);
#undef X
// ==================== MJLOGCONFIG ==========================================
py::class_<MjLogConfigWrapper> mjLogConfig(m, "MjLogConfig");
mjLogConfig.def(py::init<>());
mjLogConfig.def("__copy__", [](const MjLogConfigWrapper& other) {
return MjLogConfigWrapper(other);
});
mjLogConfig.def("__deepcopy__",
[](const MjLogConfigWrapper& other, py::dict) {
return MjLogConfigWrapper(other);
});
DefineStructFunctions(mjLogConfig);
mjLogConfig.def_property(
"logto_console",
[](const MjLogConfigWrapper& d) { return d.get()->logto_console; },
[](MjLogConfigWrapper& d, bool rhs) { d.get()->logto_console = rhs; });
mjLogConfig.def_property(
"logto_file",
[](const MjLogConfigWrapper& d) { return d.get()->logto_file; },
[](MjLogConfigWrapper& d, bool rhs) { d.get()->logto_file = rhs; });
mjLogConfig.def_property(
"logfile",
[](const MjLogConfigWrapper& d) { return std::string(d.get()->logfile); },
[](MjLogConfigWrapper& d, const std::string& rhs) {
std::strncpy(d.get()->logfile, rhs.c_str(), 1023);
d.get()->logfile[1023] = '\0';
});
mjLogConfig.def_property(
"topics", [](const MjLogConfigWrapper& d) { return d.get()->topics; },
[](MjLogConfigWrapper& d, int rhs) { d.get()->topics = rhs; });
mjLogConfig.def_static("get", []() {
MjLogConfigWrapper wrapper;
*wrapper.get() = mju_getLogConfig();
return wrapper;
});
mjLogConfig.def("set", [](const MjLogConfigWrapper& self) {
mju_setLogConfig(*self.get());
});
// ==================== MJLOGMESSAGE =========================================
py::class_<MjLogMessageWrapper> mjLogMessage(m, "MjLogMessage");
mjLogMessage.def(py::init<>());
mjLogMessage.def("__copy__", [](const MjLogMessageWrapper& other) {
return MjLogMessageWrapper(other);
});
mjLogMessage.def("__deepcopy__",
[](const MjLogMessageWrapper& other, py::dict) {
return MjLogMessageWrapper(other);
});
DefineStructFunctions(mjLogMessage);
mjLogMessage.def_property(
"level", [](const MjLogMessageWrapper& d) { return d.get()->level; },
[](MjLogMessageWrapper& d, int rhs) { d.get()->level = rhs; });
mjLogMessage.def_property(
"topic", [](const MjLogMessageWrapper& d) { return d.get()->topic; },
[](MjLogMessageWrapper& d, int rhs) { d.get()->topic = rhs; });
mjLogMessage.def_property(
"subject",
[](const MjLogMessageWrapper& d) {
return std::string(d.get()->subject);
},
[](MjLogMessageWrapper& d, const std::string& rhs) {
std::strncpy(d.get()->subject, rhs.c_str(), 1023);
d.get()->subject[1023] = '\0';
});
mjLogMessage.def_property_readonly(
"body",
[](const MjLogMessageWrapper& d) -> py::object {
if (d.get()->body) return py::str(d.get()->body);
return py::none();
});
mjLogMessage.def_property_readonly(
"func",
[](const MjLogMessageWrapper& d) -> py::object {
if (d.get()->func) return py::str(d.get()->func);
return py::none();
});
mjLogMessage.def_property_readonly(
"file",
[](const MjLogMessageWrapper& d) -> py::object {
if (d.get()->file) return py::str(d.get()->file);
return py::none();
});
mjLogMessage.def_property(
"line", [](const MjLogMessageWrapper& d) { return d.get()->line; },
[](MjLogMessageWrapper& d, int rhs) { d.get()->line = rhs; });
mjLogMessage.def_property(
"timestamp",
[](const MjLogMessageWrapper& d) { return d.get()->timestamp; },
[](MjLogMessageWrapper& d, bool rhs) { d.get()->timestamp = rhs; });
// ==================== MJTIMERSTAT ==========================================
py::class_<MjTimerStatWrapper> mjTimerStat(m, "MjTimerStat");
mjTimerStat.def(py::init<>());
@@ -960,18 +1050,22 @@ This is useful for example when the MJB is not available as a file on disk.)"));
#undef X
// ==================== MJRVERTEXATTRIBUTE ===================================
py::class_<raw::MjrVertexAttribute> mjrVertexAttribute(m, "MjrVertexAttribute");
py::class_<raw::MjrVertexAttribute> mjrVertexAttribute(m,
"MjrVertexAttribute");
mjrVertexAttribute.def(py::init([](int usage, int type) {
return raw::MjrVertexAttribute{nullptr, usage, type};
}),
py::arg("usage") = 0, py::arg("type") = 0);
mjrVertexAttribute.def("__copy__",
[](const raw::MjrVertexAttribute& other) { return raw::MjrVertexAttribute(other); });
mjrVertexAttribute.def("__deepcopy__", [](const raw::MjrVertexAttribute& other, py::dict) {
mjrVertexAttribute.def("__copy__", [](const raw::MjrVertexAttribute& other) {
return raw::MjrVertexAttribute(other);
});
mjrVertexAttribute.def("__deepcopy__",
[](const raw::MjrVertexAttribute& other, py::dict) {
return raw::MjrVertexAttribute(other);
});
DefineStructFunctions(mjrVertexAttribute);
#define X(var) mjrVertexAttribute.def_readwrite(#var, &raw::MjrVertexAttribute::var)
#define X(var) \
mjrVertexAttribute.def_readwrite(#var, &raw::MjrVertexAttribute::var)
X(usage);
X(type);
#undef X