Atlas Robotics
ROS2 PackageTrung bình

Parameter trong ROS2 — cấu hình node không cần sửa code

Atlasbot · 17/8/2026 · 11 phút đọc

Parameter trong ROS2 — cấu hình node không cần sửa code
Ba nguồn có thể set giá trị cho một parameter, theo thứ tự ưu tiên

Một node điều khiển động cơ viết cứng max_speed = 0.5 trong code thì mỗi lần đổi robot (hoặc chỉ đơn giản là muốn thử tốc độ khác) đều phải sửa code, build lại. Parameter giải quyết đúng việc này: khai giá trị cấu hình bên ngoài code, node đọc vào lúc chạy — đổi giá trị chỉ cần sửa file YAML hoặc gõ một cờ dòng lệnh, không cần build lại.

Khái niệm chính

import rclpy
from rclpy.node import Node

class MotorNode(Node):
    def __init__(self):
        super().__init__("motor_node")
        self.declare_parameter("max_speed", 0.5)
        max_speed = self.get_parameter("max_speed").value
        self.get_logger().info(f"max_speed = {max_speed}")

declare_parameter(tên, giá_trị_mặc_định) bắt buộc phải gọi trước khi đọc — ROS2 chủ động yêu cầu khai báo tường minh (khác ROS1 cho phép đọc parameter bất kỳ không cần khai trước) để tránh lỗi gõ nhầm tên parameter mà không hay biết.

Nguyên lý hoạt động

Ba cách nạp giá trị, theo thứ tự ưu tiên:

# config/motor_params.yaml
motor_node:
  ros__parameters:
    max_speed: 0.8
    frame_id: "base_link"
# Trong launch file
Node(
    package="my_pkg",
    executable="motor_node",
    parameters=["config/motor_params.yaml"],
)
# Ghi đè nhanh từ dòng lệnh, không cần sửa file YAML
ros2 run my_pkg motor_node --ros-args -p max_speed:=1.2

Giá trị cuối cùng node nhận được là giá trị được nạp sau cùng — nếu cả launch file lẫn dòng lệnh -p cùng set max_speed, cờ -p trên dòng lệnh thắng vì chạy sau.

Tóm lại: Giá trị mặc định trong declare_parameter() là lớp phòng hờ cuối cùng nếu không file YAML/launch nào ghi đè — nên luôn đặt mặc định là giá trị an toàn nhất (ví dụ tốc độ thấp), không phải giá trị "thường dùng nhất".

Callback khi parameter đổi lúc đang chạy:

from rcl_interfaces.msg import SetParametersResult

def parameter_callback(self, params):
    for p in params:
        if p.name == "max_speed":
            self.get_logger().info(f"max_speed đổi thành {p.value}")
    return SetParametersResult(successful=True)

# Trong __init__:
self.add_on_set_parameters_callback(self.parameter_callback)

Callback này cho phép node phản ứng ngay khi ai đó gọi ros2 param set mà không cần restart node.

Kiến thức kỹ thuật

Thông số

Các kiểu dữ liệu parameter được hỗ trợ, và một số ràng buộc có thể khai qua ParameterDescriptor:

Kiểu parameterVí dụ
boolenable_camera: true
int64max_retries: 3
doublemax_speed: 0.8
stringframe_id: "base_link"
Mảng (bool[], int64[], double[], string[])wheel_names: ["left", "right"]

ParameterDescriptor cho phép thêm ràng buộc khi khai báo, VD: read_only=True (không cho phép ros2 param set đổi giá trị lúc runtime — dùng cho tham số chỉ nên set 1 lần lúc khởi động, như địa chỉ I2C của cảm biến).

Protocol

Mỗi node ROS2 tự động "lộ ra" một bộ Service chuẩn để thao tác parameter — get_parameters, set_parameters, list_parameters, describe_parameters — đây chính xác là cơ chế mà cả ros2 param (dòng lệnh) lẫn rqt_reconfigure (giao diện đồ hoạ) dùng bên dưới để đọc/ghi parameter của bất kỳ node nào đang chạy, không có gì đặc biệt hơn 1 lần gọi Service thông thường đã học ở chuyên mục ROS2 Communication.

Ứng dụng thực tế

Với một dòng sản phẩm robot có nhiều model khác nhau dùng chung 1 codebase (VD: robot AMR cỡ nhỏ và cỡ lớn chỉ khác bán kính bánh xe, tốc độ tối đa, vị trí lắp cảm biến), tách các giá trị này thành file YAML riêng cho từng model (config/robot_small.yaml, config/robot_large.yaml) cho phép cùng 1 bộ code chạy đúng trên mọi model — chỉ cần đổi file YAML nạp vào lúc launch, không phải maintain nhiều nhánh code khác nhau cho từng kích cỡ robot.

Ví dụ thực tế

$ ros2 param get /motor_node max_speed
Output:
Double value is: 0.8
$ ros2 param set /motor_node max_speed 1.2
Output:
Set parameter successful
Log của node (nếu có parameter_callback như ví dụ trên):
[INFO] [motor_node]: max_speed đổi thành 1.2

Toàn bộ thao tác này diễn ra không cần restart node — minh chứng trực tiếp cho giá trị của add_on_set_parameters_callback, hữu ích khi cần tinh chỉnh tham số ngay trong lúc robot đang chạy thử để quan sát ảnh hưởng tức thời.

Lỗi thường gặp

  • Đọc parameter chưa declare_parameter() — gây exception ngay lập tức, khác với hành vi im lặng của ROS1 — luôn khai báo trước khi đọc, kể cả với giá trị "chắc chắn sẽ được set từ YAML".
  • Sai kiểu dữ liệu giữa giá trị mặc định và giá trị trong YAML — VD: khai declare_parameter("max_speed", 0.5) (kiểu double) nhưng YAML ghi max_speed: 1 (không có dấu thập phân, bị hiểu là int) — ROS2 có thể báo lỗi kiểu không khớp (ParameterTypeException) tuỳ cấu hình.
  • Tên node trong YAML không khớp tên node thực tế — file config/motor_params.yaml khai motor_node: nhưng node thực tế chạy với tên khác (do remap hoặc namespace) — parameter sẽ không được áp dụng, không có cảnh báo rõ ràng, node vẫn chạy với giá trị mặc định.
  • Cố ros2 param set một parameter đã khai read_only=True — request bị từ chối với successful=False trong response — kiểm tra ros2 param describe để biết parameter nào bị khoá trước khi debug tưởng nhầm là lỗi callback.

Kết luận

Parameter là cơ chế chuẩn để tách cấu hình khỏi code, hỗ trợ 3 tầng nạp giá trị (mặc định → YAML/launch → dòng lệnh) và có thể thay đổi runtime qua đúng cơ chế Service đã học. Luôn đặt giá trị mặc định an toàn và khai báo tường minh trước khi đọc. Đây cũng là bài cuối cùng của chuyên mục ROS2 Package — đủ nền tảng để đóng gói hoàn chỉnh 1 package ROS2 từ code, build system, tới cấu hình runtime. Chuyên mục tiếp theo, ROS2 Tools, đi sâu vào từng công cụ dòng lệnh đã nhắc qua xuyên suốt các bài trước.

Parameter trong ROS2 — cấu hình node không cần sửa code — Atlasbot