# The Startup Process of the Robot and Application Management

This page explains which applications are started during the boot process of the robot, how to start/stop/restart them, and how to configure the boot process.

## The Boot Process

When the robot boots up, the software required for its operation starts automatically. The startup process can be monitored in the Web user interface.

The startup manager will search for ROS packages in the specified directories. If a package is found in one of the directories, it will ignore the same package in the directories that come after it in the list.

- `/home/pal/deployed_ws` — this is where your own code is stored (see *Deploying ROS 2 packages on your robot* to know more)
- `/opt/pal/$PAL_DISTRO`
- `/opt/ros/$ROS_DISTRO`

### Adding a New Workspace

To change the workspace source procedure, for example to add a new ROS workspace, the file at `/usr/bin/init_pal_env.sh` can be modified to adapt the environment of the startup process.

## The PAL Module Manager

The PAL Module Manager is the process that manages the startup of the robot and defines which applications are started. This is done with **Modules** and **Module sets**. A Module defines how an application is launched. A Module set defines which of these modules are launched on startup.

### Modules

A module represents an execution unit plus some parameters that detail how to and when to run it; the expected outcome may also be specified. Modules are set up using `yaml` files.

Three ways of running applications are supported. This is the only mandatory module parameter and only one may be specified:

- `run` — executes ROS 2 nodes. Works in the same way as the command `ros2 run`.
- `launch` — executes ROS 2 launch files. Works in the same way as the command `ros2 launch`.
- `exec` — executes commands directly.

#### Module States

Modules can be in different states:

| State | Description |
|---|---|
| `LOADED` | Module is loaded and ready to start. |
| `WAITING` | Module has been started but it is waiting for dependencies. |
| `RUNNING` | Module is loaded and running. |
| `FINISHED` | Module finished execution on its own. This was an expected outcome. |
| `TERMINATED` | Module was stopped and ended execution by sending a termination signal. |
| `KILLED` | Module was stopped but failed to end execution; it was force-stopped with a kill signal. |
| `CRASHED` | Module ended execution unexpectedly. |

#### Module Parameters

There are additional optional parameters that can be used to modify the behavior of the module:

| Parameter | Default | Description |
|---|---|---|
| `after` | (empty) | Do not start the module until the specified modules are running. |
| `waits` | (empty) | Wait until the specified modules are finished before starting. The modules specified here must set `finishes: True`. |
| `dependencies` | (empty) | A list of diagnostics the module will wait for to be in OK or WARN status before starting. |
| `finishes` | `false` | Specify whether a module is expected to finish execution on its own once started. |
| `termination_timeout` | `5s` | Time to wait before sending a kill signal when trying to stop a module. |
| `enable_unbuffer` | `true` | When enabled, output is printed as soon as it is generated rather than buffered. Preferred for logging. |
| `enable_multilog` | `true` | Enables log rotation — the log file is switched after it reaches a certain size. Preferred for applications that log large amounts of data. |

#### Module Example

Modules are specified in `yaml` files. An example file for a single module:

```yaml
foo_module:
  run: "foo_package foo_node"
```

Multiple modules per `yaml` file can be specified:

```yaml
foo_module:
  run: "foo_package foo_node"

bar_module:
  launch: "bar_package bar.launch.py"
  dependencies: ["Foo Feature"]
```

The modules can make use of robot info parameters to make them more generic. These parameters are kept by the `robot_info_publisher` node. Use `@parameter_name@` and the Module Manager will do the replacement at runtime. The `play_motion2` module is a good example:

```yaml
play_motion2:
  launch: "@robot_type@_bringup @robot_type@_play_motion2.launch.py
    arm_type:=@arm_type@
    base_type:=@base_type@
    end_effector:=@end_effector@
    ft_sensor:=@ft_sensor@"
```

### Module Sets

Module sets define which modules are started when starting the robot. Just like modules, module sets are defined in `yaml` files. Sets are just a list of modules.

Here is a sample module set yaml file:

```yaml
my_set:
  - foo_module
  - bar_module
```

Multiple module sets per yaml file can be specified:

```yaml
my_set:
  - foo_module
  - bar_module

my_other_set:
  - my_module
```

### Virtual Groups

Virtual groups define a group of modules that can be managed as a group. Just like module sets, virtual groups are set up using yaml files and are just a list of modules.

The key difference with module sets is that module sets define modules that are started automatically, while virtual groups allow you to manage a group of modules as a single unit.

Here is a sample virtual group yaml file:

```yaml
my_virtual_group:
  - foo_module
  - bar_module
```

## Startup Customization

The startup process can be customized by registering new modules and module sets. Registering is done in the `CMakeLists.txt` of a ROS package. For detailed instructions on how to create new modules and module sets, see the tutorial *Configure an application to launch at start-up*.

