A Discrete-Event Network Simulator
API
outdoor-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: refactor for hierarchical model
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 use HierarchicalMobilityModel
21  */
22 
63 #include <iostream>
64 #include "ns3/core-module.h"
65 #include <ns3/mobility-module.h>
66 #include "ns3/network-module.h"
67 #include "ns3/buildings-module.h"
68 
69 using namespace ns3;
70 
71 NS_LOG_COMPONENT_DEFINE ("OutdoorGroupMobilityExample");
72 
73 std::ofstream g_timeSeries;
74 
75 void
77 {
78  if (node == nullptr) return;
79  Ptr<MobilityModel> model = node->GetObject<MobilityModel> ();
80  if (model == nullptr) return;
81  NS_LOG_LOGIC ("Node: " << node->GetId () << " Position: " << model->GetPosition ());
82  g_timeSeries << Simulator::Now ().GetSeconds () << " " << node->GetId () << " " << model->GetPosition () << std::endl;
83 
84 }
85 
86 void
88 {
89  std::ofstream outFile;
90  outFile.open (filename.c_str (), std::ios_base::out | std::ios_base::trunc);
91  if (!outFile.is_open ())
92  {
93  NS_LOG_ERROR ("Can't open file " << filename);
94  return;
95  }
96  uint32_t index = 1;
98  {
99  ++index;
100  Box box = (*it)->GetBoundaries ();
101  outFile << "set object " << index
102  << " rect from " << box.xMin << "," << box.yMin
103  << " to " << box.xMax << "," << box.yMax
104  << std::endl;
105  }
106 }
107 
108 int
109 main (int argc, char *argv[])
110 {
111  Time simTime = Seconds (800);
112  uint32_t numPrints = 800;
113  bool useHelper = false;
114 
115  CommandLine cmd (__FILE__);
116  cmd.AddValue ("useHelper", "Whether to use helper code", useHelper);
117  cmd.Parse (argc, argv);
118 
119  g_timeSeries.open ("outdoor-group-mobility-time-series.mob");
120 
122  n.Create (3);
123 
124  // The primary mobility model is the RandomWalk2dOutdoorMobilityModel
125  // defined within this bounding box (along with four buildings, not shown):
126  //
127  // (0,50) (100,50)
128  // +-------------------------+
129  // | |
130  // | |
131  // | |
132  // | |
133  // | |
134  // +-------------------------+
135  // (0,0) (100,0)
136  //
137  //
138  // There are two buildings centered at (50,10) and (50,40), and two
139  // additional small buildings centered at (20,25) and (80,25) that
140  // create obstacles for the nodes to avoid.
141 
142  std::vector<Ptr<Building> > buildingVector;
143  Ptr<Building> building = CreateObject<Building> ();
144  building->SetBoundaries (Box (45, 55, 5, 15, 0, 10));
145  buildingVector.push_back (building);
146  building = CreateObject<Building> ();
147  building->SetBoundaries (Box (45, 55, 35, 45, 0, 10));
148  buildingVector.push_back (building);
149  building = CreateObject<Building> ();
150  building->SetBoundaries (Box (17.5, 22.5, 22.5, 27.5, 0, 10));
151  buildingVector.push_back (building);
152  building = CreateObject<Building> ();
153  building->SetBoundaries (Box (77.5, 82.5, 22.5, 27.5, 0, 10));
154  buildingVector.push_back (building);
155 
156  // print the list of buildings to file
157  PrintGnuplottableBuildingListToFile ("outdoor-group-mobility-buildings.txt");
158 
159  // The program now branches into two: one using the low-level API, and
160  // one using the GroupMobilityHelper. Both branches result in equivalent
161  // configuration.
162 
163  int64_t streamIndex = 1;
164  if (useHelper == false)
165  {
166  // The reference (parent) mobility model starts at coordinate (10, 10, 0)
167  // and performs a buildings-aware random walk.
168  //
169  Ptr<RandomWalk2dOutdoorMobilityModel> outdoorMm = CreateObject<RandomWalk2dOutdoorMobilityModel> ();
170  outdoorMm->SetAttribute ("Bounds", RectangleValue (Rectangle (0, 100, 0, 50)));
171  // The tolerance value is used to prevent the child mobility models from
172  // crossing building walls. The child mobility models are defined as
173  // offsets from the parent but are not buildings-aware, so it could be
174  // the case that the parent mobility model was just outside of a wall
175  // but the child mobility model was inside of a wall. The tolerance
176  // value (in meters) prevents the composite position from passing
177  // through a building wall.
178  outdoorMm->SetAttribute ("Tolerance", DoubleValue (2));
179  // The initial position can be directly set
180  outdoorMm->SetPosition (Vector (10, 10, 0));
181  streamIndex += outdoorMm->AssignStreams (streamIndex);
182 
183  // Each HierachicalMobilityModel contains the above model as the Parent,
184  // and a user defined model as the Child. Two MobilityModel objects are
185  // instantiated per node, and each node also shares the same parent model.
186 
187  // Mobility model for the first node (node 0)
188  Ptr<HierarchicalMobilityModel> hierarchical0 = CreateObject<HierarchicalMobilityModel> ();
189  hierarchical0->SetParent (outdoorMm);
190 
191  // Child model for the first node (node 0)
192  Ptr<ConstantPositionMobilityModel> child0 = CreateObject<ConstantPositionMobilityModel> ();
193  child0->SetPosition (Vector (1, 0, 0)); // 1 m offset from parent position
194  // There is no need to AssignStreams() to child0 because the position
195  // is constant and deterministic
196  hierarchical0->SetChild (child0);
197  n.Get (0)->AggregateObject (hierarchical0);
198 
199  // Repeat for other two nodes
200  Ptr<HierarchicalMobilityModel> hierarchical1 = CreateObject<HierarchicalMobilityModel> ();
201  hierarchical1->SetParent (outdoorMm); // Same parent as before
202  Ptr<ConstantPositionMobilityModel> child1 = CreateObject<ConstantPositionMobilityModel> ();
203  child1->SetPosition (Vector (-1, 0, 0));
204  hierarchical1->SetChild (child1);
205  n.Get (1)->AggregateObject (hierarchical1);
206  Ptr<HierarchicalMobilityModel> hierarchical2 = CreateObject<HierarchicalMobilityModel> ();
207  hierarchical2->SetParent (outdoorMm); // Same parent as before
208  Ptr<ConstantPositionMobilityModel> child2 = CreateObject<ConstantPositionMobilityModel> ();
209  child2->SetPosition (Vector (0, 1, 0));
210  hierarchical2->SetChild (child2);
211  n.Get (2)->AggregateObject (hierarchical2);
212  }
213  else
214  {
215  // This branch demonstrates an equivalent set of commands but using
216  // the GroupMobilityHelper
217  GroupMobilityHelper group;
218 
219  // The helper provides a method to set the reference mobility model
220  // for construction by an object factory, but in this case, since we
221  // are using the WaypointMobilityModel, which requires us to add
222  // waypoints directly on the object, we will just pass in the pointer.
223  group.SetReferenceMobilityModel ("ns3::RandomWalk2dOutdoorMobilityModel",
224  "Bounds", RectangleValue (Rectangle (0, 100, 0, 50)),
225  "Tolerance", DoubleValue (2));
226  Ptr<ListPositionAllocator> listPosition = CreateObject<ListPositionAllocator> ();
227  listPosition->Add (Vector (10, 10, 0));
228  group.SetReferencePositionAllocator (listPosition);
229 
230  group.SetMemberMobilityModel ("ns3::ConstantPositionMobilityModel");
231  listPosition = CreateObject<ListPositionAllocator> ();
232  listPosition->Add (Vector (1, 0, 0)); // first child
233  listPosition->Add (Vector (-1, 0, 0)); // second child
234  listPosition->Add (Vector (0, 1, 0)); // second child
235  group.SetMemberPositionAllocator (listPosition);
236 
237  // Install to all three nodes
238  group.Install (n);
239 
240  // After installation, use the helper to make the equivalent
241  // stream assignments as above
242  group.AssignStreams (n, streamIndex);
243  }
244 
245  AsciiTraceHelper ascii;
246  MobilityHelper::EnableAsciiAll (ascii.CreateFileStream ("outdoor-group-mobility-course-change.mob"));
247 
248  // Use a logging PrintPosition() to record time-series position
249  for (unsigned int i = 0; i < numPrints; i++)
250  {
251  for (auto nodeIt = n.Begin (); nodeIt != n.End (); ++nodeIt)
252  {
253  Simulator::Schedule (NanoSeconds (i * simTime.GetNanoSeconds () / numPrints), &PrintPosition, (*nodeIt));
254  }
255  }
256 
257  Simulator::Stop (simTime);
258  Simulator::Run ();
259  g_timeSeries.close ();
261 }
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::BuildingList::Begin
static Iterator Begin(void)
Definition: building-list.cc:173
ns3::GroupMobilityHelper::SetReferenceMobilityModel
void SetReferenceMobilityModel(Ptr< MobilityModel > mobility)
Set the reference mobility model which will be installed as the parent mobility model during GroupMob...
Definition: group-mobility-helper.cc:114
ns3::CommandLine
Parse command-line arguments.
Definition: command-line.h:228
ns3::ListPositionAllocator::Add
void Add(Vector v)
Add a position to the list of positions.
Definition: position-allocator.cc:70
g_timeSeries
std::ofstream g_timeSeries
Definition: outdoor-group-mobility-example.cc:71
ns3::Node::GetId
uint32_t GetId(void) const
Definition: node.cc:109
ns3::HierarchicalMobilityModel::SetParent
void SetParent(Ptr< MobilityModel > model)
Sets the parent mobility model to a new one, possibly replacing an existing one.
Definition: hierarchical-mobility-model.cc:84
ns3::Simulator::Now
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::GroupMobilityHelper::Install
void Install(Ptr< Node > node)
Install and configure a hierarchical mobility model to the given node, based on the configured refere...
Definition: group-mobility-helper.cc:173
ns3::GroupMobilityHelper::SetMemberPositionAllocator
void SetMemberPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of the member mobility...
Definition: group-mobility-helper.cc:81
ns3::Box::xMin
double xMin
The x coordinate of the left bound of the box.
Definition: box.h:110
ns3::Object::GetObject
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
ns3::RectangleValue
AttributeValue implementation for Rectangle.
Definition: rectangle.h:97
ns3::MobilityModel::SetPosition
void SetPosition(const Vector &position)
Definition: mobility-model.cc:88
ns3::ObjectBase::SetAttribute
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
PrintGnuplottableBuildingListToFile
void PrintGnuplottableBuildingListToFile(std::string filename)
Definition: outdoor-group-mobility-example.cc:87
ns3::Simulator::Schedule
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
ns3::BuildingList::End
static Iterator End(void)
Definition: building-list.cc:178
ns3::Box::yMin
double yMin
The y coordinate of the bottom bound of the box.
Definition: box.h:114
ns3::DoubleValue
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
ns3::HierarchicalMobilityModel::SetChild
void SetChild(Ptr< MobilityModel > model)
Sets the child mobility model to a new one, possibly replacing an existing one.
Definition: hierarchical-mobility-model.cc:60
ns3::Ptr< Node >
ns3::BuildingList::Iterator
std::vector< Ptr< Building > >::const_iterator Iterator
Definition: building-list.h:36
ns3::Simulator::Stop
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
ns3::NanoSeconds
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
ns3::MobilityHelper::EnableAsciiAll
static void EnableAsciiAll(Ptr< OutputStreamWrapper > stream)
Definition: mobility-helper.cc:250
ns3::Building::SetBoundaries
void SetBoundaries(Box box)
Set the boundaries of the building.
Definition: building.cc:139
ns3::AsciiTraceHelper::CreateFileStream
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.
Definition: trace-helper.cc:191
ns3::MobilityModel::AssignStreams
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: mobility-model.cc:114
ns3::GroupMobilityHelper::SetReferencePositionAllocator
void SetReferencePositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of the reference mobil...
Definition: group-mobility-helper.cc:48
ns3::Time
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
second.cmd
cmd
Definition: second.py:35
ns3::Time::GetNanoSeconds
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:392
ns3::Rectangle
a 2d rectangle
Definition: rectangle.h:35
NS_LOG_LOGIC
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
ns3::Simulator::Run
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
ns3::GroupMobilityHelper::SetMemberMobilityModel
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...
Definition: group-mobility-helper.cc:148
NS_LOG_ERROR
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
ns3::AsciiTraceHelper
Manage ASCII trace files for device models.
Definition: trace-helper.h:163
ns3::GroupMobilityHelper::AssignStreams
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...
Definition: group-mobility-helper.cc:214
PrintPosition
void PrintPosition(Ptr< Node > node)
Definition: outdoor-group-mobility-example.cc:76
ns3::Seconds
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
ns3::Simulator::Destroy
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
ns3::Box
a 3d box
Definition: box.h:35
ns3::GroupMobilityHelper
Helper class used to assign positions and mobility models to nodes for a group mobility configuration...
Definition: group-mobility-helper.h:47
ns3::MobilityModel
Keep track of the current position and velocity of an object.
Definition: mobility-model.h:40
ns3::NodeContainer
keep track of a set of node pointers.
Definition: node-container.h:39
ns3::MobilityModel::GetPosition
Vector GetPosition(void) const
Definition: mobility-model.cc:64
ns3::Box::xMax
double xMax
The x coordinate of the right bound of the box.
Definition: box.h:112
ns3::Time::GetSeconds
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
sample-rng-plot.n
n
Definition: sample-rng-plot.py:37
ns3::Box::yMax
double yMax
The y coordinate of the top bound of the box.
Definition: box.h:116