# WallTime - Hướng dẫn sử dụng ## Tổng quan `WallTime` là class đại diện cho **thời gian thực (wall-clock time)** trong thư viện `robot_time`. Khác với `Time`, `WallTime` luôn sử dụng thời gian thực từ hệ thống và **không bị ảnh hưởng bởi simulated time**. ## Đặc điểm chính ### 1. Luôn sử dụng thời gian thực - `WallTime` luôn lấy thời gian từ system clock - Không phụ thuộc vào simulated time - Không cần khởi tạo (`Time::init()`) - Không bao giờ throw exception ### 2. Không cần khởi tạo ```cpp // Time - CẦN khởi tạo robot::Time::init(); // Phải gọi trước robot::Time t = robot::Time::now(); // Có thể throw exception // WallTime - KHÔNG cần khởi tạo robot::WallTime t = robot::WallTime::now(); // Luôn hoạt động ``` ### 3. Không bị ảnh hưởng bởi simulated time ```cpp // Trong simulation với /use_sim_time = true robot::Time t1 = robot::Time::now(); // Trả về simulated time robot::WallTime t2 = robot::WallTime::now(); // Vẫn trả về thời gian thực ``` ## API Reference ### Constructors ```cpp // Default constructor - khởi tạo với giá trị 0 robot::WallTime t1; // Constructor với giây và nanosecond robot::WallTime t2(1234567890, 123456789); // Constructor từ số thực (giây) robot::WallTime t3(1234567890.123456789); ``` ### Static Methods #### `static WallTime now()` Trả về thời gian hiện tại (wall-clock time). ```cpp robot::WallTime current_time = robot::WallTime::now(); ``` **Đặc điểm:** - Luôn trả về thời gian thực - Không cần khởi tạo trước - Không throw exception - Thread-safe #### `static bool sleepUntil(const WallTime& end)` Ngủ cho đến khi đạt đến thời điểm `end`. ```cpp robot::WallTime end_time = robot::WallTime::now() + robot::WallDuration(5.0); bool success = robot::WallTime::sleepUntil(end_time); ``` **Return value:** - `true`: Đã ngủ đến thời điểm mong muốn - `false`: Bị gián đoạn hoặc có lỗi #### `static bool isSystemTime()` Luôn trả về `true` vì `WallTime` luôn sử dụng system time. ```cpp bool is_system = robot::WallTime::isSystemTime(); // Luôn là true ``` ### Methods kế thừa từ `TimeBase` #### Chuyển đổi đơn vị ```cpp robot::WallTime t(1234567890, 123456789); // Chuyển sang giây (double) double seconds = t.toSec(); // 1234567890.123456789 // Chuyển sang nanosecond uint64_t nanoseconds = t.toNSec(); // Khởi tạo từ giây t.fromSec(1234567890.123456789); // Khởi tạo từ nanosecond t.fromNSec(1234567890123456789ULL); ``` #### So sánh ```cpp robot::WallTime t1 = robot::WallTime::now(); robot::WallDuration d(1.0); robot::WallTime t2 = t1 + d; // So sánh bool is_equal = (t1 == t2); // false bool is_less = (t1 < t2); // true bool is_greater = (t1 > t2); // false bool is_less_equal = (t1 <= t2); // true bool is_greater_equal = (t1 >= t2); // false ``` #### Phép toán với WallDuration ```cpp robot::WallTime t = robot::WallTime::now(); robot::WallDuration d(5.0); // Cộng duration robot::WallTime future = t + d; // Trừ duration robot::WallTime past = t - d; // Trừ hai WallTime để được WallDuration robot::WallDuration elapsed = future - t; // Compound assignment t += d; // t = t + d t -= d; // t = t - d ``` #### Kiểm tra giá trị ```cpp robot::WallTime t; // Kiểm tra có phải zero không bool is_zero = t.isZero(); // true // Kiểm tra các giá trị đặc biệt bool is_max = (t == robot::WallTime::MAX); bool is_min = (t == robot::WallTime::MIN); bool is_zero_const = (t == robot::WallTime::ZERO); ``` ### Constants ```cpp robot::WallTime::MAX // Giá trị lớn nhất robot::WallTime::MIN // Giá trị nhỏ nhất robot::WallTime::ZERO // Zero (0, 0) robot::WallTime::UNINITIALIZED // Uninitialized (0, 0) ``` ## So sánh với `Time` | Đặc điểm | `Time` | `WallTime` | |----------|--------|------------| | Nguồn thời gian | Simulated hoặc wall-clock | Luôn wall-clock | | Cần khởi tạo | Có (`Time::init()`) | Không | | Có thể throw exception | Có (nếu chưa init) | Không | | Ảnh hưởng bởi sim time | Có | Không | | Dùng trong ROS messages | Nên dùng | Không nên | | Đo thời gian thực thi | Không phù hợp | Phù hợp | | Timeout thực tế | Không phù hợp | Phù hợp | | Logging với timestamp | Có thể | Phù hợp | ## Use Cases ### 1. Đo thời gian thực thi (Profiling/Benchmarking) ```cpp // Đo thời gian thực thi của một hàm robot::WallTime start = robot::WallTime::now(); // Thực hiện công việc doSomething(); robot::WallTime end = robot::WallTime::now(); robot::WallDuration elapsed = end - start; std::cout << "Thời gian thực thi: " << elapsed.toSec() << " giây" << std::endl; ``` **Ví dụ thực tế từ codebase:** ```cpp // Trong clear_costmap_recovery.cpp robot::WallTime t0 = robot::WallTime::now(); clear(global_costmap_); ROS_DEBUG("Global costmap cleared in %fs", (robot::WallTime::now() - t0).toSec()); ``` ### 2. Timeout và thời gian chờ ```cpp // Đặt timeout cho một thao tác robot::WallTime start = robot::WallTime::now(); robot::WallDuration timeout(5.0); // 5 giây while (!operation_complete) { if (robot::WallTime::now() - start > timeout) { std::cout << "Timeout!" << std::endl; break; } // Thực hiện công việc doWork(); // Sleep một chút robot::WallDuration(0.1).sleep(); } ``` ### 3. Logging với timestamp thực ```cpp void logMessage(const std::string& msg) { robot::WallTime now = robot::WallTime::now(); std::cout << "[" << now.toSec() << "] " << msg << std::endl; } ``` ### 4. Giao tiếp với hardware ```cpp // Giao tiếp với hardware cần timing chính xác robot::WallTime last_update = robot::WallTime::now(); robot::WallDuration update_interval(0.02); // 50Hz while (running) { // Cập nhật hardware updateHardware(); // Đợi đến lần cập nhật tiếp theo robot::WallTime next_update = last_update + update_interval; robot::WallTime::sleepUntil(next_update); last_update = robot::WallTime::now(); } ``` ### 5. Performance monitoring ```cpp class PerformanceMonitor { private: robot::WallTime start_time_; std::vector measurements_; public: void start() { start_time_ = robot::WallTime::now(); } void record() { robot::WallTime now = robot::WallTime::now(); robot::WallDuration elapsed = now - start_time_; measurements_.push_back(elapsed); start_time_ = now; } double getAverageTime() { if (measurements_.empty()) return 0.0; double total = 0.0; for (const auto& d : measurements_) { total += d.toSec(); } return total / measurements_.size(); } }; ``` ## Best Practices ### 1. Sử dụng WallTime cho đo đạc thời gian thực ```cpp // ✅ ĐÚNG - Dùng WallTime để đo thời gian thực thi robot::WallTime start = robot::WallTime::now(); processData(); robot::WallDuration elapsed = robot::WallTime::now() - start; // ❌ SAI - Dùng Time có thể không chính xác trong simulation robot::Time start = robot::Time::now(); processData(); robot::Duration elapsed = robot::Time::now() - start; ``` ### 2. Sử dụng Time cho ROS messages ```cpp // ✅ ĐÚNG - Dùng Time cho ROS messages geometry_msgs::PoseStamped msg; msg.header.stamp = robot::Time::now(); // ❌ SAI - Không nên dùng WallTime cho ROS messages msg.header.stamp = robot::WallTime::now(); // Không tương thích ``` ### 3. Kết hợp Time và WallTime ```cpp // Sử dụng Time cho ROS operations robot::Time ros_time = robot::Time::now(); publishMessage(msg); // Sử dụng WallTime cho performance monitoring robot::WallTime wall_start = robot::WallTime::now(); expensiveOperation(); robot::WallDuration wall_elapsed = robot::WallTime::now() - wall_start; std::cout << "Operation took " << wall_elapsed.toSec() << " seconds" << std::endl; ``` ### 4. Timeout với WallTime ```cpp // ✅ ĐÚNG - Dùng WallTime cho timeout thực tế robot::WallTime deadline = robot::WallTime::now() + robot::WallDuration(10.0); while (robot::WallTime::now() < deadline) { if (tryOperation()) break; robot::WallDuration(0.1).sleep(); } ``` ## Ví dụ hoàn chỉnh ### Ví dụ 1: Đo thời gian thực thi của nhiều operations ```cpp #include #include #include void benchmarkOperations() { std::vector operations = {"operation1", "operation2", "operation3"}; for (const auto& op_name : operations) { robot::WallTime start = robot::WallTime::now(); // Thực hiện operation (giả lập) performOperation(op_name); robot::WallDuration elapsed = robot::WallTime::now() - start; std::cout << op_name << " took " << elapsed.toSec() << " seconds" << std::endl; } } ``` ### Ví dụ 2: Rate limiting với WallTime ```cpp class RateLimiter { private: robot::WallTime last_time_; robot::WallDuration min_interval_; public: RateLimiter(double min_rate_hz) : min_interval_(1.0 / min_rate_hz) , last_time_(robot::WallTime::now()) {} bool canProceed() { robot::WallTime now = robot::WallTime::now(); robot::WallDuration elapsed = now - last_time_; if (elapsed >= min_interval_) { last_time_ = now; return true; } return false; } }; ``` ### Ví dụ 3: Timeout handler ```cpp class TimeoutHandler { private: robot::WallTime start_time_; robot::WallDuration timeout_; public: TimeoutHandler(double timeout_seconds) : timeout_(timeout_seconds) , start_time_(robot::WallTime::now()) {} bool isExpired() const { robot::WallTime now = robot::WallTime::now(); return (now - start_time_) > timeout_; } robot::WallDuration remaining() const { robot::WallTime now = robot::WallTime::now(); robot::WallDuration elapsed = now - start_time_; robot::WallDuration remaining = timeout_ - elapsed; return (remaining > robot::WallDuration(0)) ? remaining : robot::WallDuration(0); } void reset() { start_time_ = robot::WallTime::now(); } }; ``` ## Tương thích với ROS `robot::WallTime` được thiết kế để tương thích với `ros::WallTime` trong ROS. Các API và behavior đều giống nhau: ```cpp // ROS ros::WallTime t1 = ros::WallTime::now(); ros::WallDuration d = ros::WallDuration(1.0); ros::WallTime t2 = t1 + d; // robot_time (tương đương) robot::WallTime t1 = robot::WallTime::now(); robot::WallDuration d = robot::WallDuration(1.0); robot::WallTime t2 = t1 + d; ``` ## Lưu ý quan trọng 1. **Không dùng WallTime cho ROS messages**: ROS messages yêu cầu `Time`, không phải `WallTime` 2. **Precision**: `WallTime` có độ chính xác nanosecond, nhưng độ chính xác thực tế phụ thuộc vào hệ thống 3. **Thread safety**: Tất cả operations của `WallTime` đều thread-safe 4. **Performance**: `WallTime::now()` rất nhanh, có thể gọi thường xuyên mà không lo về performance 5. **Cross-platform**: Hoạt động trên cả Linux và Windows ## Tài liệu tham khảo - `README.md` - Tổng quan về thư viện robot_time - `time.h` - Header file với API đầy đủ - ROS Documentation: http://docs.ros.org/en/diamondback/api/rostime/html/classros_1_1WallTime.html