{{ name }}
====================

Welcome to this example of a 'LLM mission controller'. This template implements
the basic infrastructure to handle user input (using the ROS4HRI standard),
submit it to a LLM chatbot, and handle the result.

What are the next steps?


## Prerequisites

Before being able to use this supervisor, you need to install `ollama` and the
`ollama` python bindings (they are required for the `ollama_connector` node to work):

- install `ollama`: https://ollama.com/download
- download a LLM model. For instance: `ollama pull llama3.2:1b`
- start `ollama` as a server: `ollama server`

> Note: you can configure `ollama` to [start at startup](https://github.com/ollama/ollama/blob/main/docs/linux.md#adding-ollama-as-a-startup-service-recommended).

- install the `ollama` python bindings: `pip install ollama`


## Compile and install the mission controller

You need a ROS 2 environment to compile the template.

You can for instance use PAL Robotics public 'tutorials' Docker image:

```
> docker pull palrobotics/public-tutorials-alum-devel
> docker run -it --name ros2_sandbox \
             -v <path to your workspace>:/home/user/exchange/ws \
             palrobotics/public-tutorials-alum-devel bash
```

Then, simply run:

```
> cd /home/user/exchange/ws
> colcon build
> source install/setup.bash
```

You can now start your mission controller with:

```
> ros2 launch {{id}} {{id}}.launch.py
```

This launch file will also start the Ollama connector node and the 
'greet' task node.

## Testing

You can test the application from the terminal by publishing some input speech, and monitoring the
`/intents` topic for results.

In a second terminal, run:

```
ros2 topic echo /intents
```

> Note: you can open a new terminal in the same Docker image with:
> ```
> docker exec -it ros2_sandbox bash
> ```

Then (from a third terminal) let's pretend that a voice is heard by the robot:

```
ros2 topic pub -1 /humans/voices/tracked hri_msgs/msg/IdsList "ids: ['test_speaker']"
```

Then:

```
ros2 topic pub -1 /humans/voices/test_speaker/speech hri_msgs/msg/LiveSpeech "final: 'hello robot, what can you do for me?'"
```

You should now see intents being published, based on what the LLM chatbot has recognised.

## Customize your supervisor

By default, the template does not do anything useful. However, it demonstrates
how to use *intents* to trigger behaviours or react to events.

*Intents* are usually generated by the user. It can happen:
- through automatic perception (eg, someone approaches and seems to interact),
- through verbal interaction (eg, someone tells the robot to go somewhere)
- from other interactions, like a remote touchscreen (eg, someone presses
  a button to trigger a behaviour) or mobile app.

For this example, we are mostly interested in verbal interactions.

## Install on the robot

To install you app on the robot, you need to follow the following steps:

1. deploy your code to the robot using PAL's `deploy` tool.
2. install the webpages (if you are using any)

### Deploy the application controller to the robot

**To deploy the code to the robot, you have to run the following commands from
*inside* your PAL OS Developer Docker image**.

- from within the PAL OS Developer Docker image, go to root of the project
- run `ros2 run pal_deploy deploy --package {{ id }} {{ robot | lower
  }}-XXc` (replace `{{ robot | lower }}-XXc` by your actual robot)

You can now `ssh` onto the robot (`ssh pal@{{ robot | lower }}-XXc`, password
`pal`), and go to your project: `cd ~/deployed_ws/share/{{ id }}`

## Run your application

`ssh` onto the robot (`ssh pal@{{ robot | lower }}-XXc`, password `pal`).

There are several ways to run the application:

1. Automatically launch the app and transition to an active state:

`ros2 launch {{ id }} {{ id }}.launch.py`

2. Manually run your application:

`ros2 run {{ id }} run_app`

Since your application controller is a lifecycle node, you need to manage it
through the lifecycle tools. You can execute the following to transit the
mission controller as follows:

``ros2 lifecycle set /app_{{ id }} configure``
``ros2 lifecycle set /app_{{ id }} activate``

To stop it (but not reseting it's internal variables):
``ros2 lifecycle set /app_{{ id }} activate``

To stop it and clean it:
``ros2 lifecycle set /app_{{ id }} deactivate``
``ros2 lifecycle set /app_{{ id }} cleanup``


3. Automatically start your application at startup:

To make your application run at startup, uncomment the related lines in
`setup.py` and reinstall the package. You can then start, stop or view the logs
of the application as a module. See [Application
management](https://docs.pal-robotics.com/sdk-dev/management/application-management)
for more details. 


