A Discrete-Event Network Simulator
API
reference-point-group-mobility-example.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Institute for the Wireless Internet of Things, Northeastern University, Boston, MA
4  * Copyright (c) 2021 University of Washington: for HierarchicalMobilityModel
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Michele Polese <michele.polese@gmail.com>
20  * Heavily edited by Tom Henderson (to reuse HierachicalMobilityModel)
21  */
22 
60 #include <iostream>
61 #include "ns3/core-module.h"
62 #include <ns3/mobility-module.h>
63 #include "ns3/network-module.h"
64 
65 using namespace ns3;
66 
67 NS_LOG_COMPONENT_DEFINE ("ReferencePointGroupMobilityExample");
68 
69 std::ofstream g_timeSeries;
70 
71 void
73 {
74  if (node == nullptr) return;
75  Ptr<MobilityModel> model = node->GetObject<MobilityModel> ();
76  if (model == nullptr) return;
77  NS_LOG_LOGIC ("Node: " << node->GetId () << " Position: " << model->GetPosition ());
78  g_timeSeries << Simulator::Now ().GetSeconds () << " " << node->GetId () << " " << model->GetPosition () << std::endl;
79 
80 }
81 
82 int
83 main (int argc, char *argv[])
84 {
85  Time simTime = Seconds (800);
86  uint32_t numPrints = 800;
87  bool useHelper = false;
88 
89  CommandLine cmd (__FILE__);
90  cmd.AddValue ("useHelper", "Whether to use helper code", useHelper);
91  cmd.Parse (argc, argv);
92 
93  g_timeSeries.open ("reference-point-time-series.mob");
94 
95  NodeContainer n;
96  n.Create (3);
97 
98  // The primary mobility model is the WaypointMobilityModel defined within
99  // this bounding box:
100  //
101  // (0,50) (100,50)
102  // +-------------------------+
103  // | .(10,40) (90,40). |
104  // | |
105  // | |
106  // | .(10,10) (90,10). |
107  // | |
108  // +-------------------------+
109  // (0,0) (100,0)
110  //
111 
112  // The reference (parent) mobility model starts at coordinate (10,10
113  // and walks clockwise to each waypoint, making two laps. The time
114  // to travel between each waypoint is 100s, so the velocity alternates
115  // between two values due to the rectangular path.
116  // No actual node is represented by the position of this mobility
117  // model; it forms the reference point from which the node's child
118  // mobility model position is offset.
119  //
120  Ptr<WaypointMobilityModel> waypointMm = CreateObject<WaypointMobilityModel> ();
121  waypointMm->AddWaypoint (Waypoint (Seconds (0), Vector (10, 10, 0)));
122  waypointMm->AddWaypoint (Waypoint (Seconds (100), Vector (10, 40, 0)));
123  waypointMm->AddWaypoint (Waypoint (Seconds (200), Vector (90, 40, 0)));
124  waypointMm->AddWaypoint (Waypoint (Seconds (300), Vector (90, 10, 0)));
125  waypointMm->AddWaypoint (Waypoint (Seconds (400), Vector (10, 10, 0)));
126  waypointMm->AddWaypoint (Waypoint (Seconds (500), Vector (10, 40, 0)));
127  waypointMm->AddWaypoint (Waypoint (Seconds (600), Vector (90, 40, 0)));
128  waypointMm->AddWaypoint (Waypoint (Seconds (700), Vector (90, 10, 0)));
129  waypointMm->AddWaypoint (Waypoint (Seconds (800), Vector (10, 10, 0)));
130 
131  // Each HierachicalMobilityModel contains the above model as the Parent,
132  // and a user defined model as the Child. Two MobilityModel objects are
133  // instantiated per node (one hierarchical, and one child model), and
134  // a single parent model is reused across all nodes.
135 
136  // The program now branches into two: one using the low-level API, and
137  // one using the GroupMobilityHelper. Both branches result in equivalent
138  // configuration.
139 
140  int64_t streamIndex = 1;
141  if (useHelper == false)
142  {
143  // Assign random variable stream numbers on the parent and each child
144  streamIndex += waypointMm->AssignStreams (streamIndex);
145 
146  // Mobility model for the first node (node 0)
147  Ptr<HierarchicalMobilityModel> hierarchical0 = CreateObject<HierarchicalMobilityModel> ();
148  hierarchical0->SetParent (waypointMm);
149 
150  // Child Mobility model for the first node (node 0). This can be any
151  // other mobility model type; for this example, we reuse the random walk
152  // but with a small 10m x 10m bounding box.
153  Ptr<RandomWalk2dMobilityModel> childRandomWalk0 = CreateObject<RandomWalk2dMobilityModel> ();
154  // Position in reference to the original random walk
155  childRandomWalk0->SetAttribute ("Bounds", RectangleValue (Rectangle (-5, 5, -5, 5)));
156  childRandomWalk0->SetAttribute ("Speed", StringValue ("ns3::ConstantRandomVariable[Constant=0.1]"));
157  streamIndex += childRandomWalk0->AssignStreams (streamIndex);
158  hierarchical0->SetChild (childRandomWalk0);
159  n.Get (0)->AggregateObject (hierarchical0);
160  // Repeat for other two nodes
161  Ptr<HierarchicalMobilityModel> hierarchical1 = CreateObject<HierarchicalMobilityModel> ();
162  hierarchical1->SetParent (waypointMm); // Same parent as before
163  Ptr<RandomWalk2dMobilityModel> childRandomWalk1 = CreateObject<RandomWalk2dMobilityModel> ();
164  childRandomWalk1->SetAttribute ("Bounds", RectangleValue (Rectangle (-5, 5, -5, 5)));
165  childRandomWalk1->SetAttribute ("Speed", StringValue ("ns3::ConstantRandomVariable[Constant=0.1]"));
166  streamIndex += childRandomWalk1->AssignStreams (streamIndex);
167  hierarchical1->SetChild (childRandomWalk1);
168  n.Get (1)->AggregateObject (hierarchical1);
169  Ptr<HierarchicalMobilityModel> hierarchical2 = CreateObject<HierarchicalMobilityModel> ();
170  hierarchical2->SetParent (waypointMm); // Same parent as before
171  Ptr<RandomWalk2dMobilityModel> childRandomWalk2 = CreateObject<RandomWalk2dMobilityModel> ();
172  childRandomWalk2->SetAttribute ("Bounds", RectangleValue (Rectangle (-5, 5, -5, 5)));
173  childRandomWalk2->SetAttribute ("Speed", StringValue ("ns3::ConstantRandomVariable[Constant=0.1]"));
174  streamIndex += childRandomWalk2->AssignStreams (streamIndex);
175  hierarchical2->SetChild (childRandomWalk2);
176  n.Get (2)->AggregateObject (hierarchical2);
177  }
178  else
179  {
180  // This branch demonstrates an equivalent set of commands but using
181  // the GroupMobilityHelper
182  GroupMobilityHelper group;
183 
184  // The helper provides a method to set the reference mobility model
185  // for construction by an object factory, but in this case, since we
186  // are using the WaypointMobilityModel, which requires us to add
187  // waypoints directly on the object, we will just pass in the pointer.
188  group.SetReferenceMobilityModel (waypointMm);
189 
190  // The WaypointMobilityModel does not need a position allocator
191  // (it can use its first waypoint as such), but in general, the
192  // GroupMobilityHelper can be configured to accept configuration for
193  // a PositionAllocator for the reference model. We skip that here.
194 
195  // Next, configure the member mobility model
196  group.SetMemberMobilityModel ("ns3::RandomWalk2dMobilityModel",
197  "Bounds", RectangleValue (Rectangle (-5, 5, -5, 5)),
198  "Speed", StringValue ("ns3::ConstantRandomVariable[Constant=0.1]"));
199 
200  // Again, we could call 'SetMemberPositionAllocator' and provide a
201  // position allocator here for the member nodes, but none is provided
202  // in this example, so they will start at time zero with the same
203  // position as the reference node.
204 
205  // Install to all three nodes
206  group.Install (n);
207 
208  // After installation, use the helper to make the equivalent
209  // stream assignments as above
210  group.AssignStreams (n, streamIndex);
211  }
212 
213  // Note: The tracing methods are static methods declared on the
214  // MobilityHelper class, not on the GroupMobilityHelper class
215  AsciiTraceHelper ascii;
216  MobilityHelper::EnableAsciiAll (ascii.CreateFileStream ("reference-point-course-change.mob"));
217 
218  // Use a logging PrintPosition() to record time-series position
219  for (unsigned int i = 0; i < numPrints; i++)
220  {
221  for (auto nodeIt = n.Begin (); nodeIt != n.End (); ++nodeIt)
222  {
223  Simulator::Schedule (NanoSeconds (i * simTime.GetNanoSeconds () / numPrints), &PrintPosition, (*nodeIt));
224  }
225  }
226 
227  Simulator::Stop (simTime);
228  Simulator::Run ();
229  g_timeSeries.close ();
231 }
Manage ASCII trace files for device models.
Definition: trace-helper.h:163
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
Parse command-line arguments.
Definition: command-line.h:229
Helper class used to assign positions and mobility models to nodes for a group mobility configuration...
int64_t AssignStreams(NodeContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the mobility models on t...
void Install(Ptr< Node > node)
Install and configure a hierarchical mobility model to the given node, based on the configured refere...
void SetReferenceMobilityModel(Ptr< MobilityModel > mobility)
Set the reference mobility model which will be installed as the parent mobility model during GroupMob...
void SetMemberMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
Configure the mobility model which will be installed as the member (child) mobility model during Grou...
static void EnableAsciiAll(Ptr< OutputStreamWrapper > stream)
Keep track of the current position and velocity of an object.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Vector GetPosition(void) const
keep track of a set of node pointers.
Iterator Begin(void) const
Get an iterator which refers to the first Node in the container.
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t GetId(void) const
Definition: node.cc:109
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
a 2d rectangle
Definition: rectangle.h:35
AttributeValue implementation for Rectangle.
Definition: rectangle.h:97
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:391
a (time, location) pair.
Definition: waypoint.h:36
void AddWaypoint(const Waypoint &waypoint)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:35
std::ofstream g_timeSeries
void PrintPosition(Ptr< Node > node)