目标
1. 设计C++时间管理类,实现类似ROS中ros::Time::now()功能,能够直接输出double类型的时间戳。不过有所变化:可以选择时间戳的精度;
2. 可以获取时间段,比如用于计算频率/帧率,统计代码耗时等。
实施
目标1
在函数体static TimeUtil now()中使用非静态变量时,会报错:
Error: invalid use of member in static member function
c++ - Error: invalid use of member in static member function - Stack Overflowhttps://stackoverflow.com/questions/17391853/error-invalid-use-of-member-in-static-member-functioninvalid use of member in static member function - arduino - Stack Overflow
https://stackoverflow.com/questions/55105861/invalid-use-of-member-in-static-member-function-arduino
整体代码如下:
#ifndef TIME_UTIL_H_
#define TIME_UTIL_H_
#include <ctime>
#include <cstdlib>
#include <chrono>
enum TimeUnit{milliS, microS, nanoS}; //毫秒,微秒,纳秒, 默认微秒
class TimeUtil
{
public:
TimeUtil()
{
}
TimeUtil(TimeUnit timeUnit)
// :tu_(timeUnit)
{
tuS_ = timeUnit;
}
TimeUtil(const double &stamp)
:now_(stamp * 1000)
{
}
~TimeUtil(){}
static TimeUtil now()
{
TimeUtil t;
switch (tuS_)
{
case milliS:
t.now_ = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
break;
case nanoS:
t.now_ = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
break;
default:
t.now_ = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
break;
}
return t;
}
double toSec()
{
switch (tuS_)
{
case milliS:
stamp_ = static_cast<double>(now_) * 0.001;
break;
case nanoS:
stamp_ = static_cast<double>(now_) * 1.e-9;
break;
default:
stamp_ = static_cast<double>(now_) * 1.e-6;
break;
}
return stamp_;
}
private:
uint64_t now_;
double stamp_;
// TimeUnit tu_;
static TimeUnit tuS_;
};
#endif
因为ROS的多了一个精度选择,所以需要变量,完全仿ROS的话,使用时要给static TimeUnit tuS_;在目标对象定义一次,不大好用。
因此就不完全仿ROS的格式,改成以下代码算了:
#ifndef TIME_UTIL_H_
#define TIME_UTIL_H_
#include <ctime>
#include <cstdlib>
#include <chrono>
enum TimeUnit{milliS, microS, nanoS}; //毫秒,微秒,纳秒, 默认微秒
class TimeUtil
{
public:
TimeUtil()
{
}
TimeUtil(TimeUnit timeUnit)
:tu_(timeUnit)
{
}
TimeUtil(const double &stamp)
:now_(stamp * 1000)
{
}
~TimeUtil(){}
TimeUtil now()
{
TimeUtil t;
switch (tu_)
{
case milliS:
t.now_ = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
break;
case nanoS:
t.now_ = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
break;
default:
t.now_ = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
break;
}
return t;
}
double toSec()
{
switch (tu_)
{
case milliS:
stamp_ = static_cast<double>(now_) * 0.001;
break;
case nanoS:
stamp_ = static_cast<double>(now_) * 1.e-9;
break;
default:
stamp_ = static_cast<double>(now_) * 1.e-6;
break;
}
return stamp_;
}
private:
uint64_t now_;
double stamp_;
TimeUnit tu_;
};
使用时定义一下,就可以获得double类型的时间戳了。
TimeUtil stamp;
cout << "fusion and vo calibration first time: " << stamp.now().toSec() << endl;
目标2
整体代码如下:
class TicToc
{
public:
TicToc()
{
tic();
}
void tic()
{
start = std::chrono::system_clock::now();
}
double toc()
{
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
return elapsed_seconds.count() * 1000;
}
private:
std::chrono::time_point<std::chrono::system_clock> start, end;
};