Running Recipes¶
One of the things that makes EMOS satisfying to work with is that a recipe is just a Python script. A complete robot behavior – the components, the ML models, and the topics that wire them together – fits in a single file that you can run with python recipe.py. No build step, no launch-file XML, no per-component configuration sprawl. The same file then runs unchanged on a deployed robot via emos run, with pre-launch sensor checks, persistent logs, and a dashboard card layered on top automatically.
Once you have a recipe in hand – whether you wrote it from a tutorial or pulled one with emos pull – there are two distinct flows: one tuned for the developer who is still shaping the recipe, and one tuned for the end user (or your future self, on a deployed robot) who just wants to launch a finished recipe and watch it work.
Development vs production¶
When you are developing a recipe – writing it, tweaking parameters, debugging a bad output – you want the tightest edit-run-debug loop possible. When somebody runs a finished recipe in production, they want sensor checks, persistent logs, and a dashboard they can manage from a browser without ever opening a terminal. EMOS gives you one flow for each.
Development |
Production |
|
|---|---|---|
Who it’s for |
The recipe author iterating on the script. |
An operator – often a non-developer – running a finished recipe on a robot. |
How to launch |
|
|
Environment setup |
You source ROS / activate the EMOS env yourself. |
The CLI activates the right environment for your install mode (Native / Pixi / Container). |
Pre-launch checks |
None – the script crashes if a sensor topic is missing. |
Pre-flight check that every sensor topic the recipe declares is actually publishing. |
Logs |
Stream to the terminal. No retention. |
Stream to the terminal and persist to |
Dashboard visibility |
The recipe doesn’t show up on the dashboard. |
A card on the Recipes → Installed tab, ready for an operator to launch from the browser. |
In short: ship the script with python while you’re shaping it; drop it into ~/emos/recipes/ once it’s solid and hand it to an operator (or your future self) to run via emos run or the dashboard.
Promoting a recipe to production¶
Moving a recipe from development to production – so an operator can launch it via emos run or the dashboard – is drop-in: there is no registration step, no plugin manifest to declare. The CLI and the dashboard both look at ~/emos/recipes/. Anything you put there is automatically picked up.
1. Move the recipe into ~/emos/recipes/¶
mkdir -p ~/emos/recipes/my_recipe
cp recipe.py ~/emos/recipes/my_recipe/recipe.py
The directory must be named the same as what you’ll pass to emos run. The file inside must be called recipe.py.
2. (Optional) Add a manifest.json¶
{
"name": "My Recipe",
"description": "Does the thing.",
"zenoh_router_config_file": "my_recipe/zenoh_config.json5"
}
Field |
Purpose |
|---|---|
|
Display name shown on the dashboard’s recipe card. Falls back to the directory name. |
|
Short blurb shown on the recipe detail page. |
|
Path (relative to |
The manifest is entirely optional – omit it and the recipe still runs.
Note
Sensor requirements are auto-extracted from recipe.py by parsing Topic(name=..., msg_type=...) declarations. You do not list them in the manifest.
3. Verify the CLI sees it¶
emos ls # the recipe directory should be listed
emos info my_recipe # inferred sensor topics, suggested drivers
4. Launch¶
emos run my_recipe
Open the dashboard in a browser: the recipe now shows up on the Recipes → Installed tab. From there, an operator can click Run to launch it directly from the browser, with the live log console and run history filling in as the recipe progresses. The terminal path stays available too – emos run my_recipe does the same execution and writes the same log file to ~/emos/logs/, just driven from a shell instead of the GUI.
Install-mode reference¶
The two flows behave differently across install modes. The production flow is mode-aware out of the box; in development you handle the environment yourself.
Mode |
Development ( |
Production ( |
|---|---|---|
Native |
Works after |
Works. |
Pixi |
From the EMOS repo directory: |
Works – the CLI activates the pixi env and sources the colcon overlay for you. |
Container (OSS) |
Does not work from the host shell. The |
Works – the CLI runs the recipe inside the container. |
Tip
The dashboard’s in-browser live log console and run history light up when you launch a recipe from the dashboard’s Run button – the daemon owns the run end-to-end and streams progress straight to the browser. Terminal launches (emos run or direct python) are equally valid; they stream output to your shell and write the same log file to ~/emos/logs/. Pick the surface that fits the moment: dashboard for hands-off monitoring from a browser, terminal when you’re already in one.
Where logs go¶
Every emos run invocation writes to ~/emos/logs/<recipe>_<YYYYMMDD_HHMMSS>.log. The same log is streamed to your terminal during a foreground run, and to the dashboard’s run console when started from there. Direct python recipe.py runs do not write to ~/emos/logs/ – redirect manually if you want the file.
See also
Dashboard – pairing, recipes tab, run console.
EMOS CLI – the full command reference, including
emos runflags (--rmw,--skip-sensor-check).Troubleshooting – sensor verification failures and mode-specific gotchas.