robot_cpp/README.md
2026-01-31 17:20:07 +07:00

12 KiB

robot_cpp

Tổng quan

robot_cpp là một thư viện C++ cung cấp các công cụ tiện ích cốt lõi cho phát triển ứng dụng robot, tương tự như các utilities trong ROS nhưng hoàn toàn độc lập, không phụ thuộc vào ROS. Thư viện này cung cấp nền tảng cơ bản cho việc xây dựng các hệ thống robot tự động.

Mục đích và phạm vi ứng dụng

Thư viện robot_cpp được thiết kế để giải quyết các nhu cầu cơ bản trong phát triển ứng dụng robot:

  • Logging và Debugging: Cung cấp hệ thống logging với màu sắc để dễ dàng phân biệt các loại thông điệp
  • Quản lý cấu hình: Hỗ trợ quản lý tham số từ file YAML, tương tự ROS parameter server
  • Quản lý vòng đời: Cung cấp cơ chế quản lý lifecycle của hệ thống robot, xử lý shutdown graceful
  • Plugin Loading: Hỗ trợ tìm kiếm và load các dynamic plugins sử dụng boost::dll

Các thành phần chính

1. Console Module - Hệ thống Logging

Module Console cung cấp hệ thống logging với hỗ trợ màu sắc ANSI để phân biệt các loại thông điệp.

Đặc điểm:

  • Hỗ trợ nhiều mức độ logging: info, success, warning, error, debug
  • Tự động phát hiện khả năng hỗ trợ màu của terminal
  • Throttle logging để giới hạn tần suất log, tránh spam console
  • Hỗ trợ logging với thông tin file và line number để debug
  • Tự động reset màu sau khi in để tránh ảnh hưởng đến output tiếp theo
  • Có thể bật/tắt màu sắc tùy theo môi trường

Cơ chế hoạt động:

  • Kiểm tra biến môi trường NO_COLORTERM để xác định hỗ trợ màu
  • Sử dụng static variables để lưu timestamp cho throttle logging
  • Tự động thêm newline nếu format string không kết thúc bằng newline
  • Hỗ trợ nhiều màu sắc: red, green, yellow, blue, cyan, magenta, white và các biến thể bright

Ứng dụng:

  • Debug và monitoring trong quá trình phát triển
  • Hiển thị trạng thái hệ thống với màu sắc dễ phân biệt
  • Logging có điều kiện với throttle để tránh spam
  • Tích hợp vào các hệ thống logging lớn hơn

2. NodeHandle Module - Quản lý Tham số

Module NodeHandle cung cấp interface quản lý tham số giống ROS parameter server, sử dụng YAML files làm backend.

Đặc điểm:

  • Hỗ trợ namespace phân cấp giống ROS
  • Tự động load YAML files từ config directory
  • Hỗ trợ nhiều kiểu dữ liệu: bool, int, double, float, string, vector, map
  • Merge nhiều YAML files vào một parameter tree
  • Thread-safe parameter access
  • Hỗ trợ nested parameters với cấu trúc phân cấp

Cơ chế hoạt động:

  • Sử dụng YAML::Node để lưu trữ tham số trong memory
  • Static root_ node chứa toàn bộ parameter tree, được chia sẻ giữa tất cả NodeHandle instances
  • Mỗi NodeHandle instance scope vào một namespace cụ thể
  • Tự động tìm và load YAML files từ config directory khi khởi tạo
  • Hỗ trợ remapping parameters tương tự ROS

Namespace System:

  • Root namespace ("" hoặc "/"): Truy cập toàn bộ parameter tree
  • Private namespace ("~"): Map tới config directory của node hiện tại
  • Nested namespaces: Sử dụng / separator (ví dụ: "robot/base/velocity")
  • Tất cả NodeHandle instances chia sẻ cùng một static parameter tree

Ứng dụng:

  • Quản lý cấu hình robot từ file YAML
  • Truyền tham số giữa các modules
  • Runtime configuration changes
  • Testing với các bộ tham số khác nhau

3. Init Module - Quản lý Vòng đời Hệ thống

Module Init quản lý vòng đời của robot system, tương tự ros::init()ros::ok() trong ROS.

