前言
根据文章 NS_3中添加GPSR协议 所说的安装步骤,结合源码( 源码下载链接 ),在 ns-3.26
(ns3.26下载链接)安装GPSR协议。
在安装过程中踩了一些坑,大致说一下我的解决方案。
ns3版本
最开始我没看到文章中说要在 ns3.26
安装 GPSR
,因为版本兼容问题安装失败。下载了 ns3.26
版本后得到解决。具体安装步骤如下
cd ~/<你的ns-3解压目录>/ns-3
sudo ./waf clean # 清理以前的安装记录
sudo ./waf -d debug --enable-example --enable-tests configure # 选择编译选项,如果要安装可视化--vis参数,记得要让visualizer是enabled
sudo ./waf # 执行安装
如果要开启可视化,要如下图所示, PyViz visualizer: enabled
。如果不是 enabled
,需要安装提示将对应的包安装好然后重新编译。
第1个bug
很快就遇到了第一个bug,这个是GPSR的bug。很明显,图中画圈的部分应该被改为 m_dstPosy == o.m_dstPosy
。
于是将 ~/<你的ns-3解压目录>/ns-3/src/gpsr/model/gpsr-packet.cc
的第285行的 m_dstPosy == m_dstPosy
改为 m_dstPosy == o.m_dstPosy
。
第2个bug
第2个bug应该是 ns3.26
的bug。翻阅源代码,对比后续版本的 ns3
不难发现,此处应当把 ||
改成 |
。修改方式和上面的bug是类似的。
第3个bug
第3个bug也是 ns3.26
的bug。修改方式为将报错这两处的 SS_STATE_WAITING_RNG_RSP
改成 GetState () == SS_STATE_WAITING_RNG_RSP
。
第4个bug
这个 bug
就要麻烦些了,想偷懒可以不以 debug
模式编译,正经解决方案按照下面我说的步骤即可。
按照后续版本的 ns3
的解决方案,首先在前面 #include <sstream>
,然后把原来89行的
void
SNRToBlockErrorRateManager::LoadTraces (void)
{
std::ifstream m_ifTraceFile;
ClearRecords ();
double snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2;
for (int i = 0; i < 7; i++)
{
char traceFile[1024];
sprintf (traceFile, "%s/modulation%d.txt", m_traceFilePath, i);
m_ifTraceFile.open (traceFile, std::ifstream::in);
if (m_ifTraceFile.good () == false)
{
NS_LOG_INFO ("Unable to load " << traceFile << "!! Loading default traces...");
LoadDefaultTraces ();
return;
}
while (m_ifTraceFile.good ())
{
m_ifTraceFile >> snrValue >> bitErrorRate >> burstErrorRate >> sigma2 >> I1 >> I2;
SNRToBlockErrorRateRecord *record = new SNRToBlockErrorRateRecord (snrValue,
bitErrorRate,
burstErrorRate,
sigma2,
I1,
I2);
m_recordModulation[i]->push_back (record);
}
m_ifTraceFile.close ();
}
m_activateLoss = true;
}
替换为
void
SNRToBlockErrorRateManager::LoadTraces (void)
{
std::ifstream traceFile;
ClearRecords ();
double snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2;
for (int i = 0; i < 7; i++)
{
std::stringstream traceFilePath;
traceFilePath << m_traceFilePath << "/modulation" << i << ".txt";
traceFile.open (traceFilePath.str ().c_str (), std::ifstream::in);
if (traceFile.good () == false)
{
NS_LOG_INFO ("Unable to load " << traceFilePath.str () << "!! Loading default traces...");
LoadDefaultTraces ();
return;
}
while (traceFile.good ())
{
traceFile >> snrValue >> bitErrorRate >> burstErrorRate >> sigma2 >> I1 >> I2;
SNRToBlockErrorRateRecord *record = new SNRToBlockErrorRateRecord (snrValue,
bitErrorRate,
burstErrorRate,
sigma2,
I1,
I2);
m_recordModulation[i]->push_back (record);
}
traceFile.close ();
}
m_activateLoss = true;
}
247行的
void
SNRToBlockErrorRateManager::ReLoadTraces (void)
{
double snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2;
ClearRecords ();
std::ifstream m_ifTraceFile;
for (int i = 0; i < 7; i++)
{
char traceFile[1024];
sprintf (traceFile, "%s/Modulation%d.txt", m_traceFilePath, i);
m_ifTraceFile.open (traceFile, std::ifstream::in);
if (m_ifTraceFile.good () == false)
{
NS_LOG_INFO ("Unable to load " << traceFile << "!!Loading default traces...");
LoadDefaultTraces ();
return;
}
while (m_ifTraceFile.good ())
{
m_ifTraceFile >> snrValue >> bitErrorRate >> burstErrorRate >> sigma2 >> I1 >> I2;
SNRToBlockErrorRateRecord *record = new SNRToBlockErrorRateRecord (snrValue,
bitErrorRate,
burstErrorRate,
sigma2,
I1,
I2);
m_recordModulation[i]->push_back (record);
}
m_ifTraceFile.close ();
}
m_activateLoss = true;
}
替换为
void
SNRToBlockErrorRateManager::ReLoadTraces (void)
{
double snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2;
ClearRecords ();
std::ifstream traceFile;
for (int i = 0; i < 7; i++)
{
std::stringstream traceFilePath;
traceFilePath << m_traceFilePath << "/Modulation" << i << ".txt";
traceFile.open (traceFilePath.str ().c_str (), std::ifstream::in);
if (traceFile.good () == false)
{
NS_LOG_INFO ("Unable to load " << traceFilePath.str () << "!!Loading default traces...");
LoadDefaultTraces ();
return;
}
while (traceFile.good ())
{
traceFile >> snrValue >> bitErrorRate >> burstErrorRate >> sigma2 >> I1 >> I2;
SNRToBlockErrorRateRecord *record = new SNRToBlockErrorRateRecord (snrValue,
bitErrorRate,
burstErrorRate,
sigma2,
I1,
I2);
m_recordModulation[i]->push_back (record);
}
traceFile.close ();
}
m_activateLoss = true;
}
编译成功
终于,经过一番折磨后,我们成功编译好了。
运行example踩坑1
终于编译成功了,让我们来跑一个 examples
吧。玛德,怎么又报错了?
仔细检查,发现 examples
在 wscript
里根本没加进去,即缺少下面红框的代码
解决方案:在 ~/<你的ns-3解压目录>/ns-3/src/gpsr/wscript
里加上红框这段代码
if bld.env['ENABLE_EXAMPLES']:
bld.recurse('examples')
然后顺便把 ~/<你的ns-3解压目录>/ns-3/src/gpsr/examples/wscript
的
obj = bld.create_ns3_program('gpsr',
['wifi', 'internet', 'gpsr'])
改成
obj = bld.create_ns3_program('gpsr-test1',
['wifi', 'internet', 'gpsr'])
运行example踩坑2
修改完毕后,发现如下报错。
没事,咱已经习惯了。根据报错提示,容易发现在 ~/<你的ns-3解压目录>/ns-3/src/gpsr/model/gpsr.cc
的第120行的 "PerimeterMode "
多了一个空格
.AddAttribute ("PerimeterMode ", "Indicates if PerimeterMode is enabled",
BooleanValue (false),
MakeBooleanAccessor (&RoutingProtocol::PerimeterMode),
MakeBooleanChecker ())
改成下面这个样子(删掉空格)就行了
.AddAttribute ("PerimeterMode", "Indicates if PerimeterMode is enabled",
BooleanValue (false),
MakeBooleanAccessor (&RoutingProtocol::PerimeterMode),
MakeBooleanChecker ())
运行成功
终于,经历了九九八十一难后,我们运行成功了!
可视化运行
运行是成功了,但 --vis
参数还是不能启用。解决方案为:在 ~/<你的ns-3解压目录>/ns-3/src/gpsr/wscript
里加上这一行代码
bld.ns3_python_bindings()
然后加上 --vis
参数,大功告成!