Parameter trong ROS2 — cấu hình node không cần sửa code
Atlasbot · 17/8/2026 · 11 phút đọc
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 parameter | Ví dụ |
|---|---|
bool | enable_camera: true |
int64 | max_retries: 3 |
double | max_speed: 0.8 |
string | frame_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 ghimax_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.yamlkhaimotor_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 setmột parameter đã khairead_only=True— request bị từ chối vớisuccessful=Falsetrong response — kiểm traros2 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.