Skip to content

Commit 01161bb

Browse files
authored
feat(ansible): add acados role (#6835)
Signed-off-by: Mete Fatih Cırıt <mfc@autoware.org>
1 parent a06b188 commit 01161bb

File tree

7 files changed

+203
-0
lines changed

7 files changed

+203
-0
lines changed

ansible/playbooks/openadkit.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
when: module == 'all' and install_devel=='y'
3131

3232
# Module specific dependencies
33+
- role: autoware.dev_env.acados
34+
when: module == 'all'
3335
- role: autoware.dev_env.geographiclib
3436
when: module == 'perception-localization' or module == 'all'
3537
- role: autoware.dev_env.cuda
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- name: Setup acados
2+
hosts: localhost
3+
connection: local
4+
roles:
5+
- role: autoware.dev_env.acados

ansible/playbooks/universe.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
when: rosdistro == 'humble'
5252

5353
# Autoware module dependencies
54+
- role: autoware.dev_env.acados
5455
- role: autoware.dev_env.geographiclib
5556
- role: autoware.dev_env.cuda
5657
when: prompt_install_nvidia == 'y'

ansible/roles/acados/README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Setup acados
2+
3+
Installs [acados](https://github.com/acados/acados), a fast and embedded solver for nonlinear optimal control, from source.
4+
5+
## What it does
6+
7+
1. Clones the acados repository (shallow) to `/opt/acados`
8+
2. Initializes submodules (shallow)
9+
3. Builds and installs acados in-tree with `QPOASES` and position-independent code enabled
10+
4. Downloads the [tera renderer](https://github.com/acados/tera_renderer) binary to `/opt/acados/bin/t_renderer` (supports `x86_64` and `aarch64`)
11+
5. Creates a Python virtual environment at `/opt/acados/.venv`
12+
6. Installs `casadi`, `sympy`, and `acados_template` (editable) in the venv
13+
7. Adds `CMAKE_PREFIX_PATH`, `ACADOS_SOURCE_DIR`, and `LD_LIBRARY_PATH` to the user's `.bashrc`
14+
15+
## Installation ⭐
16+
17+
Install ansible following the instructions in the [ansible installation guide](../../README.md#ansible-installation).
18+
19+
```bash
20+
cd ~/autoware # The root directory of the cloned repository
21+
ansible-galaxy collection install -f -r "ansible-galaxy-requirements.yaml"
22+
```
23+
24+
This step should be repeated when the ansible directory is updated.
25+
26+
```bash
27+
ansible-playbook autoware.dev_env.setup_acados --ask-become-pass
28+
```
29+
30+
## Directory layout
31+
32+
After running, `/opt/acados` contains both the source tree and installed artifacts:
33+
34+
```text
35+
/opt/acados/
36+
├── .venv/ # Python virtual environment
37+
├── bin/t_renderer # tera renderer binary
38+
├── build/ # cmake build directory
39+
├── cmake/ # acadosConfig.cmake (used by find_package)
40+
├── lib/ # built shared libraries
41+
├── include/ # headers
42+
├── interfaces/ # acados_template Python package (installed to .venv)
43+
├── external/ # submodules (qpoases, etc.)
44+
└── ... # remaining source tree
45+
```
46+
47+
## Usage in CMake
48+
49+
After provisioning, any CMake project can use acados with:
50+
51+
```cmake
52+
find_package(acados REQUIRED)
53+
target_link_libraries(your_target PRIVATE acados)
54+
```
55+
56+
No additional path configuration is needed, `CMAKE_PREFIX_PATH` is set via `.bashrc`.
57+
58+
## Using the Python interface during `colcon build`
59+
60+
If your ROS 2 package generates acados C code at build time (e.g. via a Python script that uses `acados_template` and `casadi`), you need to source the venv so the code-generation script can find the installed packages.
61+
62+
The Ansible role already exports `ACADOS_SOURCE_DIR` and `LD_LIBRARY_PATH` in `.bashrc`, so those are available to `colcon build` as long as you've sourced your shell. The only extra step is pointing CMake at the venv Python so `casadi`, `sympy`, and `acados_template` are importable:
63+
64+
```cmake
65+
find_program(ACADOS_PYTHON NAMES python3 PATHS $ENV{ACADOS_SOURCE_DIR}/.venv/bin NO_DEFAULT_PATH)
66+
67+
add_custom_command(
68+
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/acados_solver.c
69+
COMMAND ${ACADOS_PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_solver.py
70+
--output-dir ${CMAKE_CURRENT_BINARY_DIR}/generated
71+
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_solver.py
72+
COMMENT "Generating acados solver C code"
73+
)
74+
```
75+
76+
The generated C code is then compiled as part of your normal CMake target, no Python dependency at runtime.
77+
78+
## Requirements
79+
80+
- CMake
81+
- A C compiler (gcc/clang)
82+
- `make`
83+
- `git`
84+
- `python3` with `venv` module (`python3-venv` on Ubuntu)
85+
86+
## Idempotency
87+
88+
The role is safe to run multiple times. The git clone resets any local modifications, and the build steps re-run on each invocation to ensure correctness when the version is changed. The `.bashrc` entries use `lineinfile` with regex matching to avoid duplication. The venv creation is skipped if it already exists (`creates` guard).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
acados_version: v0.5.3
2+
acados_tera_renderer_version: v0.2.0
3+
acados_pip_packages:
4+
- casadi
5+
- sympy

ansible/roles/acados/meta/main.yaml

Whitespace-only changes.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
- name: Clone acados repository (shallow) with submodules
2+
become: true
3+
ansible.builtin.git:
4+
repo: https://github.com/acados/acados.git
5+
dest: /opt/acados
6+
version: "{{ acados_version }}"
7+
depth: 1
8+
force: true
9+
recursive: true
10+
11+
- name: Create build directory
12+
become: true
13+
ansible.builtin.file:
14+
path: /opt/acados/build
15+
state: directory
16+
mode: "0755"
17+
18+
# cspell:ignore DACADOS
19+
- name: Configure acados with CMake
20+
become: true
21+
ansible.builtin.command:
22+
cmd: >
23+
cmake
24+
-DACADOS_WITH_QPOASES=ON
25+
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
26+
..
27+
chdir: /opt/acados/build
28+
changed_when: false
29+
30+
- name: Build and install acados
31+
become: true
32+
ansible.builtin.command:
33+
cmd: make install -j{{ ansible_processor_vcpus }}
34+
chdir: /opt/acados/build
35+
changed_when: false
36+
37+
- name: Create acados bin directory
38+
become: true
39+
ansible.builtin.file:
40+
path: /opt/acados/bin
41+
state: directory
42+
mode: "0755"
43+
44+
- name: Set tera renderer architecture
45+
ansible.builtin.set_fact:
46+
acados_tera_arch: "{{ {'x86_64': 'amd64', 'aarch64': 'arm64'}[ansible_architecture] }}"
47+
48+
- name: Download tera renderer
49+
become: true
50+
ansible.builtin.get_url:
51+
url: https://github.com/acados/tera_renderer/releases/download/{{ acados_tera_renderer_version }}/t_renderer-{{ acados_tera_renderer_version }}-linux-{{ acados_tera_arch }}
52+
dest: /opt/acados/bin/t_renderer
53+
mode: "0755"
54+
55+
# ---------- Python virtual environment ----------
56+
57+
- name: Create acados Python virtual environment
58+
become: true
59+
ansible.builtin.command:
60+
cmd: python3 -m venv /opt/acados/.venv
61+
creates: /opt/acados/.venv/bin/activate
62+
63+
- name: Upgrade pip inside the virtual environment
64+
become: true
65+
ansible.builtin.command:
66+
cmd: /opt/acados/.venv/bin/pip install --upgrade pip
67+
changed_when: false
68+
69+
- name: Install Python packages in acados venv
70+
become: true
71+
ansible.builtin.command:
72+
cmd: /opt/acados/.venv/bin/pip install {{ acados_pip_packages | join(' ') }}
73+
changed_when: false
74+
75+
- name: Install acados_template (editable) in acados venv
76+
become: true
77+
ansible.builtin.command:
78+
cmd: /opt/acados/.venv/bin/pip install -e /opt/acados/interfaces/acados_template
79+
changed_when: false
80+
81+
# ---------- Environment (.bashrc) ----------
82+
83+
- name: Add acados CMAKE_PREFIX_PATH to .bashrc
84+
ansible.builtin.lineinfile:
85+
path: "{{ ansible_env.HOME }}/.bashrc"
86+
line: export CMAKE_PREFIX_PATH="/opt/acados:${CMAKE_PREFIX_PATH}"
87+
regexp: CMAKE_PREFIX_PATH.*acados
88+
state: present
89+
90+
- name: Add ACADOS_SOURCE_DIR to .bashrc
91+
ansible.builtin.lineinfile:
92+
path: "{{ ansible_env.HOME }}/.bashrc"
93+
line: export ACADOS_SOURCE_DIR="/opt/acados"
94+
regexp: ACADOS_SOURCE_DIR
95+
state: present
96+
97+
- name: Add acados LD_LIBRARY_PATH to .bashrc
98+
ansible.builtin.lineinfile:
99+
path: "{{ ansible_env.HOME }}/.bashrc"
100+
line: export LD_LIBRARY_PATH="/opt/acados/lib:${LD_LIBRARY_PATH}"
101+
regexp: LD_LIBRARY_PATH.*acados
102+
state: present

0 commit comments

Comments
 (0)