add WallTime và WallTimer
This commit is contained in:
331
examples/walltime_example.cpp
Normal file
331
examples/walltime_example.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
/*********************************************************************
|
||||
* WallTime Usage Examples
|
||||
*
|
||||
* File này minh họa cách sử dụng WallTime trong các tình huống thực tế
|
||||
*********************************************************************/
|
||||
|
||||
#include <robot/time.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
// Ví dụ 1: Đo thời gian thực thi của một hàm
|
||||
void example1_measureExecutionTime()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 1: Đo thời gian thực thi ===" << std::endl;
|
||||
|
||||
robot::WallTime start = robot::WallTime::now();
|
||||
|
||||
// Giả lập một công việc tốn thời gian
|
||||
double sum = 0.0;
|
||||
for (int i = 0; i < 1000000; ++i)
|
||||
{
|
||||
sum += std::sin(i);
|
||||
}
|
||||
|
||||
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;
|
||||
std::cout << "Thời gian thực thi: " << elapsed.toNSec() << " nanoseconds" << std::endl;
|
||||
}
|
||||
|
||||
// Ví dụ 2: Timeout với WallTime
|
||||
void example2_timeout()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 2: Timeout ===" << std::endl;
|
||||
|
||||
robot::WallTime start = robot::WallTime::now();
|
||||
robot::WallDuration timeout(2.0); // 2 giây timeout
|
||||
|
||||
int iterations = 0;
|
||||
while (robot::WallTime::now() - start < timeout)
|
||||
{
|
||||
iterations++;
|
||||
// Giả lập công việc
|
||||
robot::WallDuration(0.1).sleep();
|
||||
}
|
||||
|
||||
robot::WallDuration actual_elapsed = robot::WallTime::now() - start;
|
||||
std::cout << "Số lần lặp: " << iterations << std::endl;
|
||||
std::cout << "Thời gian thực tế: " << actual_elapsed.toSec() << " giây" << std::endl;
|
||||
}
|
||||
|
||||
// Ví dụ 3: So sánh Time và WallTime
|
||||
void example3_compareTimeAndWallTime()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 3: So sánh Time và WallTime ===" << std::endl;
|
||||
|
||||
// Khởi tạo Time (cần thiết)
|
||||
robot::Time::init();
|
||||
|
||||
robot::Time ros_time = robot::Time::now();
|
||||
robot::WallTime wall_time = robot::WallTime::now();
|
||||
|
||||
std::cout << "ROS Time: " << ros_time.toSec() << std::endl;
|
||||
std::cout << "Wall Time: " << wall_time.toSec() << std::endl;
|
||||
|
||||
// Trong trường hợp không có simulated time, chúng sẽ giống nhau
|
||||
// Nhưng WallTime không cần init()
|
||||
}
|
||||
|
||||
// Ví dụ 4: Sleep until một thời điểm cụ thể
|
||||
void example4_sleepUntil()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 4: Sleep until ===" << std::endl;
|
||||
|
||||
robot::WallTime start = robot::WallTime::now();
|
||||
robot::WallTime target = start + robot::WallDuration(1.5); // 1.5 giây sau
|
||||
|
||||
std::cout << "Bắt đầu: " << start.toSec() << std::endl;
|
||||
std::cout << "Mục tiêu: " << target.toSec() << std::endl;
|
||||
|
||||
bool success = robot::WallTime::sleepUntil(target);
|
||||
|
||||
robot::WallTime end = robot::WallTime::now();
|
||||
robot::WallDuration actual = end - start;
|
||||
|
||||
std::cout << "Kết thúc: " << end.toSec() << std::endl;
|
||||
std::cout << "Thời gian thực tế: " << actual.toSec() << " giây" << std::endl;
|
||||
std::cout << "Thành công: " << (success ? "Có" : "Không") << std::endl;
|
||||
}
|
||||
|
||||
// Ví dụ 5: Benchmark nhiều operations
|
||||
void example5_benchmark()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 5: Benchmark ===" << std::endl;
|
||||
|
||||
std::vector<std::string> operations = {
|
||||
"Operation A",
|
||||
"Operation B",
|
||||
"Operation C"
|
||||
};
|
||||
|
||||
for (const auto& op_name : operations)
|
||||
{
|
||||
robot::WallTime start = robot::WallTime::now();
|
||||
|
||||
// Giả lập công việc với thời gian khác nhau
|
||||
if (op_name == "Operation A")
|
||||
{
|
||||
robot::WallDuration(0.1).sleep();
|
||||
}
|
||||
else if (op_name == "Operation B")
|
||||
{
|
||||
robot::WallDuration(0.2).sleep();
|
||||
}
|
||||
else
|
||||
{
|
||||
robot::WallDuration(0.15).sleep();
|
||||
}
|
||||
|
||||
robot::WallDuration elapsed = robot::WallTime::now() - start;
|
||||
std::cout << op_name << ": " << elapsed.toSec() << " giây" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Ví dụ 6: Rate limiting với WallTime
|
||||
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;
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
robot::WallTime now = robot::WallTime::now();
|
||||
robot::WallDuration elapsed = now - last_time_;
|
||||
|
||||
if (elapsed < min_interval_)
|
||||
{
|
||||
robot::WallDuration remaining = min_interval_ - elapsed;
|
||||
remaining.sleep();
|
||||
last_time_ = robot::WallTime::now();
|
||||
}
|
||||
else
|
||||
{
|
||||
last_time_ = now;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void example6_rateLimiter()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 6: Rate Limiter ===" << std::endl;
|
||||
|
||||
RateLimiter limiter(2.0); // Tối đa 2 lần/giây
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
robot::WallTime start = robot::WallTime::now();
|
||||
limiter.wait();
|
||||
robot::WallTime end = robot::WallTime::now();
|
||||
|
||||
robot::WallDuration elapsed = end - start;
|
||||
std::cout << "Lần " << (i+1) << ": " << elapsed.toSec() << " giây" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Ví dụ 7: Timeout handler
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
void example7_timeoutHandler()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 7: Timeout Handler ===" << std::endl;
|
||||
|
||||
TimeoutHandler handler(3.0); // 3 giây timeout
|
||||
|
||||
int count = 0;
|
||||
while (!handler.isExpired() && count < 10)
|
||||
{
|
||||
robot::WallDuration remaining = handler.remaining();
|
||||
std::cout << "Còn lại: " << remaining.toSec() << " giây" << std::endl;
|
||||
|
||||
robot::WallDuration(0.5).sleep();
|
||||
count++;
|
||||
}
|
||||
|
||||
if (handler.isExpired())
|
||||
{
|
||||
std::cout << "Timeout!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Hoàn thành trước khi timeout" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Ví dụ 8: Phép toán với WallTime và WallDuration
|
||||
void example8_arithmetic()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 8: Phép toán ===" << std::endl;
|
||||
|
||||
robot::WallTime t1 = robot::WallTime::now();
|
||||
robot::WallDuration d(5.0); // 5 giây
|
||||
|
||||
// Cộng duration
|
||||
robot::WallTime t2 = t1 + d;
|
||||
std::cout << "t1: " << t1.toSec() << std::endl;
|
||||
std::cout << "t2 = t1 + 5s: " << t2.toSec() << std::endl;
|
||||
|
||||
// Trừ duration
|
||||
robot::WallTime t3 = t2 - robot::WallDuration(2.0);
|
||||
std::cout << "t3 = t2 - 2s: " << t3.toSec() << std::endl;
|
||||
|
||||
// Trừ hai WallTime để được WallDuration
|
||||
robot::WallDuration elapsed = t2 - t1;
|
||||
std::cout << "t2 - t1 = " << elapsed.toSec() << " giây" << std::endl;
|
||||
|
||||
// So sánh
|
||||
std::cout << "t1 < t2: " << (t1 < t2) << std::endl;
|
||||
std::cout << "t1 == t3: " << (t1 == t3) << std::endl;
|
||||
}
|
||||
|
||||
// Ví dụ 9: Chuyển đổi đơn vị
|
||||
void example9_conversion()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 9: Chuyển đổi đơn vị ===" << std::endl;
|
||||
|
||||
// Tạo WallTime từ giây
|
||||
robot::WallTime t1(1234567890.123456789);
|
||||
std::cout << "Từ giây: " << t1.toSec() << std::endl;
|
||||
std::cout << "Sang nanosecond: " << t1.toNSec() << std::endl;
|
||||
|
||||
// Tạo từ giây và nanosecond
|
||||
robot::WallTime t2(1234567890, 123456789);
|
||||
std::cout << "Từ sec/nsec: " << t2.toSec() << std::endl;
|
||||
|
||||
// Chuyển đổi
|
||||
double seconds = t2.toSec();
|
||||
uint64_t nanoseconds = t2.toNSec();
|
||||
std::cout << "Giây: " << seconds << std::endl;
|
||||
std::cout << "Nanosecond: " << nanoseconds << std::endl;
|
||||
}
|
||||
|
||||
// Ví dụ 10: Constants
|
||||
void example10_constants()
|
||||
{
|
||||
std::cout << "\n=== Ví dụ 10: Constants ===" << std::endl;
|
||||
|
||||
std::cout << "MAX: " << robot::WallTime::MAX.toSec() << std::endl;
|
||||
std::cout << "MIN: " << robot::WallTime::MIN.toSec() << std::endl;
|
||||
std::cout << "ZERO: " << robot::WallTime::ZERO.toSec() << std::endl;
|
||||
std::cout << "UNINITIALIZED: " << robot::WallTime::UNINITIALIZED.toSec() << std::endl;
|
||||
|
||||
robot::WallTime t;
|
||||
std::cout << "Default WallTime is zero: " << t.isZero() << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::cout << "========================================" << std::endl;
|
||||
std::cout << "WallTime Usage Examples" << std::endl;
|
||||
std::cout << "========================================" << std::endl;
|
||||
|
||||
example1_measureExecutionTime();
|
||||
example2_timeout();
|
||||
example3_compareTimeAndWallTime();
|
||||
example4_sleepUntil();
|
||||
example5_benchmark();
|
||||
example6_rateLimiter();
|
||||
example7_timeoutHandler();
|
||||
example8_arithmetic();
|
||||
example9_conversion();
|
||||
example10_constants();
|
||||
|
||||
std::cout << "\n========================================" << std::endl;
|
||||
std::cout << "Tất cả ví dụ đã hoàn thành!" << std::endl;
|
||||
std::cout << "========================================" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
229
examples/walltimer_example.cpp
Normal file
229
examples/walltimer_example.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
/*********************************************************************
|
||||
* WallTimer Example
|
||||
*
|
||||
* Demonstrates various uses of robot::WallTimer
|
||||
*********************************************************************/
|
||||
|
||||
#include <robot/wall_timer.h>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
// Example 1: Simple periodic callback
|
||||
void simpleCallback(const robot::WallTimerEvent& event)
|
||||
{
|
||||
std::cout << "[Simple] Timer fired at wall time: "
|
||||
<< event.current_real.toSec() << std::endl;
|
||||
std::cout << "[Simple] Time since last callback: "
|
||||
<< event.last_duration.toSec() << " seconds" << std::endl;
|
||||
}
|
||||
|
||||
// Example 2: Performance monitoring
|
||||
class PerformanceMonitor
|
||||
{
|
||||
public:
|
||||
void start()
|
||||
{
|
||||
timer_ = std::make_unique<robot::WallTimer>(
|
||||
robot::WallDuration(1.0), // Check every 1 second
|
||||
[this](const robot::WallTimerEvent& event) {
|
||||
this->monitor(event);
|
||||
},
|
||||
false, // Repeating
|
||||
true // Auto-start
|
||||
);
|
||||
}
|
||||
|
||||
void monitor(const robot::WallTimerEvent& event)
|
||||
{
|
||||
static int count = 0;
|
||||
count++;
|
||||
|
||||
double actual_interval = event.last_duration.toSec();
|
||||
double expected_interval = 1.0;
|
||||
|
||||
std::cout << "[Monitor] Check #" << count
|
||||
<< " - Expected: " << expected_interval
|
||||
<< "s, Actual: " << actual_interval << "s";
|
||||
|
||||
if (actual_interval > expected_interval * 1.1)
|
||||
{
|
||||
std::cout << " (DRIFT DETECTED!)";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if (timer_)
|
||||
{
|
||||
timer_->stop();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<robot::WallTimer> timer_;
|
||||
};
|
||||
|
||||
// Example 3: One-shot delayed action
|
||||
void delayedAction(const robot::WallTimerEvent& event)
|
||||
{
|
||||
std::cout << "[Delayed] Action executed after delay!" << std::endl;
|
||||
std::cout << "[Delayed] Executed at wall time: "
|
||||
<< event.current_real.toSec() << std::endl;
|
||||
}
|
||||
|
||||
// Example 4: Dynamic period adjustment
|
||||
class DynamicTimer
|
||||
{
|
||||
public:
|
||||
void start()
|
||||
{
|
||||
timer_ = std::make_unique<robot::WallTimer>(
|
||||
robot::WallDuration(1.0), // Start with 1 second
|
||||
[this](const robot::WallTimerEvent& event) {
|
||||
this->callback(event);
|
||||
},
|
||||
false, // Repeating
|
||||
true // Auto-start
|
||||
);
|
||||
|
||||
// After 3 seconds, change period to 0.5 seconds
|
||||
adjust_thread_ = std::thread([this]() {
|
||||
robot::WallDuration(3.0).sleep();
|
||||
std::cout << "[Dynamic] Changing period to 0.5 seconds..." << std::endl;
|
||||
timer_->setPeriod(robot::WallDuration(0.5), true);
|
||||
});
|
||||
}
|
||||
|
||||
void callback(const robot::WallTimerEvent& event)
|
||||
{
|
||||
static int count = 0;
|
||||
count++;
|
||||
std::cout << "[Dynamic] Callback #" << count
|
||||
<< " at " << event.current_real.toSec() << std::endl;
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if (timer_)
|
||||
{
|
||||
timer_->stop();
|
||||
}
|
||||
if (adjust_thread_.joinable())
|
||||
{
|
||||
adjust_thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<robot::WallTimer> timer_;
|
||||
std::thread adjust_thread_;
|
||||
};
|
||||
|
||||
// Example 5: Timer with member function
|
||||
class TimerClass
|
||||
{
|
||||
public:
|
||||
void startTimer()
|
||||
{
|
||||
timer_ = std::make_unique<robot::WallTimer>(
|
||||
robot::WallDuration(0.5), // 2 Hz
|
||||
&TimerClass::timerCallback,
|
||||
this,
|
||||
false, // Repeating
|
||||
true // Auto-start
|
||||
);
|
||||
}
|
||||
|
||||
void timerCallback(const robot::WallTimerEvent& event)
|
||||
{
|
||||
static int count = 0;
|
||||
count++;
|
||||
std::cout << "[Class] Member function callback #" << count
|
||||
<< " at " << event.current_real.toSec() << std::endl;
|
||||
}
|
||||
|
||||
void stopTimer()
|
||||
{
|
||||
if (timer_)
|
||||
{
|
||||
timer_->stop();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<robot::WallTimer> timer_;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "=== WallTimer Examples ===" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example 1: Simple timer
|
||||
std::cout << "Example 1: Simple periodic callback" << std::endl;
|
||||
{
|
||||
robot::WallTimer timer(
|
||||
robot::WallDuration(1.0),
|
||||
simpleCallback,
|
||||
false, // Repeating
|
||||
true // Auto-start
|
||||
);
|
||||
|
||||
robot::WallDuration(3.0).sleep(); // Run for 3 seconds
|
||||
timer.stop();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example 2: Performance monitoring
|
||||
std::cout << "Example 2: Performance monitoring" << std::endl;
|
||||
{
|
||||
PerformanceMonitor monitor;
|
||||
monitor.start();
|
||||
|
||||
robot::WallDuration(5.0).sleep(); // Run for 5 seconds
|
||||
monitor.stop();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example 3: One-shot timer
|
||||
std::cout << "Example 3: One-shot delayed action" << std::endl;
|
||||
{
|
||||
robot::WallTimer timer(
|
||||
robot::WallDuration(2.0),
|
||||
delayedAction,
|
||||
true, // One-shot
|
||||
true // Auto-start
|
||||
);
|
||||
|
||||
robot::WallDuration(3.0).sleep(); // Wait for it to fire
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example 4: Dynamic period adjustment
|
||||
std::cout << "Example 4: Dynamic period adjustment" << std::endl;
|
||||
{
|
||||
DynamicTimer dynamic;
|
||||
dynamic.start();
|
||||
|
||||
robot::WallDuration(8.0).sleep(); // Run for 8 seconds
|
||||
dynamic.stop();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example 5: Member function callback
|
||||
std::cout << "Example 5: Member function callback" << std::endl;
|
||||
{
|
||||
TimerClass timer_obj;
|
||||
timer_obj.startTimer();
|
||||
|
||||
robot::WallDuration(3.0).sleep(); // Run for 3 seconds
|
||||
timer_obj.stopTimer();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "All examples completed!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user