```cmake
find_package(pal_module_cmake QUIET)

# Registering a module
if(pal_module_cmake_FOUND)
  pal_register_modules(
    module/my_custom_module.yaml
  )
endif()

# Registering a module set
if(pal_module_cmake_FOUND)
  pal_register_module_sets(
    module/my_custom_module_set.yaml
  )
endif()

# Registering a virtual group
if(pal_module_cmake_FOUND)
  pal_register_virtual_groups(
    module/my_custom_virtual_group.yaml
  )
endif()
```

## Startup Command Line Tools

To interact with the Module Manager there are command line interfaces available. The commands are listed below.

### Module Commands

- `pal module list` — lists all the modules that are loaded in the robot.
- `pal module info <module-name>` — prints information about the selected module. Pressing TAB will list the modules whose information can be seen.
- `pal module show <module-name>` — prints the content of the selected module file. Pressing TAB will list the modules whose content can be seen.
- `pal module start <module-name>` — starts a module in the robot. Pressing TAB will list the applications that can be started.
- `pal module stop <module-name>` — stops a module in the robot. Pressing TAB will list the applications that can be stopped.
- `pal module restart <module-name>` — restarts a module in the robot. Pressing TAB will list the applications that can be restarted.
- `pal module log <module-name>` — prints the name and path of the log file of the selected application. Using `pal module log <module-name> cat` will directly print the log file contents.
- `pal module enable <module-name>` — enables a module so it will be run on the next start of the module manager. This does not immediately start the module (use `pal module start` for that).
- `pal module disable <module-name>` — disables a module so it will not be run on the next start of the module manager. This does not immediately stop the module (use `pal module stop` for that).

### Module Set Commands

- `pal module_set list` — lists all the module sets that are loaded in the robot.
- `pal module_set info <module-set-name>` — shows practical information about the selected module set.
- `pal module_set show <module-set-name>` — shows the content of the file that defines the selected module set.

### Virtual Group Commands

- `pal virtual_group list` — lists all loaded modules along with their current status in each virtual group.
- `pal virtual_group status <virtual-group-name>` — prints all loaded modules along with their current status in the specified virtual group.
- `pal virtual_group info <virtual-group-name>` — prints information about a virtual group.
- `pal virtual_group show <virtual-group-name>` — displays the content of the file that defines a virtual group.
- `pal virtual_group start <virtual-group-name>` — starts all modules in a virtual group.
- `pal virtual_group stop <virtual-group-name>` — stops all modules in a virtual group.
- `pal virtual_group restart <virtual-group-name>` — restarts all modules in a virtual group.
- `pal virtual_group enable <virtual-group-name>` — enables a virtual group so all its modules will be started when the module manager starts.
- `pal virtual_group disable <virtual-group-name>` — disables a virtual group so its modules will not be started when the module manager starts.

### Module Manager Commands

- `pal module_manager start` — starts the module manager.
- `pal module_manager stop` — stops the module manager.
- `pal module_manager restart` — restarts the module manager.
- `pal module_manager enable` — enables the module manager; it will be started on boot.
- `pal module_manager disable` — disables the module manager; it will not be started on boot.
- `pal module_manager status` — shows the current status of the service that manages the module manager.
- `pal module_manager log` — shows the logs of the module manager.

```{caution}
Disabling the module manager will prevent the robot from starting its applications on boot. This is not recommended.
```

```{note}
The module manager commands are convenience wrappers around `systemctl` and `journalctl` calls.
```

## Module Manager ROS API

The command line interface uses services provided by the Module Manager to interact with it. These services are available in the `/module_manager_node/` namespace.

| Service | Description |
|---|---|
| `list_modules` | Lists all loaded modules. For each module its name and status is reported. |
| `get_module_log_file_path` | Reports the log file path of a given module. The file may be empty or not exist if the module has not been started yet. |
| `get_module_info` | Reports name, status, log file path, list of dependencies, and file paths that define the module. |
| `start_module` | Starts a non-running module. Can optionally ignore `after` and `dependencies` parameters to force start. |
| `stop_module` | Stops a running module. |
| `enable_module` | Enables a module. The module will be started on boot. |
| `disable_module` | Disables a module. The module will not be started on boot. |
| `list_module_sets` | Lists all module sets. For each set the contained list of modules is reported. |
| `configure_module_manager` | Configures or reconfigures the module manager. Useful to reload module configuration changes or add new modules/sets without restarting the manager. |
| `start_module_manager` | Starts the module manager. |
| `stop_module_manager` | Stops the module manager. |
| `list_virtual_groups` | Lists all virtual groups. For each group the contained list of modules is reported. |
| `get_virtual_group_info` | Reports name, modules, and file paths that define the virtual group. |
| `start_virtual_group` | Starts all modules in a virtual group. |
| `stop_virtual_group` | Stops all modules in a virtual group. |
| `enable_virtual_group` | Enables a virtual group. Its modules will be started when the module manager is started. |
| `disable_virtual_group` | Disables a virtual group. Its modules will not be started when the module manager is started. |

## See Also

- [Application Management — PAL Robotics Documentation](https://docs.pal-robotics.com/25.01/management/application-management.html)