Đặc điểm:

  • Quản lý trạng thái system (đang chạy hay đã shutdown)
  • Xử lý shutdown graceful với signal handling
  • Tự động xử lý SIGINT (Ctrl-C) để shutdown an toàn
  • Hỗ trợ custom signal handler
  • Thread-safe với std::atomic

Cơ chế hoạt động:

  • Sử dụng std::atomic để đảm bảo thread-safety
  • Tự động cài đặt SIGINT handler để xử lý Ctrl-C
  • Quản lý trạng thái shutdown với 2 flags: shutdown_requestedshutdown_complete
  • Hỗ trợ custom signal handler nếu cần xử lý đặc biệt

Các trạng thái:

  • Running: System đang chạy bình thường
  • Shutdown Requested: Shutdown đã được yêu cầu (ngay lập tức khi gọi shutdown())
  • Shutdown Complete: System đã shutdown hoàn toàn

Ứng dụng:

  • Main loops với kiểm tra robot::ok()
  • Thread loops cần kiểm tra trạng thái system
  • Long-running callbacks cần early exit khi shutdown
  • Graceful shutdown với cleanup resources

4. PluginLoaderHelper Module - Tìm kiếm Plugin Libraries

Module PluginLoaderHelper giúp tìm đường dẫn library file (.so) từ tên symbol (export name) được sử dụng với BOOST_DLL_ALIAS.

Đặc điểm:

  • Map tên symbol (export name) sang đường dẫn library file
  • Đọc cấu hình từ YAML file hoặc NodeHandle
  • Tự động tìm build directory tại runtime
  • Hỗ trợ nhiều cách tìm kiếm: từ config, từ build directory, từ system paths

Cơ chế hoạt động:

  • Đọc file YAML (boost_dll_plugins.yaml) hoặc từ NodeHandle
  • Map symbol names (ví dụ: "CustomPlanner") sang library paths
  • Tự động tìm build directory từ environment variables hoặc config
  • Hỗ trợ fallback mechanisms nếu không tìm thấy trong config

Ứng dụng:

  • Dynamic loading của global planners, local planners, recovery behaviors
  • Plugin discovery trong runtime
  • Tích hợp với boost::dll để load plugins
  • Quản lý plugin registry

Kiến trúc

Cấu trúc thư mục

robot_cpp/
├── include/robot/
│   ├── console.h              # Console logging API
│   ├── node_handle.h          # NodeHandle parameter management API
│   ├── init.h                 # System initialization and shutdown API
│   └── plugin_loader_helper.h # Plugin loader helper API
├── src/
│   ├── console.cpp            # Console implementation
│   ├── node_handle.cpp        # NodeHandle implementation
│   ├── init.cpp               # Init implementation
│   └── plugin_loader_helper.cpp # PluginLoaderHelper implementation
├── test/
│   └── test_node_handle.cpp   # Unit tests
├── INIT_USAGE.md              # Hướng dẫn chi tiết về Init module
├── PLUGIN_LOADER_README.md    # Hướng dẫn về PluginLoaderHelper
└── CMakeLists.txt

Mối quan hệ giữa các modules

  • Console là module độc lập, không phụ thuộc vào modules khác
  • NodeHandle sử dụng yaml-cpp để parse YAML files
  • Init quản lý lifecycle chung của system, được sử dụng bởi tất cả modules khác
  • PluginLoaderHelper sử dụng NodeHandle để đọc cấu hình plugins

Dependencies

  • yaml-cpp: Thư viện parse YAML files (cho NodeHandle và PluginLoaderHelper)
  • robot_xmlrpcpp: Hỗ trợ XmlRpcValue conversion (optional, cho NodeHandle)
  • robot_time: Thư viện quản lý thời gian (cho Init module với Rate/Duration)
  • C++17: Yêu cầu C++ standard 17 trở lên
  • Boost.DLL: Được sử dụng bởi PluginLoaderHelper (thông qua boost::dll)

Build và Installation

Thư viện hỗ trợ cả Catkin và Standalone CMake:

  • Với Catkin: Tích hợp vào catkin workspace và build như các ROS packages khác
  • Với Standalone CMake: Có thể build độc lập, không cần ROS

