ROS 2 Jazzy to Kilted Migration Guide (2026)

ROS 2 Jazzy to Kilted Migration Guide (2026)

ROS 2 Jazzy to Kilted Migration Guide (2026)

If you maintain a production robot fleet, the ROS 2 Jazzy to Kilted migration is, in the main, a controlled refactor rather than a rewrite. Jazzy Jalisco remains the current Tier-1 LTS distribution; Kilted Kaiju is the non-LTS interim release that shipped in mid-2025 and carries roughly twelve months of support per the OSRA release cadence. The OS target stays on Ubuntu 24.04 Noble Numbat for Tier-1, so the bulk of your work is choosing an RMW (Fast DDS, Cyclone DDS, Iceoryx 2, or Zenoh), absorbing the rclcpp Kilted breaking changes flagged in the upstream release notes, tidying a handful of launch-file and lifecycle deprecations, and re-baselining Nav2, MoveIt 2, and ros2_control against frozen simulation bags. Most teams should pilot Kilted in a side-by-side dev container and hold production on Jazzy until the next LTS lands in 2026 (per the OSRA roadmap, subject to change). This guide walks the whole rollover end to end, with code that compiles, a phased rollout plan, and a rollback path you can actually run at 2 a.m.

The target reader is a robotics engineer or platform lead who already ships ROS 2 on Jazzy, runs CI, and has at least one robot in the field. We will assume Ubuntu 24.04, colcon, and a DDS-based RMW. If you are still on Humble or Iron, the ROS 2 Jazzy EOL migration rules apply first — get to Jazzy, stabilise, then read the rest of this guide.

Why migrate now: Jazzy lifecycle and Kilted release cadence

ROS 2 distributions follow REP-2000. Jazzy Jalisco is an LTS released in May 2024 with support through to mid-2027. Kilted Kaiju is the interim release that followed in May 2025 and is supported for about a year — that puts its EOL in the second half of 2026, which is uncomfortably close to the next planned LTS. The implication for a fleet operator is straightforward: Kilted is where new APIs and middleware features land first, but it is not where you park a long-running production deployment without a clear bridge plan to the next LTS.

There are three sensible postures right now:

  1. Stay on Jazzy in production, pilot Kilted in dev. This is the default for most commercial fleets. You get the long support tail of Jazzy, you learn the Kilted breaking changes early, and you ride the next LTS in 2026 with confidence.
  2. Jump to Kilted now in production. Justified only if you need a specific Kilted feature (for example, an Iceoryx 2 zero-copy path, a Zenoh bridge, or a Nav2 capability) and you have the bandwidth to migrate again to the next LTS within a year.
  3. Skip Kilted entirely. Stay on Jazzy and plan a single hop to the next LTS. Lower migration cost overall, at the price of being a year behind on upstream features.

The diagram below sketches the windows and recommended actions on a single timeline so you can plan headcount and sprint capacity around it.

ROS 2 Jazzy LTS vs Kilted Kaiju release windows and recommended migration actions

Whichever posture you pick, the engineering work is the same: freeze a known-good Jazzy baseline, prove parity under Kilted, then ship. The rest of the guide is that work, in order.

What’s new in Kilted Kaiju at a glance

Treat this section as a checklist, not a release-notes substitute. Read the upstream Kilted release notes (linked in Further reading) before you touch any code; we will not invent API names here.

  • rclcpp and rclcpp_lifecycle. Per Kilted release notes, expect deprecations in the executor and lifecycle node APIs, plus tightening around node-options. Your safest move is to build with -Werror=deprecated-declarations and fix what surfaces.
  • rclpy. Per Kilted release notes, expect deprecations in the executor lifecycle and parameter callback handling. The Python side tends to move with the C++ side, but with a one-cycle lag for some APIs.
  • launch. Per Kilted release notes, expect minor changes to substitution and event handlers. Existing Python launch files generally keep working with deprecation warnings; XML launch files are stable.
  • rmw layer. The big story is choice: the DDS Iceoryx ROS 2 2026 story has matured (Iceoryx 2 as an RMW for zero-copy shared memory), Zenoh continues to mature as an alternative, and Cyclone DDS and Fast DDS remain first-class.
  • Build system. ament_cmake and colcon are stable across the bump; you may see CMake policy nudges if your packages still call legacy commands.
  • Tooling. ros2 bag, ros2 doctor, and ros2 topic see incremental improvements; nothing that should break a script.

