** TimeBase基類**
首先看time.h文件,它定義了一個(gè)叫TimeBase的類。注釋中說(shuō),TimeBase是個(gè)基類,定義了兩個(gè)成員變量uint32_t sec, nsec,還重載了+ ++、? -?、< <<、> >>、= ==等運(yùn)算符。
成員變量uint32_t sec, nsec其實(shí)就是時(shí)間的秒和納秒兩部分,它們合起來(lái)構(gòu)成一個(gè)完整的時(shí)刻。
至于為啥要分成兩部分而不是用一個(gè)來(lái)定義,可能是考慮到整數(shù)表示精度的問(wèn)題。
因?yàn)?2位整數(shù)最大表示的數(shù)字是2147483647。如果我們要用納秒這個(gè)范圍估計(jì)是不夠的。
你可能會(huì)問(wèn),機(jī)器人系統(tǒng)怎么會(huì)使用到納秒這么高精度的時(shí)間分辨率,畢竟控制器的定時(shí)器最高精度可能也只能到微秒?
如果你做過(guò)自動(dòng)駕駛項(xiàng)目,有使用過(guò)GPS和激光雷達(dá)傳感器的經(jīng)驗(yàn),就會(huì)發(fā)現(xiàn)GPS的時(shí)鐘精度就是納秒級(jí)的,它可以同步激光雷達(dá)每個(gè)激光點(diǎn)的時(shí)間戳。
還有,為什么定義TimeBase這個(gè)基類,原因大家很容易就能猜到。
因?yàn)樵诔绦蚶铮瑫r(shí)間本質(zhì)上就是一個(gè)數(shù)字而已,數(shù)字系統(tǒng)的序關(guān)系(能比較大小)和運(yùn)算(加減乘除)也同樣適用于時(shí)間這個(gè)東西。
當(dāng)然,這里只有加減沒(méi)有乘除,因?yàn)闀r(shí)間的乘除沒(méi)有意義。
Time類
緊接著TimeBase類的是Time類,它是TimeBase的子類。我們做機(jī)器人應(yīng)用程序開發(fā)時(shí)用不到TimeBase基類,但是Time類會(huì)經(jīng)常使用。
now()函數(shù)
Time類比TimeBase類多了now()函數(shù),它是我們的老熟人了。在開發(fā)應(yīng)用的時(shí)候,我們直接用下面的代碼就能得到當(dāng)前的時(shí)間戳:
ros::Time begin = ros::Time::now(); //獲取當(dāng)前時(shí)間
now()函數(shù)的定義在rostimesrctime.cpp里,因?yàn)樗艹S煤苤匾P者就把代碼粘貼在這里,如下。
函數(shù)很簡(jiǎn)單,可以看到,如果定義了使用仿真時(shí)間(g_use_sim_time為true),那就使用仿真時(shí)間,否則就使用墻上時(shí)間。
Time Time::now()
{
if (!g_initialized)
throw TimeNotInitializedException();
if (g_use_sim_time)
{
boost::mutex::scoped_lock lock(g_sim_time_mutex);
Time t = g_sim_time;
return t;
}
Time t;
ros_walltime(t.sec, t.nsec);
return t;
}
在ROS里,時(shí)間分成兩類,一種叫仿真時(shí)間,一種叫墻上時(shí)間。
顧名思義,墻上時(shí)間就是實(shí)際的客觀世界的時(shí)間,它一秒一秒地流逝,誰(shuí)都不能改變它,讓它快一點(diǎn)慢一點(diǎn)都不可能,除非你有超能力。
仿真時(shí)間則是可以由你控制的,讓它快它就快。之所以多了一個(gè)仿真時(shí)間,是因?yàn)橛袝r(shí)我們?cè)诜抡鏅C(jī)器人希望可以自己控制時(shí)間,例如為了提高驗(yàn)證算法的效率,讓它按我們的期望速度推進(jìn)。
在使用墻上時(shí)間的情況下,now()函數(shù)調(diào)用了ros_walltime函數(shù),這個(gè)函數(shù)也在rostimesrctime.cpp里。
剝開層層洋蔥皮,最后發(fā)現(xiàn),這個(gè)ros_walltime函數(shù)才是真正調(diào)用操作系統(tǒng)時(shí)間函數(shù)的地方,而且它還是個(gè)跨平臺(tái)的實(shí)現(xiàn)(Windows和Linux)。
如果操作系統(tǒng)是Linux,那它會(huì)使用clock_gettime函數(shù),在筆者使用的Ubuntu 18.04系統(tǒng)中這個(gè)函數(shù)在usrinclude路徑下。
但是萬(wàn)一缺少這個(gè)函數(shù),那么ROS會(huì)使用gettimeofday函數(shù),但是gettimeofday沒(méi)有clock_gettime精確,clock_gettime能提供納秒的精確度。
如果操作系統(tǒng)是Windows,那它會(huì)使用標(biāo)準(zhǔn)庫(kù)STL的chrono庫(kù)獲取當(dāng)前的時(shí)刻,要用這個(gè)庫(kù)只需要引用它的頭文件,所以在time.cpp中引用了#include。
具體使用的函數(shù)就是
std::chrono::system_clock::now().time_since_epoch()。
當(dāng)然,時(shí)間得是秒和納秒的形式,所以用了count方法:
uint64_t now_ns = std::chrono::duration_cast< std::chrono::nanoseconds >
(std::chrono::system_clock::now().time_since_epoch()).count();
WallTime類
后面又接著聲明了WallTime類和SteadyTime類。
-
控制器
+關(guān)注
關(guān)注
114文章
17113瀏覽量
184336 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3298瀏覽量
118963 -
文件
+關(guān)注
關(guān)注
1文章
579瀏覽量
25373 -
ROS
+關(guān)注
關(guān)注
1文章
288瀏覽量
17752
發(fā)布評(píng)論請(qǐng)先 登錄
怎么解決依賴關(guān)系中vi沖突?
【Toybrick RK3399Pro AI開發(fā)板試用體驗(yàn)】Fedora系統(tǒng)安裝ROS
ROS是否適用于工業(yè)?
在Android中使用ROS
ROS與STM32之間的聯(lián)系
怎樣去使用ROS中的launch啟動(dòng)文件呢
在FirePrime開發(fā)板上編譯安裝ROS jade
ROS教程之ROS機(jī)器人操作系統(tǒng)基礎(chǔ)知識(shí)概述資料免費(fèi)下載

如何在IDEA中查看依賴關(guān)系
ROS是如何設(shè)計(jì)的 ROS客戶端庫(kù)

Unity與ROS鏈接介紹

ROS Motion Planning運(yùn)動(dòng)規(guī)劃庫(kù)如何安裝相關(guān)依賴
ros的基本概念是什么
ros怎么設(shè)置環(huán)境變量
如何將python文件導(dǎo)入到ROS系統(tǒng)中

評(píng)論