Moro 0.6.0 Release Notes

Moro 0.6.0 focuses on interactive visualization of serial robot manipulators in Jupyter and Colab. It refines the geometry produced from classic Denavit–Hartenberg models, makes scales and camera framing more reliable, and adopts Three.js as the default plotting and animation backend.

Highlights

Geometry from evaluated Denavit–Hartenberg parameters

The visualization layer now retains evaluated signed d and a translation segments rather than relying only on straight lines between consecutive frame origins. Segment identities and zero-length segments are preserved for consistent animation topology.

SceneData also includes joint motion-axis metadata in the base frame so that revolute and prismatic joints can be depicted according to their actual kinematic axes.

Scales and camera fitting

A backend-independent layout resolves nominal link, joint, base and coordinate-frame sizes. Shared scene bounds and fitting instructions:

  • adapt to different linear units, such as meters and millimeters;

  • include displayed DH geometry and kinematic joint solids;

  • preserve stable global bounds across animation samples;

  • support offset, folded, and degenerate configurations.

The fitted region covers the sampled animation frames, not every continuous intermediate pose between frames.

Joint representations

Three.js supports schematic R/P joint symbols and solid representations, with distinct default colors for revolute and prismatic joints.

VisualizationStyle(joint_representation="auto") is now the default. With complete evaluated joint metadata, Three.js uses solid kinematic joints. With old manually constructed scenes lacking joint metadata, it falls back to simple spherical markers. Matplotlib also uses spherical markers by default and can draw schematic kinematic symbols when requested explicitly.

For conventional spheres in Three.js, set:

from moro.visualization import VisualizationStyle

style = VisualizationStyle(joint_representation="simple")
viz.plot(values, style=style)

For schematic R/P symbols in either backend:

style = VisualizationStyle(
    joint_representation="kinematic",
    joint_appearance="schematic",
)
viz.plot(values, style=style)

Solid kinematic joints are currently supported only by Three.js.

Touchpad-friendly camera controls

The interactive Three.js viewer now supports conventional navigation: left drag to orbit, right drag to pan, wheel/pinch to zoom, and one-finger touch drag to orbit.

The toolbar offers Front, Right, Top, and Isometric camera directions. Fit View recovers a suitable framing without changing the current viewing direction, projection mode, or animation playback.

Animation playback interval

Three.js animations support a configurable frame interval in milliseconds, with a default of 100:

viz.animate(configurations, interval=50)

The interval controls browser playback; it does not automatically reproduce a trajectory’s potentially nonuniform physical time grid.

Important migration: Three.js is now the default

This is a breaking change. In Moro 0.5.x:

fig, ax = viz.plot(values)
animation = viz.animate(configurations)

returned Matplotlib objects. In Moro 0.6.0, omitted backend arguments select Three.js and return IPython.display.HTML objects.

To keep the previous return types, make the Matplotlib backend explicit:

fig, ax = viz.plot(values, backend="matplotlib")
animation = viz.animate(configurations, backend="matplotlib")

For interactive notebooks, no backend argument is needed:

viz.plot(values)
viz.animate(configurations)

The backends retain their own configuration arguments: for example, view_init and figsize belong to Matplotlib, while width and height belong to Three.js. Moro does not silently translate these arguments or detect the execution environment to change backends.

Dependencies, compatibility and limitations

Moro 0.6.0 requires Python 3.11 or newer. Its direct dependencies are SymPy, NumPy, Matplotlib, SciPy, and now IPython for the default interactive HTML output.

Three.js and OrbitControls assets are downloaded by the browser from a CDN. The interactive viewer is therefore not a fully self-contained offline experience. For ordinary Python scripts or offline graphics, use backend="matplotlib".

Existing numerical robot modeling, kinematics, dynamics, trajectory, workspace, and explicit Matplotlib workflows remain available.

See also