For the diagram-level picture of how a workspace flows from frozen Jazzy through a Kilted dev container and CI parity into production, see the workspace migration pipeline below.

ROS 2 workspace migration pipeline from Jazzy baseline through Kilted dev container to CI parity and cut-over

Compatibility matrix: distributions, OS, RMW

Use the matrix below as a starting point; always cross-check against REP-2000 and the per-package READMEs for your stack.

Element Jazzy Jalisco Kilted Kaiju
Tier-1 OS Ubuntu 24.04 (noble) Ubuntu 24.04 (noble)
Tier-1 architecture amd64, arm64 amd64, arm64
Default RMW rmw_fastrtps_cpp rmw_fastrtps_cpp
Supported RMWs Fast DDS, Cyclone DDS, Connext (per vendor) Fast DDS, Cyclone DDS, Iceoryx 2, Zenoh (per release notes)
Python 3.12 3.12
C++ standard C++17 baseline, C++20 friendly C++17 baseline, C++20 friendly
Status LTS, supported to mid-2027 Interim, ~12 months support

The headline is that Ubuntu 24.04 carries through, which means most of your base images, CI runners, and toolchains keep working. Your Dockerfile changes are minimal: a different apt source list entry and a different metapackage.

Migration plan: a phased rollover

A reliable migration plan has four phases:

  1. Freeze. Tag the Jazzy workspace, pin every dependency, and capture a known-good Docker image. This is your rollback target.
  2. Port. Build the workspace under Kilted in a side-by-side container, fix what breaks, get tests green.
  3. Parity. Run both distros through CI on every PR; compare behaviour against frozen simulation bags.
  4. Cut over. Canary one robot, then a few, then the fleet. Keep the Jazzy image warm.

We will work through each step with concrete commands.

Step 1 — Containerise your Jazzy workspace as a frozen baseline

The first rule of any migration is that you must be able to go back. That means a Jazzy Docker image that is reproducible to the SHA, including system packages.

A minimal Jazzy baseline Dockerfile:

# syntax=docker/dockerfile:1.7
FROM ros:jazzy-ros-base-noble

