← Quay lại Blog
navigationros2tutorialamr

ROS 2 từ A đến Z (Phần 1): Cài đặt và Node đầu tiên

Hướng dẫn cài đặt ROS 2 Humble trên Ubuntu 22.04 và viết node publisher/subscriber đầu tiên — bước khởi đầu cho kỹ sư robotics.

Nguyễn Anh Tuấn9 tháng 1, 20269 phút đọc
ROS 2 từ A đến Z (Phần 1): Cài đặt và Node đầu tiên

ROS 2 Humble — Bắt đầu từ đâu?

Nếu bạn đang muốn học ROS 2 để xây dựng robot, bài viết này chính là điểm khởi đầu. Chúng ta sẽ đi từ cài đặt ROS 2 Humble trên Ubuntu 22.04, tạo workspace, viết node publisher/subscriber đầu tiên bằng Python, cho đến khi bạn có thể build và chạy được package của riêng mình. Mình đã từng hướng dẫn nhiều bạn kỹ sư bắt đầu với ROS 2, và kinh nghiệm cho thấy: cứ làm theo từng bước, bạn sẽ nắm được nền tảng rất nhanh.

Nếu bạn chưa biết ROS 2 là gì hay tại sao nên dùng ROS 2 thay vì ROS 1, hãy đọc bài Giới thiệu ROS 2: Nền tảng lập trình robot thế hệ mới trước nhé.

Ubuntu terminal với ROS 2 Humble

Cài đặt ROS 2 Humble trên Ubuntu 22.04

Yêu cầu hệ thống

Bước 1: Cấu hình locale

ROS 2 yêu cầu locale hỗ trợ UTF-8:

sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

# Kiểm tra
locale

Bước 2: Thêm ROS 2 repository

# Cài đặt dependencies
sudo apt install -y software-properties-common curl
sudo add-apt-repository universe

# Thêm GPG key
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
  -o /usr/share/keyrings/ros-archive-keyring.gpg

# Thêm repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
  http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" \
  | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

Bước 3: Cài đặt ROS 2 Humble

sudo apt update
sudo apt upgrade -y

# Bản đầy đủ (bao gồm RViz, Gazebo demos, rqt tools)
sudo apt install -y ros-humble-desktop

# Hoặc bản tối thiểu (chỉ libraries + CLI, không GUI)
# sudo apt install -y ros-humble-ros-base

Quá trình cài đặt mất khoảng 5-15 phút tuỳ tốc độ mạng.

Bước 4: Cài đặt công cụ build

# colcon — build tool chính của ROS 2
sudo apt install -y python3-colcon-common-extensions

# rosdep — quản lý dependencies
sudo apt install -y python3-rosdep2
sudo rosdep init
rosdep update

Bước 5: Source environment

# Thêm vào .bashrc để tự động source mỗi khi mở terminal
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

# Kiểm tra cài đặt thành công
ros2 --version
# Kết quả: ros2 0.xx.x

Kiểm tra nhanh với Turtlesim

Trước khi đi tiếp, hãy chắc chắn mọi thứ hoạt động:

# Terminal 1: Chạy turtlesim
ros2 run turtlesim turtlesim_node

# Terminal 2: Điều khiển rùa bằng bàn phím
ros2 run turtlesim turtle_teleop_key

Nếu thấy cửa sổ con rùa hiện ra và bạn điều khiển được bằng phím mũi tên — chúc mừng, ROS 2 đã sẵn sàng!

Tạo ROS 2 Workspace

Workspace là nơi chứa toàn bộ source code của bạn. ROS 2 sử dụng colcon làm build system (thay thế catkin của ROS 1).

# Tạo cấu trúc workspace
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws

# Build workspace rỗng (tạo thư mục build, install, log)
colcon build
source install/setup.bash

Cấu trúc sau khi build:

~/ros2_ws/
├── build/          # Build artifacts
├── install/        # Installed packages (source cái này)
├── log/            # Build logs
└── src/            # Source code của bạn

Tip quan trọng: Luôn source workspace sau khi build:

# Thêm vào .bashrc
echo "source ~/ros2_ws/install/setup.bash" >> ~/.bashrc

Tạo Package đầu tiên

ROS 2 hỗ trợ 2 loại package: ament_python (Python thuần) và ament_cmake (C++). Trong series này, mình dùng Python cho dễ tiếp cận.

cd ~/ros2_ws/src

# Tạo package Python
ros2 pkg create --build-type ament_python my_first_robot \
  --dependencies rclpy std_msgs

