robot_time/WALLTIME_USAGE.md

467 lines
12 KiB
Markdown

# 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``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<robot::WallDuration> 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 <robot/time.h>
#include <iostream>
#include <vector>
void benchmarkOperations()
{
std::vector<std::string> 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