【 ns-3.30の使い方 → 1 → 2 → [3] → 4 → 5 → 6 → 7 】
ネットワークシミュレータであるns3の説明をいくつかにわけて投稿しています.この投稿は「3. ドキュメントの極意・いち」です.
3. ドキュメントの極意・いち
頻繁にバージョンが変わり仕様変更があるns3では,参考にしたい記事のコードが古くてエラーが出る等の問題によく直面します.ns3と付き合うためにはドキュメントを自ら読む力が大切です.この記事では,利用できる公式ドキュメントを列挙し,「2. ネットワーク構築(前編)」で生じた疑問を解決する例を示します.
- 公式ドキュメント
- ソースコード
- サンプルコード
- 疑問1. NodeContainerのメソッドは他に何があるか
- 疑問2. どんな属性変数があるか
- 疑問3. シナリオファイルで何をインクルードすればいいのか
- まとめ
公式ドキュメント
最新版のドキュメントはns3公式ページの[Documentation] > [Latest Release]から見つけられます.現在の最新版はns-3.30です.
利用できるドキュメントは3つです.
-
Manual
- ns3のアーキテクチャとns3全体に及ぶ基本概念についての説明
- 乱数やロギング,シミュレーション時間など
-
Model Library
- ns3が有するモデル(いわばクラス)についての説明
- CSMAやWiFi,エネルギー,モビリティなど
- 例:LTEを使いたいときはここのLTE Moduleを読むとよい
-
API Documentation
- ns3が有するC++のクラス・属性変数・トレースソースなどの説明
- Doxygenによって生成される
ドキュメントを見る際はバージョンの違いに注意してください.グーグルから検索すると開発バージョンのドキュメントが表示されます.
ソースコード
ソースコードを見た方がはやいという方は,ns3の開発版のコードがGitLabとGitHubで公開されているので,そちらを見るといいです.タグ経由でバージョンを変更してください.GitHubはGitLabをミラーリングしているだけで,少し更新が遅いようです.実際に,ns-3.30のタグづけがまだされていませんでした(2019/09/20時点).
GitLab: https://gitlab.com/nsnam/ns-3-dev/tree/ns-3.30
GitHub: https://github.com/nsnam/ns-3-dev-git
サンプルコード
チュートリアル用のコードや代表的なシミュレーションのサンプルコードはexamples/の中に,各モジュールのサンプルコードはsrc/[module]/examples/にあります.
疑問1. NodeContainerのメソッドは他に何があるか
「2. ネットワーク構築(前編)」ではNodeContainerがCreate()以外にもAdd()やGet()というメソッドを持つことを説明しました.オブジェクトの調べ方の例として,NodeContainerの他のメソッドを調べてみます.
API Documentationのページを開き,右上のSearchからNodeContainerと検索します.
候補が出てくるので,ns3::NodeContainerをクリックします.NodeContainerクラスの説明ページが現れます.
Public Member Functionsにメソッドの一覧が表示されています.各メソッドをクリックすると詳細を見ることができます.Add()やCreate()もありますね.複数あるのはC++のオーバーロードという仕組みです.
知らないメソッドとしてGetN()とBegin()/End()がありますが,どのように使うのでしょうか.GetN()は説明文からおそらくイメージつくでしょう.
// GetN()の例
NodeContainer nodes;
nodes.Create (2);
uint32_t n = nodes.GetN();
std::cout << "nodes.GetN() = " << n << "\n"; // 2
問題はBegin()/End()です.こういうときはこれらが使われているコードをgithub上で検索するのがてっとり早いです.検索窓に「NodeContainer Begin」で検索します.
検索結果の2つ目を見ると,どうやらBegin()とEnd()はfor文でセットで使うようだ,ということがわかりました.これはイテレータというC++の機能の1つです.使用例をあげます.
// Begin(),End()の例
NodeContainer nodes;
nodes.Create (2);
for (auto i = nodes.Begin(); i != nodes.End(); i++)
{
// iにはPtr<Node>の中身が入る
// iに対して何かしらの処理をする
}
疑問2. どんな属性変数があるか
「2. ネットワーク構築(前編)」では,P2Pリンクの速度と遅延を属性変数で変えました.リンク速度はPointToPointNetDeviceの"DataRate"で,遅延はPointToPointChannelの"Delay"です.他にP2Pに関するどんな属性変数があるかを調べてみます.
API documentationで「PointToPointNetDevice」を検索して,ns3::PointToPointNetDeviceクラスを開き,More...をクリックします.検索対象は「PointToPointHelper」でないことに注意してください.PointToPointHelperではPointToPointNetDeviceの属性変数を設定していたにすぎません.
Attributesに設定できる属性変数が列挙されています.DataRateもありますね.他にも,MTUやMACアドレスを属性変数で変更できます.余力があればPointToPointChannelの属性変数も検索してみてください.
さて,検索すべきクラスがわからない時や,こんな属性変数があれば使いたい,というときはどうすればいいでしょうか.API documentationには全ての属性変数を列挙したページがあります.
ここからブラウザの検索機能を使って探してみてください.同じ名前の属性変数が別々のクラスで存在することがあるので,その場合はモジュールのドキュメントを読む必要があるかもしれません.
疑問3. シナリオファイルで何をインクルードすればいいのか
説明するよりもまず例お見せします.first.ccを開いてください.first.ccを上から眺めて,ns3独自の関数名やオブジェクトがあるたびにそれらをAPI documentationで検索してきます.
NS_LOG_COMPONENT_DEFINE()を検索するとns3のマクロのようで,log.hに定義があるとわかります.CommandLineを検索するとcommand-line.hをインクルードしろとあります.同様に残りの部分についても検索していき,それらすべてをヘッダファイルとして#includeします.ただし,"ns3/"とつけてください.
// core module
#include "ns3/simulator.h"
#include "ns3/command-line.h"
#include "ns3/nstime.h"
#include "ns3/uinteger.h"
#include "ns3/string.h"
#include "ns3/log.h"
// network module
#include "ns3/node-container.h"
#include "ns3/net-device-container.h"
// point-to-point module
#include "ns3/point-to-point-helper.h"
// internet module
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-interface-container.h"
// applications module
#include "ns3/udp-echo-helper.h"
#include "ns3/application-container.h"
このようにしてインクルードファイルを列挙していきます.
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
さて,これらはfirst.ccで実際に#includeしているファイルとは異なります.しかし両方を見比べるとあることに気づきます.モジュール名に"-module.h"として#includeするとモジュールに含まれる全てのヘッダファイルをインクルードするのです.例えば,"core-module.h"を#includeすると,coreモジュールに含まれる全てのヘッダファイルがインクルードされます.実際にcore-module.hというファイルがあるわけではありません.使用しないヘッダファイルまでインクルードするためビルド時間が長くなりますが,より簡潔に記述できます.好みで使い分けてください.
そのヘッダファイルがどのモジュールに含まれるかは,ヘッダファイルのパスからわかります.
まとめ
ドキュメントを読めるようになれば,ns3のバージョンアップにも自身で対応できるようになります.
次の記事ではネットワーク構築(後編)ということで,WifiとEthernetを混ぜたトポロジーを作成する例を示します.