環境
この記事は以下の環境で動いています。
項目 | 値 |
---|---|
CPU | Core i5-8250U |
Ubuntu | 16.04 |
ROS | Kinetic |
インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。
概要
ROSで複数マシンを使うときに問題になるものとして時刻の問題があります。ロボットの処理では時刻に依存するものがあります。しかしROSを1つのマシンで動かしている分では時刻ずれの問題は発生しないのでこれにつて考慮されることは少ないです。
普段PCはインターネットに接続されているのでNTPによってNTPサーバーと時刻が同期されるので、複数PC間でこのような処理を行っても問題は起こりません。しかし展示会等でインターネット接続がない環境に持って行った瞬間にこの問題が顕在化します。PCのRTCでは最大で1日で1秒ほど時間がずれることもあります。
クローズな環境(=インターネット接続がない環境)でコンピューターのうち1つをNTPサーバーとして、それにほかのPCがクライアントとして時刻同期する設定を説明します。
時刻ずれによる問題
一番分かりやすいところはrvizのtfの表示です。例えば2つのPC、PC-AとPC-BでROSを実行していて、Rvizを表示しているPC-AよりもPC-Bのほうが1秒時計が遅れているとします。PC-Bがtfでjointを動かしたとすると、rviz上では1秒遅れて表示されます。
非NTPでの時刻ずれ
PCの時刻は電源が入っている時はCPUのカウンターが時間をナノ秒単位で管理しています。これをシステムクロックと呼びます。しかしPCの電源を切っている時はこのカウンターは使えません。実はPCに電源が供給されていなくても(デスクトップPCで電源を抜いていても、ノートPCでバッテリーが抜けていても)マザーボードのバックアップ電池(という名のただのコイン電池)によってRTCというユニットは動いています。RTCには32.768kHz(=$2^{15}$Hz)の水晶発振子を持っていてこれで常に時間を数えています。これをハードウェアクロックと呼びます。
しかしこの水晶発振子も完全には正確ではなくずれがあります。一般的には20ppm$(=20\times10^{-6})$程度です。1日は86,400秒なので1日で約1.6秒ずれることとなります。これだけずれればロボットの制御はできません。
NTPの仕組み
NTPクライアントがNTPサーバーに問い合わせるとサーバーが時刻を返すという仕組みです。
stratum
世の中には原子時計のようにはるかに正確な時計がありますが、値段や扱いの問題でもちろんすべてのPCに乗せることはできないので一部のサーバーにのみ正確な時計を載せます。このサーバーをstratum0と呼びます。ほかのPCはこのサーバーに時刻を問い合わせることで時刻を合わせることができます。stratum0に問い合わせて時刻を合わせたPCをstratum1と呼びます。すべてのPCがstratum0のサーバーに問い合わせるのは現実的でないので、stratum1に問い合わせるPCもいます。stratum1に問い合わせて時刻を合わせたPCをstratum2と呼びます。NTPではこのようにツリー構造で多くのPCが時間を合わせます。大体のPCはstratum4や5になりますが、それで十分な時刻の精度を持ちます。Ubuntuなら標準でntp.ubuntu.com
というインターネット上のサーバーに問い合わせます。そのためにインターネット接続がないと時間同期をすることができなくなります。
stepとslewモード
NTPサーバーから返ってくる時刻に即座に合わせる方式をstepモードといいます。しかしこの方法だとPCの時刻が不連続になってしまってシステムに問題が起きることがあります。NTPの時刻にで徐々に合わせます方式をslewモードと呼びます。大体のPCの設定ではこの方式で時刻を合わせます。
NTPとその実装
古くはNTPDがありましたが、今はchronyが主流です。
chronyの設定
Ubuntu16.04だとchronyは標準でインストールされています。
sudo apt-get install chrony
非インターネット環境で使うためにはchronyの設定を変更する必要があります。
sudo vim /etc/chrony/chrony.conf
サーバー側設定
上記のファイルに以下の2行を書き加えます(場所は問いません)。
local stratum 10
allow 192.168/16
- 1行目は上位のNTPサーバーが無くても、このPC自体がNTPサーバーとしてふるまうための設定です。
- 2行目はクライアント接続の許可設定です。この書き方だと
192.168.0.0~192.168.255.255
からのNTPのリクエストに対して応答します。
クライアント側設定
この設定を書くことで自動的に設定したNTPサーバーにアクセスして時刻合わせをします。
server 192.168.2.102 minpoll 0 maxpoll 5
makestep 10 3
- 1行目は問い合わせるNTPサーバーの設定です。
192.168.2.102
にNTPの問い合わせをしに行きます。後ろのオプションは何回かNTPの問い合わせをして時刻合わせの精度を上げるための設定です。 - 2行目は時刻ずれが10秒以上の時はstepモードで時間合わせを行うという設定です。
参考
NTPの仕組み
NTPDとchronyの違い
クロック用発信子のデータシート