A flexible 3D visualizer for displaying, debugging, presenting, and understanding ns-3 scenarios.
- About
- Requirements
- Installation
- Documentation
- Configuration Options
- Running the Examples
- Feature Overview
This is the ns-3 companion module the NetSimulyzer. Link this module & run your scenario to see it in 3D.
- A C++ 17 compliant compiler
- Minimum supported compilers:
- GCC 10.5.0
- Clang 12.0.0
- Minimum supported compilers:
Clone the project into a directory called netsimulyzer
in
the contrib
directory of a supported version of ns-3
cd
into thecontrib
directory ofns-3
cd contrib/
- Clone the project from one of the below URLs
# Pick one of the below
# HTTPS (Choose this one if you're uncertain)
git clone https://github.com/usnistgov/NetSimulyzer-ns3-module netsimulyzer
# SSH
git clone [email protected]:usnistgov/NetSimulyzer-ns3-module.git netsimulyzer
- (Re)configure & (Re)build
ns-3
If you're using a version of ns-3 without CMake, replace./ns3
with./waf
# --enable-examples is optional, see `Running the Examples`
# for how to run them
./ns3 configure --enable-examples
./ns3
If, for whatever reason, git
is not available, download the
project & unzip it into the contrib
directory of ns-3
.
Note that updates will have to be performed manually using this method
- Download the ZIP of the project from the url below:
https://github.com/usnistgov/NetSimulyzer-ns3-module/archive/master.zip
- Unzip the file into the
ns-3
contrib/
directory
unzip NetSimulyzer-ns3-module-master.zip
- Rename the resulting directory to
netsimulyzer
, as ns-3 will not accept a module named differently than its directory.
mv NetSimulyzer-ns3-module-master netsimulyzer
If you are linking your module/program to the netsimulyzer
module add the following to your CMakeLists.txt
(CMake)
or wscript
(Waf)
For CMake, add the NetSimulyzer's target ${libnetsimulyzer}
to your libraries_to_link
list
# Example
build_lib_example(
NAME your-example-name
SOURCE_FILES example.cc
LIBRARIES_TO_LINK
${libnetsimulyzer}
# ...
)
# Module
build_lib(
LIBNAME your-module-name
SOURCE_FILES
# ...
HEADER_FILES
# ...
LIBRARIES_TO_LINK
${libnetsimulyzer}
# ...
)
For waf, add the NetSimulyzer's module name netsimulyzer
to the dependency list
# Program
obj = bld.create_ns3_program('program-name', ['netsimulyzer', '''...'''])
# Module
module = bld.create_ns3_module('module-name', ['netsimulyzer', '''...'''])
You may now include & use the netsimulyzer
module in code:
#include <ns3/netsimulyzer-module.h>
//...
int main ()
{
// ...
auto orchestrator = CreateObject<netsimulyzer::Orchestrator> ("example.json");
// ...
}
You may wish for your module to not have a hard dependency on the netsimulyzer
module.
The following steps will allow you to link the module & still allow your code to build &
run without the module being present.
Check for the NetSimulyzer in the ns3-all-enabled-modules
list to confirm
if the module is present.
Note: if the module linking to the NetSimulyzer module is in the src/
directory,
then you'll need to add the HAS_NETSIMULYZER
C++ define
yourself when you check for the presence of the module.
See the N.B. comment in the example below
# Create a list of your required modules to link
# 'core' & 'mobility' are just examples here
set(libraries_to_link "${libcore};${libmobility}")
if(HAS_NETSIMULYZER)
# If it's there, then it's safe to add to the library list
list(APPEND libraries_to_link ${libnetsimulyzer})
# N.B if the module you're linking to is in the `src/` directory
# of ns-3, then (at least for now), you must also add the C++ define
# yourself, like this.
#
# There's no harm in repeated definitions of the same value, so there's no
# need to guard this statement
add_definitions(-DHAS_NETSIMULYZER)
endif()
# Use the `libraries_to_link` list as your dependency list
# Module
build_lib(
LIBNAME your-module
SOURCE_FILES
# ...
HEADER_FILES
# ...
LIBRARIES_TO_LINK
${libraries_to_link}
)
# Example
build_lib_example(
NAME your-scenario
SOURCE_FILES scenario.cc
LIBRARIES_TO_LINK
${libraries_to_link}
)
If you wish for your module/program to be able to build without the netsimulyzer
module
you may check for its existence by reading bld.env['HAS_NETSIMULYZER']
in your wscript
. See below:
def build(bld):
# Create a list of your required modules to link
# 'core' & 'mobility' are just examples here
linked_modules = ['core', 'mobility']
# Check if 'HAS_NETSIMULYZER' was defined during configuration
if 'HAS_NETSIMULYZER' in bld.env:
# If it was defined, then the 'netsimulyzer' is present and we may link it
linked_modules.append('netsimulyzer')
# Be sure to pass your list of `linked_modules` to `create_ns3_program`
# or `create_ns3_module`
obj = bld.create_ns3_program('application-name', linked_modules)
In addition to the variable in the build environment, the module also defines a C++ macro
also named HAS_NETSIMULYZER
. This macro may be used in C++ code to check for the presence
of the netsimulyzer
module.
Note, if you're using CMake and the module is in the src/
directory, you may have to add
this definition yourself (scratch/
and module examples are fine).
See the CMake build system section for more information.
See the below code sample:
// Guard the include with the macro
#ifdef HAS_NETSIMULYZER
#include <ns3/netsimulyzer-module.h>
#endif
// ...
int main ()
{
// ...
// Guard any NetSimulyzer references in code with the macro as well
#ifdef HAS_NETSIMULYZER
auto orchestrator = CreateObject<netsimulyzer::Orchestrator> ("example.json");
// ...
#endif
}
To update the cloned module, move to the module's root directory and perform a git pull
# From the ns-3 root
cd contrib/netsimulyzer
git pull
To update a ZIP installation, remove the old module and replace it with the updated one.
# From the ns-3 root
cd contrib
rm -Rf netsimulyzer
#use this command, or download manually
wget https://github.com/usnistgov/NetSimulyzer-ns3-module/archive/refs/heads/master.zip -O NetSimulyzer-ns3-module-master.zip
unzip NetSimulyzer-ns3-module-master.zip
# Make sure the directory in the ns-3 contrib/ directory is
# named `netsimulyzer`
mv NetSimulyzer-ns3-module-master netsimulyzer
For prebuilt versions of the documentation, see the Releases page on GitHub.
Sphinx is required to build the documentation.
To run Sphinx to build the documentation, cd into the doc
directory in the module
and run make [type]
for the type of documentation you wish to build.
# From the ns-3 root directory
cd contrib/netsimulyzer/doc
# HTML (Several Pages)
make html
# HTML (One Page)
make singlehtml
# PDF
make latexpdf
# To list other options, just run make
make
The built documentation will now be found in doc/build/[type]
.
To configure the build, any of the below may be passed to the configuration stage of
ns-3 (ns3 configure
) with -- -D[Option1]=ON -D[Option2]=OFF
in the form:
./ns3 configure -- -DNETSIMULYZER_PRE_NS3_41_ENUM_VALUE=OFF
All of the following are optional
NETSIMULYZER_PRE_NS3_41_ENUM_VALUE
: DefaultOFF
, set toON
to force compatibility withEnumValue
with versions of ns-3 before ns-3.41.NETSIMULYZER_CRASH_HANDLER
: DefaultON
, set toOFF
to disable the use of NetSimulyzer crash handler that tries to write output in the event of some unusual exit conditions.
Listed below are the commands to run the examples provided with the module:
If you're using a version of ns-3 without CMake, replace ./ns3 run
with ./waf --run
.
Note that some of these may be disabled for older versions of ns-3.
Example demonstrating tracing the state of a custom ns3::Application
using the StateTransitionSink
.
./ns3 run application-state-trace-example-netsimulyzer
An adaptation of the 'lena-radio-link-failure' example from the LTE
module with statistics
tied into the NetSimulyzer
./ns3 run "lena-radio-link-failure-netsimulyzer --simTime=20 --numberOfEnbs=2 --visual=true"
Example demonstrating topology/mobility output to the NetSimulyzer
./ns3 run mobility-buildings-example-netsimulyzer
Example demonstrating how to connect the netsimulyzer::ThroughputSink
to the UDP Echo Client & Server applications to graph throughput.
./ns3 run throughput-sink-example-netsimulyzer
The WiFi Bianchi example from the wifi
module with topology, logs, and several statistics.
Note: this example is disabled for waf
builds (ns3-35 and prior)
./ns3 run "wifi-bianchi-netsimulyzer --trials=1 --nMinStas=10 --nMaxStas=10 --visual=true"
A simple example from the buildings
module demonstrating integration into an existing scenario
./ns3 run outdoor-random-walk-example-netsimulyzer
Create a NodeConfigurationHelper
, set a model for the Nodes and Install()
on the Nodes you wish to be displayed in the application.
using namespace ns3;
netsimulyzer::NodeConfigurationHelper nodeHelper{orchestrator};
nodeHelper.Set ("Model", netsimulyzer::models::SMARTPHONE_VALUE);
// Shows every Node in the scenario
for (auto node = NodeList::Begin (); node != NodeList::End (); node++)
nodeHelper.Install (*node);
// Or install on a container
NodeContainer containerNodes;
containerNodes.Create (2);
nodeHelper.Install (containerNodes);
To show that two Nodes are 'linked' in some way, create a LogicalLinkHelper
and pass in the two Nodes to link
using namespace ns3;
NodeContainer containerNodes;
containerNodes.Create (2);
// Nodes should be configured by the `NodeHelper` before linking
netsimulyzer::NodeConfigurationHelper nodeHelper{orchestrator};
nodeHelper.Set ("Model", netsimulyzer::models::SMARTPHONE_VALUE);
nodeHelper.Install (containerNodes);
netsimulyzer::LogicalLinkHelper linkHelper{orchestrator};
linkHelper.Set ("Color", BLUE_VALUE);
// Create a visual link between the Nodes
auto link = LogicalLinkHelper.Link (containerNodes.Get (0), containerNodes.Get (1));
// Later ...
Simulator::Schedule(/* ... */, [link] () {
// Most properties may be changed during the simulation
link->SetColor(RED);
// To remove the link, call `Deactivate()`
link->Deactivate();
});
Buildings have a similar setup to Nodes, only there is no requirement for a model.
using namespace ns3;
// Show every building in the scenario
netsimulyzer::BuildingConfigurationHelper buildingHelper{orchestrator};
for (auto building = BuildingList::Begin (); building != BuildingList::End (); building++)
buildingHelper.Install (*building);
For purely visual elements add a Decoration
. A Decoration
is similar to a NodeConfiguration
except its position is set manually.
auto decoration = CreateObject<netsimulyzer::Decoration>(orchestrator);
decoration->SetAttribute ("Model", netsimulyzer::models::CELL_TOWER_POLE_VALUE);
decoration->SetAttribute ("Height", OptionalValue<double>{250.0});
decoration->SetPosition ({5.0, 5.0, 0.0});
To draw attention to certain areas in the topology, it may be defined as an area.
A RectangularArea
will draw a rectangle with a border at some defined coordinates
// ns-3 Rectangle from the Mobility Model
// 5x5 area around the origin
Rectangle start{-5.0, 5.0, -5.0, 5.0};
auto startingArea = CreateObject<netsimulyzer::RectangularArea>(orchestrator, start);
// Optional (Default: Black)
startingArea->SetAttribute ("BorderColor", GREEN_VALUE);
// The Rectangle may be constructed in place as well
auto finishingArea = CreateObject<netsimulyzer::RectangularArea>(orchestrator, Rectangle{10.0, 7.0, 10.0, 7.0});
finishingArea->SetAttribute ("BorderColor", RED_VALUE);
A LogStream
may be used to output messages at a given time during the scenario.
A LogStream
works similar to a C++ stream (e.g. std::cout
).
auto infoLog = CreateObject<netsimulyzer::LogStream> (orchestrator);
// Optional, but highly recommended you set a name for each stream
infoLog->SetAttribute ("Name", StringValue ("Info"));
// Use like std::cout
// Note the * at the beginning
// and '\n' at the end of the message
*infoLog << "Hello "
<< "world!\n";
int number = 5;
*infoLog << "Logs convert numbers to strings for you\n"
<< "See: " << number << '\n';
A series is a collection of points which may be displayed on a chart in the application.
A series may be added to as the scenario runs and points are added at the same time during playback as they were added in the simulation.
There are several types of series, but the simplest is the XYSeries
shown below.
For the other series types, refer to the documentation.
auto xy = CreateObject<netsimulyzer::XYSeries> (orchestrator);
// Optional, but highly recommended
xy->SetAttribute ("Name", StringValue ("XY Series Example"));
// Default is `Line` (line graph),
// there is also `None` (scatter plot)
xy->SetAttribute ("Connection", EnumValue (netsimulyzer::XYSeries::Line));
// Points are added through `Append (x, y)` calls,
// and may occur at any time
// before or during the simulation
xy->Append (1.0, 1.0);