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