Skip to main content

Extensions

An extension is a Git repository cloned into extensions/<extension>/ that adds a robot platform, a device, or any other package to OpenRoSDE without forking it. Extensions keep OpenRoSDE a platform-agnostic core, with everything specific to a robot or a product around it, as the OpenRoSDE Split describes.

A private extension, cloned from a private repository of a company or a lab, works exactly as a public one. OpenRoSDE never needs to know where an extension comes from.

๐Ÿงฉ Kinds of Extensionsโ€‹

OpenRoSDE treats every extension the same way, and only what an extension holds gives it its role.

KindWhat it holdsNamed afterExample name
PlatformOne robot as sold, with its public drivers: env/<platform>.env, docker/<platform>-devel/, ros/<platform>_catkin_ws/The robot, lowercase, without its makeropenrosde-platform-ur5e
DeviceOne upstream driver of hardware anyone can buy, such as a gripper, a camera, or an input device, with every model that driver supports, and naming no robotThe driveropenrosde-device-realsense
ExtensionAnything else added beside a platform, such as the bindings of a product, the packages of a lab, or the setups of a companyIts owner or its purposemy-lab-packages

A device covers a family rather than one model, since one driver usually supports a whole product line: openrosde-device-onrobot covers the OnRobot RG and VG grippers, and openrosde-device-spacenav every 3Dconnexion device that spacenavd supports. A device ships no tmux/*.panes, since which of its launch files run, and with which arguments, is the choice of each setup, whose panes start them.

A setup is one installation of a robot: the platform, devices, and extensions it pins, the description that mounts the devices, and the calibration, addresses, serial numbers, layouts, and runbook of that installation alone. A setup is a template that any extension holds rather than a repository of its own, so one private extension of a company or a lab can hold its packages and the setups of all its robots. A setup is named <owner>-<platform>-<place>, such as my-lab-ur5e-bench, so that the setups of the core, of a company, and of its clients never share a name. Platforms and devices anyone can buy are usually public, while setups are usually private.

The canonical platforms and the public devices are listed in Platforms & Devices.

๐Ÿ“ Layoutโ€‹

An extension shares the layout of the core, so that OpenRoSDE finds its files with the same rules:

extensions/<extension>/
env/<platform>.env # Platform template, the default setup, which declares 'OPENROSDE_ROBOT_PLATFORM=<platform>' and 'OPENROSDE_ROBOT_SETUP=<platform>' (platforms only).
env/<setup>.env # Setup template, which declares 'OPENROSDE_ROBOT_SETUP=<setup>', its platform, and its extensions (optional).
env/<setup>.repos # Repositories of the setup for 'vcstool' (optional).
docker/<platform>-devel/Dockerfile # Platform image, built on 'openrosde-base', or on 'openrosde-base-ros2' for a platform on ROS 2 (platforms only).
docker/<name>-devel/Dockerfile # Docker layer of a device or an extension, built on the image below it (optional).
docker/docker-compose-<name>.yaml # Docker Compose overlay: environment variables, volumes, devices.
ros/<name>_catkin_ws/src/ # One or more Catkin workspaces, for a platform on ROS 1.
ros2/<name>_colcon_ws/src/ # One or more colcon workspaces, for a platform on ROS 2, as 'docs/ros2.md' describes.
scripts/<platform>/ # Optional platform scripts (shell, bringup, Chrony), as for the core.
tmux/<name>.panes # Panes of the 'tmux' session, in its standard windows 'robot' and 'extra'.
terminator/<platform>.config # Terminator layouts of the platform, until 'tmux' replaces them (platforms only).
patches/ # Patches of the Git submodules of this extension.
ci/check-in-container.bash # Checks that the CI runs in the container of every setup that activates the extension (optional).
ci/allowed-duplicate-nodes.txt # Nodes that two panes of one layout may both start on purpose (optional).
ci/allowed-simulation-launches.txt # Launch files of simulations that the scripts of 'ci/' may start (optional).
docs/ # Documentation of the extension.
tip

Give the extension a .gitignore for the files that catkin build and catkin_init_workspace create in its Catkin workspaces, and that colcon build creates in its colcon workspaces, since the .gitignore of the core does not reach into another repository. The **/ prefix also covers the workspaces of its parts:

