mobility: Add Reference Point Group Mobility (RPGM) example and script
This commit is contained in:
89
src/mobility/examples/reference-point-group-mobility-animate.sh
Executable file
89
src/mobility/examples/reference-point-group-mobility-animate.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2019, University of Padova, Dep. of Information Engineering, SIGNET lab
|
||||
# Copyright (c) 2021, University of Washington: animation extensions
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 as
|
||||
# published by the Free Software Foundation;
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Authors: Michele Polese <michele.polese@gmail.com>
|
||||
# Tom Henderson <tomhend@uw.edu>
|
||||
|
||||
#
|
||||
# Plot the trace generated by reference-point-group-mobility-example.cc
|
||||
# in a manner that enables animation
|
||||
#
|
||||
|
||||
# This Bash script is a variant of outdoor-random-walk-example.sh that
|
||||
# generates a large number of PNG image files, one for each node position
|
||||
# traced in the mobility trace file 'reference-point-time-series.mob'.
|
||||
#
|
||||
# This script relies on gnuplot (version 5.0 or greater).
|
||||
#
|
||||
# The PNGs are named in increasing numerical order from '0000.png' to
|
||||
# '0799.png'. The images can be assembled into an animated gif file
|
||||
# using a tool such as ImageMagick's convert utility, such as:
|
||||
#
|
||||
# $ convert -delay 10 -loop 0 *.png rpgm-animation.gif
|
||||
#
|
||||
# and the output file 'rpgm-animation.gif' can be viewed by an image viewer.
|
||||
#
|
||||
# Because this file generates many PNG files, it is recommended to move
|
||||
# this script and the generated time-series mobility file
|
||||
# named 'reference-point-time-series.mob' to a subdirectory, and then
|
||||
# run:
|
||||
# $ ./reference-point-group-mobility-animation.sh
|
||||
# $ convert -delay 10 -loop 0 *.png rpgm-animation.gif
|
||||
#
|
||||
|
||||
# The script first checks and enforces that only three nodes are present
|
||||
num_nodes=`cat reference-point-time-series.mob | awk '{ print $2 }' | sort -n | uniq | wc -l`
|
||||
if [ "$num_nodes" -ne "3" ]; then
|
||||
echo "Exiting: this tracing program designed only for 3 nodes"
|
||||
exit 1
|
||||
fi
|
||||
# Next, reduce the trace
|
||||
cat reference-point-time-series.mob | awk -F " " '{ print $3 }' | awk -F ":" '{ print $1" "$2 }' > rpgm-time-series.tmp
|
||||
# read three lines at a time from the reduced trace, convert to
|
||||
# a plottable temporary file, and invoke gnuplot. Loop until done.
|
||||
n=0
|
||||
while read p1 && read p2 && read p3; do
|
||||
basename=$(printf "%04d" "$n")
|
||||
cat >plotcmds <<EOL
|
||||
# If you do not have pngcairo installed, you can 'set terminal png' below,
|
||||
# but it will render the dashed bounding box as a solid line
|
||||
set terminal pngcairo dashed
|
||||
set output '$basename.png'
|
||||
set view map
|
||||
set xlabel 'X [m]'
|
||||
set ylabel 'Y [m]'
|
||||
set xrange [-10:110]
|
||||
set yrange [-10:60]
|
||||
set style fill transparent solid 0.5
|
||||
unset key
|
||||
set style fill transparent solid 0.35 noborder
|
||||
set style circle radius 0.5
|
||||
# Define dashed lines to mark the outer bounding box
|
||||
set arrow from 0,0 to 100,0 nohead dt "-" lc rgb "light-grey"
|
||||
set arrow from 100,0 to 100,50 nohead dt "-" lc rgb "light-grey"
|
||||
set arrow from 0,50 to 100,50 nohead dt "-" lc rgb "light-grey"
|
||||
set arrow from 0,0 to 0,50 nohead dt "-" lc rgb "light-grey"
|
||||
plot "<echo '$p1'" with circles lc rgb "red",\
|
||||
"<echo '$p2'" with circles lc rgb "blue",\
|
||||
"<echo '$p3'" with circles lc rgb "black"
|
||||
EOL
|
||||
gnuplot plotcmds
|
||||
rm plotcmds
|
||||
(( n++ ))
|
||||
done < rpgm-time-series.tmp
|
||||
rm rpgm-time-series.tmp
|
||||
169
src/mobility/examples/reference-point-group-mobility-example.cc
Normal file
169
src/mobility/examples/reference-point-group-mobility-example.cc
Normal file
@@ -0,0 +1,169 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2020 Institute for the Wireless Internet of Things, Northeastern University, Boston, MA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Michele Polese <michele.polese@gmail.com>
|
||||
*
|
||||
* Heavily edited by Tom Henderson (for proof-of-concept purposes)
|
||||
* - Reduced from src/mobility/examples/group-mobility-example.cc
|
||||
*/
|
||||
|
||||
/**
|
||||
* This example shows how to use the ns3::HierarchicalMobilityModel
|
||||
* to construct a Reference Point Group Mobility model (RPGM) model
|
||||
* as described in "A survey of mobility models for ad hoc network
|
||||
* research" by Tracy Camp, Jeff Boleng, and Vanessa Davies, Wireless
|
||||
* Communications and Mobile Computing, 2002: vol. 2, pp. 2483-502.
|
||||
*
|
||||
* The HierarchicalMobilityModel is composed of two mobility models;
|
||||
* a parent and a child. The position of the child is expressed
|
||||
* in reference to the position of the parent. For group mobility,
|
||||
* each node in the group can install the same parent mobility model
|
||||
* and different child mobility models.
|
||||
*
|
||||
* Standard ns-3 mobility model course change output is traced in
|
||||
* 'reference-point-course-change.mob' file. This file only traces
|
||||
* position when there is a course change. A second trace is produced,
|
||||
* which is a time-series of node positions sampled every second.
|
||||
* This file is 'reference-point-time-series.mob' and can be plotted
|
||||
* with the 'reference-point-group-mobility-animation.sh' program.
|
||||
*
|
||||
* There is a bit of randomness in the child mobility models (random
|
||||
* walk within a 10m x 10m box surrounding the parent mobility position);
|
||||
* slightly different output can be rendered by changing the ns-3 random
|
||||
* number 'run number' global value.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "ns3/core-module.h"
|
||||
#include <ns3/mobility-module.h>
|
||||
#include "ns3/network-module.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("ReferencePointGroupMobilityExample");
|
||||
|
||||
std::ofstream g_timeSeries;
|
||||
|
||||
void
|
||||
PrintPosition (Ptr<Node> node)
|
||||
{
|
||||
if (node == nullptr) return;
|
||||
Ptr<MobilityModel> model = node->GetObject<MobilityModel> ();
|
||||
if (model == nullptr) return;
|
||||
NS_LOG_LOGIC ("Node: " << node->GetId () << " Position: " << model->GetPosition ());
|
||||
g_timeSeries << Simulator::Now ().GetSeconds () << " " << node->GetId () << " " << model->GetPosition () << std::endl;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
Time simTime = Seconds (800);
|
||||
uint32_t numPrints = 800;
|
||||
|
||||
CommandLine cmd (__FILE__);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
g_timeSeries.open ("reference-point-time-series.mob");
|
||||
|
||||
NodeContainer n;
|
||||
n.Create (3);
|
||||
|
||||
// The primary mobility model is the WaypointMobilityModel defined within
|
||||
// this bounding box:
|
||||
//
|
||||
// (0,50) (100,50)
|
||||
// +-------------------------+
|
||||
// | .(10,40) (90,40). |
|
||||
// | |
|
||||
// | |
|
||||
// | .(10,10) (90,10). |
|
||||
// | |
|
||||
// +-------------------------+
|
||||
// (0,0) (100,0)
|
||||
//
|
||||
|
||||
// The reference (parent) mobility model starts at coordinate (10,10
|
||||
// and walks clockwise to each waypoint, making two laps. The time
|
||||
// to travel between each waypoint is 100s, so the velocity alternates
|
||||
// between two values due to the rectangular path.
|
||||
// No actual node is represented by the position of this mobility
|
||||
// model; it forms the reference point from which the node's child
|
||||
// mobility model position is offset.
|
||||
//
|
||||
Ptr<WaypointMobilityModel> waypointMm = CreateObject<WaypointMobilityModel> ();
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (0), Vector (10, 10, 0)));
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (100), Vector (10, 40, 0)));
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (200), Vector (90, 40, 0)));
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (300), Vector (90, 10, 0)));
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (400), Vector (10, 10, 0)));
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (500), Vector (10, 40, 0)));
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (600), Vector (90, 40, 0)));
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (700), Vector (90, 10, 0)));
|
||||
waypointMm->AddWaypoint (Waypoint (Seconds (800), Vector (10, 10, 0)));
|
||||
|
||||
// Each HierachicalMobilityModel contains the above model as the Parent,
|
||||
// and a user defined model as the Child. Two MobilityModel objects are
|
||||
// instantiated per node (one hierarchical, and one child model), and
|
||||
// a single parent model is reused across all nodes.
|
||||
|
||||
// Mobility model for the first node (node 0)
|
||||
Ptr<HierarchicalMobilityModel> hierarchical0 = CreateObject<HierarchicalMobilityModel> ();
|
||||
hierarchical0->SetParent (waypointMm);
|
||||
|
||||
// Child Mobility model for the first node (node 0). This can be any
|
||||
// other mobility model type; for this example, we reuse the random walk
|
||||
// but with a small 10m x 10m bounding box.
|
||||
Ptr<RandomWalk2dMobilityModel> childRandomWalk0 = CreateObject<RandomWalk2dMobilityModel> ();
|
||||
// Position in reference to the original random walk
|
||||
childRandomWalk0->SetAttribute ("Bounds", RectangleValue (Rectangle (-5, 5, -5, 5)));
|
||||
childRandomWalk0->SetAttribute ("Speed", StringValue ("ns3::ConstantRandomVariable[Constant=0.1]"));
|
||||
hierarchical0->SetChild (childRandomWalk0);
|
||||
n.Get (0)->AggregateObject (hierarchical0);
|
||||
// Repeat for other two nodes
|
||||
Ptr<HierarchicalMobilityModel> hierarchical1 = CreateObject<HierarchicalMobilityModel> ();
|
||||
hierarchical1->SetParent (waypointMm); // Same parent as before
|
||||
Ptr<RandomWalk2dMobilityModel> childRandomWalk1 = CreateObject<RandomWalk2dMobilityModel> ();
|
||||
childRandomWalk1->SetAttribute ("Bounds", RectangleValue (Rectangle (-5, 5, -5, 5)));
|
||||
childRandomWalk1->SetAttribute ("Speed", StringValue ("ns3::ConstantRandomVariable[Constant=0.1]"));
|
||||
hierarchical1->SetChild (childRandomWalk1);
|
||||
n.Get (1)->AggregateObject (hierarchical1);
|
||||
Ptr<HierarchicalMobilityModel> hierarchical2 = CreateObject<HierarchicalMobilityModel> ();
|
||||
hierarchical2->SetParent (waypointMm); // Same parent as before
|
||||
Ptr<RandomWalk2dMobilityModel> childRandomWalk2 = CreateObject<RandomWalk2dMobilityModel> ();
|
||||
childRandomWalk2->SetAttribute ("Bounds", RectangleValue (Rectangle (-5, 5, -5, 5)));
|
||||
childRandomWalk2->SetAttribute ("Speed", StringValue ("ns3::ConstantRandomVariable[Constant=0.1]"));
|
||||
hierarchical2->SetChild (childRandomWalk2);
|
||||
n.Get (2)->AggregateObject (hierarchical2);
|
||||
|
||||
AsciiTraceHelper ascii;
|
||||
MobilityHelper::EnableAsciiAll (ascii.CreateFileStream ("reference-point-course-change.mob"));
|
||||
|
||||
// Use a logging PrintPosition() to record time-series position
|
||||
for (unsigned int i = 0; i < numPrints; i++)
|
||||
{
|
||||
for (auto nodeIt = n.Begin (); nodeIt != n.End (); ++nodeIt)
|
||||
{
|
||||
Simulator::Schedule (NanoSeconds (i * simTime.GetNanoSeconds () / numPrints), &PrintPosition, (*nodeIt));
|
||||
}
|
||||
}
|
||||
|
||||
Simulator::Stop (simTime);
|
||||
Simulator::Run ();
|
||||
g_timeSeries.close ();
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
@@ -27,3 +27,7 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('bonnmotion-ns2-example',
|
||||
['core', 'mobility'])
|
||||
obj.source = 'bonnmotion-ns2-example.cc'
|
||||
|
||||
obj = bld.create_ns3_program('reference-point-group-mobility-example',
|
||||
['core', 'network', 'mobility'])
|
||||
obj.source = 'reference-point-group-mobility-example.cc'
|
||||
|
||||
Reference in New Issue
Block a user