# Kết quả:
# my_first_robot/
# ├── my_first_robot/
# │   └── __init__.py
# ├── package.xml          # Metadata + dependencies
# ├── setup.py             # Python package config
# ├── setup.cfg            # Entry points config
# ├── resource/
# │   └── my_first_robot
# └── test/

Cấu trúc workspace ROS 2 với colcon build

Viết Node Publisher đầu tiên

Node là đơn vị xử lý cơ bản trong ROS 2. Mỗi node là một process làm một nhiệm vụ cụ thể. Hãy viết một node giả lập sensor nhiệt độ, publish dữ liệu lên topic /temperature.

Tạo file publisher

# ~/ros2_ws/src/my_first_robot/my_first_robot/temperature_publisher.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32
import random


class TemperaturePublisher(Node):
    """Node giả lập sensor nhiệt độ, publish mỗi giây."""

    def __init__(self):
        super().__init__('temperature_publisher')

        # Tạo publisher: msg type, topic name, queue size
        self.publisher_ = self.create_publisher(Float32, '/temperature', 10)

        # Timer gọi callback mỗi 1 giây
        self.timer = self.create_timer(1.0, self.timer_callback)

        # Nhiệt độ ban đầu
        self.base_temp = 25.0

        self.get_logger().info('Temperature publisher node started!')

    def timer_callback(self):
        msg = Float32()
        # Giả lập nhiệt độ dao động quanh 25°C
        msg.data = self.base_temp + random.uniform(-2.0, 2.0)

        self.publisher_.publish(msg)
        self.get_logger().info(f'Published temperature: {msg.data:.1f}°C')


def main(args=None):
    rclpy.init(args=args)

    node = TemperaturePublisher()

    try:
        rclpy.spin(node)  # Giữ node chạy liên tục
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()
        rclpy.shutdown()


if __name__ == '__main__':
    main()

Giải thích code

Viết Node Subscriber

Bây giờ viết node nhận dữ liệu nhiệt độ và xử lý (ví dụ: cảnh báo khi quá nóng):

# ~/ros2_ws/src/my_first_robot/my_first_robot/temperature_subscriber.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32


class TemperatureSubscriber(Node):
    """Node nhận nhiệt độ và cảnh báo khi vượt ngưỡng."""

    def __init__(self):
        super().__init__('temperature_subscriber')

        # Tạo subscription
        self.subscription = self.create_subscription(
            Float32,
            '/temperature',
            self.listener_callback,
            10
        )

        # Ngưỡng cảnh báo
        self.warning_threshold = 26.5
        self.critical_threshold = 27.5

        self.get_logger().info('Temperature subscriber node started!')

    def listener_callback(self, msg):
        temp = msg.data

        if temp >= self.critical_threshold:
            self.get_logger().error(
                f'CRITICAL: Temperature {temp:.1f}°C exceeds {self.critical_threshold}°C!'
            )
        elif temp >= self.warning_threshold:
            self.get_logger().warn(
                f'WARNING: Temperature {temp:.1f}°C above normal'
            )
        else:
            self.get_logger().info(f'Temperature OK: {temp:.1f}°C')


def main(args=None):
    rclpy.init(args=args)
    node = TemperatureSubscriber()

    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()
        rclpy.shutdown()


if __name__ == '__main__':
    main()

Đăng ký entry points và build

Cập nhật setup.py

Để ROS 2 biết cách chạy các node, cần đăng ký chúng trong setup.py:

# ~/ros2_ws/src/my_first_robot/setup.py
from setuptools import find_packages, setup

package_name = 'my_first_robot'

setup(
    name=package_name,
    version='0.1.0',
    packages=find_packages(exclude=['test']),
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='your_name',
    maintainer_email='[email protected]',
    description='My first ROS 2 robot package',
    license='Apache-2.0',
    entry_points={
        'console_scripts': [
            'temp_pub = my_first_robot.temperature_publisher:main',
            'temp_sub = my_first_robot.temperature_subscriber:main',
        ],
    },
)

Build và chạy

# Về workspace root
cd ~/ros2_ws

# Build chỉ package của mình (nhanh hơn build all)
colcon build --packages-select my_first_robot --symlink-install

# Source lại workspace
source install/setup.bash

# Terminal 1: Chạy publisher
ros2 run my_first_robot temp_pub

# Terminal 2: Chạy subscriber
ros2 run my_first_robot temp_sub

Flag --symlink-install rất hữu ích: nó tạo symlink thay vì copy file, nên khi bạn sửa code Python, không cần build lại (chỉ cần restart node).

