.. # Copyright (c) 2021-2026, Arm Limited. # # SPDX-License-Identifier: Apache-2.0 ############## Architecture ############## The safety island hosts the Autoware trajectory follower and talks to the main compute over DDS. This page describes how the pieces fit together at runtime on the Zephyr backend. The controller logic is shared across backends via a platform abstraction layer (``actuation_module/include/platform/``); a FreeRTOS POSIX simulator uses the same core with a different backend under ``include/platform/freertos/``. ************************ Two-domain DDS topology ************************ The main compute and the safety island live on separate CycloneDDS domains: - **Domain 1** — Autoware main compute (full ROS 2 graph). - **Domain 2** — Safety island (Zephyr + CycloneDDS, no ROS 2 runtime). A ``ros2 domain_bridge`` instance running on the main compute forwards exactly the topics the safety island needs between the two domains. The list is fixed in ``demo/bridge/bridge-config.yaml``. .. mermaid:: graph LR subgraph "Main compute (domain 1)" Autoware[Autoware Universe] Bridge[domain_bridge] end subgraph "Safety island (domain 2)" Firmware[Zephyr firmware
Controller Node] end Autoware -- trajectory, odometry,
steering, accel,
operation_mode --> Bridge Bridge -- forwarded topics --> Firmware Firmware -- control_cmd --> Bridge Bridge -- control_cmd --> Autoware Full topic list with message types: :doc:`topics`. Both domains are configured through ``demo/cyclonedds.xml``. The key tunables are shared across the two domains: - ``MaxMessageSize = 1400B`` — matches the safety-island MTU. - ``AllowMulticast = spdp`` — SPDP discovery over multicast, application traffic unicast. - Domain 2 pins its interface to ``tap0`` (the VPN tunnel). If your VPN creates a different interface, update this file — see :doc:`/user_guide/troubleshooting`. ********************** Controller node ********************** The entry point is ``actuation_module/src/main.cpp``. It brings up DHCP, optionally syncs time via SNTP (``CONFIG_ENABLE_SNTP``), and instantiates a single ``Controller`` node. The controller is defined in ``actuation_module/src/autoware/autoware_trajectory_follower_node/src/controller_node.cpp``. At construction the controller: 1. Declares a control period. Default **150 ms**. Upstream Autoware uses 30 ms; the safety island runs slower because the MPC solve is the dominant cost on a Cortex-R class core. 2. Declares a stale-output timeout of **0.5 s**. If the last control command produced by either the lateral or longitudinal controller is older than this, the controller refuses to publish it (``isTimeOut`` in ``controller_node.cpp``). Missing inputs are handled separately: ``processData`` skips the tick and logs a throttled "Waiting for ..." message. 3. Instantiates the lateral controller (``mpc`` — only mode currently supported) and the longitudinal controller (``pid``). 4. Creates five subscriptions and three publishers. See :doc:`topics`. 5. Starts a periodic timer that runs ``callbackTimerControl`` every ``ctrl_period``. **************** RTOS primitives **************** The ``common`` abstraction layer under ``actuation_module/include/common/`` hides Zephyr specifics behind small interfaces: - ``node/node.hpp`` — thread and timer wrappers. Uses the pthread API (``CONFIG_POSIX_API=y``) on top of Zephyr-allocated stacks; the caller still provides stack memory via ``K_THREAD_STACK_DEFINE``. - ``dds/`` — CycloneDDS publisher/subscriber templates with ROS 2 topic-name translation. - ``clock/clock.hpp`` — monotonic clock, optional SNTP-backed wall clock. - ``logger/logger.hpp`` — throttled logging. This layering means replacing the RTOS backend is a question of swapping these four headers, not rewriting the controller. The FreeRTOS backend under ``include/platform/freertos/`` demonstrates this in practice. **************** Build pipeline **************** ``build.sh`` drives the whole pipeline: 1. Compiles the CycloneDDS host tools (IDLC) under ``build/cyclonedds_host``. 2. Invokes ``west build`` with the selected target (``fvp_baser_aemv8r_smp`` or ``s32z270dc2_rtu0_r52@D``). 3. Produces ``build/actuation_module/zephyr/zephyr.elf``. IDL messages under ``actuation_module/src/autoware/autoware_msgs/`` are compiled to C by IDLC and linked into the firmware. The Autoware C++ packages (``autoware_mpc_lateral_controller``, etc.) are compiled directly against Zephyr; there is no ROS 2 runtime on the safety island.