Replace functionally opaque Viscous Pause with functionally transparent "Viscous posing mode" toggle.
PiperOrigin-RevId: 947527204 Change-Id: I122a9730fa22ac9e8809762046a89fb0a774d827
This commit is contained in:
committed by
Copybara-Service
parent
3c6080b1c0
commit
0ce8f7b06b
@@ -32,14 +32,12 @@ PYBIND11_MODULE(sim, m, pybind11::mod_gil_not_used()) {
|
||||
py::enum_<StepControl::Status>(m, "StepStatus")
|
||||
.value("OK", StepControl::Status::kOk)
|
||||
.value("PAUSED", StepControl::Status::kPaused)
|
||||
.value("VISCOUS_PAUSED", StepControl::Status::kViscousPaused)
|
||||
.value("AUTO_RESET", StepControl::Status::kAutoReset)
|
||||
.value("DIVERGED", StepControl::Status::kDiverged);
|
||||
|
||||
py::enum_<StepControl::PauseState>(m, "PauseState")
|
||||
.value("UNPAUSED", StepControl::PauseState::kUnpaused)
|
||||
.value("NORMAL_PAUSED", StepControl::PauseState::kNormalPaused)
|
||||
.value("VISCOUS_PAUSED", StepControl::PauseState::kViscousPaused);
|
||||
.value("NORMAL_PAUSED", StepControl::PauseState::kNormalPaused);
|
||||
|
||||
py::class_<StepControl>(m, "StepControl")
|
||||
.def(py::init<>())
|
||||
|
||||
@@ -157,15 +157,8 @@ def handle_step_control_keyboard_events(
|
||||
|
||||
pressed = imgui.IsKeyChordPressed
|
||||
|
||||
if pressed(int(imgui.Key.Ctrl) | int(imgui.Key.Space)):
|
||||
if step_control.get_pause_state() == sim.PauseState.VISCOUS_PAUSED:
|
||||
step_control.set_pause_state(sim.PauseState.UNPAUSED)
|
||||
else:
|
||||
step_control.set_pause_state(sim.PauseState.VISCOUS_PAUSED)
|
||||
return True
|
||||
elif pressed(imgui.Key.Space):
|
||||
pause = step_control.get_pause_state()
|
||||
if pause in (sim.PauseState.VISCOUS_PAUSED, sim.PauseState.UNPAUSED):
|
||||
if pressed(imgui.Key.Space):
|
||||
if step_control.get_pause_state() == sim.PauseState.UNPAUSED:
|
||||
step_control.set_pause_state(sim.PauseState.NORMAL_PAUSED)
|
||||
else:
|
||||
step_control.set_pause_state(sim.PauseState.UNPAUSED)
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <ratio>
|
||||
|
||||
#include <mujoco/mujoco.h>
|
||||
@@ -32,31 +31,7 @@ static mjtNum Timer() {
|
||||
return Milliseconds(Clock::now() - start).count();
|
||||
}
|
||||
|
||||
// Updates key viscous pause parameters restores them when done.
|
||||
struct ViscousPauseState {
|
||||
ViscousPauseState(mjModel* model) : model(model) {
|
||||
if (model) {
|
||||
mju_copy3(gravity, model->opt.gravity);
|
||||
viscosity = model->opt.viscosity;
|
||||
disableflags = model->opt.disableflags;
|
||||
mju_zero3(model->opt.gravity);
|
||||
model->opt.viscosity = 10;
|
||||
model->opt.disableflags |= mjDSBL_SPRING;
|
||||
}
|
||||
}
|
||||
|
||||
~ViscousPauseState() {
|
||||
if (model) {
|
||||
mju_copy3(model->opt.gravity, gravity);
|
||||
model->opt.viscosity = viscosity;
|
||||
model->opt.disableflags = disableflags;
|
||||
}
|
||||
}
|
||||
mjModel* model;
|
||||
mjtNum gravity[3];
|
||||
mjtNum viscosity;
|
||||
int disableflags;
|
||||
};
|
||||
|
||||
|
||||
StepControl::StepControl() { mjcb_time = Timer; }
|
||||
@@ -100,10 +75,6 @@ StepControl::Status StepControl::Advance(mjModel* m, mjData* d) {
|
||||
return Status::kOk;
|
||||
}
|
||||
|
||||
std::optional<ViscousPauseState> viscous_pause_state;
|
||||
if (m && pause_state_ == PauseState::kViscousPaused) {
|
||||
viscous_pause_state.emplace(m);
|
||||
}
|
||||
|
||||
if (pause_state_ == PauseState::kNormalPaused) {
|
||||
// When we eventually unpause, we need to make sure we sync to immediately
|
||||
|
||||
@@ -38,9 +38,6 @@ class StepControl {
|
||||
// Simulation was not stepped because it is paused.
|
||||
kPaused,
|
||||
|
||||
// Simulation is viscously paused (stepping with zero gravity, high
|
||||
// viscosity, and no spring forces).
|
||||
kViscousPaused,
|
||||
|
||||
// Simulation diverged with autoreset enabled.
|
||||
kAutoReset,
|
||||
@@ -73,7 +70,7 @@ class StepControl {
|
||||
void SetPreStepCallback(StepFn step_fn);
|
||||
void SetPostStepCallback(StepFn step_fn);
|
||||
|
||||
enum class PauseState { kUnpaused, kNormalPaused, kViscousPaused };
|
||||
enum class PauseState { kUnpaused, kNormalPaused };
|
||||
|
||||
// Sets the pause state of the simulation.
|
||||
void SetPauseState(PauseState state);
|
||||
|
||||
@@ -511,9 +511,6 @@ void StepControlGui(StepControl* step_control, int& speed_index) {
|
||||
make_button(ICON_FA_PAUSE, StepControl::PauseState::kNormalPaused, yellow,
|
||||
ImDrawFlags_RoundCornersLeft, "Pause", .3f, 1.6f);
|
||||
ImGui::SameLine(0.f, 0.f);
|
||||
make_button(ICON_FA_MAGIC, StepControl::PauseState::kViscousPaused, yellow,
|
||||
ImDrawFlags_RoundCornersNone, "Viscous Pause", .3f, 1.3f);
|
||||
ImGui::SameLine(0.f, 0.f);
|
||||
make_button(ICON_FA_PLAY, StepControl::PauseState::kUnpaused, green,
|
||||
ImDrawFlags_RoundCornersRight, "", .3f, 1.6f);
|
||||
|
||||
@@ -983,6 +980,30 @@ void PhysicsGui(mjModel* model, float min_width) {
|
||||
}
|
||||
|
||||
if (SectionHeader("Physical Parameters")) {
|
||||
// Viscous posing mode toggle: disables gravity and passive springs, adds
|
||||
// viscosity. All changes are directly visible in the parameters below.
|
||||
{
|
||||
constexpr mjtNum kPosingViscosity = 10;
|
||||
bool active = (opt.disableflags & mjDSBL_GRAVITY) &&
|
||||
(opt.disableflags & mjDSBL_SPRING) &&
|
||||
(opt.viscosity >= kPosingViscosity);
|
||||
if (ImGui_ButtonToggle("Viscous posing mode", &active)) {
|
||||
if (active) {
|
||||
opt.disableflags |= mjDSBL_GRAVITY;
|
||||
opt.disableflags |= mjDSBL_SPRING;
|
||||
opt.viscosity += kPosingViscosity;
|
||||
} else {
|
||||
opt.disableflags &= ~mjDSBL_GRAVITY;
|
||||
opt.disableflags &= ~mjDSBL_SPRING;
|
||||
opt.viscosity = std::max<mjtNum>(0, opt.viscosity - kPosingViscosity);
|
||||
}
|
||||
}
|
||||
ImGui::SetItemTooltip(
|
||||
"Disable gravity and passive springs,\n"
|
||||
"add viscosity for easier posing.");
|
||||
}
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui_InputN("Gravity", opt.gravity, 3);
|
||||
ImGui_InputN("Wind", opt.wind, 3);
|
||||
ImGui_InputN("Magnetic", opt.magnetic, 3);
|
||||
|
||||
@@ -733,16 +733,8 @@ void App::HandleKeyboardEvents() {
|
||||
LoadHistory(sim_history_.GetIndex() + 1);
|
||||
}
|
||||
}
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiMod_Ctrl | ImGuiKey_Space)) {
|
||||
if (step_control_.GetPauseState() == PauseState::kViscousPaused) {
|
||||
step_control_.SetPauseState(PauseState::kUnpaused);
|
||||
} else {
|
||||
step_control_.SetPauseState(PauseState::kViscousPaused);
|
||||
}
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_Space)) {
|
||||
if (step_control_.GetPauseState() == PauseState::kViscousPaused) {
|
||||
step_control_.SetPauseState(PauseState::kNormalPaused);
|
||||
} else if (step_control_.GetPauseState() == PauseState::kUnpaused) {
|
||||
if (step_control_.GetPauseState() == PauseState::kUnpaused) {
|
||||
step_control_.SetPauseState(PauseState::kNormalPaused);
|
||||
} else {
|
||||
step_control_.SetPauseState(PauseState::kUnpaused);
|
||||
@@ -1461,6 +1453,7 @@ void App::TimelineScrubberGui() {
|
||||
|
||||
// Advance layout cursor past this row.
|
||||
ImGui::SetCursorScreenPos(ImVec2(cursor.x, cursor.y + total_h));
|
||||
ImGui::Dummy(ImVec2(0.0f, 0.0f));
|
||||
}
|
||||
|
||||
void App::ModelOptionsGui() {
|
||||
@@ -2178,8 +2171,8 @@ void App::ToolBarGui() {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, right_width);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() +
|
||||
ImGui::GetStyle().WindowPadding.x);
|
||||
ImGui::Dummy(ImVec2(ImGui::GetStyle().WindowPadding.x, 0.0f));
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
|
||||
const float btn_size = ImGui::GetFrameHeight();
|
||||
const ImVec2 square_size(btn_size, btn_size);
|
||||
@@ -2200,7 +2193,7 @@ void App::ToolBarGui() {
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Reset");
|
||||
|
||||
// Combined (Normal Pause, Viscous Pause, Play) widget and Speed selection.
|
||||
// Combined (Pause, Play) widget and Speed selection.
|
||||
ImGui::SameLine(0, separator_width);
|
||||
platform::StepControlGui(&step_control_, tmp_.speed_index);
|
||||
|
||||
@@ -2228,9 +2221,6 @@ void App::StatusBarGui() {
|
||||
|
||||
if (!has_model()) {
|
||||
ImGui::Text("No model loaded");
|
||||
} else if (step_control_.GetPauseState() == PauseState::kViscousPaused) {
|
||||
ImGui::Text("Viscous Pause");
|
||||
ImGui::SetItemTooltip("Zero gravity, high viscosity, no spring forces");
|
||||
} else if (step_control_.GetPauseState() == PauseState::kNormalPaused) {
|
||||
ImGui::Text("Paused");
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user