Skip to content

Backend registry: single name → constructor dispatch #902

Open

Description

@petercorke

Part of #886. Groundwork for the new backends; each backend issue is blocked by this one.

Problem

Backend selection is spread over several places:

  • backends.load_backend(): an if/elif over "swift", "pyplot", "pyplot2"
  • BaseRobot._get_graphical_backend(): a Literal of the same names, an isinstance chain to pick a default, a Pyodide special case, and Swift-specific fallback logic
  • BaseRobot.plot(): type(env).__name__ == "Swift" and isinstance(env, PyPlot) checks

Adding a backend means editing all of these. Also, default_backend isn't lowercased, so robot.default_backend = "Swift" fails with ValueError at plot time.

Proposal

  1. One registry in roboticstoolbox.backends, mapping name → target, e.g. "swift": "roboticstoolbox.backends.swift:Swift". Built-in backends are entries here.
  2. load_backend(name) looks the name up (case-insensitive). A string target is imported only when chosen. An unknown name gives an error listing the registered names. A missing optional package gives ModuleNotFoundError naming the pip extra.
  3. register_backend(name, target, *, replace=False), public:
    • target is a lazy "module:Class" string, or a callable returning a Connector
    • registering an existing name raises unless replace=True
    • registration is per process (call it before plot()); entry-point discovery may come later
    • lets a backend be developed, tested and used outside the RTB tree, e.g. register_backend("isaacsim", "rtb_isaacsim:IsaacSim"); once accepted into RTB, that call becomes a registry entry
    • backends that can't live in RTB (licence, GPU) can stay as separate packages
  4. Default choice stays in _get_graphical_backend, but works only with names: explicit argument → robot/class default → robot kind → "pyplot". Defaults by robot kind pick only built-ins; a registered backend is used when named or set with set_default_backend(). Normalise case at every entry point.
  5. Capability flags replace type checks. Add flags to Connector, and use getattr(env, flag, default) in plot():
    • embeds_in_notebook replaces __name__ == "Swift"
    • supports_movie replaces isinstance(env, PyPlot)
    • existing: supports_teach, supports_ellipse
  6. Type hints. The backend argument becomes str, validated at runtime against the registry, so the names live in one place and registered names are valid too.

Out of scope

Tests

  • Lookup: case-insensitivity, unknown-name error, missing-package error
  • register_backend with a string target and a callable target, the duplicate-name error, and replace=True, all using a fake backend
  • Default resolution for each robot kind and for Pyodide
  • Capability flags read with the right defaults
  • The mocked Swift tests use register_backend and no longer need a class named Swift

Done when

  • Adding a backend is one registry entry plus the backend module
  • No __name__ or backend isinstance checks remain in BaseRobot
  • Existing tests pass, including the Swift ones
  • The docs list the registered backends and their flags, and show register_backend usage

Activity

  1. self-assigned this
    on Oct 25, 2026
  2. alexermolovich commented on Oct 26, 2026

    @alexermolovich

    Hello @petercorke, I do not see any PR associated with this issue so I will start working on this one as well in parallel with the #903, so you can assign me to both if you wish. If there is any work on this done already and I just did not see it please let me know and I will just pull it into my #903 draft.

  3. alexermolovich commented on Oct 26, 2026

    @alexermolovich

    I opened a PR to work on this issue: #904

  4. petercorke commented on Oct 27, 2026

    @petercorke
    OwnerAuthor

    Alex, I'm traveling and not getting to things quickly. I was planning on taking this one, I am assigned, leave you to do the heavy lifting on IsaacSim proper. If you've started submit a PR. I created sub issues to allow different folk to claim different backends

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions