Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: model_updater easy to get for more custom rerun use cases #20

Merged
merged 3 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyorerun/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .biorbd_components.model_display_options import DisplayModelOptions
from .biorbd_components.model_interface import BiorbdModel, BiorbdModelNoMesh
from .biorbd_components.model_updapter import ModelUpdater
from .live_animation import LiveModelAnimation
from .multi_phase_rerun import MultiPhaseRerun

Expand Down
2 changes: 1 addition & 1 deletion pyorerun/biorbd_components/local_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ def to_rerun(self, q: np.ndarray) -> None:
rr.Transform3D(
# scale=self.scale,
translation=homogenous_matrices[:3, 3],
mat3x3=homogenous_matrices[:3, :3],
mat3x3=homogenous_matrices[:3, :3] * 0.25,
),
)
33 changes: 33 additions & 0 deletions pyorerun/biorbd_components/model_updapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,39 @@ def __init__(self, name, model: BiorbdModel):
self.segments = self.create_segments_updater()
self.muscles = self.create_muscles_updater()

@classmethod
def from_file(cls, model_path: str):
"""
This factory method is meant to be used with rerun easily. For example, to display a model in rerun,
and add its custom experimental data.

Parameters
----------
model_path: str
The path to the bioMod file, such as "path/to/model.bioMod".

Returns
-------
ModelUpdater

Examples
--------
>>> import rerun as rr
>>> import numpy as np
>>> from pyorerun import ModelUpdater

>>> q = np.zeros(10)
>>> model = ModelUpdater.from_file("path/to/model.bioMod")

>>> rr.init("my_thing", spawn=True)
>>> rr.set_time_sequence(timeline="step", sequence=0)
>>> model.to_rerun(q)
>>> rr.log("anything", rr.Anything())

"""
model = BiorbdModel(model_path)
return cls(model.name, model)

def create_markers_updater(self):
if self.model.nb_markers == 0:
return EmptyUpdater(self.name + "/markers")
Expand Down
25 changes: 13 additions & 12 deletions pyorerun/live_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import rerun as rr

from .biorbd_components.model_interface import BiorbdModel
from .phase_rerun import PhaseRerun
from .biorbd_components.model_updapter import ModelUpdater


class LiveModelAnimation:
Expand Down Expand Up @@ -43,20 +43,28 @@ def __init__(self, model_path: str, with_q_charts: bool = False):
"""

self.counter = 0
self.model = BiorbdModel(model_path)
self.model_updater = ModelUpdater.from_file(model_path)
self.model = self.model_updater.model
self.biorbd_model = self.model.model

self.q = np.zeros(self.biorbd_model.nbQ())
self.dof_sliders = []
self.dof_slider_values = []
self.update_functions = []
self.with_q_charts = with_q_charts

def update_viewer(self, event, dof_index: int):
the_dof_idx, the_value = self.fetch_and_update_slider_value(event, dof_index)
self.update_rerun_components(the_dof_idx, the_value)

def fetch_and_update_slider_value(self, event, dof_index: int) -> tuple[int, float]:
the_dof_idx = dof_index
the_value = self.dof_sliders[the_dof_idx].get()
# update the slider value q
self.dof_slider_values[the_dof_idx].config(text=f"{the_value:.2f}")
# update joint angles q
return the_dof_idx, the_value

def update_rerun_components(self, the_dof_idx: int, the_value: float):
self.q[the_dof_idx] = the_value
# update counter
self.counter += 1
Expand All @@ -68,7 +76,7 @@ def update_viewer(self, event, dof_index: int):
self.update_trajectories(self.q)

def update_model(self, q: np.ndarray):
self.viz.biorbd_models.rerun_models[0].to_rerun(q)
self.model_updater.to_rerun(q)

def update_trajectories(self, q: np.ndarray):
q_ranges = [q_range for segment in self.biorbd_model.segments() for q_range in segment.QRanges()]
Expand All @@ -88,16 +96,9 @@ def to_serie_line(self, name: str, min: float, max: float, val: float):
rr.log(f"{name}/value", rr.Scalar(val))

def rerun(self, name: str = None):
# Building a fake pyorerun animation
nb_frames = 1
nb_seconds = 0
t_span = np.linspace(0, nb_seconds, nb_frames)
q = np.zeros((self.model.model.nbQ(), nb_frames))
self.viz = PhaseRerun(t_span)
self.viz.add_animated_model(self.model, q)

# update manually here
rr.init(application_id=f"{self.model.name}" if name is None else name, spawn=True)
self.update_rerun_components(the_dof_idx=0, the_value=0.0)
self.create_window_with_sliders()

def create_window_with_sliders(self):
Expand Down