ARG WORKSPACE=/workspaces/robot_ws
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends \
      build-essential \
      git \
      python3-colcon-common-extensions \
      python3-rosdep \
      python3-vcstool \
      ros-jazzy-nav2-bringup \
      ros-jazzy-moveit \
      ros-jazzy-ros2-control \
      ros-jazzy-ros2-controllers \
    && rm -rf /var/lib/apt/lists/*

WORKDIR ${WORKSPACE}
COPY ./src ./src

# Pin rosdep snapshot date for reproducibility
RUN rosdep update --rosdistro=jazzy \
    && rosdep install --from-paths src --ignore-src -r -y --rosdistro=jazzy

RUN . /opt/ros/jazzy/setup.sh \
    && colcon build \
        --symlink-install \
        --event-handlers console_direct+ \
        --cmake-args -DCMAKE_BUILD_TYPE=Release

CMD ["bash", "-lc", ". install/setup.sh && ros2 launch robot_bringup robot.launch.py"]

Tag the image with the git SHA of the workspace and push it to your registry:

git -C src/robot_bringup rev-parse --short HEAD > .baseline_sha
docker build -t registry.example.com/robot:jazzy-$(cat .baseline_sha) .
docker push  registry.example.com/robot:jazzy-$(cat .baseline_sha)

That image is now your rollback target. Record the SHA, the Cyclone or Fast DDS configuration, and the URDF/SDF versions in a small BASELINE.md so on-call can pull it without you.

Step 2 — Side-by-side Kilted dev container

The trick to a low-risk migration is never doing both distros in the same container. Spin up a Kilted dev container in parallel:

# syntax=docker/dockerfile:1.7
FROM ros:kilted-ros-base-noble

ARG WORKSPACE=/workspaces/robot_ws
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends \
      build-essential \
      git \
      python3-colcon-common-extensions \
      python3-rosdep \
      python3-vcstool \
      ros-kilted-nav2-bringup \
      ros-kilted-moveit \
      ros-kilted-ros2-control \
      ros-kilted-ros2-controllers \
    && rm -rf /var/lib/apt/lists/*

WORKDIR ${WORKSPACE}
COPY ./src ./src

RUN rosdep update --rosdistro=kilted \
    && rosdep install --from-paths src --ignore-src -r -y --rosdistro=kilted

RUN . /opt/ros/kilted/setup.sh \
    && colcon build \
        --symlink-install \
        --event-handlers console_direct+ \
        --cmake-args -DCMAKE_BUILD_TYPE=Release \
                     -DCMAKE_CXX_FLAGS="-Wno-error=deprecated-declarations"

Note the -Wno-error=deprecated-declarations on first build — you want warnings to surface without failing the build until you have triaged them. Once green, flip it to -Werror=deprecated-declarations to harden against future regressions.

You will also want a compose.yaml so engineers can flip between the two containers without retyping flags:

services:
  jazzy:
    image: registry.example.com/robot:jazzy-${BASELINE_SHA}
    network_mode: host
    ipc: host
    pid: host
    privileged: true
    environment:
      - ROS_DOMAIN_ID=42
      - RMW_IMPLEMENTATION=rmw_fastrtps_cpp
  kilted:
    image: registry.example.com/robot:kilted-${KILTED_SHA}
    network_mode: host
    ipc: host
    pid: host
    privileged: true
    environment:
      - ROS_DOMAIN_ID=43        # IMPORTANT: different domain to avoid cross-talk
      - RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

The different ROS_DOMAIN_ID is not optional. If you run both on the same host on the same domain, discovery will cross over and you will spend a day debugging ghost nodes. We have seen this happen.

If you also use a Rerun-based visualiser as part of your dev loop, it is worth standing both distros up against the same Rerun viewer for an apples-to-apples bag replay. We covered that workflow in the Rerun.io robotics telemetry visualisation tutorial and the same approach applies here.

Step 3 — Library and API changes (rclcpp, rclpy, launch, lifecycle)

This is the part where you will spend the most time. Work through it package by package; do not try to fix everything at once.

package.xml: bump the format and dependency keys

If you are still on format="2", move to format="3". It is supported in both Jazzy and Kilted and gives you cleaner export and group dependency semantics.

<?xml version="1.0"?>
<package format="3">
  <name>robot_bringup</name>
  <version>2.6.0</version>
  <description>Bringup for the example robot</description>
  <maintainer email="robotics@example.com">Robotics Team</maintainer>
  <license>Apache-2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>rclcpp</depend>
  <depend>rclcpp_lifecycle</depend>
  <depend>rclpy</depend>
  <depend>launch_ros</depend>
  <depend>nav2_bringup</depend>
  <depend>ros2_control</depend>
  <depend>ros2_controllers</depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

There are no Kilted-specific keys to add — the same <depend> entries resolve against both distros via rosdep. The change here is mostly about hygiene before the bump.

rclcpp: deprecation hygiene

The right discipline on the C++ side is to treat deprecations as build failures the moment your workspace is green. A minimal node that compiles cleanly on both Jazzy and Kilted:

#include <chrono>
#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

class Heartbeat : public rclcpp::Node
{
public:
  Heartbeat()
  : rclcpp::Node("heartbeat")
  {
    pub_ = this->create_publisher<std_msgs::msg::String>("heartbeat", rclcpp::QoS(10));
    timer_ = this->create_wall_timer(
      1s,
      [this]() {
        std_msgs::msg::String msg;
        msg.data = "alive";
        pub_->publish(msg);
      });
  }

private:
  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_;
  rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);
  auto node = std::make_shared<Heartbeat>();
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}

Build with deprecation warnings escalated:

colcon build \
  --symlink-install \
  --cmake-args -DCMAKE_BUILD_TYPE=Release \
               -DCMAKE_CXX_FLAGS="-Werror=deprecated-declarations -Wall -Wextra"

Anything that surfaces here is a candidate for the migration changelog. Per Kilted release notes, expect deprecations in executor construction and node-options helpers — fix them in place rather than wrapping them.

rclpy: parameter and executor patterns

On the Python side, prefer the modern parameter and executor patterns; they work on both distros today and are unlikely to be deprecated in the next cycle.

import rclpy
from rclpy.node import Node
from rclpy.executors import MultiThreadedExecutor
from std_msgs.msg import String


class Heartbeat(Node):
    def __init__(self) -> None:
        super().__init__("heartbeat_py")
        self.declare_parameter("period_s", 1.0)
        period = self.get_parameter("period_s").get_parameter_value().double_value
        self.pub = self.create_publisher(String, "heartbeat_py", 10)
        self.timer = self.create_timer(period, self._tick)

    def _tick(self) -> None:
        msg = String()
        msg.data = "alive"
        self.pub.publish(msg)


def main() -> None:
    rclpy.init()
    node = Heartbeat()
    executor = MultiThreadedExecutor()
    executor.add_node(node)
    try:
        executor.spin()
    finally:
        node.destroy_node()
        rclpy.shutdown()


if __name__ == "__main__":
    main()

launch: Python launch files

Python launch files are the most common source of breakage. The pattern below is conservative and works under both distros:

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node


def generate_launch_description() -> LaunchDescription:
    use_sim_time = LaunchConfiguration("use_sim_time")

    return LaunchDescription([
        DeclareLaunchArgument(
            "use_sim_time",
            default_value="false",
            description="Use simulation clock if true",
        ),
        Node(
            package="robot_bringup",
            executable="heartbeat",
            name="heartbeat",
            output="screen",
            parameters=[{"use_sim_time": use_sim_time}],
        ),
        Node(
            package="robot_bringup",
            executable="heartbeat_py",
            name="heartbeat_py",
            output="screen",
            parameters=[{"use_sim_time": use_sim_time, "period_s": 0.5}],
        ),
    ])

Run it the same way under either distro:

ros2 launch robot_bringup heartbeat.launch.py use_sim_time:=true

If you rely on event handlers (OnProcessExit, RegisterEventHandler), re-test them under Kilted; per the release notes, the event handler internals have seen changes across the cycle.

lifecycle nodes

If you use rclcpp_lifecycle, build your lifecycle nodes under Kilted with deprecation warnings escalated and fix what surfaces. The state machine semantics are unchanged; it is the C++ surface that drifts.

Step 4 — RMW choice (Fast DDS, Cyclone DDS, Iceoryx 2, Zenoh)

The RMW choice is the single biggest behavioural lever you have. Kilted broadens that menu meaningfully: alongside the long-standing Fast DDS and Cyclone DDS implementations, Iceoryx 2 lands as a true zero-copy shared-memory transport, and Zenoh continues to mature as a routed pub-sub alternative.

Use this decision tree as a starting point. Then benchmark on the target hardware — the right RMW for a Jetson Orin in a warehouse is rarely the right RMW for an industrial PC bridging two networks.

RMW decision tree for ROS 2 Kilted: latency budget, zero-copy, and network topology

A small but useful sanity-check script for any RMW choice:

#!/usr/bin/env bash
set -euo pipefail

export RMW_IMPLEMENTATION="${RMW_IMPLEMENTATION:-rmw_cyclonedds_cpp}"
export ROS_DOMAIN_ID="${ROS_DOMAIN_ID:-42}"

echo "Using RMW=${RMW_IMPLEMENTATION} on domain ${ROS_DOMAIN_ID}"

ros2 doctor --report | tee doctor_${RMW_IMPLEMENTATION}.log
ros2 topic pub -r 100 /bench std_msgs/msg/Header "{}" &
PUB_PID=$!
sleep 1
timeout 10 ros2 topic hz /bench | tee hz_${RMW_IMPLEMENTATION}.log
kill ${PUB_PID} || true

Run it on both Jazzy and Kilted with each RMW you are considering and store the logs alongside your CI artefacts. If you cannot reproduce the same hz within a sensible tolerance across distros, you have a discovery or QoS issue to chase before the cut-over.

A few rules of thumb that have held up well in production:

  • Default to Cyclone DDS for new fleets. Its defaults are sensible, configuration is short, and discovery is well-behaved on flat LANs.
  • Choose Fast DDS where you need rich QoS. Large fleets with many topics often need the QoS surface and tooling that Fast DDS provides.
  • Pick Iceoryx 2 only for tight single-host pipelines. Sub-millisecond paths between perception and control, on the same SoC, with zero-copy. Do not use it across hosts.
  • Pick Zenoh for cloud-edge bridging. When you need to span a NAT, a sketchy radio link, or a routed cloud topology, Zenoh’s model maps better than DDS discovery.

Step 5 — Nav2, MoveIt, ros2_control deltas

The high-level libraries are where most fleets actually feel a distro bump. Nav2 changes BT node names from cycle to cycle; MoveIt updates parameter schemas; ros2_control rotates plugin XML conventions.

The diagram below summarises the per-module work and where it gates CI parity.

Module migration deltas for Nav2, MoveIt 2, ros2_control, and image_pipeline under ROS 2 Kilted

Concretely, per Kilted release notes, expect deprecations in:

  • Nav2: behaviour-tree node names, costmap layer parameter keys, and a handful of recovery server defaults.
  • MoveIt 2: planning pipeline parameter names, ServoNode parameter group restructuring, and OMPL configuration paths.
  • ros2_control: hardware interface plugin XML declarations and controller parameter namespaces.
  • image_pipeline: QoS defaults on rectification and debayer nodes.

The right discipline is to keep behaviour-tree XML, planner YAML, and controller YAML under version control, and to diff them per-distro. Do not edit them in place; copy them under a kilted/ prefix and run both copies through CI.

If your stack also includes a digital-twin simulation in NVIDIA Isaac Sim, this is the moment to re-baseline your domain-randomisation runs against the Kilted image; we walked through the relevant pipeline in the Isaac Sim 4.5 domain randomisation tutorial, and the same patterns apply for distro re-baselining.

Step 6 — CI, simulation, and integration tests

If you do not run both distros through CI on every PR, you will not catch the regressions until they hit a robot. The minimum viable matrix has two jobs:

name: ros2-matrix
on:
  pull_request:
  push:
    branches: [main]

jobs:
  build-test:
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: false
      matrix:
        distro: [jazzy, kilted]
    container:
      image: ros:${{ matrix.distro }}-ros-base-noble
    steps:
      - uses: actions/checkout@v4
        with:
          path: src/robot_ws
      - name: rosdep
        run: |
          apt-get update
          rosdep update --rosdistro=${{ matrix.distro }}
          rosdep install --from-paths src --ignore-src -r -y --rosdistro=${{ matrix.distro }}
      - name: build
        run: |
          . /opt/ros/${{ matrix.distro }}/setup.sh
          colcon build \
            --symlink-install \
            --event-handlers console_direct+ \
            --cmake-args -DCMAKE_BUILD_TYPE=Release
      - name: test
        run: |
          . /opt/ros/${{ matrix.distro }}/setup.sh
          colcon test --event-handlers console_direct+
          colcon test-result --verbose

On top of the build and unit-test matrix, add a sim-in-the-loop job that replays a frozen rosbag through Nav2 or the controller stack and compares against a recorded reference. The bag is your contract: if tf rates, path tracking error, or controller torques drift outside a band, the PR fails.

A practical recipe with ros2 bag:

. /opt/ros/${ROS_DISTRO}/setup.sh

# Record a baseline once on Jazzy
ros2 bag record -a -o baseline_${ROS_DISTRO}_$(date +%Y%m%d) --max-bag-duration 60

# In CI, replay through a parity harness
ros2 bag play baseline_jazzy_20260601 --clock --rate 1.0 &
PLAY_PID=$!

ros2 launch robot_test parity_harness.launch.py \
  reference_bag:=baseline_jazzy_20260601 \
  candidate_distro:=${ROS_DISTRO}

wait ${PLAY_PID}

The parity harness compares topic rates, message counts, and a small set of numeric KPIs (cross-track error, controller effort, lifecycle transition times) against the reference bag.

Step 7 — Cut-over plan and rollback

The cut-over is the part that goes wrong if you let it be informal. The plan below is the minimum you should commit to before any production robot pulls the Kilted image.

  1. Canary one robot. Move a single robot to the Kilted image for at least one week. Watch CPU, dropped messages, DDS discovery time, and Nav2 lifecycle transitions.
  2. Expand by ones. Add one robot a day until 10% of the fleet is on Kilted. Keep the Jazzy image hot on every robot — systemd should be one unit-file switch away from rollback.
  3. Hold and observe. Hold at 10% for a week with no upgrades. This is the window for slow-burn regressions: thermal drift, log rotation, DDS heap growth.
  4. Ramp. Move in 25% increments thereafter, with at least 48 hours of observation between steps.
  5. Decommission the Jazzy image only after the next LTS lands. Until then, the Jazzy image is your safety net.

The rollback flow below is the one you want pinned in your runbook. The trigger is any telemetry alert that crosses your release-criteria thresholds, not a vibes call from on-call.

Rollback flow for ROS 2 Kilted regressions in a production robot fleet

A small detail that pays for itself: store the entire config bundle alongside the image, not just the image itself. RMW selection, cyclonedds.xml, Nav2 YAML, MoveIt YAML, URDF, and any environment files all belong in a versioned bundle. Rolling back the image without rolling back the config is how you end up with a fleet that runs but behaves wrong.

Trade-offs and gotchas

A short, honest list of the things that bite teams during this migration.

  • Mixed-distro discovery. If a Jazzy node and a Kilted node share a ROS_DOMAIN_ID and the same RMW vendor, discovery can converge and confuse you. Use separate domain IDs during the migration window.
  • Iceoryx 2 is single-host. It is genuinely fast. It is also not the answer for inter-robot communication. Do not let a benchmark on a single SoC convince you otherwise.
  • Zenoh is not a drop-in DDS. The model is different; your QoS reasoning has to be re-done. Pilot it in a non-safety-critical path first.
  • Time sync still matters. use_sim_time and chrony/ptp get more brittle as your fleet grows. A distro bump is a good moment to audit clocks across robots.
  • rosbag2 format compatibility. Re-record reference bags under Kilted once your harness is stable; do not assume a Jazzy-recorded bag replays identically forever.
  • CI minutes. A two-distro matrix doubles your CI bill. Budget for it.
  • Documentation drift. Internal wikis lag distros badly. Date every runbook with the distro it was last verified against.
  • Third-party drivers. Vendor drivers are the most common Kilted blocker. Check vendor support before you start, not after.

Practical recommendations

  • For most commercial fleets: stay on Jazzy in production, pilot Kilted in a dev container, plan to land on the next LTS in 2026 (per the OSRA roadmap, subject to change).
  • For research labs: move to Kilted in the lab now; the new RMW options are worth it.
  • For safety-critical deployments: stay on Jazzy and qualify the next LTS. Do not run a non-LTS distro in safety-critical paths.
  • For all teams: invest in the two-distro CI matrix early. The cost is real and the protection is enormous.
  • For platform leads: version the entire config bundle, not just the image; pin rosdep snapshot dates; tag every Docker image with the workspace SHA.
  • For on-call: keep the Jazzy image pinned and warm on every robot through at least the next LTS GA, and rehearse the rollback before you need it.

FAQ

1. Is Kilted Kaiju an LTS release?
No. Kilted is a non-LTS interim release with approximately twelve months of support per the OSRA release cadence. Jazzy Jalisco is the current LTS; the next LTS after Jazzy is planned for 2026 per the OSRA roadmap, subject to change.

2. Do I have to change my Ubuntu version to migrate from Jazzy to Kilted?
No. Both Jazzy and Kilted target Ubuntu 24.04 Noble Numbat as the Tier-1 OS. Your base image, kernel, and most system packages can stay the same; only the ROS metapackages and apt source lists change.

3. Should I switch to Iceoryx 2 as part of the migration?
Only if you have a single-host, zero-copy use case where the latency budget genuinely requires it (typically sub-millisecond perception-to-control on the same SoC). Iceoryx 2 is not a substitute for a network RMW. Most fleets should keep Cyclone DDS or Fast DDS and treat Iceoryx 2 as an optimisation for specific paths.

4. How do I run Jazzy and Kilted side by side without them seeing each other?
Use different ROS_DOMAIN_ID values, run them in separate containers, and prefer the same RMW vendor on both so debugging discovery stays simple. Sharing a host is fine for development as long as the domain IDs differ; sharing a domain is not.

5. What is the biggest source of breakage during the Jazzy to Kilted bump?
In our experience, it is high-level libraries — Nav2 behaviour-tree node names, MoveIt parameter schemas, and ros2_control plugin XML conventions — not the rclcpp or rclpy core. Build deprecations are usually quick fixes; library config drift is what eats sprints.

6. When should I plan to leave Kilted?
Plan to leave Kilted before its EOL, ideally onto the next LTS once it has reached GA and your stack supports it. Treat Kilted as a staging post, not a destination.

Further reading

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *