目 录CONTENT

文章目录

例程-reference-point-group-mobility-example.cc

Rho
Rho
2023-08-30 / 0 评论 / 0 点赞 / 27 阅读 / 11039 字
该代码是一个用于模拟网络节点移动的示例程序。它使用了ns-3网络模拟器库,其中包含了一些用于处理核心功能、网络和移动性的头文件。

代码的主要功能如下:

  1. 创建了一个包含3个节点的节点容器。
  2. 定义了一个参考点(parent)的移动模型,它按照预定义的路径在一个矩形区域内移动。这个移动模型不代表实际的节点,只用作参考点。
  3. 使用层次化移动模型(HierarchicalMobilityModel)将参考点移动模型作为父模型,并创建了一个子模型(RandomWalk2dMobilityModel)作为每个节点的移动模型。
  4. 使用低级API或GroupMobilityHelper两种方式配置节点的移动模型。
  5. 配置节点的位置记录和追踪。
  6. 运行模拟并记录节点的位置和移动轨迹。

代码中的函数PrintPosition用于将节点的位置信息写入时间序列文件。main函数根据命令行参数配置模拟时间、打印次数和是否使用辅助函数。然后,它创建节点容器,并根据选择的方式配置节点的移动模型。最后,它启动模拟器并运行模拟。

这段代码展示了如何使用ns-3库来模拟网络节点的移动,并记录节点的位置信息。它可以作为学习和使用ns-3进行网络模拟的参考示例。

/\*\*

- 本示例展示了如何使用ns3::HierarchicalMobilityModel构建一个参考点组移动模型(Reference Point Group Mobility model,RPGM)模型,
- 此模型在"Wireless Communications and Mobile Computing, 2002: vol. 2, pp. 2483-502"一文中由Tracy Camp、Jeff Boleng和Vanessa Davies描述。
-
- HierarchicalMobilityModel由两个移动模型组成:父模型和子模型。子模型的位置是相对于父模型的位置而言的。对于群组移动,
- 群组中的每个节点都安装相同的父模型和不同的子模型。
-
- 父模型(参考模型)没有与之关联的节点。相反,所有节点都与包含父模型和子模型的层次移动模型关联,并且节点的位置是父模型位置和子模型位置的矢量和。
-
- 标准的ns-3移动模型在'reference-point-course-change.mob'文件中追踪课程变化的输出。该文件仅在发生课程变化时追踪位置。
- 该示例还生成第二个跟踪:每秒采样一次的节点位置的时间序列。该文件是'reference-point-time-series.mob',可以使用'reference-point-group-mobility-animation.sh'程序绘制出来。
-
- 子模型中存在一定的随机性(在围绕父模型位置的10m x 10m的方框内进行随机游走);通过更改ns-3的'RunNumber'值(请参阅ns-3随机变量的文档),
- 可以产生稍微不同的输出。
-
- 有一个程序选项:'useHelper'。这仅用于代码演示目的;它选择使用帮助对象配置移动性的代码分支,还是直接使用CreateObject\<>()进行配置和处理指针。
- 生成的跟踪应该是相同的。
  \*/
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include <ns3/mobility-module.h>

#include <iostream>

using namespace ns3;

NS_LOG_COMPONENT_DEFINE("ReferencePointGroupMobilityExample");

/// The time series file.
std::ofstream g_timeSeries;

/**
 * Print the node position to the time series file.
 *
 * \param node The node.
 */
void
PrintPosition(Ptr<Node> node)
{
    if (!node)
    {
        return;
    }
    Ptr<MobilityModel> model = node->GetObject<MobilityModel>();
    if (!model)
    {
        return;
    }
    NS_LOG_LOGIC("Node: " << node->GetId() << " Position: " << model->GetPosition());
    g_timeSeries << Simulator::Now().GetSeconds() << " " << node->GetId() << " "
                 << model->GetPosition() << std::endl;
}

int
main(int argc, char* argv[])
{
    Time simTime = Seconds(800); // 模拟时间
    uint32_t numPrints = 800; // 记录节点位置的次数
    bool useHelper = false; // 是否使用Helper方法

    CommandLine cmd(__FILE__);
    cmd.AddValue("useHelper", "Whether to use helper code", useHelper);
    cmd.Parse(argc, argv);

    g_timeSeries.open("reference-point-time-series.mob");// 打开时间序列文件

    NodeContainer n;
    n.Create(3);

    // The primary mobility model is the WaypointMobilityModel defined within
    // this bounding box:
    //
    // (0,50)                   (100,50)
    //   +-------------------------+
    //   |  .(10,40)    (90,40).   |
    //   |                         |
    //   |                         |
    //   |  .(10,10)    (90,10).   |
    //   |                         |
    //   +-------------------------+
    // (0,0)                     (100,0)
    //

    // The reference (parent) mobility model starts at coordinate (10,10
    // and walks clockwise to each waypoint, making two laps.  The time
    // to travel between each waypoint is 100s, so the velocity alternates
    // between two values due to the rectangular path.
    // No actual node is represented by the position of this mobility
    // model; it forms the reference point from which the node's child
    // mobility model position is offset.
    //
    // 主要移动性模型是WaypointMobilityModel,定义了参考点的移动路径
    // 参考点移动路径示意图见注释中的图形描述
    Ptr<WaypointMobilityModel> waypointMm = CreateObject<WaypointMobilityModel>();
    waypointMm->AddWaypoint(Waypoint(Seconds(0), Vector(10, 10, 0)));
    waypointMm->AddWaypoint(Waypoint(Seconds(100), Vector(10, 40, 0)));
    waypointMm->AddWaypoint(Waypoint(Seconds(200), Vector(90, 40, 0)));
    waypointMm->AddWaypoint(Waypoint(Seconds(300), Vector(90, 10, 0)));
    waypointMm->AddWaypoint(Waypoint(Seconds(400), Vector(10, 10, 0)));
    waypointMm->AddWaypoint(Waypoint(Seconds(500), Vector(10, 40, 0)));
    waypointMm->AddWaypoint(Waypoint(Seconds(600), Vector(90, 40, 0)));
    waypointMm->AddWaypoint(Waypoint(Seconds(700), Vector(90, 10, 0)));
    waypointMm->AddWaypoint(Waypoint(Seconds(800), Vector(10, 10, 0)));

    // Each HierachicalMobilityModel contains the above model as the Parent,
    // and a user defined model as the Child.  Two MobilityModel objects are
    // instantiated per node (one hierarchical, and one child model), and
    // a single parent model is reused across all nodes.

    // The program now branches into two:  one using the low-level API, and
    // one using the GroupMobilityHelper.  Both branches result in equivalent
    // configuration.

    int64_t streamIndex = 1;
    if (useHelper == false)
    {
        // Assign random variable stream numbers on the parent and each child
        // 为参考点及每个节点的子移动性模型分配随机变量流编号
        streamIndex += waypointMm->AssignStreams(streamIndex);

        // Mobility model for the first node (node 0) 为第一个节点创建层次移动性模型
        Ptr<HierarchicalMobilityModel> hierarchical0 = CreateObject<HierarchicalMobilityModel>();
        hierarchical0->SetParent(waypointMm);

        // Child Mobility model for the first node (node 0).  This can be any
        // other mobility model type; for this example, we reuse the random walk
        // but with a small 10m x 10m bounding box.
        // 为第一个节点创建子移动性模型(RandomWalk2dMobilityModel)
        Ptr<RandomWalk2dMobilityModel> childRandomWalk0 = CreateObject<RandomWalk2dMobilityModel>();
        // Position in reference to the original random walk
        childRandomWalk0->SetAttribute("Bounds", RectangleValue(Rectangle(-5, 5, -5, 5)));
        childRandomWalk0->SetAttribute("Speed",
                                       StringValue("ns3::ConstantRandomVariable[Constant=0.1]"));
        streamIndex += childRandomWalk0->AssignStreams(streamIndex);
        hierarchical0->SetChild(childRandomWalk0);
        n.Get(0)->AggregateObject(hierarchical0);
        // Repeat for other two nodes
        Ptr<HierarchicalMobilityModel> hierarchical1 = CreateObject<HierarchicalMobilityModel>();
        hierarchical1->SetParent(waypointMm); // Same parent as before
        Ptr<RandomWalk2dMobilityModel> childRandomWalk1 = CreateObject<RandomWalk2dMobilityModel>();
        childRandomWalk1->SetAttribute("Bounds", RectangleValue(Rectangle(-5, 5, -5, 5)));
        childRandomWalk1->SetAttribute("Speed",
                                       StringValue("ns3::ConstantRandomVariable[Constant=0.1]"));
        streamIndex += childRandomWalk1->AssignStreams(streamIndex);
        hierarchical1->SetChild(childRandomWalk1);
        n.Get(1)->AggregateObject(hierarchical1);
        Ptr<HierarchicalMobilityModel> hierarchical2 = CreateObject<HierarchicalMobilityModel>();
        hierarchical2->SetParent(waypointMm); // Same parent as before
        Ptr<RandomWalk2dMobilityModel> childRandomWalk2 = CreateObject<RandomWalk2dMobilityModel>();
        childRandomWalk2->SetAttribute("Bounds", RectangleValue(Rectangle(-5, 5, -5, 5)));
        childRandomWalk2->SetAttribute("Speed",
                                       StringValue("ns3::ConstantRandomVariable[Constant=0.1]"));
        streamIndex += childRandomWalk2->AssignStreams(streamIndex);
        hierarchical2->SetChild(childRandomWalk2);
        n.Get(2)->AggregateObject(hierarchical2);
    }
    else
    {
        // This branch demonstrates an equivalent set of commands but using
        // the GroupMobilityHelper
        GroupMobilityHelper group;

        // The helper provides a method to set the reference mobility model
        // for construction by an object factory, but in this case, since we
        // are using the WaypointMobilityModel, which requires us to add
        // waypoints directly on the object, we will just pass in the pointer.
        group.SetReferenceMobilityModel(waypointMm);

        // The WaypointMobilityModel does not need a position allocator
        // (it can use its first waypoint as such), but in general, the
        // GroupMobilityHelper can be configured to accept configuration for
        // a PositionAllocator for the reference model.  We skip that here.

        // Next, configure the member mobility model
        group.SetMemberMobilityModel("ns3::RandomWalk2dMobilityModel",
                                     "Bounds",
                                     RectangleValue(Rectangle(-5, 5, -5, 5)),
                                     "Speed",
                                     StringValue("ns3::ConstantRandomVariable[Constant=0.1]"));

        // Again, we could call 'SetMemberPositionAllocator' and provide a
        // position allocator here for the member nodes, but none is provided
        // in this example, so they will start at time zero with the same
        // position as the reference node.

        // Install to all three nodes
        group.Install(n);

        // After installation, use the helper to make the equivalent
        // stream assignments as above
        group.AssignStreams(n, streamIndex);
    }

    // Note:  The tracing methods are static methods declared on the
    // MobilityHelper class, not on the GroupMobilityHelper class
    AsciiTraceHelper ascii;
    MobilityHelper::EnableAsciiAll(ascii.CreateFileStream("reference-point-course-change.mob"));

    // Use a logging PrintPosition() to record time-series position
    for (unsigned int i = 0; i < numPrints; i++)
    {
        for (auto nodeIt = n.Begin(); nodeIt != n.End(); ++nodeIt)
        {
            Simulator::Schedule(NanoSeconds(i * simTime.GetNanoSeconds() / numPrints),
                                &PrintPosition,
                                (*nodeIt));
        }
    }

    Simulator::Stop(simTime);
    Simulator::Run();
    g_timeSeries.close();
    Simulator::Destroy();
}


0

评论区