Kết quả bạn sẽ thấy:

[INFO] [temperature_publisher]: Published temperature: 24.3°C
[INFO] [temperature_publisher]: Published temperature: 26.8°C
[INFO] [temperature_subscriber]: Temperature OK: 24.3°C
[WARN] [temperature_subscriber]: WARNING: Temperature 26.8°C above normal

Introspect với CLI tools

ROS 2 CLI rất mạnh cho việc debug:

# Xem danh sách nodes đang chạy
ros2 node list
# /temperature_publisher
# /temperature_subscriber

# Xem thông tin chi tiết một node
ros2 node info /temperature_publisher

# Xem danh sách topics
ros2 topic list
# /temperature
# /parameter_events
# /rosout

# Xem dữ liệu trên topic (real-time)
ros2 topic echo /temperature

# Xem tần suất publish
ros2 topic hz /temperature
# average rate: 1.000

# Xem kiểu message
ros2 topic type /temperature
# std_msgs/msg/Float32

# Xem cấu trúc message
ros2 interface show std_msgs/msg/Float32
# float32 data

Launch Files — Chạy nhiều node cùng lúc

Thay vì mở nhiều terminal, hãy dùng launch file:

# ~/ros2_ws/src/my_first_robot/launch/temperature_system.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node


def generate_launch_description():
    return LaunchDescription([
        Node(
            package='my_first_robot',
            executable='temp_pub',
            name='temperature_publisher',
            output='screen',
            parameters=[{
                'publish_rate': 1.0,
            }],
        ),
        Node(
            package='my_first_robot',
            executable='temp_sub',
            name='temperature_subscriber',
            output='screen',
        ),
    ])

Để launch file được nhận, thêm vào setup.py:

import os
from glob import glob

# Thêm vào data_files:
data_files=[
    ('share/ament_index/resource_index/packages',
        ['resource/' + package_name]),
    ('share/' + package_name, ['package.xml']),
    # Thêm dòng này cho launch files
    (os.path.join('share', package_name, 'launch'),
        glob(os.path.join('launch', '*launch.[pxy][yma]*'))),
],

Tạo thư mục launch và build lại:

mkdir -p ~/ros2_ws/src/my_first_robot/launch
# Copy file launch vào đây

cd ~/ros2_ws
colcon build --packages-select my_first_robot --symlink-install
source install/setup.bash

# Chạy cả hệ thống
ros2 launch my_first_robot temperature_system.launch.py

ROS 2 rqt_graph hiển thị kết nối giữa publisher và subscriber

Visualize với rqt_graph

# Cài đặt rqt (nếu chưa có trong desktop install)
sudo apt install -y ros-humble-rqt ros-humble-rqt-graph

# Mở graph viewer
ros2 run rqt_graph rqt_graph

Bạn sẽ thấy sơ đồ trực quan: node temperature_publisher nối với temperature_subscriber qua topic /temperature. Đây là cách debug rất hiệu quả khi hệ thống phức tạp.

Tổng kết và bước tiếp theo

Trong bài này, bạn đã:

Đây là nền tảng cho mọi thứ tiếp theo. Trong Phần 2, chúng ta sẽ đi sâu vào 3 primitives giao tiếp của ROS 2: Topics, Services và Actions — để bạn biết khi nào dùng cái gì khi thiết kế hệ thống robot.


Bài viết liên quan

Bài viết liên quan

Deep DiveDigital Twins và ROS 2: Simulation trong sản xuất
simulationros2digital-twinPhần 6

Digital Twins và ROS 2: Simulation trong sản xuất

Ứng dụng simulation trong công nghiệp — digital twins, ROS 2 + Gazebo/Isaac integration cho nhà máy thông minh.

3/4/202611 phút đọc
TutorialSim-to-Real Pipeline: Từ training đến robot thật
simulationsim2realtutorialPhần 5

Sim-to-Real Pipeline: Từ training đến robot thật

End-to-end guide: train policy trong sim, evaluate, domain randomization, deploy lên robot thật và iterate.

2/4/202615 phút đọc
TutorialBắt đầu với MuJoCo: Cài đặt đến mô phỏng robot đầu tiên
simulationmujocotutorialPhần 2

Bắt đầu với MuJoCo: Cài đặt đến mô phỏng robot đầu tiên

Hands-on tutorial MuJoCo — cài đặt, tạo MJCF model, simulate robot arm và visualize kết quả với Python.

30/3/202611 phút đọc