Use Cases

Configuration Management

Sử dụng NodeHandle để quản lý tất cả cấu hình robot từ file YAML, cho phép thay đổi cấu hình mà không cần recompile.

System Logging

Sử dụng Console module để log thông tin, cảnh báo, và lỗi với màu sắc, giúp dễ dàng debug và monitor hệ thống.

Lifecycle Management

Sử dụng Init module để quản lý vòng đời của ứng dụng, đảm bảo shutdown graceful khi nhận Ctrl-C hoặc signal khác.

Plugin Discovery

Sử dụng PluginLoaderHelper để tìm và load các plugins động tại runtime, cho phép mở rộng hệ thống mà không cần recompile.

Multi-threaded Applications

Tất cả các modules đều thread-safe, cho phép sử dụng an toàn trong các ứng dụng đa luồng.

Best Practices

  1. Sử dụng NodeHandle cho tất cả cấu hình: Tránh hardcode parameters, sử dụng YAML files

  2. Sử dụng Console logging thay vì printf/cout: Có màu sắc và throttle logging tự động

  3. Luôn kiểm tra robot::ok() trong loops: Đảm bảo có thể shutdown gracefully

  4. Sử dụng throttle logging cho frequent messages: Tránh spam console với các messages lặp lại

  5. Namespace organization: Sử dụng namespace phân cấp để tổ chức parameters một cách logic

  6. Plugin configuration: Sử dụng PluginLoaderHelper thay vì hardcode library paths

Tính năng nổi bật

1. Color Support với Auto-detection

Console module tự động phát hiện khả năng hỗ trợ màu của terminal và tự động tắt màu nếu:

  • Biến môi trường NO_COLOR được set
  • Terminal không hỗ trợ ANSI colors
  • Output được redirect vào file

2. Throttle Logging

Mỗi hàm throttle sử dụng static variable riêng để lưu timestamp, cho phép:

  • Giới hạn tần suất log của các messages lặp lại
  • Tránh spam console với các messages thường xuyên
  • Tự động reset sau một khoảng thời gian

3. YAML Auto-loading

NodeHandle tự động tìm và load YAML files từ config directory khi khởi tạo:

  • Tìm tất cả .yaml.yml files trong config directory
  • Merge tất cả files vào một parameter tree
  • Hỗ trợ nested structures và arrays

4. Thread-safe Operations

Tất cả các operations đều thread-safe:

  • NodeHandle sử dụng static parameter tree với thread-safe access
  • Init module sử dụng std::atomic cho flags
  • Console logging thread-safe với static variables

5. Graceful Shutdown

Init module cung cấp cơ chế shutdown graceful:

  • Tự động xử lý SIGINT (Ctrl-C)
  • Hỗ trợ custom signal handlers
  • Phân biệt giữa "shutdown requested" và "shutdown complete"
  • Cho phép early exit trong long-running callbacks

Lưu ý quan trọng

  • NodeHandle static tree: Tất cả NodeHandle instances chia sẻ cùng một static parameter tree, thay đổi từ một instance sẽ ảnh hưởng đến tất cả instances khác

  • YAML loading order: YAML files được load và merge theo thứ tự filesystem, file sau sẽ override parameters của file trước nếu có conflict

  • Throttle logging scope: Mỗi hàm throttle sử dụng static variable riêng, các lời gọi từ cùng một vị trí code sẽ chia sẻ cùng một throttle counter

  • Plugin path resolution: PluginLoaderHelper tìm library paths theo thứ tự: config file → build directory → system paths

  • Init timing: Cần gọi robot::init() trước khi sử dụng các modules khác, đặc biệt là robot::Time::now()

Tài liệu tham khảo

  • INIT_USAGE.md - Hướng dẫn chi tiết về Init module với các use cases và best practices
  • PLUGIN_LOADER_README.md - Hướng dẫn về PluginLoaderHelper và cách cấu hình plugins
  • README.md (file này) - Tổng quan về toàn bộ thư viện

License

BSD License - Xem file LICENSE trong thư mục gốc.