# Recipes Launcher
**Recipes: One script to rule them all.**
The [`Launcher`](../apidocs/ros_sugar/ros_sugar.launch.launcher.md) is your entry point to the Sugarcoat ecosystem. It provides a clean, Pythonic API to configure, spawn, and orchestrate your ROS2 nodes without writing XML or complex launch files.
Under the hood, every Launcher spawns an internal **Monitor** node. This hidden "Brain" is responsible for tracking component health, listening for events, and executing the orchestration logic.
## Execution Architectures
The Launcher supports two execution modes, configured via the `multi_processing` flag.
::::{tab-set}
:::{tab-item} Multi-Threaded
:sync: threaded
**Default for Debugging** (`multi_processing=False`)
All components run in the same process as the Launcher and Monitor.
* **Pros:** Fast startup, shared memory, easy debugging (breakpoints work everywhere).
* **Cons:** The Global Interpreter Lock (GIL) can bottleneck performance if you have many heavy nodes.
```{figure} /_static/images/diagrams/multi_threaded_dark.png
:class: dark-only
:alt: multi-threaded architecture
:align: center
```
```{figure} /_static/images/diagrams/multi_threaded_light.png
:class: light-only
:alt: multi-threaded architecture
:align: center
Multi-threaded Execution
```
:::
:::{tab-item} Multi-Process
:sync: process
**Production Mode** (`multi_processing=True`)
Each component runs in its own isolated process. The Monitor the still runs in the same process as the Launcher.
* **Pros:** True parallelism, crash isolation (one node crashing doesn't kill the system).
* **Cons:** Higher startup overhead.
```{figure} /_static/images/diagrams/multi_process_dark.png
:class: dark-only
:alt: multi-process architecture
:align: center
```
```{figure} /_static/images/diagrams/multi_process_light.png
:class: light-only
:alt: multi-process architecture
:align: center
Multi-process Execution
```
:::
::::
## Launcher Features
### 1. Package & Component Loading
You can add components from your current script or external packages.
```python
# Add from an external entry point (for multi-process separation)
launcher.add_pkg(
package_name="my_robot_pkg",
components=[vision_component] # Pass config/events here
multiprocessing=True
)
```
### 2. Lifecycle Management
Sugarcoat components are Lifecycle nodes. The Launcher handles the transition state machine for you.
* `activate_all_components_on_start=True`: Automatically transitions all nodes to **Active** after spawning.
### 3. Global Fallbacks
Define "Catch-All" policies for the entire system.
```python
# If ANY component reports a crash, restart it.
launcher.on_component_fail(action_name="restart")
```
### 4. Events Orchestration
Pass your events/actions dictionary **once** to the `Launcher` and it will handle delegating the event monitoring to the concerned component.
## Complete Usage Example
```python
from ros_sugar.core import BaseComponent, Event, Action
from ros_sugar.actions import log, restart
from ros_sugar.io import Topic
from ros_sugar import Launcher
# 1. Define Components
# (Usually imported from your package)
driver = BaseComponent(component_name='lidar_driver')
planner = BaseComponent(component_name='path_planner')
# Set Fallback Policy
# If the driver crashes, try to restart it automatically
driver.on_component_fail(fallback=restart(component=driver))
# 2. Define Logic for Events
battery = Topic(name="/battery", msg_type="Float32")
low_batt_evt = Event(battery.msg.data < 15.0)
log_action = log(msg="WARNING: Battery Low!")
# 3. Initialize Launcher
launcher = Launcher(
config_file='config/robot_params.toml', # Can optionally pass a configuration file
activate_all_components_on_start=True,
multi_processing=True # Use separate processes
)
# 4. Register Components
# You can attach specific events to specific groups of components
launcher.add_pkg(
components=[driver, planner],
ros_log_level="error"
events_actions={low_batt_evt: log_action}
)
# 7. Launch!
# This blocks until Ctrl+C is pressed
launcher.bringup()
```
## The Monitor (Internal Engine)
:::{note}
The Monitor is configured automatically. You do not need to instantiate or manage it manually.
:::
The **Monitor** is a specialized, non-lifecycle ROS2 node that acts as the central management node.
**Responsibilities:**
1. **Custom Actions Execution:** Handles executing custom Actions defined in the recipe.
2. **Health Tracking:** Subscribes to the `/status` topic of every component.
3. **Orchestration:** Holds clients for every component's Lifecycle and Parameter services, allowing it to restart, reconfigure, or stop nodes on demand.
**Architecture:**
::::{tab-set}
:::{tab-item} Configuration
:sync: config
How the Launcher configures the Monitor with Events and Actions at startup.
```{figure} /_static/images/diagrams/events_actions_config_dark.png
:class: dark-only
:alt: Monitoring events diagram
:align: center
:scale: 70
```
```{figure} /_static/images/diagrams/events_actions_config_light.png
:class: light-only
:alt: Monitoring events diagram
:align: center
:scale: 70
Monitoring events
```
:::
:::{tab-item} Execution
:sync: exec
How the Monitor processes triggers and executes actions at runtime.
```{figure} /_static/images/diagrams/events_actions_exec_dark.png
:class: dark-only
:alt: An Event Trigger diagram
:align: center
:scale: 70
```
```{figure} /_static/images/diagrams/events_actions_exec_light.png
:class: light-only
:alt: An Event Trigger diagram
:align: center
:scale: 70
An Event Trigger
```
:::
::::