Build and install the pendant
On this page
The v5 pendant ships as one directory, RosiePendantV5, that you build on a Linux workstation and copy to a Steam Deck. It holds the native app, OLP's program logic bundled for Qt's JavaScript engine, the OLP server it runs headless on the Deck, and the source trees that server reads. To use it once it is installed, see Program from the Steam Deck pendant.
Danger
Not qualified for real motion. The v5 pendant has not been qualified on physical stick, trigger and rear-button input, real robot motion, network faults, or a full plan, Load and Play on the Deck, and no CI workflow builds it. Its hold-to-enable trigger is a software deadman, not a safety-rated enabling device. Keep the cell's hardware E-stop within reach whenever the drives are powered, and use the pendant in simulation until the cell owner has qualified it. See the safety model.
Before you start#
On the build workstation, Ubuntu 22.04 or WSL2:
sudo apt install g++ make pkg-config qtbase5-dev libassimp-dev curlYou also need:
- Qt5Qml. Install
qtdeclarative5-dev, or, without root, extract it to a sysroot (below). - Node 22 and the OLP UI's packages, for esbuild and OLP's TypeScript sources.
- Go 1.26.2, to build the OLP server for the Deck.
- The C++17 toolchain for
motion-server/v1, which the build uses for the pendant's Cartesian solver. sshaccess to the Deck, for deploying.
Qt5Qml without root#
The Makefile looks for a sysroot at ~/.rosie/qt5qml-sysroot, or wherever QML_SYSROOT points:
mkdir -p ~/.rosie/qt5qml-sysroot/debs && cd ~/.rosie/qt5qml-sysroot/debs
apt-get download qtdeclarative5-dev libqt5qml5 libqt5qmlmodels5 libqt5quick5
for d in *.deb; do dpkg-deb -x "$d" ..; doneBuild#
From the repository root:
(cd offline-programming/v1/ui && npm ci)
make -C steamdeck/real/v5 -j4 allThis builds three things in steamdeck/real/v5/build/:
| File | What it is |
|---|---|
rosie-pendant-v5 | The native Qt 5.15 app |
olp-core.js | OLP's program and machine logic, from offline-programming/v1/ui/src and steamdeck/real/v5/olp-core, bundled by esbuild as ES2016 for Qt's engine |
robot-v4-cartesiand | The Cartesian solver the OLP server uses, built from motion-server/v1 |
The bundle depends on every non-test .ts file under OLP's ui/src, so a change to OLP rebuilds it. That is how the pendant and the desktop stay one implementation.
Test#
make -C steamdeck/real/v5 check| Check | What it covers |
|---|---|
session.test.ts, machine.test.ts | The pendant's session and machine logic, under Node |
core-check | The built olp-core.js inside Qt's JavaScript engine, as the app runs it |
capture-check | The app's C++ capture TCP pose against OLP's own poses, for both robot descriptions |
view-check | Offscreen: the input interlock, display kinematics, description identity and both robots' mesh sets |
Run it on the workstation#
Start an OLP server on port 8794 (the quickstart does), then:
cd steamdeck/real/v5
LD_LIBRARY_PATH=~/.rosie/qt5qml-sysroot/usr/lib/x86_64-linux-gnu \
build/rosie-pendant-v5 --windowed --robots ../../../robot_description/robotsLeave out LD_LIBRARY_PATH if Qt5Qml is installed system-wide.
| Option | Default | Description |
|---|---|---|
--olp <origin> | http://127.0.0.1:8794 | The OLP server the pendant fronts |
--bundle <path> | <app dir>/olp-core.js | The OLP logic bundle |
--robots <dir> | <app dir>/../olp/robot_description/robots | Robot descriptions, for the 3D view |
--programs <dir> | ~/Rosie programs | The folder for OPEN and SAVE AS |
--windowed | full screen | Run in a desktop window |
--snapshot <prefix> | Render every page at 1280×800 to <prefix>-<n>.png after 3 s, then exit |
Package#
steamdeck/real/v5/package.sh # the app and the OLP tree
steamdeck/real/v5/package.sh --with-tesseract-env # also the Tesseract pixi environment (about 1 GB)package.sh runs make all, builds the OLP server for Linux x86-64, and stages steamdeck/real/v5/build/package/RosiePendantV5:
| Path | Contents |
|---|---|
run.sh, start-olp.sh, controller.vdf | The launcher, the OLP server's start script, and the Steam Input layout |
bin/ | rosie-pendant-v5, olp-core.js, robot-v4-cartesiand |
lib/ | libassimp.so.5, libdraco.so.4 and libminizip.so.1 from the build host, with their Debian copyright files. SteamOS ships Qt 5.15 but not Assimp. |
olp/ | The files of offline-programming/v1, motion-server/v1, robot_description, tesseract/v1, weld_planner/v1, cadquery/v1, and rt-core/config/{cells,machines,drives}, which the server needs to resolve remote cells. Also the server binary and a stub ui/dist/index.html, because serve refuses to start without one. |
SHA256SUMS | A hash of every file except the Tesseract environment |
Pass --with-tesseract-env on the first deploy, and again whenever tesseract/v1/pixi.lock changes. The OLP server needs that environment.
package.sh adds the ~/.rosie toolchain directories to the front of PATH. If your Go and Node live elsewhere, have them on PATH already.
The package never contains site files: the cell catalogue, the rt-core binding, planner.env or credentials.
Deploy#
Exit the pendant on the Deck first. Then, with your Deck's address:
steamdeck/real/v5/deploy.sh deck@rosie-deck.localThe optional second argument is the directory on the Deck. It defaults to devkit-game/RosiePendantV5 in the deck user's home. deploy.sh:
- refuses while the pendant or its
rosie-v5-olpunit is running, so nothing that holds a machine grant is replaced underneath it - removes the files of the retired browser kiosk from the app directory
- copies the package over
ssh - checks every staged hash on the Deck with
sha256sum -c SHA256SUMS, and printsdeploy: all staged hashes match
Site files on the Deck are left alone.
Add it to Steam#
- Add
run.shas a non-Steam game (or devkit) shortcut. - Set
controller.vdfas that shortcut's Steam Input layout. It maps the rear buttons L4, L5, R4 and R5 to F1, F2, F3 and F4, makes the right trackpad an absolute mouse, and makes the left trackpad scroll. See Pendant controls.
run.sh:
- starts
start-olp.shas the systemd user unitrosie-v5-olp, unless it is already running - waits up to 30 s for
http://127.0.0.1:8794/api/offline-programming/v1/health - starts the app full screen, with Steam's
LD_PRELOADandLD_LIBRARY_PATHremoved,LD_LIBRARY_PATHset to the package'slib/,QT_QPA_PLATFORM=xcband a scale factor of 1 - stops the unit when the app exits. The server's shutdown stops any machine it armed before it releases control.
Arguments to run.sh go to the app. The server's log is journalctl --user -u rosie-v5-olp.
Site files#
Put these beside run.sh on each Deck. They are never committed and never packaged:
| File | Read by | Contents |
|---|---|---|
olp-cells.json | OLP server, as OFFLINE_PROGRAMMING_CELLS | The cell catalogue: which cells the CELL page lists. See Connect to a cell and run a program. |
olp-rt-core.json | OLP server, as OFFLINE_PROGRAMMING_RT_CORE_CONFIG | The server-only rt-core backend configuration, for a local simulation entry |
planner.env | start-olp.sh, if present | Where the weld planner is, and how to run the seam worker |
client credentials (*.pem) | OLP server, through the catalogue | The mutual-TLS credentials for remote cells, named by the catalogue. See Remote access (mTLS). |
start-olp.sh also sets OFFLINE_PROGRAMMING_EXECUTION_BACKEND=rt_core, OFFLINE_PROGRAMMING_JOG_BACKEND=rt_core and the solver path, and starts offline-programming-linux serve --listen 127.0.0.1:8794 --enable-local-simulator. It leaves ROSIE_RT_* unset on purpose: OLP's disconnected local jog would otherwise take the simulation adapter's only controller slot and lock the pendant out.
planner.env#
Planning and Load both need a weld planner on a workstation the Deck can reach. Every plan also runs the seam worker once on the Deck, to pack the .weldplan. The package ships the seam worker's sources but no pixi environment. Packing uses only the Python standard library, so the Deck's system Python can run it:
OFFLINE_PROGRAMMING_WELD_PLANNER_MOTION_ORIGIN=http://planner.local:8796
SEAM_WORKER_PYTHON=/usr/bin/python3
# Spare workers preload OpenCASCADE, which the system Python does not have.
SEAM_WORKER_SPARES=0Without an origin, the RUN page shows the server's refusal and nothing is planned or loaded. Without SEAM_WORKER_PYTHON and without pixi on the Deck, planning fails because the seam worker cannot start. The alternative is pixi on the Deck and pixi install -e default in olp/weld_planner/v1.
Warning
The weld planner must listen on the network for the Deck to reach it, and it has no authentication. Firewall port 8796 so that only the Deck and your own machine can reach it. See Bind it safely.
A complete plan, Load and Play from the Deck against the weld planner has not been qualified.