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
73std::ofstream g_timeSeries;
74
75void
77{
78 if (node == nullptr) return;
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
86void
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;
97 for (BuildingList::Iterator it = BuildingList::Begin (); it != BuildingList::End (); ++it)
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
108int
109main (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
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 ();
260 Simulator::Destroy ();
261}
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...
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...
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...
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: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
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:257
#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 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: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
void PrintGnuplottableBuildingListToFile(std::string filename)
std::ofstream g_timeSeries
void PrintPosition(Ptr< Node > node)