在ns3.26安装GPSR大量踩坑日志+解决方案

本文档详细记录了在ns3.26版本中安装GPSR协议时遇到的四个主要bug,包括源码的错误和编译问题。作者提供了针对每个bug的解决方案,涉及文件的修改和编译选项设置。最终成功编译并运行了example,同时也解决了--vis参数无法启用的问题。
摘要由CSDN通过智能技术生成

前言

根据文章 NS_3中添加GPSR协议 所说的安装步骤,结合源码( 源码下载链接 ),ns-3.26ns3.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 吧。玛德,怎么又报错了?
在这里插入图片描述

仔细检查,发现 exampleswscript 里根本没加进去,即缺少下面红框的代码

在这里插入图片描述

解决方案:在 ~/<你的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 参数,大功告成!

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值