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