**/ros/*_catkin_ws/CMakeLists.txt
**/ros/*_catkin_ws/.catkin_tools/
**/ros/*_catkin_ws/build/
**/ros/*_catkin_ws/devel/
**/ros/*_catkin_ws/logs/
**/ros/*_catkin_ws/src/CMakeLists.txt
**/ros2/*_colcon_ws/build/
**/ros2/*_colcon_ws/install/
**/ros2/*_colcon_ws/log/

๐Ÿงฑ Partsโ€‹

A company or a lab with several robots can keep the units of all of them in one extension, split into parts. A part is a folder parts/<part>/ of the extension with the layout of the core, such as the setup of one robot, the bindings of a product, or a private platform, and it is activated by its name alone, like an extension:

extensions/<extension>/
README.md # Files that OpenRoSDE never reads, such as 'README.md', 'LICENSE', 'docs/', and the tools of the extension.
.gitmodules # Git submodules of every part.
parts/acme-bench/ # Setup of one robot: 'env/acme-ur5e-lab.env', 'env/acme-ur5e-lab.repos', 'tmux/acme-ur5e-lab.panes', and its workspaces and layers.
parts/acme-binding/ # Packages added beside a platform, such as the bindings of a product: 'ros/', 'docker/', and 'tmux/'.
parts/acme-robot/ # Private platform with its setups: 'env/<platform>.env', 'docker/<platform>-devel/', and 'ros/<platform>_catkin_ws/'.
  • OpenRoSDE looks up the templates of every part right after those of its extension, so the platforms and setups of a part are listed and selected like any other.
  • OPENROSDE_ROBOT_EXTENSIONS takes the name of an extension in extensions/<name>/ or of a part in extensions/<extension>/parts/<name>/, which must be the only folder of that name, so name each part after its owner and its purpose, such as acme-binding.
  • A setup lists the parts it needs in OPENROSDE_ROBOT_EXTENSIONS, such as "acme-binding", while the part that holds the setup and the part that holds the platform are active without being listed.
  • An active part counts as one unit: all its Catkin workspaces and Docker layers are used, and its files named after a platform or a setup only when that platform or setup is active.
  • The Git submodules of a part belong to the repository of the extension, which declares them in its .gitmodules, and each part keeps its own patches/, which mirror the submodule paths from the folder of the part.
  • Keep env/, docker/, ros/, and tmux/ out of the folder of the extension itself, so that every unit lives in a part.

๐Ÿ”Ž How OpenRoSDE Finds Filesโ€‹

  • An environment template env/<name>.env is looked up in the core first, then in every cloned extension followed by its parts, in alphabetical order.
  • A file named after the setup, such as scripts/<setup>/bringup-ros-robot.bash, terminator/<setup>.config, or tmux/<setup>.panes, comes from the folder that holds the setup.
  • A file named after the platform, such as docker/<platform>-devel/Dockerfile, docker/docker-compose-<platform>.yaml, or tmux/<platform>.panes, comes from the folder that holds the platform, then from the core, so a clone that is not active never supplies one.
  • An active folder may still add an overlay or a pane file named after the active platform or setup, such as a device with an overlay for each platform it supports, which comes after the file of the platform.
  • bash ./SWITCH-ROBOT-PLATFORM.bash lists the platforms of the core, of every cloned extension, and of every part, so a platform extension needs no registration.
  • The extensions and parts listed in OPENROSDE_ROBOT_EXTENSIONS are the active ones, and the folders that hold the active platform and the active setup are always active.
  • The Catkin workspaces are built and sourced in this order: ros/openrosde_catkin_ws of the core, the workspace of the platform, every other workspace of the active extensions in the order of OPENROSDE_ROBOT_EXTENSIONS, the workspaces of the setup, then ros/user_catkin_ws of the core.
  • A platform on ROS 2 takes the colcon workspaces of ros2/ in the same order, from ros2/openrosde_colcon_ws to ros2/user_colcon_ws, and its sessions open the panes of the core of tmux/openrosde-ros2.panes, as ROS 2 describes.
  • RUN-DOCKER-CONTAINER.bash adds the overlay of the platform, then every docker/docker-compose*.yaml of the active folders, apart from those named after a platform or a setup that is not active.
  • RUN-TMUX-SESSION.bash opens the panes of the setup, or else of the platform, whose own tmux/<platform>.panes the panes of the setup replace, then those of every tmux/*.panes of the active folders, apart from those named after a platform or a setup that is not active, then those of the core, and a setup can declare a layout of its own, such as lab-demo, for its demo.
  • Every pane opens in one of the standard windows of the tmux sessions, in the order robot, extra, tools, user, host, whatever part declares it: robot for the bringup, visualization, planning, and drivers of the platform and its devices, and extra for the optional processes of a setup or an extension, such as cameras, perception, or a demo, while tools, user, and host belong to the core, as Advanced Usage describes.
  • BUILD-DOCKER-IMAGE.bash builds the image of the platform from the folder that holds the platform, so that the COPY instructions of its docker/<platform>-devel/Dockerfile read from there, as those of a layer do.
  • BUILD-DOCKER-IMAGE.bash builds every docker/<name>-devel/Dockerfile of the active extensions whose <name> is not a platform, each on top of the previous one, between the platform image and the user overlay, as the section on Docker layers below shows.
  • bash ./scripts/update-git-submodules.bash updates the Git submodules of the core and of every cloned extension, and applies the patches/ of each repository and of each part to its own submodules.
note

Docker Compose resolves the relative paths of every overlay against docker/ of the core, so an overlay of an extension writes its paths from there, such as ../extensions/<extension>/config:/root/config.

scripts/load-extension-paths.bash holds these rules, on the host and inside the Docker container alike.

๐Ÿงญ Setupsโ€‹

A setup is an environment template env/<setup>.env that declares its own name, its platform, and its extensions:

OPENROSDE_ROBOT_PLATFORM=ur5e
OPENROSDE_ROBOT_SETUP=my-lab-ur5e-bench
OPENROSDE_ROBOT_EXTENSIONS="openrosde-device-onrobot openrosde-device-realsense"

OpenRoSDE finds platforms and setups by reading the lines OPENROSDE_ROBOT_PLATFORM=<platform> and OPENROSDE_ROBOT_SETUP=<setup> of each template as they are, without running it. Write each of them alone on its line, with no quotes, no spaces, and no trailing comment, while OPENROSDE_ROBOT_EXTENSIONS takes quotes around several names. scripts/list-robot-platforms.bash and scripts/list-robot-setups.bash name every template that breaks this rule with an error, and warn when two templates declare the same name, in which case OpenRoSDE uses the first one in the order of the core, then of every extension followed by its parts. Name a setup in lowercase letters and digits separated by dashes, as my-lab-ur5e-bench is, since the name of the setup also names its local Docker images, openrosde-local/<setup>/, where Docker takes no uppercase letter. OpenRoSDE lowercases the names of the setup and of its layers in those images, and scripts/load-openrosde-env.bash prints an error for a setup name that Docker refuses even so.

The template of every platform is its default setup, named after the platform, so bash ./SWITCH-ROBOT-PLATFORM.bash <platform> and bash ./SWITCH-ROBOT-SETUP.bash <platform> do the same.

Beside the template, env/<setup>.repos lists where to clone the repositories the setup needs, in the format of vcstool, the tool ROS projects use for the same purpose:

repositories:
openrosde-device-onrobot:
type: git
url: https://github.com/openrosde/openrosde-device-onrobot.git
version: v1.0.0
openrosde-device-realsense:
type: git
url: https://github.com/openrosde/openrosde-device-realsense.git
version: v1.2.0

The versions of this example only show the format, so pin each repository at a tag or a branch that it publishes. bash ./SWITCH-ROBOT-SETUP.bash <setup> clones the repositories that are missing from extensions/, at the versions the file pins, leaves the ones already cloned as they are, then copies the template to .env.custom. Run vcs import --input <setup>.repos extensions to bring the cloned ones to the pinned versions as well. The switch warns about a clone whose origin points to another repository than the URL that the file lists, which vcs import would leave as it is, and prints a git remote set-url command that would point it there. A clone over SSH of a repository that the file lists over HTTPS, or the reverse, is the same repository and raises no warning. It fails, and leaves the setup unchanged, when the platform of the setup or a name of its OPENROSDE_ROBOT_EXTENSIONS is still missing once the repositories are cloned.

A setup may also pin the version of OpenRoSDE it was tested with, as a release tag or a branch:

OPENROSDE_CORE_VERSION=v3.0.0

bash ./SWITCH-ROBOT-SETUP.bash <setup> then warns when OpenRoSDE is checked out at another version, neither a tag of the checked out commit nor the checked out branch, and prints the git checkout command of the pinned version. The switch still succeeds, since the setup may well run on another version. A checkout of a release tag still pulls the main images by default. The CI publishes the images of a release under its tag, such as v3.0.0, from the release pipeline on, so set OPENROSDE_DOCKER_IMAGE_TAG to that tag in .env.custom to pull them, or build the images of an older release locally with bash ./BUILD-DOCKER-IMAGE.bash local.

The folder that holds the setup is always active, after the extensions of OPENROSDE_ROBOT_EXTENSIONS, so its workspace builds last, before the user workspace. A file named after the setup takes precedence over the file named after its platform, such as scripts/<setup>/bringup-ros-robot.bash over scripts/<platform>/bringup-ros-robot.bash, terminator/<setup>.config over terminator/<platform>.config, or tmux/<setup>.panes over tmux/<platform>.panes, whose panes it replaces.

note

A .env.custom written before setups existed declares no setup, so OpenRoSDE uses its platform as the setup and keeps its platform files.

๐Ÿณ Docker Layersโ€‹

A device or an extension that needs system packages, such as the driver of a camera, holds a Docker layer in docker/<name>-devel/Dockerfile, built on the image below it:

# Inherit from the image below this layer, given by 'BUILD-DOCKER-IMAGE.bash'.
ARG OPENROSDE_PARENT_IMAGE
FROM ${OPENROSDE_PARENT_IMAGE}

# Install the system dependencies of the extension.
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-noetic-realsense2-camera \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

# Embed the commit hash of this Dockerfile for traceability.
ARG OPENROSDE_DOCKERFILE_COMMIT_SHORT_SHA

The layers stack in the order of the active folders, so the image of a setup reads from the bottom up:

openrosde-base -> <platform>-devel -> <device>-devel -> <extension>-devel -> <setup>-devel -> user-devel
  • Each layer is built from the folder of its extension, so its COPY instructions read from there.
  • The layers are always built locally by scripts/build-extension-layers.bash, which BUILD-DOCKER-IMAGE.bash runs in both its default and local modes, and never pushed, like the user overlay, so the layers of a private extension never leave the machine.
  • Each layer is tagged openrosde-local/<setup>/<name>-devel:latest, and the user overlay openrosde-local/<setup>/user-devel:latest, rather than with the name of the registry. A name without a registry host points to Docker Hub, where a repository has a namespace and a name without /, so no repository of three components can exist there, and a docker push of a private layer fails with push access denied rather than publishing it. Two setups that share a device also never overwrite the layer of each other.
  • A CI job builds the layers of a setup with the same script, on top of the platform image that it pulls, and pushes none of them, as the CI of OpenRoSDE does for every setup it tests.

๐Ÿš€ Using an Extensionโ€‹

  1. For a setup, clone the extension that holds it, then switch to it, which clones the rest:

    git clone <repository-url> extensions/<extension>
    bash ./SWITCH-ROBOT-SETUP.bash <setup>

    Otherwise, clone the extension into extensions/, with your own credentials if it is private:

    git clone <repository-url> extensions/<extension>
    bash ./scripts/update-git-submodules.bash
  2. For a platform extension, switch to its platform, which SWITCH-ROBOT-PLATFORM.bash lists like a platform of the core:

    bash ./SWITCH-ROBOT-PLATFORM.bash <platform>
  3. For any other extension or part, add its folder name to OPENROSDE_ROBOT_EXTENSIONS in .env.custom, separated by spaces, in the order its workspaces build:

    OPENROSDE_ROBOT_EXTENSIONS="openrosde-device-realsense my-lab-packages"
  4. Build the images and the workspaces as usual:

    bash ./BUILD-DOCKER-IMAGE.bash
    bash ./RUN-DOCKER-CONTAINER.bash
    openrosde-reset-catkin-workspaces

๐Ÿค– Canonical Platformsโ€‹

The canonical platforms of OpenRoSDE live in public repositories of their own, under the Apache License 2.0, each with the layout of the core, as Platforms & Devices lists.

Clone one into extensions/, then switch to it, as for any platform extension:

git clone https://github.com/openrosde/openrosde-platform-fetch.git extensions/openrosde-platform-fetch
bash ./SWITCH-ROBOT-PLATFORM.bash fetch
  • gitlab-ci/extensions.repos pins each of them at a commit of its main, so the CI of the core clones them, builds or reuses their images, and publishes them as ghcr.io/openrosde/<platform>-devel.
  • Each platform repository tests its own changes with its workflow .github/workflows/test-with-openrosde.yml, which Testing a Public Extension describes, and a pull request of the core moves the pin once a change of the platform is merged.
  • The NOTICE of each platform repository records the licenses of its third-party software, some of which allow no commercial use.
  • The UR5e in openrosde-platform-ur5e is the plain robot as sold, and a setup that mounts a gripper or cameras on it names its own description package in OPENROSDE_UR5E_DESCRIPTION_PACKAGE, as docs/robot-platforms/ur5e.md of that repository describes.

๐Ÿงช Testing an Extensionโ€‹

The CI of OpenRoSDE runs on GitHub Actions, as the section GitHub Actions describes, and tests every setup it finds, in the core and in the public extensions that gitlab-ci/extensions.repos pins, in the format of vcstool:

repositories:
openrosde-platform-foo:
type: git
url: https://github.com/openrosde/openrosde-platform-foo.git
version: v1.0.0

Keep that layout, with each name indented by two spaces and its keys by four, since gitlab-ci/clone-extensions.bash refuses any other rather than testing nothing. Update a version by hand, and never write the file with vcs export of the whole extensions/ folder, which would add every clone of the checkout, private ones included.

  • The generate job and every other job clone these repositories with gitlab-ci/clone-extensions.bash, anonymously over HTTPS, and never with a token of the job, so a run of OpenRoSDE, which anyone can read, never reaches a private repository.
  • The image job of a platform builds its image from the folder that holds it, and reuses an image whose folders hash the same, each folder hashed in the Git repository that holds it.
  • The test job of a setup selects the setup as bash ./SWITCH-ROBOT-SETUP.bash <setup> does, builds its Docker layers and its Catkin workspaces in the image of its platform, then disconnects the container from every network before any check runs.
  • It then checks that every launch entry point of the panes of the setup resolves with roslaunch --files, and that no two panes of one layout start a node of the same name with roslaunch --nodes, both of which start no node, and fails when neither the setup nor its platform has a pane file.
  • On ROS 2, it loads every launch entry point with ros2 launch --show-args, which starts no node either, and leaves out the node names, which ROS 2 cannot list without starting the nodes.
  • It then runs ci/check-in-container.bash of every active extension that holds one, with the setup as its argument, in the container where the workspaces of the setup are built and sourced, once check-scripts-job has passed.
  • The panes that name no package run the launch package of the platform, openrosde_<platform>_launch, unless scripts/<setup or platform>/initialize-bash-shell.bash sets another OPENROSDE_LAUNCH_PACKAGE, as it does in a shell of the container.

Two panes of one layout that start a node of the same name shut each other down, so the check names both. An extension that does this on purpose lists the node in ci/allowed-duplicate-nodes.txt, one <layout> <node-name> [<launch-file> ...] per line, where <layout> is * for every layout. A line that names launch files, as written in the panes, allows the node only when every pane that starts it runs one of them, such as two panes that a session runs one at a time:

default-gazebo /robot_state_publisher foo_navigation_default_gazebo.launch foo_mapping_default.launch
important

A check in ci/ never moves a robot. gitlab-ci/check-no-motion.bash fails on any roslaunch beyond --files, --nodes, or --dump-params, and on any rosrun, rostopic pub, or rosservice call, even after a path such as /opt/ros/noetic/bin/, and an option in a trailing comment does not count. On ROS 2, it fails on any ros2 launch beyond --show-args, --show-arguments, -s, --print, --print-description, or -p, and on any ros2 run, ros2 topic pub, ros2 service call, ros2 action send_goal, ros2 bag play, or ros2 lifecycle set. It lets a script of ci/ start only the launch files of simulations that ci/allowed-simulation-launches.txt names, one file name per line, such as foo_bringup_default_gazebo.launch or foo_bringup_default_gazebo.launch.xml, and a roslaunch or a ros2 launch of several launch files only when the list names every one of them.

A private extension runs the same scripts in a CI of its own, in a private repository, with OpenRoSDE checked out at the version it pins, since OpenRoSDE never clones a private repository. It reads the public base and platform images by setting OPENROSDE_CI_IMAGE_REGISTRY to ghcr.io/openrosde and OPENROSDE_CI_IMAGE_TAG to the tag of that version, dev or a release such as v3.0.0, and keeps its own images in its own registry. Both are needed, since gitlab-ci/test-catkin-workspaces.bash names no image without them, and the workflows of OpenRoSDE set them to the images of their own run, pipeline-<run-id>. It may instead pass the image to gitlab-ci/test-catkin-workspaces.bash as its second argument, such as ghcr.io/openrosde/ur5e-devel:v3.0.0. Outside the CI, the script refuses to replace an existing .env.custom, so move it aside before running the script by hand.

๐Ÿ™ GitHub Actionsโ€‹

The workflows of .github/workflows/ run the scripts of gitlab-ci/, a folder named after the GitLab CI that ran the versions before 3.0.0, which #13 renames, and keep the names that those scripts give the jobs.

WorkflowRuns onWhat it does
checks.ymlEvery pull request, forks included, and every run of ci.ymlShellCheck, actionlint, the test suites of tests/, check-scripts-job, and generate-pipeline-job, with no secret
ci.ymlEvery push to dev or main and every release tag vX.Y.Z of openrosde/openrosde that changes something that goes into an image or a workspaceThe image jobs, check-mesh-glbs-job, one test job per setup and for the core alone, and publish-images-job
extension.ymlThe workflow of an extension that calls itcheck-scripts-job, check-mesh-glbs-job, and the test jobs of the setups that activate the extension
  • generate-pipeline-job lists the jobs with gitlab-ci/generate-ci-pipeline.bash, which prints them as a GitLab child pipeline whose jobs extend those of gitlab-ci/openrosde-pipeline.yml, and .github/scripts/print-ci-matrices.bash turns them into the matrices of the workflows.
  • ci.yml pushes its images to ghcr.io/openrosde as pipeline-<run-id>, reuses an image whose sources hash the same, and publishes them as dev, main, or vX.Y.Z once every image job and every test has passed.
  • Only its image jobs and its publish job may write packages, and they run only on a push to openrosde/openrosde, so a pull request builds no image and its workspaces are tested once it is merged into dev.
  • OPENROSDE_CI_REGISTRY_IMAGE names the registry in one place at the top of ci.yml.
  • The jobs that build or pull the base images free disk space first with .github/actions/free-disk-space, since a hosted runner has little room for them.

๐Ÿ” Testing a Public Extensionโ€‹

A public extension tests its pull requests and its branch main against the core with a workflow of its own, .github/workflows/test-with-openrosde.yml, that calls extension.yml, as every platform and every device of OpenRoSDE does:

name: Test with OpenRoSDE

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: test-with-openrosde-${{ github.ref }}
cancel-in-progress: true

jobs:
openrosde:
uses: openrosde/openrosde/.github/workflows/extension.yml@dev
with:
core-ref: dev
  • The workflow checks out the core at core-ref, clones the extensions of gitlab-ci/extensions.repos, and checks out the commit under test in place of the pinned clone, which works for a fork, a pull request, and an extension that the file does not list.
  • It tests only the setups that activate the extension, and a device that no setup lists yet passes extra-extensions: openrosde-device-<driver> to add it to every setup.
  • setups keeps the test jobs of the setups it names, separated by spaces, such as ur5e for a device of ROS 1 that extra-extensions adds to every setup, so that the device is never built on a setup of ROS 2, and the workflow fails when none of them activates the extension.
  • It runs in the repository that calls it, which cannot push to the registry of the core, so each test job builds the image of its platform locally on the published images of core-ref, with the published image of that platform as its cache, and it publishes nothing.
  • Keep core-ref on the version after the @, since the workflow runs the scripts of the core that it checks out.
  • Its other inputs name the folder of the extension when it differs from the name of the repository (extension-name), the core (core-repository), and the published images (image-registry, image-tag).
  • workflow_dispatch lets a maintainer run the workflow again by hand, such as after a change of the core.

โš™๏ธ Configurationโ€‹

VariableDefaultPurpose
OPENROSDE_ROBOT_SETUPThe platformActive setup, named after its template env/<setup>.env
OPENROSDE_ROBOT_EXTENSIONSEmptyFolder names of the active extensions in extensions/ or of their parts, separated by spaces, in the order their workspaces build
OPENROSDE_DOCKER_REGISTRYghcr.io/openrosdeRegistry where the base and platform images are pulled from and pushed to
OPENROSDE_DOCKER_BUILD_FALLBACKtrueImages that BUILD-DOCKER-IMAGE.bash builds locally when their pull fails: true for the base and platform images, platform for the platform image alone, or false for neither
OPENROSDE_QUIETfalseLeaves out the list of every OPENROSDE_* variable that the entry scripts print, whose passwords, tokens, and secrets always print as <redacted>
OPENROSDE_CORE_VERSIONEmptyVersion of OpenRoSDE that a setup template pins, as a release tag or a branch, which SWITCH-ROBOT-SETUP.bash compares with the checkout

A platform image that the registry does not hold, such as the image of a private platform, is built locally by BUILD-DOCKER-IMAGE.bash, which falls back to a build when the pull fails. A CI job sets OPENROSDE_DOCKER_BUILD_FALLBACK=platform in .env.custom to build a private platform but never the base image, which takes hours, or false to fail as soon as a pull fails. Set OPENROSDE_DOCKER_REGISTRY in .env.custom to use a registry of your own.

๐Ÿ›ฃ๏ธ What Comes Nextโ€‹

  • Terminator leaves OpenRoSDE with #3, now that the tmux sessions have run on a real robot, together with RUN-TERMINATOR-TERMINAL.bash, the terminator/ layouts of the platforms, and the checks of tests/suites/test-terminator-parity.bash.
  • The folder gitlab-ci/ takes a neutral name with #13, which also removes what only GitLab CI used, so an extension that calls its scripts updates their paths then.