😊

学ロボerのためのIPネットワーク通信入門

2024/12/25に公開

はじめに

メリークリスマス!

本稿は2024年学ロボアドベントカレンダー(https://adventar.org/calendars/10297)の19日目の記事となります(なお現在24日,大遅刻してますごめんなさい...)
ていうか全然書き終わる目処がつかず(なんかこの流れ去年もあったな...)クリスマス終わっちゃいかねないので書きかけだけど放出します(
メリークリスマス!(やけくそ)

動機・背景

近年では学生ロボコンにおいて操縦者とロボット間の通信にwifiを用いることがデファクトスタンダードとなっています.wifiを用いた通信においてはIP通信の使用が事実上必要不可欠です.
一方でIP通信は基本的にOSの諸機能を密接に利用し,このため学ロボで用いられるその他の通信とは少々毛頭が異なると感じることがあります.これは特に技術スタックが学生ロボコンに特化している諸学生(i.e. 大学入って初めてプログラム等さわり,そのまま学ロボのソフト班やってるような人)には少々とっつきづらいと感じられる人も観測されます.
本稿では,学生ロボコンで実用されるIP通信について最低限の知識と実例を示すことを目的とします.
最初にIP通信の前段となるEthernet通信について軽く触れた後,IP通信の概要と学ロボで用いられることの多い機能を説明し,その後簡単なサンプルプログラムによりいくつかを実例します.
上記モチベーションのため,本稿は学生ロボコンで必要なIP通信技術の表層を簡単にさらうことを目的とし,より複雑な点には立ち入りません.(ていうか僕自身そんなに詳しくない)
特に学ロボでは基本的に必要の無いEthernet以外のL2プロトコルやネットワーク関連の知識(i.e. DNS,ルーティングプロトコル,BGP等)や大規模ネットワーク管理で用いられるような技術は扱わず,LANレベルでのIP通信に限ったお話になります.

EthernetとWifi

IP通信はOSI参照モデルでいうところのネットワーク層のプロトコルとして生まれました.ネットワーク層のプロトコルは複数のネットワークをまたいだデータのやりとりや論理アドレス(IPアドレス)を用いた識別が主な役割となります.
OSI参照モデル
ネットワーク層の通信が実際に機能するには,さらにその下のデータリンク層や物理層が必要になります.データリンク層では隣接する機器同士の通信を司り,ここにはEthernetやWifiが含ま,MACアドレスでの送受信先の識別やCRCなどの誤り検出などを行います.
OSI参照モデルでの通信フロー
実際の運用では機器を直接つなぐことは少なく,間にスイッチやルーター・アクセスポイントのを入れることがほとんどです.
OSI参照モデルは少々わかりにくいため,TCP/IPモデルで上記を図示した図が以下になります.TCP/IPモデルでの図示
TCP/IPモデルでのデータフロー
ここでは,ネットワークインターフェイスレイヤーにEthernetやWifiは位置します.こっちのが断然わかりやすいですね(
EthernetやWifiはそれぞれEthernetフレーム,Wifiフレームと呼ばれるデータ構造に規定されます.Ethernetフレームの例
ここで,DAは送信先MACアドレス(Destination Address),SAは送信者MACアドレス(Source Address)です.そのためMACを用いればEthernet単体でも当然通信は十分に行えます.ちょっとお隣さんと通信するためにIPアドレスなんてものは必要無いのです.
通信フレームの例に漏れず(CANフレームとか思い浮かべてもらえれば...),フレームには通常の通信他エラーフレームなど多数の種類がありますが,このフレームの内データ部分にIPフレームが乗っかることで,IP通信はEthernet通信の上で通信できます.一方で無論データには任意の者を取ることが可能なため,通信したいデータを直接入れたり,あるいは独自プロトコルを利用することも可能です.
EtherCATプロトコル
例えばEtherCATプロトコルは近年ロボット用のネットワークとして注目されていますが,これはEthernetプロトコルの上に構築されています.

IP通信に話を戻します.ルーターはネットワーク間のルーティングが可能な一方,スイッチはあくまでMACアドレスに基づくスイッチングのみを行います.アクセスポイントは無線版のスイッチとの認識でかまいません.
実際に学ロボで複数のネットワークを用いることはまれなので,ルーティングの機能はオプショナルです.ただインターネットとの接続やIPアドレスの自動割り振り,その他の便利機能を用いるために実際はルーターを持ちることが多いようです.
もちろん,業務用のWifiアクセスポイントを用いたいなどの理由でアクセスポイントをあえて用いることもできます.

学生ロボコンでは,ネットワークをまたぐ通信は基本的に必要無いです.また動的にIPアドレスを割り振ることもまれなため,正直IP通信は不要です.
ただ実用的に考えた場合,Ethernetフレームを直接やりとりするのとIPを用いるとでは,Linuxなどを用いる場合あまり大差がない(難しい処理はすべてOSが行う)ため,IP通信が実用上用いられます.

IP通信

IP通信の設定

まず,一般のコンピューターでIP通信を疎通させるための設定について触れます.

IPアドレス

IPアドレスはネットワーク内のIDとなるもので,IP通信の基盤です.IPアドレスの設定なしには通信を行うことは出来ません.
単一のネットワーク内において,IPアドレスはMACアドレスと1対1で設定されます.
MACアドレスはネットワークインターフェース層に属するアドレスであり,その名の通りネットワークインターフェースに一つ一つ存在します.そのため1つのコンピュータに複数のネットワークインターフェースが存在する(複数個のLANポートがあるなど)場合はそれぞれ個別のIPアドレスをとります.
MACアドレスが(基本的には)ユニークな物理アドレスであるの(まあMACも任意に変更できたりするのでセキュリティの観点では話は変わるが)に対し,IPアドレスは論理的な設定であり,自由に付け替えが可能です.
IPアドレスはIPv4では32bitの値を4つのオクテットに分割して表現します.例として192.168.1.100のようにピリオドで区切ります.またIPアドレスと後述するサブネットマスクを同時に表記する手法として,192.168.1.100/24といった表現が主流です.
このIPアドレスを介して機器同士が通信を行う際には,MACアドレスと対応付ける仕組みとしてARP(Address Resolution Protocol)が動きます.

サブネットマスク

サブネットマスクはネットワーク部とホスト部の境界を示すためのマスク情報です.たとえば255.255.255.0のように書かれ,先頭の255.255.255部分がネットワーク部,最後の0部分がホスト部を表します.ネットワーク部はルーティングが必要な部位で,ホスト部はスイッチングのみで到達可能な部位との解釈ができます.先述の192.168.1.100/24という表現は,サブネットマスク255.255.255.0が適用されることを意味します./24の“24”は上位から24bit分がネットワーク部であることを示します.
一方で,ネットワーク部の一部をサブネットとして切り出し,ホスト部のようにNICから直接アクセス可能(ルーティングをせずにアクセス可能)にすることが出来ます.
これをサブネット化と呼びます.
サブネット化の例
サブネットマスクを正しく設定しないと,同じネットワークにいるつもりでもホスト同士で通信できない状態に陥ることがあります.

たとえば先述の192.168.1.100/24の場合は,そのNICはルーティングの必要無く先述の192.168.1.0~192.168.1.255までのすべてのアドレスに到達可能です.一方192.168.2.10のように,この範囲を逸脱するIPにはルーティングが必要で,スイッチングのみではつながれません.
一方,先述のサブネットマスクを255.255.254.0の用に設定した場合,(つまり192.168.1.100/23),このNICは192.168.0.1~192.168.1.254まで見ることが可能です.

実用的な観点で考えると,学ロボでは基本的に単一のネットワークを用い,ルーティングを省くことがほとんどです.ルーティングが入ってくると一気にネットワーク構築での落とし穴が増えるため,これは妥当な判断です.
一方で,例えば自宅の開発環境(例えば自宅のPCは192.168.1.100)と実機の開発環境(例えば実機のLidarが192.168.0.100)で別々のネットワークを用いている場合などで相互に疎通させたい場合,サブネットマスクを255.255.254.0などに設定することで,.1ネットワークと.0ネットワークの双方をアクセスできるように設定することが可能です.

LinuxでのIPアドレス設定例

学ロボの現場などでは,GUIを使わず単純にコマンドラインからIPアドレスを設定したいことが多いです.Linuxではいくつか方法がありますが,近年主流の「ip」コマンドを例として挙げます.

1.現在のネットワークインターフェイスやIPアドレスを確認する
ip addr show (或いは省略形としてip show a)
これにより,各ネットワークインターフェイス(e.g.eth0,enp0s3など)の状態や割り当たっているアドレスを確認できます.
ipコマンドの例
2.IPアドレスを付与する(例としてenp0s3に192.168.1.100/24を割り当てる場合)
sudo ip addr add 192.168.1.100/24 dev enp0s3
このコマンドでenp0s3に対して192.168.1.100というIPアドレスを割り当てます.

3.インターフェイスを有効化する(UP状態にする)
sudo ip link set enp0s3 up
IPアドレスを付与してもインターフェイスがDOWN状態のままだと通信できません.
このコマンドで有効化します.

4.ゲートウェイを設定する(必要に応じて)
sudo ip route add default via 192.168.1.1
ローカルネットワークを超えて通信する際(i.e. インターネットに疎通したいときなど)は,デフォルトゲートウェイとなるルーターのアドレスを登録します.単にLANだけを使うのであれば省略可能です.

もし昔ながらのifconfigコマンドが使える環境であれば,
sudo ifconfig enp0s3 192.168.1.100 netmask 255.255.255.0 up
のような書き方でもほぼ同様のことができます.もっとも今後はipコマンドで操作するほうが一般的です.

こうして任意のNICに対してIPアドレスとサブネットマスクを設定すれば,LANレベルでのIP通信を行うための準備が整います.
学ロボの場面では,複数台のLinux機器を持ち込んで簡単に通信確認がしたい場合などに便利です.あとはこの設定の上でTCPやUDPを用いたソケット通信を行えばよく,必要な複雑な処理はすべてOSに任せられるという点がIP通信の大きなメリットです.

IPパケット/データグラム

IP通信で実際に通信される信号をIPパケットと呼びます.
このIPパケットは下位の通信のデータ部に格納されます.以下にIPパケットを説明した図を示します.

より詳細な図,ところでなんでみんなこの分かりづらい縦型の図にするんや...
より詳細な図,ところでなんでみんなこの分かりづらい縦型の図にするんや...
ここで重要なのは,IPパケットには必ず送信先IPアドレスと送信元IPアドレス(一般にプログラムの中ではこれらはDestination Address(略してdst_addrなど)やSoruce Address(略してsrc_addrなど)と呼ばれることが多いです)が必ず存在する点です.
後述するマルチキャストやブロードキャストなど,必ずしも通信が一対一でない場合も存在しますが,これらの場合は特殊な送信先IPアドレスを用います.

ところで,興味深い点としてIPのデータ部(ペイロード)は最大で65535バイト(64Kbyte)と定義されているが,一方でより下位のレイヤーのデータ部はEthernetで1500byteなど,それよりも遥かに小さい.
これはつまりIPパケットは,必ずしも1つの下位レイヤーフレーム(例えばEthernetフレーム)の中に納まるとは限らないということです.Ethernetフレームが1500バイト程度までしかデータを運べない場合でも,IPヘッダを含めたIPパケットが1500バイトを超えるサイズを持ち得ます.このような場合,IPパケットが分割され,複数の下位フレームに分割されることがあります.これを一般に**フラグメンテーション(fragmentation)**と呼びます.
フラグメンテーション
IPパケットを分割する役割は,主に送信元ホストが担います.特定のリンクで許容されるデータサイズ(MTU: Maximum Transmission Unit)を超えるパケットが流れてきた場合,このパケットは複数の小さなパケットに分割されます.
フラグメンテーションによって分割された各パケットには,元のパケットを再構築するための情報が含まれており,受信側ではそれらを組み合わせて元のIPパケットを復元します.
フラグメンテーションの復元
フラグメンテーションは自動で処理されるため,ユーザーは意識せずに任意のデータ長(無論IPプロトコルで定義されている最大値64Kbyteを超えない範囲で)のデータを流すことが出来ます.
データの分割処理はTCPプロトコルで行われていることは有名ですが,このように限定されたデータ長ではありますがIPプロトコル側にも存在します.

なお,IPパケットはIPデータグラムとも呼ばれます.ここらへんの呼び方についての詳しい事情はよく知らないので,気になる方は調べてみてください.

マルチキャストとユニキャスト

ユニキャスト

ネットワーク通信にはさまざまな種類がありますが,もっとも基本的なのはユニキャスト(unicast)です.ユニキャストは1対1の通信を指し,送信元ホストから宛先ホストへ直接パケットを送る方式です.通常のウェブアクセスやSSH通信など,多くの場面で利用されるのはこのユニキャストです.

マルチキャスト

マルチキャスト(multicast)は,1つの送信元から“特定のグループ”に属する複数の受信者へ同時にデータを送信する仕組みです.ユニキャストのような1対1ではなく,多対多,あるいは1対多のコミュニケーションを効率的に実現できます.
たとえば,動画配信やオンライン会議システム,ストリーミングなどで多くの端末が同じデータを受け取る際に,ネットワーク負荷を軽減する手段として活用されることがあります.
なお,ネットワークに存在するすべての機器に通信をばらまく場合,それはブロードキャストと呼称されます.
学ロボにおいてプログラマが自発的にマルチキャストを利用することはほぼ無いですが,ROS2によって利用されます.

ROS2におけるマルチキャストの利用

ROS2では,DDS(Data Distribution Service)に基づく通信が利用されており,その発見(Discovery)や一部のトピック通信においてマルチキャストが活躍します.

低品質ネットワーク環境での問題と飽和

しかし,マルチキャストはネットワーク品質が十分でない環境(Wi-Fiの電波状態が悪い状況や,帯域幅が限られているネットワーク,ケーブルの品質が悪い有線環境など,学ロボ本番の通信環境は基本的に劣悪)ではパケットの衝突や遅延が増え,混雑や飽和の原因となることがあります.マルチキャストの仕組み上,一度に複数の受信機にデータを送るため,受信者が多いほどパケット量が膨大になりやすく,ネットワークのボトルネックが顕在化しやすいのです.
特にROS2のようにリアルタイム性や同期が重要なシステムでは,マルチキャストトラフィックが増えすぎると通信の遅延やパケットロスが生じ,システム全体のパフォーマンスに直接影響します.
たとえば多数のセンサーを同時に利用し,それぞれがマルチキャストを活用してトピックを配信している場合,低品質なネットワーク環境下ではすぐに飽和し始め,結果的にデータが受け取れなくなる可能性もあります.

対策と考慮点

1.ネットワーク機器の見直し
スイッチやルーターがマルチキャスト通信を正しくサポートしているかを確認し,必要に応じてIGMPスヌーピング対応機器へ置き換えるなど,インフラ全体で最適化を図ります.

2.リンク品質の改善
ケーブルの交換や,高品質な無線アクセスポイント(業務用APはイイゾ!!)の採用などで物理的なリンク品質を向上することが重要です.

3.ユニキャストへの切り替え・併用
一部の通信をユニキャストあるいはブロードキャストで置き換えて,マルチキャストを最小限に抑えるアプローチも有効です.ROS2のDDS実装によっては,Discovery時のマルチキャストを制限したり,ユニキャストのみで発見を行う設定が用意されています.(が実際にROSのDDS設定をいじるのは,特に人的開発リソースが限られている場合面倒ごとの発端となりうるためあまり推奨は出来ないです)

TCP/UDP

実際にIPパケットで直接通信を行うのはまれで,UDP通信やTCP通信をかますのがほとんどです.
先述のとおり,IPアドレスを設定して「IPパケットをやりとりできる状態」さえ整えばその上で動作する様々なプロトコル(UDPやTCPなど)を使えるようになります.
ここでは,学ロボのソフト班でよく使われるTCPとUDPについて簡単に見ていきます.

TCP

TCP (Transmission Control Protocol) は、いわゆる「コネクション指向」の通信を行うプロトコルです。データの送信元と受信先の間でコネクションを確立したうえで通信を行い,届いたデータに対し「確実に受け取りましたよ」という応答(ACK)を返す仕組みになっています.送信側は受信側からのACKをもとに再送やウィンドウ制御を行い,不足分や欠損があれば再度データを送ったりするため「信頼性の高い通信」を実現できます.

TCPでは下記のような特徴があります.
• パケットが欠損したり順番が入れ替わったりしても最終的に正しい順序のデータとしてアプリケーションに渡る.
• 確実性と引き換えに通信のオーバーヘッドが大きく,リアルタイム性は少し劣る.
• ストリーム通信(バイト列を連続的に送る形)であり,手軽にファイル転送やテキスト通信などを実装しやすい.

例えばロボット制御でも,簡単なテレメトリ情報を確実にやりとりしたい場合などにはTCPがよく使われます.

UDP

UDP(User Datagram Protocol)はコネクションレス型のプロトコルで,送信先IPアドレスとポートを指定してデータを送信するだけのシンプルな仕組みです.
受信側からの確認応答は存在しないため,パケット欠損が起きる可能性は否定できませんが,その分だけ通信負荷が低く,レイテンシを抑えられます.

UDPには下記のような特徴があります.
• データの欠損や順序の乱れを検知・回復する仕組みを標準ではもたない.
• コネクションの確立が不要な分、シンプルな構造で遅延を最小化しやすい.
• 一度に送るデータは1パケット単位になるため,データの分割や再構築はアプリケーション側で調整が必要.

リアルタイム性が重要な映像や音声ストリーミング,制御信号などにはUDPが好まれることが多く学ロボの操縦で「多少のパケット落ちより遅延を少なくしたい」という場合にはUDPが有効です.

Linuxでの実装について,どちらのプロトコルでも実装はソケットAPIを通じて行い、TCPソケットまたはUDPソケットをオープンして読み書きするだけです.
OSが裏側でプロトコル処理(パケットの生成や再送制御など)をすべてやってくれるため,プログラマとしてはどちらのソケットを使うかを決めるだけで,詳細な仕組みの理解はとりあえずは必要ありません.

学ロボでは制御系の通信でUDPが好まれることが多い一方,データの欠損が気になるケースがあるかもしれません.その場合は再送を自前で実装する,あるいはTCPを採用するといった判断を行うことになります.
極めて重要度の高い通信はそもそも920Mhz帯の通信など全く別の通信手段を選ぶなど,通信の種類や重要度を考えてプロトコルを選ぶ必要があります.

Linuxでの実装例

以下工事中

ソケットAPI

参考文献

ALANI, Mohammed M. Guide to OSI and TCP/IP models. 2014.
NATH, Pranab Bandhu; UDDIN, Md Mofiz. Tcp-ip model in data communication and networking. American Journal of Engineering Research, 2015, 4.10: 102-107.
SOMMER, Jorg, et al. Ethernet–a survey on its fields of application. IEEE Communications Surveys & Tutorials, 2010, 12.2: 263-284.
EtherCAT®とは -5分で分かる概要-https://www.macnica.co.jp/business/semiconductor/articles/texas_instruments/125025/
KOISHIGAWA, Kris. Subnet Cheat Sheet–24 Subnet Mask, 30, 26, 27, 29, and other IP Address CIDR Network References. 2021.
What is IPv4 https://support.huawei.com/enterprise/en/doc/EDOC1100145159
基礎から学ぶWindowsネットワーク 第10回 IPパケットの構造とIPフラグメンテーションhttps://atmarkit.itmedia.co.jp/ait/articles/0304/04/news001_3.html

Discussion