From d349761f15e6f04c896f30dc273e5da2362e10eb Mon Sep 17 00:00:00 2001 From: Brandon Hung Date: Wed, 10 Dec 2025 17:32:00 -0500 Subject: [PATCH 1/6] Updated the set_task to avoid recreating all the locking events --- judo/visualizers/visualizer.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/judo/visualizers/visualizer.py b/judo/visualizers/visualizer.py index 4562a9bf..77383682 100644 --- a/judo/visualizers/visualizer.py +++ b/judo/visualizers/visualizer.py @@ -56,9 +56,24 @@ def __init__( self.task_name = "" self.optimizer_name = "" + # Initializes the locks and events in the constructor to avoid recreating them each time the task is set. self.task_lock = threading.Lock() self.task_updated = threading.Event() + self.controller_config_lock = threading.Lock() + self.controller_config_updated = threading.Event() + + self.optimizer_lock = threading.Lock() + self.optimizer_updated = threading.Event() + + self.optimizer_config_lock = threading.Lock() + self.optimizer_config_updated = threading.Event() + + self.task_config_lock = threading.Lock() + self.task_config_updated = threading.Event() + + self.task_reset_updated = threading.Event() + self.sim_pause_button = sim_pause_button if self.sim_pause_button: self.sim_pause_lock = threading.Lock() @@ -120,24 +135,12 @@ def set_task(self, task_name: str, optimizer_name: str) -> None: raise ValueError(f"Optimizer {optimizer_name} not found in optimizer registry.") _, optimizer_config_cls = optimizer_entry - self.controller_config_lock = threading.Lock() - self.controller_config_updated = threading.Event() self.controller_config = ControllerConfig() self.controller_config.set_override(task_name) - self.optimizer_lock = threading.Lock() - self.optimizer_updated = threading.Event() - - self.optimizer_config_lock = threading.Lock() - self.optimizer_config_updated = threading.Event() self.optimizer_config = optimizer_config_cls() self.optimizer_config.set_override(task_name) - self.task_config_lock = threading.Lock() - self.task_config_updated = threading.Event() - - self.task_reset_updated = threading.Event() - self.setup_gui() # send the configs to the other nodes From dd6ae7b34ad9db0488aae9ffb2fa54a0f7cb9114 Mon Sep 17 00:00:00 2001 From: Brandon Hung Date: Fri, 12 Dec 2025 17:03:17 -0500 Subject: [PATCH 2/6] Updated visualizer to be safer --- judo/visualizers/visualizer.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/judo/visualizers/visualizer.py b/judo/visualizers/visualizer.py index 77383682..3bf31dfa 100644 --- a/judo/visualizers/visualizer.py +++ b/judo/visualizers/visualizer.py @@ -238,10 +238,9 @@ def _(_: viser.GuiEvent) -> None: """Callback for when the pause button is clicked.""" if sim_pause_button.label == "Pause Simulation": sim_pause_button.label = "Resume Simulation" - self.sim_pause_updated.set() else: sim_pause_button.label = "Pause Simulation" - self.sim_pause_updated.set() + self.sim_pause_updated.set() # create a display for plan time self.gui_elements["plan_time_display"] = self.server.gui.add_number( @@ -295,7 +294,6 @@ def _(_: viser.GuiEvent) -> None: def _(_: viser.GuiEvent) -> None: """Callback for when the optimizer dropdown is updated.""" # first, send the name of the new optimizer - self.optimizer_updated.set() self.optimizer_name = optimizer_dropdown.value # update config @@ -304,7 +302,6 @@ def _(_: viser.GuiEvent) -> None: optimizer_config_cls = optimizer_entry[1] self.optimizer_config = optimizer_config_cls() self.optimizer_config.set_override(self.task_name) - self.optimizer_config_updated.set() # replace optimizer param gui elements for v in self.gui_elements["optimizer_params"]: @@ -319,6 +316,8 @@ def _(_: viser.GuiEvent) -> None: # because the optimizer will be updated, we need to sent the task parameters back to it so it doesn't start # with defaults + self.optimizer_updated.set() + self.optimizer_config_updated.set() self.task_config_updated.set() @task_dropdown.on_update @@ -326,7 +325,6 @@ def _(_: viser.GuiEvent) -> None: """Callback for when the task dropdown is updated.""" # first, send the name of the new task self.task_name = task_dropdown.value - self.task_updated.set() # replace gui elements self._remove_gui_elements() @@ -334,6 +332,7 @@ def _(_: viser.GuiEvent) -> None: # set up the entire visualizer from scratch with self.task_lock: self.set_task(self.task_name, self.optimizer_name) + self.task_updated.set() def remove_handles(self, handles: list[ElementType] | ElementType) -> None: """Remove GUI handles from the visualization node.""" From 64ba1cd470fc8cd08d6d727194293bd6e7b1db17 Mon Sep 17 00:00:00 2001 From: Brandon Hung Date: Fri, 12 Dec 2025 17:21:16 -0500 Subject: [PATCH 3/6] Remove traces before the geom they're attached to gets removed, thereby fixing the floating traces sometimes left in judo --- judo/visualizers/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/judo/visualizers/model.py b/judo/visualizers/model.py index 466f9878..b4ea4852 100644 --- a/judo/visualizers/model.py +++ b/judo/visualizers/model.py @@ -295,9 +295,9 @@ def set_traces(self, traces: np.ndarray | None, all_traces_rollout_size: int) -> def remove(self) -> None: """Wrapper function to remove all geometries from Viser.""" + self.remove_traces() for geom in self._geoms: geom.remove() - self.remove_traces() def add_plane( From b0c9285a626b3c2cd060cb3c00e4b8eb0751a24e Mon Sep 17 00:00:00 2001 From: Brandon Hung Date: Fri, 12 Dec 2025 17:50:05 -0500 Subject: [PATCH 4/6] Updated version to 0.0.7 --- CHANGELOG.md | 7 +++++++ pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 305ae787..9fe904e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v0.0.7 + +## Fixed +* Fixed bug that caused traces to linger when switching from a trace task to a traceless task +* Fixed bug where task and optimizer events were cleared before the Visualizer finished rendering +* Fixed bug where events and locks are getting recreated when a task is made, causing the references to them to break + # v0.0.6 ## Added diff --git a/pyproject.toml b/pyproject.toml index e2cb6f7c..575cdb80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "judo-rai" description = "Judo: a hackable sampling-based MPC toolbox" -version = "0.0.6" +version = "0.0.7" readme = "README.md" license = { file = "LICENSE" } authors = [ From 4f7d985bcda55e49c4a1a7c6db3d3641666bf133 Mon Sep 17 00:00:00 2001 From: Brandon Hung Date: Fri, 12 Dec 2025 17:50:37 -0500 Subject: [PATCH 5/6] Updated pixi lock --- pixi.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pixi.lock b/pixi.lock index c92afb74..419c94f0 100644 --- a/pixi.lock +++ b/pixi.lock @@ -2179,8 +2179,8 @@ packages: requires_python: '>=3.9' - pypi: ./ name: judo-rai - version: 0.0.6 - sha256: e34c8db0eeda71610d7a90dd94d8a7726f392f2cbe8709d8279c8611080065f0 + version: 0.0.7 + sha256: 647aa3ce262a995a2cf97eb9657ec07492dd4dd5c478e7f33e62867855f559a5 requires_dist: - dora-utils - mujoco From bd9a3d44fb3a14b51c63733e85106ecf308e5747 Mon Sep 17 00:00:00 2001 From: Brandon Hung Date: Fri, 12 Dec 2025 17:58:32 -0500 Subject: [PATCH 6/6] Updated documentation --- CHANGELOG.md | 41 ++++++++++++++++++++++------------------- CONTRIBUTING.md | 9 +++++++++ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fe904e9..cc6985df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,41 +1,44 @@ # v0.0.7 ## Fixed -* Fixed bug that caused traces to linger when switching from a trace task to a traceless task -* Fixed bug where task and optimizer events were cleared before the Visualizer finished rendering -* Fixed bug where events and locks are getting recreated when a task is made, causing the references to them to break +* Fixed bug that caused traces to linger when switching from a trace task to a traceless task (@bhung, #108) +* Fixed bug where task and optimizer events were cleared before the Visualizer finished rendering (@bhung, #108) +* Fixed bug where events and locks are getting recreated when a task is made, causing bad references (@bhung, #108) + +## Dev +* Updated changelog with instructions on package updates (@bhung, #108) # v0.0.6 ## Added -* New copyrights +* New copyrights (@baxelrod, #103) ## Fixed -* Fixed bug that caused Viser and Mujoco to crash on visualization due to different API -* Added pycparser deps -* Fixed a new mujoco API compatibility +* Fixed bug that caused Viser and Mujoco to crash on visualization due to different API (@bhung, #107) +* Added pycparser deps (@bhung, #107) +* Fixed a new mujoco API compatibility (@bhung, #107) # v0.0.5 ## Added -* Separation between middleware implementation and core functionality -* Support for different middleware implementations -* Sliders with enforced bounds to errors caused by unintended values -* Interface to create controllers from registered tasks and optimizers -* Abstract interface to implement different simulation backends -* Removed duplication of objects inside a node to ensure that all references to data point to the same object +* Separation between middleware implementation and core functionality (@bhung, #93) +* Support for different middleware implementations (@bhung, #93) +* Sliders with enforced bounds to errors caused by unintended values (@bhung, #93) +* Interface to create controllers from registered tasks and optimizers (@bhung, #93) +* Abstract interface to implement different simulation backends (@bhung, #93) +* Removed duplication of objects inside a node to ensure that all references to data point to the same object (@bhung, #93) ## Fixed -* Fixed bug that would allow certain sliders to be set to arbitrary values that could crash the app -* Fixed bug that would allow NaN as a valid entry into the slider text box -* Fixed bug that caused the ControllerConfig to not be recreated when the `TaskConfig` was reset. +* Fixed bug that would allow certain sliders to be set to arbitrary values that could crash the app (@bhung, #93) +* Fixed bug that would allow NaN as a valid entry into the slider text box (@bhung, #93) +* Fixed bug that caused the ControllerConfig to not be recreated when the `TaskConfig` was reset. (@bhung, #93) ## Documentation -* Added specification between different slider types. -* Added guidelines on how to use the `Controller`. `Visualizer`, and `Simulation` objects +* Added specification between different slider types. (@bhung, #93) +* Added guidelines on how to use the `Controller`. `Visualizer`, and `Simulation` objects (@bhung, #93) ## Dev -* Modified release process so that any CODEOWNER can publish to pypi +* Modified release process so that any CODEOWNER can publish to pypi (@bhung, #99) # v0.0.4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4242bbc6..d258d697 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -88,6 +88,15 @@ feat(task): add fr3_stack task with novel constraints fix(mppi): guard against div-by-zero in cost calculation ``` +## 📦 Package updates and versioning + +If you are adding a significant change and would like it to be reviewed as a new package release, you will need to +update a few things: + +1. `CHANGELOG.md`: Following the format in the file, add your changes to the changelog with the proper PR references +2. `pyproject.toml`: Update the version of `judo_rai` appropriately +3. `pixi.lock`: Update the `pixi.lock` file. You can do this by running `pixi shell` and exiting after it's done. + ## 💬 Discussions Have questions or ideas?