Allow custom step function in StepControl::Advance.
The StepControl::Advance method now accepts an optional std::function to be used instead of mj_step. This allows for custom simulation logic to be executed within the stepping loop. The Python bindings for StepControl::advance have been updated to support passing a Python callable as the custom step function. PiperOrigin-RevId: 925393132 Change-Id: Id2820c4b55cbdfee6b01adc2395e99a990d4e7a3
This commit is contained in:
committed by
Copybara-Service
parent
3a5626bc27
commit
0e4749501c
@@ -42,11 +42,21 @@ PYBIND11_MODULE(sim, m) {
|
|||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
.def(
|
.def(
|
||||||
"advance",
|
"advance",
|
||||||
[](StepControl& self, mujoco::python::MjModelWrapper& model,
|
[](StepControl& self, py::object model_obj, py::object data_obj,
|
||||||
mujoco::python::MjDataWrapper& data) {
|
py::object step_fn) {
|
||||||
return self.Advance(model.get(), data.get());
|
auto& model = py::cast<mujoco::python::MjModelWrapper&>(model_obj);
|
||||||
|
auto& data = py::cast<mujoco::python::MjDataWrapper&>(data_obj);
|
||||||
|
if (step_fn.is_none()) {
|
||||||
|
return self.Advance(model.get(), data.get());
|
||||||
|
} else {
|
||||||
|
return self.Advance(
|
||||||
|
model.get(), data.get(),
|
||||||
|
[step_fn, model_obj, data_obj](mjModel*, mjData*) {
|
||||||
|
step_fn(model_obj, data_obj);
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
py::arg("model"), py::arg("data"),
|
py::arg("model"), py::arg("data"), py::arg("step_fn") = py::none(),
|
||||||
"Step physics forward, respecting speed settings and refresh budget.")
|
"Step physics forward, respecting speed settings and refresh budget.")
|
||||||
.def("force_sync", &StepControl::ForceSync,
|
.def("force_sync", &StepControl::ForceSync,
|
||||||
"Ensures the next Advance() will synchronize time and step once.")
|
"Ensures the next Advance() will synchronize time and step once.")
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <ratio>
|
#include <ratio>
|
||||||
|
|
||||||
@@ -91,7 +92,8 @@ StepControl::PauseState StepControl::GetPauseState() const {
|
|||||||
return pause_state_;
|
return pause_state_;
|
||||||
}
|
}
|
||||||
|
|
||||||
StepControl::Status StepControl::Advance(mjModel* m, mjData* d) {
|
StepControl::Status StepControl::Advance(mjModel* m, mjData* d,
|
||||||
|
StepFn step_fn) {
|
||||||
if (!m) {
|
if (!m) {
|
||||||
return Status::kOk;
|
return Status::kOk;
|
||||||
}
|
}
|
||||||
@@ -182,7 +184,11 @@ StepControl::Status StepControl::Advance(mjModel* m, mjData* d) {
|
|||||||
|
|
||||||
mjtNum prev_time = d->time;
|
mjtNum prev_time = d->time;
|
||||||
InjectNoise(m, d);
|
InjectNoise(m, d);
|
||||||
mj_step(m, d);
|
if (step_fn) {
|
||||||
|
step_fn(m, d);
|
||||||
|
} else {
|
||||||
|
mj_step(m, d);
|
||||||
|
}
|
||||||
|
|
||||||
if (mjDISABLED(mjDSBL_AUTORESET)) {
|
if (mjDISABLED(mjDSBL_AUTORESET)) {
|
||||||
for (mjtWarning w : kDivergedWarnings) {
|
for (mjtWarning w : kDivergedWarnings) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_STEP_CONTROL_H_
|
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_STEP_CONTROL_H_
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
@@ -24,6 +25,7 @@ namespace mujoco::platform {
|
|||||||
|
|
||||||
using Seconds = std::chrono::duration<double>;
|
using Seconds = std::chrono::duration<double>;
|
||||||
using Clock = std::chrono::steady_clock;
|
using Clock = std::chrono::steady_clock;
|
||||||
|
using StepFn = std::function<void(mjModel*, mjData*)>;
|
||||||
|
|
||||||
// State and logic for physics synchronization and stepping.
|
// State and logic for physics synchronization and stepping.
|
||||||
class StepControl {
|
class StepControl {
|
||||||
@@ -53,7 +55,7 @@ class StepControl {
|
|||||||
mjWARN_BADQACC, mjWARN_BADQVEL, mjWARN_BADQPOS};
|
mjWARN_BADQACC, mjWARN_BADQVEL, mjWARN_BADQPOS};
|
||||||
|
|
||||||
// Steps physics forward, respecting speed settings and refresh budget.
|
// Steps physics forward, respecting speed settings and refresh budget.
|
||||||
Status Advance(mjModel* m, mjData* d);
|
Status Advance(mjModel* m, mjData* d, StepFn step_fn = nullptr);
|
||||||
|
|
||||||
// Ensures the next call to Advance() will synchronize time and step once.
|
// Ensures the next call to Advance() will synchronize time and step once.
|
||||||
void ForceSync();
|
void ForceSync();
|
||||||
|
|||||||
Reference in New Issue
Block a user