Unit 15 · lab

Lab: Build a Repeatable ROS 2 Bringup and Verify the Runtime

This lab turns robotnix_bringup into actual startup infrastructure.

You will install a launch directory, write a Python launch file, rebuild the package, launch a named talker/listener pair, remap their communication to /robotnix/demo, inspect the graph from a second shell, override the topic argument, and preserve one stale-install failure.

Your final artifact is a Bringup Verification Record.

Choose your lane

Local Jazzy lane

Use this lane if you have ROS 2 Jazzy and demo_nodes_cpp available.

You will run the launch and collect graph evidence from a second terminal.

Supplied-evidence lane

If local ROS execution is unavailable, write the exact package and launch files, then use the supplied launch/graph evidence in this lab.

Label it supplied bringup evidence.

Guided example: source file exists, launch file not found

You create:

src/robotnix_bringup/launch/demo_pair.launch.py

but ros2 launch cannot find it.

If the package prefix resolves, the next question is not whether ROS is installed. Inspect the package install path and CMakeLists.txt.

The source launch directory must be installed:

install(
  DIRECTORY launch
  DESTINATION share/${PROJECT_NAME}
)

Then the package must be rebuilt.

That is the pattern for the lab: identify the failing layer before changing unrelated code.

Part 1: Add the launch install rule

Update CMakeLists.txt:

cmake_minimum_required(VERSION 3.8)
project(robotnix_bringup)

find_package(ament_cmake REQUIRED)

install(
  DIRECTORY launch
  DESTINATION share/${PROJECT_NAME}
)

ament_package()

Create:

~/robot_ws/src/robotnix_bringup/launch/

Part 2: Write demo_pair.launch.py

Use:

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


def generate_launch_description():
    topic_name = LaunchConfiguration("topic_name")

    return LaunchDescription([
        DeclareLaunchArgument(
            "topic_name",
            default_value="/robotnix/demo",
            description=(
                "Topic used by the demo talker/listener pair"
            ),
        ),
        Node(
            package="demo_nodes_cpp",
            executable="talker",
            name="talker_demo",
            output="screen",
            remappings=[
                ("/chatter", topic_name),
            ],
        ),
        Node(
            package="demo_nodes_cpp",
            executable="listener",
            name="listener_demo",
            output="screen",
            remappings=[
                ("/chatter", topic_name),
            ],
        ),
    ])

Check that both nodes use the same topic_name substitution.

Part 3: Rebuild and source

Run:

source /opt/ros/jazzy/setup.bash
cd ~/robot_ws
colcon build --packages-select robotnix_bringup
source install/setup.bash
ros2 pkg prefix robotnix_bringup

Preserve:

  • build summary;
  • resolved package prefix.

If either fails, repair that layer before launch.

Part 4: Launch the default configuration

Terminal A:

ros2 launch \
  robotnix_bringup \
  demo_pair.launch.py

Local lane: leave the launch active.

Supplied lane: use this transcript:

[INFO] [launch]: starting robotnix demo pair
[INFO] [talker_demo]: process started
[INFO] [listener_demo]: process started

Part 5: Verify from Terminal B

Source the same environment:

source /opt/ros/jazzy/setup.bash
source ~/robot_ws/install/setup.bash

Then run:

ros2 node list
ros2 topic list -t
ros2 topic info /robotnix/demo

Supplied graph evidence:

/talker_demo
/listener_demo

Supplied topic evidence:

/robotnix/demo [std_msgs/msg/String]
Type: std_msgs/msg/String
Publisher count: 1
Subscription count: 1

Record each command separately.

Part 6: Inspect one message

Local lane:

ros2 topic echo /robotnix/demo --once

Supplied lane:

data: 'Hello World: 1'

Label it supplied.

This adds one message observation to the bringup evidence.

Part 7: Stop the launch and verify shutdown

Stop Terminal A with:

Ctrl+C

Then rerun:

ros2 node list

Record whether /talker_demo and /listener_demo disappear from the graph.

Supplied lane: both demo nodes are absent after the supplied stop event.

Part 8: Override the launch argument

Restart with:

ros2 launch \
  robotnix_bringup \
  demo_pair.launch.py \
  topic_name:=/robotnix/test

Inspect:

ros2 topic list -t

Expected topic:

/robotnix/test [std_msgs/msg/String]

Record that the same launch source produced a different runtime topic through one launch argument.

Part 9: Create a stale-install failure

Stop the launch.

Edit the source default to:

/robotnix/stale_test

Do not rebuild yet.

Run the installed launch file again.

Local lane: record which default appears.

Supplied lane: use this result:

observed installed default: /robotnix/demo
source default: /robotnix/stale_test

Explain the mismatch.

Then repair:

cd ~/robot_ws
colcon build --packages-select robotnix_bringup
source install/setup.bash

Relaunch and verify the installed behavior now matches the edited source.

Part 10: Build the Bringup Verification Record

Your artifact must contain:

Installed launch source

  • source path;
  • CMake install rule;
  • package prefix.

Launch contract

  • package/executable/name for both nodes;
  • default topic_name;
  • remapping rule.

Default launch evidence

  • launch transcript;
  • node list;
  • topic name/type;
  • endpoint counts;
  • one message if available.

Shutdown evidence

Record post-stop node state.

Argument override

Record /robotnix/test and the command that selected it.

Stale-install failure

Preserve source default, installed behavior, missing rebuild, repair, and verified result.

Java boundary

State why this launch file does not start or integrate a WPILib Java application.

Success criteria

Your record is complete when another student can answer:

  • How is the launch directory installed?
  • Which package provides the talker/listener executables?
  • Which runtime node names are expected?
  • Why does the demo topic become /robotnix/demo?
  • How can the topic be changed without copying the launch file?
  • Which second-shell commands verify the runtime?
  • What did the stale-install case teach about source versus installed resources?
  • Which Java/WPILib behavior remains outside this ROS bringup?

A successful bringup is not "the launch command ran." It is a startup contract that another student can reproduce and verify.