Initial Release#6
Conversation
pculbertson-bdai
left a comment
There was a problem hiding this comment.
sure, lgtm (lol)
In general: I read through everything + think the code makes sense at a high level. Flagged some style stuff/things that aren't working (benchmark in particular seems bricked on my Mac) but overall support merging to use this version as the foundation for the repo.
When we get Simon's buy-in, let's merge and do an initial release on pypi. Then we can stand up an issue board/roadmap and start whacking bugs.
| The `vis_name` field specifies the name of the visualization object in the GUI backend, so it doesn't matter that much. `xyz_vis_indices` indicates which indices of the array to use for the x, y, and z coordinates of the visualization. If you set it to `None`, it will use the default values specified in `xyz_vis_defaults`. | ||
|
|
||
| <p align="center"> | ||
| <img src="/judo/_static/images/cylinder_push.gif" alt="cylinder_push_config" width="640"> |
There was a problem hiding this comment.
This image doesn't show up for me - is it just my machine?
There was a problem hiding this comment.
i believe this will show up on the actual docs website, but it does NOT show up locally. If there's a way you guys know how to resolve the image paths thing, then let me know, I fiddled with it for a few hours but couldn't figure it out - I could get it to show up locally but not on the published site or vice versa.
| @on_event("INPUT", "controller_config") | ||
| def update_controller_config(self, event: dict) -> None: | ||
| """Callback to update controller config on receiving a new config message.""" | ||
| self.controller_config = from_event(event, self.controller_config_cls) |
There was a problem hiding this comment.
Why store things in two places? Shouldn't there be one "source of truth" for these config classes?
There was a problem hiding this comment.
Yes - this is a holdover from some of the legacy judo code, where there were some configs bookkept in the dora node. In reality, the clean way to handle this is to have self.controller_config point to self.controller.controller_config using a getter, and have a setter set the config in the controller attribute.
I think cleaning up this internal logic is a good candidate for v0.0.2 release.
| def update_states(self, event: dict) -> None: | ||
| """Callback to update states on receiving a new state measurement.""" | ||
| state_msg = from_event(event, MujocoState) | ||
| self.states = np.concatenate([state_msg.qpos, state_msg.qvel]) |
There was a problem hiding this comment.
We may want to consider generalizing this to include other state data - e.g., in the official rollouts they dynamically compute what's in the full physics state.
We may also want to make a note that we only support basically Lagrangian dynamics with rigid bodies / stateless actuators atm
There was a problem hiding this comment.
Agree with the sentiment, but also there are some concerns which we might want to discuss.
I think we should have a more future-proof and robust way of handling the state data. One thing that is minimal and always shared (for rigid body Lagrangian dynamics) is passing times, generalized positions, and generalized velocities. If we allowed swapping the MuJoCo rollout backend out later, then adding other fields like the mocap fields could break things.
For example, in our lab, we were considering allowing custom function definitions like ODE callables for the rollouts (this is useful for things like doing rollouts with ROMs). If there were additional fields besides the ones I described above, it might break this proposed addition.
There was a problem hiding this comment.
Updated docs to include a note about simulation support.
| self.step() | ||
| self.write_states() | ||
|
|
||
| # Force controller to run at fixed rate specified by model dt. |
There was a problem hiding this comment.
We may want to introspect here and print warnings if the inner loop time is running slower than realtime. I'm seeing behavior that looks suspiciously slower than realtime when my CPU is working hard
There was a problem hiding this comment.
Agreed on this.
Many of the default tasks also use a pretty high number of default threads, so we may want to converge on some reasonable numbers and/or compute the min of os.cpu_count() and the specified threads.
There was a problem hiding this comment.
added a warning.
| @@ -0,0 +1,107 @@ | |||
| # Copyright (c) 2025 Robotics and AI Institute LLC. All rights reserved. | |||
There was a problem hiding this comment.
Running benchmark from the terminal errors with:
File "/Users/preston/judo/judo/cli.py", line 51, in main_benchmark
run(cfg)
File "/Users/preston/miniconda3/envs/judo/lib/python3.12/site-packages/dora_utils/launch/run.py", line 32, in run
node_name = f"tmp_{node_cfg.node_id}"
^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'node_id'
started dora coordinator
There was a problem hiding this comment.
Hmm this doesn't error for me, also doesn't error for Zach at Caltech. @slecleach does this work for you?
There was a problem hiding this comment.
Preston, If you're using conda, I think you may want to consider nuking and recreating your environment. I made some small changes to dora_utils to prep for release, so if you're using an old env, you might have some weird issues like this.
| self.times = self.task.data.time + self.spline_timesteps | ||
| self.update_spline(self.times, self.nominal_knots) | ||
|
|
||
| def update_traces(self) -> None: |
There was a problem hiding this comment.
this will probably need a refactor for readability at some point - the shapes end up being pretty arcane. curious if we could try bringing back the CatmullRomSpline type + if the performance is any different these days
There was a problem hiding this comment.
Added to the issue tracker.
There was a problem hiding this comment.
Let's reevaluate the CatmullRomSpline from Viser, if'that's too slow we could stick to plotting segments.
| self.traces = np.reshape(elites, (total_traces_rollouts, 2, 3)) | ||
|
|
||
|
|
||
| def make_spline(times: np.ndarray, controls: np.ndarray, spline_order: str) -> interp1d: |
There was a problem hiding this comment.
Having this util and the constructor in SplineData seems redundant/hard to maintain. I think we should refactor to use the class method from SplineData or vice versa.
There was a problem hiding this comment.
added an issue for this.
| def pre_optimization(self, old_times: np.ndarray, new_times: np.ndarray) -> None: | ||
| """Update sigma if the number of nodes has changed.""" | ||
| if len(self.sigma) != self.num_nodes: | ||
| self.sigma = interp1d( |
There was a problem hiding this comment.
Probably should be refactored to a unified spline call
There was a problem hiding this comment.
added an issue for this.
|
Hi Albert! thanks so much for putting this PR together. This is a huge undertaking and it's addressing some critical pain points and limitations with the current version of Judo. Some initial comments after I went through the documentation, the readme, the installation and docs building scripts.
Suggested fixes:
Minor fixes: [we can put this on the roadmap for later development if we agree on these points]
|
|
Question: how do I fix the dice in the bottom right of the docs? I can't find where the symbol is originating from. I'll happily remove it before merging this PR. Addressed the following:
Relegated the following to the v0.0.2 release:
|
This PR adds the private development changes to
judo.As per slack discussion with @pculbertson-bdai, we have an internal checklist of action items prior to release on pypi.