Merge with ns-3-lena-dev changeset: 7937:2228db567a14

This commit is contained in:
mmiozzo
2011-11-08 15:18:19 +01:00
37 changed files with 1566 additions and 320 deletions

View File

@@ -20,6 +20,10 @@ SOURCES = \
$(SRC)/aodv/doc/aodv.rst \
$(SRC)/applications/doc/applications.rst \
$(SRC)/bridge/doc/bridge.rst \
$(SRC)/buildings/doc/source/buildings.rst \
$(SRC)/buildings/doc/source/buildings-design.rst \
$(SRC)/buildings/doc/source/buildings-user.rst \
$(SRC)/buildings/doc/source/buildings-testing.rst \
$(SRC)/click/doc/click.rst \
$(SRC)/csma/doc/csma.rst \
$(SRC)/dsdv/doc/dsdv.rst \

View File

@@ -23,6 +23,7 @@ This document is written in `reStructuredText <http://docutils.sourceforge.net/r
aodv
applications
bridge
buildings
click
csma
dsdv

181
src/buildings/doc/Makefile Normal file
View File

@@ -0,0 +1,181 @@
EPSTOPDF = epstopdf
DIA = dia
CONVERT = convert
SOURCE = source
FIGURES = $(SOURCE)/figures
# specify figures from which .png and .pdf figures need to be
# generated (all dia and eps figures)
IMAGES_EPS =
# specify figures for build process (all eps figures)
GRAPHS_EPS =
# rescale pdf figures as necessary
$(FIGURES)/testbed.pdf_width = 5in
IMAGES_PNG = ${IMAGES_EPS:.eps=.png} \
$(FIGURES)/fading_pedestrian.png \
$(FIGURES)/fading_vehicular.png \
$(FIGURES)/fading_urban_3kmph.png
IMAGES_PDF = ${IMAGES_EPS:.eps=.pdf} \
$(FIGURES)/fading_pedestrian.pdf \
$(FIGURES)/fading_vehicular.pdf \
$(FIGURES)/fading_urban_3kmph.pdf
IMAGES = $(IMAGES_EPS) $(IMAGES_PNG) $(IMAGES_PDF)
%.eps : %.dia; $(DIA) -t eps $< -e $@
%.png : %.dia; $(DIA) -t png $< -e $@
%.png : %.eps; $(CONVERT) $< $@
%.pdf : %.eps; $(EPSTOPDF) $< -o=$@; if test x$($@_width) != x; then TMPFILE=`mktemp`; ./rescale-pdf.sh $($@_width) $@ $${TMPFILE} && mv $${TMPFILE} $@; fi
GRAPHS_PNG = ${GRAPHS_EPS:.eps=.png}
GRAPHS_PDF = ${GRAPHS_EPS:.eps=.pdf}
GRAPHS = $(GRAPHS_EPS) $(GRAPHS_PNG) $(GRAPHS_PDF)
%.png : %.eps; $(CONVERT) $< $@
%.pdf : %.eps; $(EPSTOPDF) $< -o=$@; if test x$($@_width) != x; then TMPFILE=`mktemp`; ./rescale-pdf.sh $($@_width) $@ $${TMPFILE} && mv $${TMPFILE} $@; fi
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCE)
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
-rm -f $(IMAGES_PNG)
-rm -f $(IMAGES_PDF)
-rm -f $(GRAPHS_PNG)
-rm -f $(GRAPHS_PDF)
frag: pickle
@if test ! -d $(BUILDDIR)/frag; then mkdir $(BUILDDIR)/frag; fi
pushd $(BUILDDIR)/frag && ../../pickle-to-xml.py ../pickle/index.fpickle > navigation.xml && popd
cp -r $(BUILDDIR)/pickle/_images $(BUILDDIR)/frag
html: $(IMAGES) ${GRAPHS}
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml: $(IMAGES)
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml: $(IMAGES)
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle: $(IMAGES)
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json: $(IMAGES)
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp: $(IMAGES)
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp: $(IMAGES)
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ns-3.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ns-3.qhc"
devhelp: $(IMAGES)
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/ns-3"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ns-3"
@echo "# devhelp"
epub: $(IMAGES)
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex: $(IMAGES) ${GRAPHS}
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf: $(IMAGES) ${GRAPHS}
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
make -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text: $(IMAGES)
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man: $(IMAGES)
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
changes: $(IMAGES)
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck: $(IMAGEs)
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest: $(IMAGES)
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
TMPFILE=`mktemp`
echo "\documentclass{book}
\usepackage{pdfpages}
\begin{document}
\includepdf[width=${1},fitpaper]{${2}}
\end{document}" >${TMPFILE}.tex
pdflatex -output-directory /tmp ${TMPFILE}.tex >/dev/null 2>/dev/null
cp ${TMPFILE}.pdf ${3}

View File

@@ -2,26 +2,25 @@
++++++++++++++++++++++++++++++++++++++
Building Pathloss Model Documentation
Design documentation
++++++++++++++++++++++++++++++++++++++
Overview
++++++++
The pathloss model included in the lte module is obtained through a combination of several well known pathloss models in order to mimic heterogeneous scenarios. In fact, we are interested in modeling different environmental scenarios such as urban, suburban and open areas. Moreover, indoor and outdoor communication has to be included since HeNB might be installed either within building and either outside. In case of indoor communication, the model has to consider also the type of building in outdoor <-> indoor communication according to some general criteria such as the wall penetration losses of the common materials; moreover it includes some general configuration for the internal walls in indoor communications. Finally, the frequency also represent an important parameter since it spans from 600 MHz up to 2600 MHz according to [TS36.101]_.
The Buildings module provides:
#. a new mobility model (BuildingsMobilityModel) that allows to specify the location, size and characteristics of buildings present in the simulated area, and allows the placement of nodes inside those buildings;
#. a new propagation model (BuildingsPropagationLossModel) working with the mobility model just introduced, that allows to model the phenomenon of indoor/outdoor propagation in the presence of buildings.
Both models have been designed with LTE in mind, though their implementation is in fact independent from any LTE-specific code, and can be used with other ns-3 wireless technologies as well (e.g., wifi).
The pathloss model included is obtained through a combination of several well known pathloss models in order to mimic different environmental scenarios such as urban, suburban and open areas. Moreover, the model considers both outdoor and indoor indoor and outdoor communication has to be included since HeNB might be installed either within building and either outside. In case of indoor communication, the model has to consider also the type of building in outdoor <-> indoor communication according to some general criteria such as the wall penetration losses of the common materials; moreover it includes some general configuration for the internal walls in indoor communications. Finally, the frequency also represent an important parameter since it spans from 600 MHz up to 2600 MHz according to [TS36.101]_.
Description of the Included Models
++++++++++++++++++++++++++++++++++
The naming used in the following will be:
* User equipment:: UE
* small cell BS (e.g., pico, femto): SC
* BS -> eNB
Both UEs and SC might be either indoor and outdoor. The model does not care about the typology of the nodes in the link pathloss computation rather then in their relative position (i.e., indoor vs. outdoor and z-axis respect to the rooftop level).
For discriminate indoor and outdoor users, the model includes a specific class called ``Building`` which contains a ns3 ``Box`` class for defining the dimension of the building. In order to implements the characteristics of the pathloss models included, the ``Building`` class provides support for:
* building type:
@@ -46,18 +45,6 @@ The ``Building`` class is included in ``BuildingsMobilityModel`` class, which in
The class ``BuildingsMobilityModel`` is used by ``BuildingsPropagationLossModel`` class, which inherits from the ns3 class ``PropagationLossModel`` and manages the pathloss computation of the single components and their composition according to the nodes' positions. Moreover, it implements also the shadowing, that is the loss due to obstacles in the main path (i.e., vegetation, buildings, etc.).
The model provides the following pathloss link computations:
* BS <-> UE (indoor and outdoor)
* SC (indoor and outdoor) <-> UE (indoor and outdoor)
The model will not include the following pathloss link computations:
* UE <-> UE
* BS <-> BS
* BS <-> SC
* SC <-> SC
In the following we present the link pathloss models included.
Okumura Hata (OH)
@@ -389,6 +376,10 @@ In the following the pseudo-code of the model is presented::
L = I1411 + BEL
Some considerations that apply when the Buildings model is used in an LTE FDD context:
* in the uplink, the txNode will be an UE, whereas the rxNode will be a
where ``txNode`` and ``rxNode`` can be one of the elements eNB, SC and UE.
We note that for SC nodes in case that the distance is greater then 1 km, we still consider the I1411 model since it better models the transmissions with antenna below the roof-top level and moreover due to the fact that OH is specifically designed for macro cells and therefore for antennas above the roof-top level. Finally, we introduced a threshold also or SC transmissions (called ``m_itu1411DistanceThreshold``) for pruning the communications between SCs and UEs too far (the default values is fixed to 2 km).

View File

@@ -1,5 +1,5 @@
+++++++++++++++++++++++++++++++++++++
Pathloss Model Testing Documentation
Testing Documentation
+++++++++++++++++++++++++++++++++++++

View File

@@ -1,9 +1,9 @@
.. include:: replace.txt
++++++++++++++++++++++++++++++++++++++++++++++++++++++
User Building Propagation & Mobility Model Documentation
++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
User Documentation
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Background

View File

@@ -0,0 +1,17 @@
#####################################################
Buildings Module
#####################################################
.. toctree::
buildings-design
buildings-user
buildings-testing

View File

@@ -0,0 +1,215 @@
# -*- coding: utf-8 -*-
#
# ns-3 documentation build configuration file, created by
# sphinx-quickstart on Tue Dec 14 09:00:39 2010.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.pngmath']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'LENA'
copyright = u'2011, CTTC'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.1'
# The full version, including alpha/beta/rc tags.
release = 'M2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
#htmlhelp_basename = 'ns-3doc'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('buildings', 'buildings.tex', u'Buildings Module Documentation', u'Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'ns-3-model-library', u'ns-3 Model Library',
[u'ns-3 project'], 1)
]

View File

@@ -0,0 +1,17 @@
#####################################################
Buildings Module
#####################################################
.. toctree::
buildings-design
buildings-user
buildings-testing

View File

@@ -0,0 +1,3 @@
.. |ns3| replace:: *ns-3*
.. |ns2| replace:: *ns-2*

View File

@@ -44,7 +44,7 @@ NS_OBJECT_ENSURE_REGISTERED (BuildingsPropagationLossModel);
class BuildingsPropagationLossModel::ShadowingLoss
{
public:
ShadowingLoss (double mean, double sigma);
ShadowingLoss (double mean, double sigma, Ptr<MobilityModel> receiver);
~ShadowingLoss ();
double GetLoss ();
Ptr<MobilityModel> GetReceiver (void);
@@ -55,8 +55,9 @@ class BuildingsPropagationLossModel::ShadowingLoss
};
BuildingsPropagationLossModel::ShadowingLoss::ShadowingLoss (double mean, double sigma) :
m_randVariable (mean, sigma*sigma) // NormalVariable class wants mean and variance (sigma is a standard deviation)
BuildingsPropagationLossModel::ShadowingLoss::ShadowingLoss (double mean, double sigma, Ptr<MobilityModel> receiver) :
m_receiver (receiver),
m_randVariable (mean, sigma*sigma) // NormalVariable class wants mean and variance (sigma is a standard deviation)
{
m_shadowingValue = m_randVariable.GetValue ();
NS_LOG_INFO (this << " New Shadowing: sigma " << sigma << " value " << m_shadowingValue);
@@ -776,20 +777,16 @@ BuildingsPropagationLossModel::GetLoss (Ptr<MobilityModel> a, Ptr<MobilityModel>
PairsSet *ps = *i;
if (ps->sender == a)
{
m_shadowingPairs.erase (i);
m_shadowingPairs.push_back (ps);
for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++)
{
ShadowingLoss *pc = *r;
if (pc->GetReceiver () == b)
{
ps->receivers.erase (r);
ps->receivers.push_back (pc);
return loss + pc->GetLoss ();
}
}
double sigma = EvaluateSigma (a1, b1);
ShadowingLoss *pc = new ShadowingLoss (0.0, sigma);
ShadowingLoss *pc = new ShadowingLoss (0.0, sigma,b);
ps->receivers.push_back (pc);
return loss + pc->GetLoss ();
}
@@ -797,19 +794,10 @@ BuildingsPropagationLossModel::GetLoss (Ptr<MobilityModel> a, Ptr<MobilityModel>
PairsSet *ps = new PairsSet;
ps->sender = a;
double sigma = EvaluateSigma (a1, b1);
ShadowingLoss *pc = new ShadowingLoss (0.0, sigma);
ShadowingLoss *pc = new ShadowingLoss (0.0, sigma, b);
ps->receivers.push_back (pc);
m_shadowingPairs.push_back (ps);
return loss + pc->GetLoss ();
// if (m_shadowingValue==0)
// {
// m_shadowingValue = new ShadowingLoss (m_shadowingMean, m_shadowingSigma);
// }
//
// return (loss + m_shadowingValue->GetLoss ());
}

View File

@@ -179,9 +179,9 @@ html_theme = 'default'
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
# ('lte-testing', 'lte-doc-testing.tex', u'LTE Simulator Testing Documentation', u'Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)', 'manual'),
('lte-design', 'lte-doc-design.tex', u'LTE Simulator Design Documentation', u'Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)', 'manual'),
('lte-user', 'lte-doc-user.tex', u'LTE Simulator User Documentation', u'Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)', 'manual'),
#('lte', 'lte-sim-doc.tex', u'LTE Simulator Documentation', u'Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)', 'manual'),
# ('lte-design', 'lte-doc-design.tex', u'LTE Simulator Design Documentation', u'Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)', 'manual'),
# ('lte-user', 'lte-doc-user.tex', u'LTE Simulator User Documentation', u'Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)', 'manual'),
('lte', 'lte-sim-doc.tex', u'LTE Simulator Documentation', u'Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of

View File

@@ -373,48 +373,51 @@ has been refined to comply with the scheduler interface specification [FFAPI]_.
of periodic wideband CQI (i.e., a single value of channel state that is deemed representative of all RBs
in use) and inband CQIs (i.e., a set of value representing the channel state for each RB).
Trace Fading Model
Propagation Models
++++++++++++++++++
The fading model is based on the one developed during the GSoC 2010 [Piro2011]_. The main characteristic of this model is the fact that the fading evaluation during simulation run-time is based on per-calculated traces. This is done for limiting the computational complexity of the simulator. On the other hand, it needs huge structures for storing the traces; therefore, a trade-off between the number of possible parameters and the memory occupancy has to be found. The most important ones are:
The naming convention used in the following will be:
* users' speed: relative speed between users (affects the Doppler frequency, which in turns affects the time-variance property of the fading)
* number of taps (and relative power): number of multiple paths considered, which affects the frequency property of the fading.
* time granularity of the trace: sampling time of the trace.
* frequency granularity of the trace: number of values in frequency to be evaluated.
* length of trace: ideally large as the simulation time, might be reduced by windowing mechanism.
* number of users: number of independent traces to be used (ideally one trace per user).
With respect to the mathematical channel propagation model, we suggest the one provided by the ``rayleighchan`` function of Matlab, since it provides a well accepted channel modelization both in time and frequency domain. For more information, the reader is referred to [mathworks]_.
The simulator provides a matlab script (``/lte/model/JakesTraces/fading-trace-generator.m``) for generating traces based on the format used by the simulator.
In detail, the channel object created with the rayleighchan function is used for filtering a discrete-time impulse signal in order to obtain the channel impulse response. The filtering is repeated for different TTI, thus yielding subsequent time-correlated channel responses (one per TTI). The channel response is then processed with the ``pwelch`` function for obtaining its power spectral density values, which are then saved in a file with the proper format compatible with the simulator model.
Since the number of variable it is pretty high, generate traces considering all of them might produce a high number of traces of huge size. On this matter, we considered the following assumptions of the parameters based on the 3GPP fading propagation conditions (see Annex B.2 of [TS36.104]_):
* users' speed: typically only a few discrete values are considered, i.e.:
* 0 and 3 kmph for pedestrian scenarios
* 30 and 60 kmph for vehicular scenarios
* 0, 3, 30 and 60 for urban scenarios
* channel taps: only a limited number of sets of channel taps are normally considered, for example three models are mentioned in Annex B.2 of [TS36.104]_.
* time granularity: we need one fading value per TTI, i.e., every 1 ms (as this is the granularity in time of the ns-3 LTE PHY model).
* frequency granularity: we need one fading value per RB (which is the frequency granularity of the spectrum model used by the ns-3 LTE model).
* length of the trace: the simulator includes the windowing mechanism implemented during the GSoC 2011, which consists of picking up a window of the trace each window length in a random fashion.
* per-user fading process: users share the same fading trace, but for each user a different starting point in the trace is randomly picked up. This choice was made to avoid the need to provide one fading trace per user.
According to the parameters we considered, the following formula express in detail the total size :math:`S_{traces}` of the fading traces:
.. math::
S_{traces} = S_{sample} \times N_{RB} \times \frac{T_{trace}}{T_{sample}} \times N_{scenarios} \mbox{ [bytes]}
where :math:`S_{sample}` is the size in bytes of the sample (e.g., 8 in case of double precision, 4 in case of float precision), :math:`N_{RB}` is the number of RB or set of RBs to be considered, :math:`T_{trace}` is the total length of the trace, :math:`T_{sample}` is the time resolution of the trace (1 ms), and :math:`N_{scenarios}` is the number of fading scenarios that are desired (i.e., combinations of different sets of channel taps and user speed values). We provide traces for 3 different scenarios one for each taps configuration defined in Annex B.2 of [TS36.104]_:
* Pedestrian: with nodes' speed of 3 kmph.
* Vehicular: with nodes' speed of 60 kmph.
* Urban: with nodes' speed of 3 kmph.
hence :math:`N_{scenarios} = 3`. All traces have :math:`T_{trace} = 10` s and :math:`RB_{NUM} = 100`. This results in a total 24 MB bytes of traces.
* User equipment: UE
* Macro Base Station: MBS
* Small cell Base Station (e.g., pico/femtocell): SC
The LTE module considers FDD only, and implements downlink and uplink propagation separately. As a consequence, the following pathloss computations are performed
* MBS <-> UE (indoor and outdoor)
* SC (indoor and outdoor) <-> UE (indoor and outdoor)
The LTE model does not provide the following pathloss computations:
* UE <-> UE
* MBS <-> MBS
* MBS <-> SC
* SC <-> SC
Supported models
----------------
The LTE module works with the channel objects provided by the Spectrum module, i.e., either SingleModelSpectrumChannel or MultiModelSpectrumChannel. Because of these, all the propagation models supported by these objecs can be used within the LTE module.
Still, the recommended propagation model to be used with the LTE module is the one provided by the Buildings module, which was in fact designed specifically with LTE (though it can be used with other wireless technologies as well). Please refer to the documentation of the Buildings module for generic information on the propagation model it provides.
Use of the Buildings model with LTE
-----------------------------------
In this section we will highlight some considerations that specifically apply when the Buildings module is used together with the LTE module.
The Buildings model does not know the actual type of the node; i.e., it is not aware of whether a transmitter node is a UE, a MBS, or a SC. Rather, the Buildings model only cares about the position of the node: whether it is indoor and outdoor, and what is its z-axis respect to the rooftop level. As a consequence, for an eNB node that is placed outdoor and at a z-coordinate above the rooftop level, the propagation models typical of MBS will be used by the Buildings module. Conversely, for an eNB that is placed outdoor but below the rooftop, or indoor, the propagation models typical of pico and femtocells will be used.
For communications involving at least one indoor node, the corresponding wall penetration losses will be calculated by the Buildings model. This covers the following use cases:
* MBS <-> indoor UE
* outdoor SC <-> indoor UE
* indoor SC <-> indoor UE
* indoor SC <-> outdoor UE
Please refer to the documentation of the Buildings module for details on the actual models used in each case.

View File

@@ -1,10 +1,7 @@
####################################
LTE Simulator Documentation
####################################
=================================
LTE Module
=================================
.. toctree::

View File

@@ -0,0 +1,272 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* 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: Manuel Requena <manuel.requena@cttc.es>
* Nicola Baldo <nbaldo@cttc.es>
*/
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/lte-module.h"
#include "ns3/config-store.h"
#include "ns3/rlc-stats-calculator.h"
#include <iomanip>
#include <string>
#include <ns3/log.h>
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("InterCellInterference");
/**
* Store the last pathloss value for each TX-RX pair. This is an
* example of how the PathlossTrace (provided by some SpectrumChannel
* implementations) work.
*
*/
class GlobalPathlossDatabase
{
public:
/**
* update the pathloss value
*
* \param context
* \param txPhy the transmitting PHY
* \param rxPhy the receiving PHY
* \param lossDb the loss in dB
*/
virtual void UpdatePathloss (std::string context, Ptr<SpectrumPhy> txPhy, Ptr<SpectrumPhy> rxPhy, double lossDb) = 0;
/**
* print the stored pathloss values to standard output
*
*/
void Print ();
protected:
// CELL ID IMSI PATHLOSS
std::map<uint16_t, std::map<uint64_t, double> > m_pathlossMap;
};
void
GlobalPathlossDatabase::Print ()
{
NS_LOG_FUNCTION (this);
for (std::map<uint16_t, std::map<uint64_t, double> >::const_iterator cellIdIt = m_pathlossMap.begin ();
cellIdIt != m_pathlossMap.end ();
++cellIdIt)
{
for (std::map<uint64_t, double>::const_iterator imsiIt = cellIdIt->second.begin ();
imsiIt != cellIdIt->second.end ();
++imsiIt)
{
std::cout << "CellId: " << cellIdIt->first << " IMSI: " << imsiIt->first << " pathloss: " << imsiIt->second << " dB" << std::endl;
}
}
}
class DownlinkGlobalPathlossDatabase : public GlobalPathlossDatabase
{
public:
// inherited from GlobalPathlossDatabase
virtual void UpdatePathloss (std::string context, Ptr<SpectrumPhy> txPhy, Ptr<SpectrumPhy> rxPhy, double lossDb);
};
void
DownlinkGlobalPathlossDatabase::UpdatePathloss (std::string context,
Ptr<SpectrumPhy> txPhy,
Ptr<SpectrumPhy> rxPhy,
double lossDb)
{
NS_LOG_FUNCTION (this << lossDb);
uint16_t cellId = txPhy->GetDevice ()->GetObject<LteEnbNetDevice> ()->GetCellId ();
uint16_t imsi = rxPhy->GetDevice ()->GetObject<LteUeNetDevice> ()->GetImsi ();
m_pathlossMap[cellId][imsi] = lossDb;
}
class UplinkGlobalPathlossDatabase : public GlobalPathlossDatabase
{
public:
// inherited from GlobalPathlossDatabase
virtual void UpdatePathloss (std::string context, Ptr<SpectrumPhy> txPhy, Ptr<SpectrumPhy> rxPhy, double lossDb);
};
void
UplinkGlobalPathlossDatabase::UpdatePathloss (std::string context,
Ptr<SpectrumPhy> txPhy,
Ptr<SpectrumPhy> rxPhy,
double lossDb)
{
NS_LOG_FUNCTION (this << lossDb);
uint16_t imsi = txPhy->GetDevice ()->GetObject<LteUeNetDevice> ()->GetImsi ();
uint16_t cellId = rxPhy->GetDevice ()->GetObject<LteEnbNetDevice> ()->GetCellId ();
m_pathlossMap[cellId][imsi] = lossDb;
}
int main (int argc, char *argv[])
{
double enbDist = 20.0;
double radius = 10.0;
uint32_t numUes = 1;
CommandLine cmd;
cmd.AddValue ("enbDist", "distance between the two eNBs", enbDist);
cmd.AddValue ("radius", "the radius of the disc where UEs are placed around an eNB", radius);
cmd.AddValue ("numUes", "how many UEs are attached to each eNB", numUes);
cmd.Parse (argc, argv);
ConfigStore inputConfig;
inputConfig.ConfigureDefaults ();
// parse again so you can override default values from the command line
cmd.Parse (argc, argv);
// determine the string tag that identifies this simulation run
// this tag is then appended to all filenames
IntegerValue runValue;
GlobalValue::GetValueByName ("RngRun", runValue);
std::ostringstream tag;
tag << "_enbDist" << std::setw (3) << std::setfill ('0') << std::fixed << std::setprecision (0) << enbDist
<< "_radius" << std::setw (3) << std::setfill ('0') << std::fixed << std::setprecision (0) << radius
<< "_numUes" << std::setw (3) << std::setfill ('0') << numUes
<< "_rngRun" << std::setw (3) << std::setfill ('0') << runValue.Get () ;
Ptr<LenaHelper> lena = CreateObject<LenaHelper> ();
// NOTE: the PropagationLoss trace source of the SpectrumChannel
// works only for single-frequency path loss model.
// e.g., it will work with the following models:
// ns3::FriisPropagationLossModel,
// ns3::TwoRayGroundPropagationLossModel,
// ns3::LogDistancePropagationLossModel,
// ns3::ThreeLogDistancePropagationLossModel,
// ns3::NakagamiPropagationLossModel
// ns3::BuildingsPropagationLossModel
// etc.
// but it WON'T work if you ONLY use SpectrumPropagationLossModels such as:
// ns3::FriisSpectrumPropagationLossModel
// ns3::ConstantSpectrumPropagationLossModel
lena->SetAttribute ("PropagationModel", StringValue ("ns3::Cost231PropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes1, ueNodes2;
enbNodes.Create (2);
ueNodes1.Create (numUes);
ueNodes2.Create (numUes);
// Position of eNBs
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (enbDist, 0.0, 0.0));
MobilityHelper enbMobility;
enbMobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
enbMobility.SetPositionAllocator (positionAlloc);
enbMobility.Install (enbNodes);
// Position of UEs attached to eNB 1
MobilityHelper ue1mobility;
ue1mobility.SetPositionAllocator ("ns3::UniformDiscPositionAllocator",
"X", DoubleValue (0.0),
"Y", DoubleValue (0.0),
"rho", DoubleValue (radius));
ue1mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
ue1mobility.Install (ueNodes1);
// Position of UEs attached to eNB 2
MobilityHelper ue2mobility;
ue2mobility.SetPositionAllocator ("ns3::UniformDiscPositionAllocator",
"X", DoubleValue (enbDist),
"Y", DoubleValue (0.0),
"rho", DoubleValue (radius));
ue2mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
ue2mobility.Install (ueNodes2);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs1;
NetDeviceContainer ueDevs2;
enbDevs = lena->InstallEnbDevice (enbNodes);
ueDevs1 = lena->InstallUeDevice (ueNodes1);
ueDevs2 = lena->InstallUeDevice (ueNodes2);
// Attach UEs to a eNB
lena->Attach (ueDevs1, enbDevs.Get (0));
lena->Attach (ueDevs2, enbDevs.Get (1));
// Activate an EPS bearer on all UEs
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lena->ActivateEpsBearer (ueDevs1, bearer);
lena->ActivateEpsBearer (ueDevs2, bearer);
Simulator::Stop (Seconds (0.5));
// Insert RLC Performance Calculator
std::string dlOutFname = "DlRlcStats";
dlOutFname.append (tag.str ());
std::string ulOutFname = "UlRlcStats";
ulOutFname.append (tag.str ());
lena->EnableMacTraces ();
lena->EnableRlcTraces ();
// keep track of all path loss values in a global object
DownlinkGlobalPathlossDatabase dlPathlossDb;
UplinkGlobalPathlossDatabase ulPathlossDb;
// we rely on the fact that LenaHelper creates the DL channel object first, then the UL channel object,
// hence the former will have index 0 and the latter 1
Config::Connect ("/ChannelList/0/PropagationLoss",
MakeCallback (&DownlinkGlobalPathlossDatabase::UpdatePathloss, &dlPathlossDb));
Config::Connect ("/ChannelList/1/PropagationLoss",
MakeCallback (&UplinkGlobalPathlossDatabase::UpdatePathloss, &ulPathlossDb));
Simulator::Run ();
// print the pathloss values at the end of the simulation
std::cout << std::endl << "Downlink pathloss:" << std::endl;
dlPathlossDb.Print ();
std::cout << std::endl << "Uplink pathloss:" << std::endl;
ulPathlossDb.Print ();
Simulator::Destroy ();
return 0;
}

View File

@@ -0,0 +1,227 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* 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: Jaume Nin <jnin@cttc.es>
*/
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/lte-module.h"
#include "ns3/config-store.h"
#include "ns3/gtk-config-store.h"
#include <ns3/buildings-propagation-loss-model.h>
#include <iomanip>
#include <string>
#include <vector>
using namespace ns3;
using std::vector;
int
main (int argc, char *argv[])
{
uint32_t nEnbPerFloor = 1;
uint32_t nUe = 1;
uint32_t nFloors = 0;
double simTime = 1.0;
std::string traceDirectory = "";
CommandLine cmd;
cmd.AddValue("nEnb", "Number of eNodeBs per floor", nEnbPerFloor);
cmd.AddValue("nUe", "Number of UEs", nUe);
cmd.AddValue("nFloors", "Number of floors, 0 for Friis propagation model",
nFloors);
cmd.AddValue("simTime", "Total duration of the simulation (in seconds)",
simTime);
cmd.AddValue("traceDirectory",
"Destination folder where the traces will be stored", traceDirectory);
cmd.Parse(argc, argv);
ConfigStore inputConfig;
inputConfig.ConfigureDefaults();
//./waf --run "lena-runtime-profiler --simTime=1 --nUe=2 --nEnb=1 --nFloors=0 --traceDirectory=/tmp"
// parse again so you can override default values from the command line
cmd.Parse(argc, argv);
// Geometry of the scenario (in meters)
// Assume squared building
double nodeHeight = 1.5;
double roomHeight = 3;
double roomLength = 8;
uint32_t nRooms = ceil (sqrt (nEnbPerFloor));
uint32_t nEnb;
Ptr < LenaHelper > lena = CreateObject<LenaHelper> ();
lena->EnableLogComponents ();
LogComponentEnable ("BuildingsPropagationLossModel", LOG_LEVEL_ALL);
if (nFloors == 0)
{
lena->SetAttribute("PropagationModel",
StringValue("ns3::FriisPropagationLossModel"));
nEnb = nEnbPerFloor;
}
else
{
lena->SetAttribute("PropagationModel",
StringValue("ns3::BuildingsPropagationLossModel"));
nEnb = nFloors * nEnbPerFloor;
}
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
vector < NodeContainer > ueNodes;
enbNodes.Create(nEnb);
for (uint32_t i = 0; i < nEnb; i++)
{
NodeContainer ueNode;
ueNode.Create(nUe);
ueNodes.push_back(ueNode);
}
MobilityHelper mobility;
vector<Vector> enbPosition;
Ptr < ListPositionAllocator > positionAlloc = CreateObject<ListPositionAllocator> ();
Ptr < Building > building;
if (nFloors == 0)
{
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
// Position of eNBs
uint32_t plantedEnb = 0;
for (uint32_t row = 0; row < nRooms; row++)
{
for (uint32_t column = 0; column < nRooms && plantedEnb < nEnbPerFloor; column++, plantedEnb++)
{
Vector v(roomLength * (column + 0.5), roomLength * (row + 0.5), nodeHeight);
positionAlloc->Add(v);
enbPosition.push_back(v);
mobility.Install(ueNodes[plantedEnb]);
}
}
mobility.SetPositionAllocator(positionAlloc);
mobility.Install (enbNodes);
}
else
{
building = Create<Building> (0.0, nRooms * roomLength,
0.0, nRooms * roomLength,
0.0, nFloors* roomHeight);
building->SetBuildingType(Building::Residential);
building->SetExtWallsType(Building::ConcreteWithWindows);
building->SetFloorsNumber(nFloors);
building->SetNumberRoomX(nRooms);
building->SetNumberRoomY(nRooms);
mobility.SetMobilityModel("ns3::BuildingsMobilityModel");
mobility.Install (enbNodes);
for (uint32_t floor = 0; floor < nFloors; floor++)
{
uint32_t plantedEnb = 0;
for (uint32_t row = 0; row < nRooms; row++)
{
for (uint32_t column = 0; column < nRooms && plantedEnb < nEnbPerFloor; column++, plantedEnb++)
{
Vector v (roomLength * (column + 0.5),
roomLength * (row + 0.5),
nodeHeight + roomHeight * floor);
positionAlloc->Add(v);
enbPosition.push_back(v);
Ptr<BuildingsMobilityModel> mmEnb = enbNodes.Get (plantedEnb)->GetObject<BuildingsMobilityModel> ();
mmEnb->SetPosition (v);
mmEnb->SetIndoor (building);
mmEnb->SetFloorNumber (floor);
mmEnb->SetRoomNumberX (row);
mmEnb->SetRoomNumberY (column);
// Positioning UEs attached to eNB
mobility.Install(ueNodes[plantedEnb]);
for (uint32_t ue = 0; ue < nUe; ue++)
{
// UniformVariable posX(v.x - roomLength * 0.5,
// v.x + roomLength * 0.5);
// UniformVariable posY(v.y - roomLength * 0.5,
// v.y + roomLength * 0.5);
Ptr<BuildingsMobilityModel> mmUe = ueNodes[plantedEnb].Get (ue)->GetObject<BuildingsMobilityModel> ();
Vector vUe (v.x, v.y, v.z);
mmUe->SetPosition (vUe);
mmUe->SetIndoor (building);
mmUe->SetFloorNumber (floor);
mmUe->SetRoomNumberX (row);
mmUe->SetRoomNumberY (column);
}
}
}
}
//mobility.SetPositionAllocator(positionAlloc);
//mobility.Install (enbNodes);
}
// Position of UEs attached to eNB
// for (uint32_t i = 0; i < nEnb; i++)
// {
//
// UniformVariable posX(enbPosition[i].x - roomLength * 0.5,
// enbPosition[i].x + roomLength * 0.5);
// UniformVariable posY(enbPosition[i].y - roomLength * 0.5,
// enbPosition[i].y + roomLength * 0.5);
// /* for (uint32_t j = 0; j < nUe; j++)
// {*/
// positionAlloc->Add(
// Vector(enbPosition[i].x, enbPosition[i].y, enbPosition[i].z));
// //Vector(posX.GetValue(), posY.GetValue(), nodeHeight));
// //}
// mobility.Install(ueNodes[i]);
// Ptr<BuildingsMobilityModel> mm = ueNodes[i].Get (0)->GetObject<BuildingsMobilityModel> ();
// }
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
vector < NetDeviceContainer > ueDevs;
//NetDeviceContainer ueDevs2;
enbDevs = lena->InstallEnbDevice(enbNodes);
for (uint32_t i = 0; i < nEnb; i++)
{
NetDeviceContainer ueDev = lena->InstallUeDevice(ueNodes[i]);
ueDevs.push_back(ueDev);
lena->Attach(ueDev, enbDevs.Get(i));
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer(q);
lena->ActivateEpsBearer(ueDev, bearer);
}
Simulator::Stop(Seconds(simTime));
lena->SetTraceDirectory(traceDirectory);
lena->EnableRlcTraces();
lena->EnableMacTraces();
Simulator::Run();
/*GtkConfigStore config;
config.ConfigureAttributes ();*/
Simulator::Destroy();
return 0;
}

View File

@@ -9,10 +9,13 @@ def build(bld):
obj.source = 'inter-cell-interference.cc'
obj = bld.create_ns3_program('lena-rlc-calculator',
['lte'])
obj.source = 'lena-rlc-calculator.cc'
obj.source = 'lena-rlc-calculator.cc'
obj = bld.create_ns3_program('lena-fading',
['lte'])
obj.source = 'lena-fading.cc'
obj = bld.create_ns3_program('profiling-reference',
obj.source = 'lena-fading.cc'
obj = bld.create_ns3_program('lena-runtime-profiler',
['lte'])
obj.source = 'profiling-reference.cc'
obj.source = 'lena-runtime-profiler.cc'
obj = bld.create_ns3_program('lena-extract-pathloss',
['lte'])
obj.source = 'lena-extract-pathloss.cc'

View File

@@ -109,7 +109,11 @@ LenaHelper::DoStart (void)
}
m_macStats = CreateObject<MacStatsCalculator> ();
m_macStats->SetDlOutputFilename("DlMacStats.csv");
m_macStats->SetUlOutputFilename("UlMacStats.csv");
m_rlcStats = CreateObject<RlcStatsCalculator> ();
m_rlcStats->SetDlOutputFilename("DlRlcStats.csv");
m_rlcStats->SetUlOutputFilename("UlRlcStats.csv");
Object::DoStart ();
}
@@ -464,10 +468,10 @@ LenaHelper::EnableLogComponents (void)
LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
@@ -475,6 +479,7 @@ LenaHelper::EnableLogComponents (void)
LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
LogComponentEnable ("RlcStatsCalculator", LOG_LEVEL_ALL);
LogComponentEnable ("MacStatsCalculator", LOG_LEVEL_ALL);
}
@@ -484,7 +489,6 @@ LenaHelper::EnableRlcTraces (void)
{
EnableDlRlcTraces ();
EnableUlRlcTraces ();
}
@@ -590,8 +594,26 @@ DlTxPduCallback (Ptr<RlcStatsCalculator> rlcStats, std::string path,
uint16_t rnti, uint8_t lcid, uint32_t packetSize)
{
NS_LOG_FUNCTION (rlcStats << path << rnti << lcid << packetSize);
uint64_t imsi = FindImsiFromEnbRlcPath (path);
uint16_t cellId = FindCellIdFromEnbRlcPath (path);
uint64_t imsi = 0;
if (rlcStats->ExistsImsiPath(path) == true)
{
imsi = rlcStats->GetImsiPath (path);
}
else
{
imsi = FindImsiFromEnbRlcPath (path);
rlcStats->SetImsiPath (path, imsi);
}
uint16_t cellId = 0;
if (rlcStats->ExistsCellIdPath(path) == true)
{
cellId = rlcStats->GetCellIdPath (path);
}
else
{
cellId = FindCellIdFromEnbRlcPath (path);
rlcStats->SetCellIdPath (path, cellId);
}
rlcStats->DlTxPdu (cellId, imsi, rnti, lcid, packetSize);
}
@@ -600,7 +622,16 @@ DlRxPduCallback (Ptr<RlcStatsCalculator> rlcStats, std::string path,
uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_FUNCTION (rlcStats << path << rnti << lcid << packetSize << delay);
uint64_t imsi = FindImsiFromUeRlcPath (path);
uint64_t imsi = 0;
if (rlcStats->ExistsImsiPath(path) == true)
{
imsi = rlcStats->GetImsiPath (path);
}
else
{
imsi = FindImsiFromUeRlcPath (path);
rlcStats->SetImsiPath (path, imsi);
}
rlcStats->DlRxPdu (imsi, rnti, lcid, packetSize, delay);
}
@@ -619,7 +650,16 @@ UlTxPduCallback (Ptr<RlcStatsCalculator> rlcStats, std::string path,
uint16_t rnti, uint8_t lcid, uint32_t packetSize)
{
NS_LOG_FUNCTION (rlcStats << path << rnti << lcid << packetSize);
uint64_t imsi = FindImsiFromUeRlcPath (path);
uint64_t imsi = 0;
if (rlcStats->ExistsImsiPath(path) == true)
{
imsi = rlcStats->GetImsiPath (path);
}
else
{
imsi = FindImsiFromUeRlcPath (path);
rlcStats->SetImsiPath (path, imsi);
}
rlcStats->UlTxPdu (imsi, rnti, lcid, packetSize);
}
@@ -628,20 +668,59 @@ UlRxPduCallback (Ptr<RlcStatsCalculator> rlcStats, std::string path,
uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_FUNCTION (rlcStats << path << rnti << lcid << packetSize << delay);
uint64_t imsi = FindImsiFromEnbRlcPath (path);
uint16_t cellId = FindCellIdFromEnbRlcPath (path);
uint64_t imsi = 0;
if (rlcStats->ExistsImsiPath(path) == true)
{
imsi = rlcStats->GetImsiPath (path);
}
else
{
imsi = FindImsiFromEnbRlcPath(path);
rlcStats->SetImsiPath (path, imsi);
}
uint16_t cellId = 0;
if (rlcStats->ExistsCellIdPath(path) == true)
{
cellId = rlcStats->GetCellIdPath (path);
}
else
{
cellId = FindCellIdFromEnbRlcPath (path);
rlcStats->SetCellIdPath (path, cellId);
}
rlcStats->UlRxPdu (cellId, imsi, rnti, lcid, packetSize, delay);
}
void
DlSchedulingCallback (Ptr<MacStatsCalculator> mac, std::string path,
uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2)
DlSchedulingCallback (Ptr<MacStatsCalculator> macStats,
std::string path, uint32_t frameNo, uint32_t subframeNo,
uint16_t rnti, uint8_t mcsTb1, uint16_t sizeTb1,
uint8_t mcsTb2, uint16_t sizeTb2)
{
NS_LOG_FUNCTION (mac << path);
uint64_t imsi = FindImsiFromEnbMac (path, rnti);
uint16_t cellId = FindCellIdFromEnbMac (path, rnti);
mac->DlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcsTb1, sizeTb1, mcsTb2, sizeTb2);
NS_LOG_FUNCTION (macStats << path);
uint64_t imsi = 0;
if (macStats->ExistsImsiPath(path) == true)
{
imsi = macStats->GetImsiPath (path);
}
else
{
imsi = FindImsiFromEnbMac (path, rnti);
macStats->SetImsiPath (path, imsi);
}
uint16_t cellId = 0;
if (macStats->ExistsCellIdPath(path) == true)
{
cellId = macStats->GetCellIdPath (path);
}
else
{
cellId = FindCellIdFromEnbMac (path, rnti);
macStats->SetCellIdPath (path, cellId);
}
macStats->DlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcsTb1, sizeTb1, mcsTb2, sizeTb2);
}
void
@@ -669,14 +748,34 @@ LenaHelper::EnableDlMacTraces (void)
}
void
UlSchedulingCallback (Ptr<MacStatsCalculator> mac, std::string path,
UlSchedulingCallback (Ptr<MacStatsCalculator> macStats, std::string path,
uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
uint8_t mcs, uint16_t size)
{
NS_LOG_FUNCTION (mac << path);
uint64_t imsi = FindImsiFromEnbMac (path, rnti);
uint16_t cellId = FindCellIdFromEnbMac (path, rnti);
mac->UlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcs, size);
NS_LOG_FUNCTION (macStats << path);
uint64_t imsi = 0;
if (macStats->ExistsImsiPath(path) == true)
{
imsi = macStats->GetImsiPath (path);
}
else
{
imsi = FindImsiFromEnbMac (path, rnti);
macStats->SetImsiPath (path, imsi);
}
uint16_t cellId = 0;
if (macStats->ExistsCellIdPath(path) == true)
{
cellId = macStats->GetCellIdPath (path);
}
else
{
cellId = FindCellIdFromEnbMac (path, rnti);
macStats->SetCellIdPath (path, cellId);
}
macStats->UlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcs, size);
}
void
@@ -686,6 +785,15 @@ LenaHelper::EnableUlMacTraces (void)
MakeBoundCallback (&UlSchedulingCallback, m_macStats));
}
void
LenaHelper::SetTraceDirectory (std::string path)
{
m_macStats->SetDlOutputFilename(path + m_macStats->GetDlOutputFilename());
m_macStats->SetUlOutputFilename(path + m_macStats->GetUlOutputFilename());
m_rlcStats->SetDlOutputFilename(path + m_rlcStats->GetDlOutputFilename());
m_rlcStats->SetUlOutputFilename(path + m_rlcStats->GetUlOutputFilename());
}
Ptr<RlcStatsCalculator>
LenaHelper::GetRlcStats (void)
{

View File

@@ -21,7 +21,6 @@
#ifndef LENA_HELPER_H
#define LENA_HELPER_H
#include <ns3/log.h>
#include <ns3/config.h>
#include <ns3/simulator.h>
#include <ns3/names.h>
@@ -197,6 +196,11 @@ public:
*/
void EnableUlRlcTraces (void);
/**
* Set the output directory for the MAC/RLC trace
*/
void SetTraceDirectory (std::string path);
Ptr<RlcStatsCalculator> GetRlcStats (void);
protected:
@@ -207,8 +211,6 @@ private:
Ptr<NetDevice> InstallSingleEnbDevice (Ptr<Node> n);
Ptr<NetDevice> InstallSingleUeDevice (Ptr<Node> n);
//uint64_t FindImsiFromEnbRlcPath(std::string path);
Ptr<SpectrumChannel> m_downlinkChannel;
Ptr<SpectrumChannel> m_uplinkChannel;
@@ -229,7 +231,6 @@ private:
Ptr<MacStatsCalculator> m_macStats;
Ptr<RlcStatsCalculator> m_rlcStats;
};

View File

@@ -0,0 +1,124 @@
/*
* lte-stats-calculator.cpp
*
* Created on: Nov 4, 2011
* Author: jnin
*/
#include "lte-stats-calculator.h"
namespace ns3 {
LteStatsCalculator::LteStatsCalculator ()
: m_dlOutputFilename (""),
m_ulOutputFilename ("")
{
// Nothing to do here
}
LteStatsCalculator::~LteStatsCalculator ()
{
// TODO Auto-generated destructor stub
}
TypeId
LteStatsCalculator::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::LteStatsCalculator")
.SetParent<Object> ()
.AddConstructor<LteStatsCalculator> ()
.AddAttribute ("DlOutputFilename",
"Name of the file where the downlink results will be saved.",
StringValue ("DlStats.csv"),
MakeStringAccessor (&LteStatsCalculator::SetDlOutputFilename),
MakeStringChecker ())
.AddAttribute ("UlOutputFilename",
"Name of the file where the uplink results will be saved.",
StringValue ("UlStats.csv"),
MakeStringAccessor (&LteStatsCalculator::SetUlOutputFilename),
MakeStringChecker ())
;
return tid;
}
void
LteStatsCalculator::SetUlOutputFilename (std::string outputFilename)
{
m_ulOutputFilename = outputFilename;
}
std::string
LteStatsCalculator::GetUlOutputFilename (void)
{
return m_ulOutputFilename;
}
void
LteStatsCalculator::SetDlOutputFilename (std::string outputFilename)
{
m_dlOutputFilename = outputFilename;
}
std::string
LteStatsCalculator::GetDlOutputFilename (void)
{
return m_dlOutputFilename;
}
bool
LteStatsCalculator::ExistsImsiPath (std::string path)
{
if (m_pathImsiMap.find(path) == m_pathImsiMap.end () )
{
return false;
}
else
{
return true;
}
}
void
LteStatsCalculator::SetImsiPath (std::string path, uint64_t imsi)
{
m_pathImsiMap[path] = imsi;
}
uint64_t
LteStatsCalculator::GetImsiPath (std::string path)
{
return m_pathImsiMap.find(path)->second;
}
bool
LteStatsCalculator::ExistsCellIdPath (std::string path)
{
if (m_pathCellIdMap.find(path) == m_pathCellIdMap.end () )
{
return false;
}
else
{
return true;
}
}
void
LteStatsCalculator::SetCellIdPath (std::string path, uint16_t cellId)
{
m_pathCellIdMap[path] = cellId;
}
uint16_t
LteStatsCalculator::GetCellIdPath (std::string path)
{
return m_pathCellIdMap.find(path)->second;
}
} // namespace ns3

View File

@@ -0,0 +1,104 @@
/*
* lte-stats-calculator.h
*
* Created on: Nov 4, 2011
* Author: jnin
*/
#ifndef LTE_STATS_CALCULATOR_H_
#define LTE_STATS_CALCULATOR_H_
#include "ns3/object.h"
#include "ns3/string.h"
#include <map>
namespace ns3 {
class LteStatsCalculator : public Object
{
public:
/**
* Constructor
*/
LteStatsCalculator ();
/**
* Destructor
*/
virtual ~LteStatsCalculator ();
static TypeId GetTypeId (void);
/**
* Set the name of the file where the uplink statistics will be stored.
*
* \param outputFilename string with the name of the file
*/
void SetUlOutputFilename (std::string outputFilename);
/**
* Get the name of the file where the uplink statistics will be stored.
*/
std::string GetUlOutputFilename (void);
/**
* Set the name of the file where the downlink statistics will be stored.
*
* @param outputFilename string with the name of the file
*/
void SetDlOutputFilename (std::string outputFilename);
/**
* Get the name of the file where the uplink statistics will be stored.
*/
std::string GetDlOutputFilename (void);
/**
* Checks if there is an already stored IMSI for the given path
* @param path Path in the attribute system to check
*/
bool ExistsImsiPath (std::string path);
/**
* Stores the (path, imsi) pairs in a map
* @param path Path in the attribute system to store
* @param imsi IMSI value to store
*/
void SetImsiPath (std::string path, uint64_t imsi);
/**
* Retrieves the imsi information for the given path
* @param path Path in the attribute system to get
*/
uint64_t GetImsiPath (std::string path);
/**
* Checks if there is an already stored cell id for the given path
* @param path Path in the attribute system to check
*/
bool ExistsCellIdPath (std::string path);
/**
* Stores the (path, cellId) pairs in a map
* @param path Path in the attribute system to store
* @param cellId cell id value to store
*/
void SetCellIdPath (std::string path, uint16_t cellId);
/**
* Retrieves the cell id information for the given path
* @param path Path in the attribute system to get
*/
uint16_t GetCellIdPath (std::string path);
private:
std::map<std::string, uint64_t> m_pathImsiMap;
std::map<std::string, uint16_t> m_pathCellIdMap;
std::string m_dlOutputFilename;
std::string m_ulOutputFilename;
};
} // namespace ns3
#endif /* LTE_STATS_CALCULATOR_H_ */

View File

@@ -30,9 +30,7 @@ NS_LOG_COMPONENT_DEFINE ("MacStatsCalculator");
NS_OBJECT_ENSURE_REGISTERED (MacStatsCalculator);
MacStatsCalculator::MacStatsCalculator ()
: m_dlOutputFilename (""),
m_dlFirstWrite (true),
m_ulOutputFilename (""),
: m_dlFirstWrite (true),
m_ulFirstWrite (true)
{
NS_LOG_FUNCTION (this);
@@ -48,48 +46,26 @@ TypeId
MacStatsCalculator::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::MacStatsCalculator")
.SetParent<Object> ()
.SetParent<LteStatsCalculator> ()
.AddConstructor<MacStatsCalculator> ()
.AddAttribute ("DlOutputFilename",
"Name of the file where the downlink results will be saved.",
StringValue ("DlMacStats.csv"),
MakeStringAccessor (&MacStatsCalculator::SetDlOutputFilename),
MakeStringChecker ())
.AddAttribute ("UlOutputFilename",
"Name of the file where the uplink results will be saved.",
StringValue ("UlMacStats.csv"),
MakeStringAccessor (&MacStatsCalculator::SetUlOutputFilename),
MakeStringChecker ())
;
return tid;
}
void
MacStatsCalculator::SetUlOutputFilename (std::string outputFilename)
{
m_ulOutputFilename = outputFilename;
}
void
MacStatsCalculator::SetDlOutputFilename (std::string outputFilename)
{
m_dlOutputFilename = outputFilename;
}
void
MacStatsCalculator::DlScheduling (uint16_t cellId, uint64_t imsi, uint32_t frameNo, uint32_t subframeNo,
uint16_t rnti, uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2)
{
NS_LOG_FUNCTION (this);
NS_LOG_INFO ("Write DL Mac Stats in " << m_dlOutputFilename.c_str ());
NS_LOG_INFO ("Write DL Mac Stats in " << GetDlOutputFilename ().c_str ());
std::ofstream outFile;
if ( m_dlFirstWrite == true )
{
outFile.open (m_dlOutputFilename.c_str ());
outFile.open (GetDlOutputFilename ().c_str ());
if (!outFile.is_open ())
{
NS_LOG_ERROR ("Can't open file " << m_dlOutputFilename.c_str ());
NS_LOG_ERROR ("Can't open file " << GetDlOutputFilename ().c_str ());
return;
}
m_dlFirstWrite = false;
@@ -98,10 +74,10 @@ MacStatsCalculator::DlScheduling (uint16_t cellId, uint64_t imsi, uint32_t frame
}
else
{
outFile.open (m_dlOutputFilename.c_str (), std::ios_base::app);
outFile.open (GetDlOutputFilename ().c_str (), std::ios_base::app);
if (!outFile.is_open ())
{
NS_LOG_ERROR ("Can't open file " << m_dlOutputFilename.c_str ());
NS_LOG_ERROR ("Can't open file " << GetDlOutputFilename ().c_str ());
return;
}
}
@@ -124,15 +100,15 @@ MacStatsCalculator::UlScheduling (uint16_t cellId, uint64_t imsi, uint32_t frame
uint32_t subframeNo, uint16_t rnti,uint8_t mcs, uint16_t size)
{
NS_LOG_FUNCTION (this);
NS_LOG_INFO ("Write UL Mac Stats in " << m_ulOutputFilename.c_str ());
NS_LOG_INFO ("Write UL Mac Stats in " << GetUlOutputFilename ().c_str ());
std::ofstream outFile;
if ( m_ulFirstWrite == true )
{
outFile.open (m_ulOutputFilename.c_str ());
outFile.open (GetUlOutputFilename ().c_str ());
if (!outFile.is_open ())
{
NS_LOG_ERROR ("Can't open file " << m_ulOutputFilename.c_str ());
NS_LOG_ERROR ("Can't open file " << GetUlOutputFilename ().c_str ());
return;
}
m_ulFirstWrite = false;
@@ -141,10 +117,10 @@ MacStatsCalculator::UlScheduling (uint16_t cellId, uint64_t imsi, uint32_t frame
}
else
{
outFile.open (m_ulOutputFilename.c_str (), std::ios_base::app);
outFile.open (GetUlOutputFilename ().c_str (), std::ios_base::app);
if (!outFile.is_open ())
{
NS_LOG_ERROR ("Can't open file " << m_ulOutputFilename.c_str ());
NS_LOG_ERROR ("Can't open file " << GetUlOutputFilename ().c_str ());
return;
}
}
@@ -160,5 +136,4 @@ MacStatsCalculator::UlScheduling (uint16_t cellId, uint64_t imsi, uint32_t frame
outFile.close ();
}
} // namespace ns3

View File

@@ -21,9 +21,9 @@
#ifndef MAC_STATS_CALCULATOR_H_
#define MAC_STATS_CALCULATOR_H_
#include "ns3/lte-stats-calculator.h"
#include "ns3/nstime.h"
#include "ns3/uinteger.h"
#include "ns3/object.h"
#include <string>
#include <fstream>
@@ -41,7 +41,7 @@ namespace ns3 {
* - MCS for transport block 2 (0 if not used)
* - Size of transport block 2 (0 if not used)
*/
class MacStatsCalculator : public Object
class MacStatsCalculator : public LteStatsCalculator
{
public:
/**
@@ -59,20 +59,6 @@ public:
*/
static TypeId GetTypeId (void);
/**
* Set the name of the file where the uplink statistics will be stored.
*
* \param outputFilename string with the name of the file
*/
void SetUlOutputFilename (std::string outputFilename);
/**
* Set the name of the file where the downlink statistics will be stored.
*
* \param outputFilename string with the name of the file
*/
void SetDlOutputFilename (std::string outputFilename);
/**
* Notifies the stats calculator that an downlink scheduling has occurred.
* @param cellId Cell ID of the attached Enb
@@ -103,10 +89,8 @@ public:
private:
std::string m_dlOutputFilename;
bool m_dlFirstWrite;
std::string m_ulOutputFilename;
bool m_dlFirstWrite;
bool m_ulFirstWrite;
};

View File

@@ -27,37 +27,12 @@
namespace ns3 {
ImsiLcidPair::ImsiLcidPair ()
{
}
ImsiLcidPair::ImsiLcidPair (const uint64_t a, const uint8_t b)
: m_imsi (a),
m_lcId (b)
{
}
bool
operator == (const ImsiLcidPair &a, const ImsiLcidPair &b)
{
return ((a.m_imsi == b.m_imsi) && (a.m_lcId == b.m_lcId));
}
bool
operator < (const ImsiLcidPair& a, const ImsiLcidPair& b)
{
return ((a.m_imsi < b.m_imsi) || ((a.m_imsi == b.m_imsi) && (a.m_lcId
< b.m_lcId)));
}
NS_LOG_COMPONENT_DEFINE ("RlcStatsCalculator");
NS_OBJECT_ENSURE_REGISTERED (RlcStatsCalculator);
RlcStatsCalculator::RlcStatsCalculator ()
: m_dlOutputFilename (""),
m_ulOutputFilename (""),
m_firstWrite (true)
: m_firstWrite (true)
{
NS_LOG_FUNCTION (this);
@@ -76,16 +51,6 @@ RlcStatsCalculator::GetTypeId (void)
TypeId ("ns3::RlcStatsCalculator")
.SetParent<Object> ()
.AddConstructor<RlcStatsCalculator> ()
.AddAttribute ("DlOutputFilename",
"Name of the file where the downlink results will be saved.",
StringValue ("DlRlcStats.csv"),
MakeStringAccessor (&RlcStatsCalculator::SetDlOutputFilename),
MakeStringChecker ())
.AddAttribute ("UlOutputFilename",
"Name of the file where the uplink results will be saved.",
StringValue ("UlRlcStats.csv"),
MakeStringAccessor (&RlcStatsCalculator::SetUlOutputFilename),
MakeStringChecker ())
.AddAttribute ("StartTime",
"Start time of the on going epoch.",
TimeValue (Seconds (0.)),
@@ -99,24 +64,12 @@ RlcStatsCalculator::GetTypeId (void)
return tid;
}
void
RlcStatsCalculator::SetUlOutputFilename (std::string outputFilename)
{
m_ulOutputFilename = outputFilename;
}
void
RlcStatsCalculator::SetDlOutputFilename (std::string outputFilename)
{
m_dlOutputFilename = outputFilename;
}
void
RlcStatsCalculator::UlTxPdu (uint64_t imsi, uint16_t rnti,
uint8_t lcid, uint32_t packetSize)
{
NS_LOG_FUNCTION (this << "UlTxPDU" << imsi << rnti << (uint32_t) lcid << packetSize);
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
if (Simulator::Now () > m_startTime)
{
m_flowId[p] = LteFlowId_t (rnti, lcid);
@@ -131,7 +84,7 @@ RlcStatsCalculator::DlTxPdu (uint16_t cellId, uint64_t imsi, uint16_t rnti,
uint8_t lcid, uint32_t packetSize)
{
NS_LOG_FUNCTION (this << "DlTxPDU" << imsi << rnti << (uint32_t) lcid << packetSize);
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
bool forceEpoch = false;
if (Simulator::Now () > m_startTime)
{
@@ -157,7 +110,7 @@ RlcStatsCalculator::UlRxPdu (uint16_t cellId, uint64_t imsi, uint16_t rnti,
uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_FUNCTION (this << "UlRxPDU" << imsi << rnti << (uint32_t) lcid << packetSize << delay);
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
bool forceEpoch = false;
if (Simulator::Now () > m_startTime)
@@ -194,7 +147,7 @@ RlcStatsCalculator::DlRxPdu (uint64_t imsi, uint16_t rnti,
uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_FUNCTION (this << "DlRxPDU" << imsi << rnti << (uint32_t) lcid << packetSize << delay);
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
if (Simulator::Now () > m_startTime)
{
m_dlRxPackets[p]++;
@@ -217,26 +170,26 @@ void
RlcStatsCalculator::ShowResults (void)
{
NS_LOG_FUNCTION (this << m_ulOutputFilename.c_str () << m_dlOutputFilename.c_str () );
NS_LOG_INFO ("Write Rlc Stats in " << m_ulOutputFilename.c_str () <<
" and in " << m_dlOutputFilename.c_str ());
NS_LOG_FUNCTION (this << GetUlOutputFilename ().c_str () << GetDlOutputFilename ().c_str () );
NS_LOG_INFO ("Write Rlc Stats in " << GetUlOutputFilename ().c_str () <<
" and in " << GetDlOutputFilename ().c_str ());
std::ofstream ulOutFile;
std::ofstream dlOutFile;
if (m_firstWrite == true)
{
ulOutFile.open (m_ulOutputFilename.c_str ());
ulOutFile.open (GetUlOutputFilename ().c_str ());
if (!ulOutFile.is_open ())
{
NS_LOG_ERROR ("Can't open file " << m_ulOutputFilename.c_str ());
NS_LOG_ERROR ("Can't open file " << GetUlOutputFilename ().c_str ());
return;
}
dlOutFile.open (m_dlOutputFilename.c_str ());
dlOutFile.open (GetDlOutputFilename ().c_str ());
if (!dlOutFile.is_open ())
{
NS_LOG_ERROR ("Can't open file " << m_dlOutputFilename.c_str ());
NS_LOG_ERROR ("Can't open file " << GetDlOutputFilename ().c_str ());
return;
}
m_firstWrite = false;
@@ -253,17 +206,17 @@ RlcStatsCalculator::ShowResults (void)
}
else
{
ulOutFile.open (m_ulOutputFilename.c_str (), std::ios_base::app);
ulOutFile.open (GetUlOutputFilename ().c_str (), std::ios_base::app);
if (!ulOutFile.is_open ())
{
NS_LOG_ERROR ("Can't open file " << m_ulOutputFilename.c_str ());
NS_LOG_ERROR ("Can't open file " << GetUlOutputFilename ().c_str ());
return;
}
dlOutFile.open (m_dlOutputFilename.c_str (), std::ios_base::app);
dlOutFile.open (GetDlOutputFilename ().c_str (), std::ios_base::app);
if (!dlOutFile.is_open ())
{
NS_LOG_ERROR ("Can't open file " << m_dlOutputFilename.c_str ());
NS_LOG_ERROR ("Can't open file " << GetDlOutputFilename ().c_str ());
return;
}
}
@@ -278,7 +231,7 @@ RlcStatsCalculator::WriteUlResults (std::ofstream& outFile)
{
// Get the unique IMSI / LCID list
std::vector<ImsiLcidPair> pairVector;
std::vector<ImsiLcidPair_t> pairVector;
for (Uint32Map::iterator it = m_ulTxPackets.begin (); it
!= m_ulTxPackets.end (); ++it)
{
@@ -290,10 +243,10 @@ RlcStatsCalculator::WriteUlResults (std::ofstream& outFile)
}
Time endTime = m_startTime + m_epochDuration;
for (std::vector<ImsiLcidPair>::iterator it = pairVector.begin (); it
for (std::vector<ImsiLcidPair_t>::iterator it = pairVector.begin (); it
!= pairVector.end (); ++it)
{
ImsiLcidPair p = *it;
ImsiLcidPair_t p = *it;
outFile << m_startTime.GetNanoSeconds () / 1.0e9 << "\t";
outFile << endTime.GetNanoSeconds () / 1.0e9 << "\t";
outFile << GetUlCellId (p.m_imsi, p.m_lcId) << "\t";
@@ -324,7 +277,7 @@ void
RlcStatsCalculator::WriteDlResults (std::ofstream& outFile)
{
// Get the unique IMSI list
std::vector<ImsiLcidPair> pairVector;
std::vector<ImsiLcidPair_t> pairVector;
for (Uint32Map::iterator it = m_dlTxPackets.begin (); it
!= m_dlTxPackets.end (); ++it)
{
@@ -336,10 +289,10 @@ RlcStatsCalculator::WriteDlResults (std::ofstream& outFile)
}
Time endTime = m_startTime + m_epochDuration;
for (std::vector<ImsiLcidPair>::iterator pair = pairVector.begin (); pair
for (std::vector<ImsiLcidPair_t>::iterator pair = pairVector.begin (); pair
!= pairVector.end (); ++pair)
{
ImsiLcidPair p = *pair;
ImsiLcidPair_t p = *pair;
outFile << m_startTime.GetNanoSeconds () / 1.0e9 << "\t";
outFile << endTime.GetNanoSeconds () / 1.0e9 << "\t";
outFile << GetDlCellId (p.m_imsi, p.m_lcId) << "\t";
@@ -405,35 +358,35 @@ RlcStatsCalculator::StartEpoch (void)
uint32_t
RlcStatsCalculator::GetUlTxPackets (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_ulTxPackets[p];
}
uint32_t
RlcStatsCalculator::GetUlRxPackets (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_ulRxPackets[p];
}
uint64_t
RlcStatsCalculator::GetUlTxData (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_ulTxData[p];
}
uint64_t
RlcStatsCalculator::GetUlRxData (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_ulRxData[p];
}
double
RlcStatsCalculator::GetUlDelay (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
Uint64StatsMap::iterator it = m_ulDelay.find (p);
if (it == m_ulDelay.end ())
{
@@ -447,7 +400,7 @@ RlcStatsCalculator::GetUlDelay (uint64_t imsi, uint8_t lcid)
std::vector<double>
RlcStatsCalculator::GetUlDelayStats (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
std::vector<double> stats;
Uint64StatsMap::iterator it = m_ulDelay.find (p);
if (it == m_ulDelay.end ())
@@ -466,7 +419,7 @@ RlcStatsCalculator::GetUlDelayStats (uint64_t imsi, uint8_t lcid)
std::vector<double>
RlcStatsCalculator::GetUlPduSizeStats (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
std::vector<double> stats;
Uint32StatsMap::iterator it = m_ulPduSize.find (p);
if (it == m_ulPduSize.end ())
@@ -485,49 +438,49 @@ RlcStatsCalculator::GetUlPduSizeStats (uint64_t imsi, uint8_t lcid)
uint32_t
RlcStatsCalculator::GetDlTxPackets (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_dlTxPackets[p];
}
uint32_t
RlcStatsCalculator::GetDlRxPackets (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_dlRxPackets[p];
}
uint64_t
RlcStatsCalculator::GetDlTxData (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_dlTxData[p];
}
uint64_t
RlcStatsCalculator::GetDlRxData (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_dlRxData[p];
}
uint32_t
RlcStatsCalculator::GetUlCellId (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_ulCellId[p];
}
uint32_t
RlcStatsCalculator::GetDlCellId (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
return m_dlCellId[p];
}
double
RlcStatsCalculator::GetDlDelay (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
Uint64StatsMap::iterator it = m_dlDelay.find (p);
if (it == m_dlDelay.end ())
{
@@ -540,7 +493,7 @@ RlcStatsCalculator::GetDlDelay (uint64_t imsi, uint8_t lcid)
std::vector<double>
RlcStatsCalculator::GetDlDelayStats (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
std::vector<double> stats;
Uint64StatsMap::iterator it = m_dlDelay.find (p);
if (it == m_dlDelay.end ())
@@ -560,7 +513,7 @@ RlcStatsCalculator::GetDlDelayStats (uint64_t imsi, uint8_t lcid)
std::vector<double>
RlcStatsCalculator::GetDlPduSizeStats (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
ImsiLcidPair_t p (imsi, lcid);
std::vector<double> stats;
Uint32StatsMap::iterator it = m_dlPduSize.find (p);
if (it == m_dlPduSize.end ())

View File

@@ -21,6 +21,8 @@
#ifndef RLC_STATS_CALCULATOR_H_
#define RLC_STATS_CALCULATOR_H_
#include "ns3/lte-stats-calculator.h"
#include "ns3/lte-common.h"
#include "ns3/uinteger.h"
#include "ns3/object.h"
#include "ns3/basic-data-calculators.h"
@@ -32,25 +34,12 @@
namespace ns3 {
struct ImsiLcidPair
{
uint64_t m_imsi;
uint8_t m_lcId;
public:
ImsiLcidPair ();
ImsiLcidPair (const uint64_t a, const uint8_t b);
friend bool operator == (const ImsiLcidPair &a, const ImsiLcidPair &b);
friend bool operator < (const ImsiLcidPair &a, const ImsiLcidPair &b);
};
typedef std::map<ImsiLcidPair, uint32_t> Uint32Map;
typedef std::map<ImsiLcidPair, uint64_t> Uint64Map;
typedef std::map<ImsiLcidPair, Ptr<MinMaxAvgTotalCalculator<uint32_t> > > Uint32StatsMap;
typedef std::map<ImsiLcidPair, Ptr<MinMaxAvgTotalCalculator<uint64_t> > > Uint64StatsMap;
typedef std::map<ImsiLcidPair, double> DoubleMap;
typedef std::map<ImsiLcidPair, LteFlowId_t> FlowIdMap;
typedef std::map<ImsiLcidPair_t, uint32_t> Uint32Map;
typedef std::map<ImsiLcidPair_t, uint64_t> Uint64Map;
typedef std::map<ImsiLcidPair_t, Ptr<MinMaxAvgTotalCalculator<uint32_t> > > Uint32StatsMap;
typedef std::map<ImsiLcidPair_t, Ptr<MinMaxAvgTotalCalculator<uint64_t> > > Uint64StatsMap;
typedef std::map<ImsiLcidPair_t, double> DoubleMap;
typedef std::map<ImsiLcidPair_t, LteFlowId_t> FlowIdMap;
@@ -63,7 +52,7 @@ typedef std::map<ImsiLcidPair, LteFlowId_t> FlowIdMap;
* - Average, min, max and standard deviation of RLC to RLC delay
* - Average, min, max and standard deviation of RLC PDU size
*/
class RlcStatsCalculator : public Object
class RlcStatsCalculator : public LteStatsCalculator
{
public:
/**
@@ -81,20 +70,6 @@ public:
*/
static TypeId GetTypeId (void);
/**
* Set the name of the file where the uplink statistics will be stored.
*
* \param outputFilename string with the name of the file
*/
void SetUlOutputFilename (std::string outputFilename);
/**
* Set the name of the file where the downlink statistics will be stored.
*
* \param outputFilename string with the name of the file
*/
void SetDlOutputFilename (std::string outputFilename);
/**
* Notifies the stats calculator that an uplink transmission has occurred.
* @param imsi IMSI of the UE who transmitted the PDU
@@ -274,7 +249,6 @@ private:
FlowIdMap m_flowId;
std::string m_dlOutputFilename;
Uint32Map m_dlCellId;
Uint32Map m_dlTxPackets;
Uint32Map m_dlRxPackets;
@@ -283,7 +257,6 @@ private:
Uint64StatsMap m_dlDelay;
Uint32StatsMap m_dlPduSize;
std::string m_ulOutputFilename;
Uint32Map m_ulCellId;
Uint32Map m_ulTxPackets;
Uint32Map m_ulRxPackets;

View File

@@ -49,6 +49,29 @@ operator < (const LteFlowId_t& a, const LteFlowId_t& b)
return ( (a.m_rnti < b.m_rnti) || ( (a.m_rnti == b.m_rnti) && (a.m_lcId < b.m_lcId) ) );
}
ImsiLcidPair_t::ImsiLcidPair_t ()
{
}
ImsiLcidPair_t::ImsiLcidPair_t (const uint64_t a, const uint8_t b)
: m_imsi (a),
m_lcId (b)
{
}
bool
operator == (const ImsiLcidPair_t &a, const ImsiLcidPair_t &b)
{
return ((a.m_imsi == b.m_imsi) && (a.m_lcId == b.m_lcId));
}
bool
operator < (const ImsiLcidPair_t& a, const ImsiLcidPair_t& b)
{
return ((a.m_imsi < b.m_imsi) || ((a.m_imsi == b.m_imsi) && (a.m_lcId
< b.m_lcId)));
}
uint16_t
LteFfConverter::double2fpS11dot3 (double val)

View File

@@ -40,6 +40,19 @@ public:
friend bool operator < (const LteFlowId_t &a, const LteFlowId_t &b);
};
struct ImsiLcidPair_t
{
uint64_t m_imsi;
uint8_t m_lcId;
public:
ImsiLcidPair_t ();
ImsiLcidPair_t (const uint64_t a, const uint8_t b);
friend bool operator == (const ImsiLcidPair_t &a, const ImsiLcidPair_t &b);
friend bool operator < (const ImsiLcidPair_t &a, const ImsiLcidPair_t &b);
};
class LteFfConverter
{

View File

@@ -39,6 +39,7 @@
#include <ns3/lte-enb-phy.h>
#include <ns3/ff-mac-scheduler.h>
#include <ns3/abort.h>
#include <ns3/log.h>
NS_LOG_COMPONENT_DEFINE ("LteEnbNetDevice");

View File

@@ -33,6 +33,7 @@
#include "lte-amc.h"
#include "ns3/ipv4-header.h"
#include <ns3/lte-mac-tag.h>
#include <ns3/log.h>
NS_LOG_COMPONENT_DEFINE ("LteNetDevice");

View File

@@ -38,8 +38,8 @@
#include "ns3/ipv4-header.h"
#include "ns3/ipv4.h"
#include "lte-amc.h"
// #include "ideal-control-messages.h"
#include <ns3/lte-ue-phy.h>
#include <ns3/log.h>
NS_LOG_COMPONENT_DEFINE ("LteUeNetDevice");

View File

@@ -717,7 +717,7 @@ PfFfMacScheduler::EstimateUlSinr (uint16_t rnti, uint16_t rb)
void
PfFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params)
{
NS_LOG_FUNCTION (this << " Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf));
// NS_LOG_FUNCTION (this << " Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf));
std::map <uint16_t,uint8_t>::iterator it;
@@ -775,23 +775,18 @@ PfFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::Sched
// limit to physical resources last resource assignment
rbPerFlow = m_cschedCellConfig.m_ulBandwidth - rbAllocated;
}
// store info on allocation for managing ul-cqi interpretation
for (int i = 0; i < rbPerFlow; i++)
{
rbgAllocationMap.push_back ((*it).first);
}
UlDciListElement_s uldci;
uldci.m_rnti = (*it).first;
uldci.m_rbStart = rbAllocated;
uldci.m_rbLen = rbPerFlow;
rbAllocated += rbPerFlow;
std::map <uint16_t, std::vector <double> >::iterator itCqi = m_ueCqi.find ((*it).first);
int cqi = 0;
if (itCqi == m_ueCqi.end ())
{
// no cqi info about this UE
uldci.m_mcs = 0; // MCS 0 -> UL-AMC TBD
//NS_LOG_DEBUG (this << " UE does not have ULCQI " << (*it).first );
// NS_LOG_DEBUG (this << " UE does not have ULCQI " << (*it).first );
}
else
{
@@ -803,7 +798,7 @@ PfFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::Sched
}
for (uint16_t i = uldci.m_rbStart; i < uldci.m_rbStart + uldci.m_rbLen; i++)
{
//NS_LOG_DEBUG (this << " UE " << (*it).first << " has CQI " << (*itCqi).second.at(i));
// NS_LOG_DEBUG (this << " UE " << (*it).first << " has SINR " << (*itCqi).second.at(i));
double sinr = (*itCqi).second.at (i);
if (sinr == NO_SINR)
{
@@ -831,11 +826,18 @@ PfFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::Sched
continue; // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213)
}
uldci.m_mcs = LteAmc::GetMcsFromCqi (cqi);
//NS_LOG_DEBUG (this << " UE " << (*it).first << " minsinr " << minSinr << " -> mcs " << (uint16_t)uldci.m_mcs);
// NS_LOG_DEBUG (this << " UE " << (*it).first << " minsinr " << minSinr << " -> mcs " << (uint16_t)uldci.m_mcs);
}
rbAllocated += rbPerFlow;
// store info on allocation for managing ul-cqi interpretation
for (int i = 0; i < rbPerFlow; i++)
{
rbgAllocationMap.push_back ((*it).first);
}
uldci.m_tbSize = (LteAmc::GetTbSizeFromMcs (uldci.m_mcs, rbPerFlow) / 8);
// NS_LOG_DEBUG (this << " UE " << (*it).first << " startPRB " << (uint32_t)uldci.m_rbStart << " nPRB " << (uint32_t)uldci.m_rbLen << " CQI " << cqi << " MCS " << (uint32_t)uldci.m_mcs << " TBsize " << uldci.m_tbSize);
// NS_LOG_DEBUG (this << " UE " << (*it).first << " startPRB " << (uint32_t)uldci.m_rbStart << " nPRB " << (uint32_t)uldci.m_rbLen << " CQI " << cqi << " MCS " << (uint32_t)uldci.m_mcs << " TBsize " << uldci.m_tbSize << " RbAlloc " << rbAllocated);
uldci.m_ndi = 1;
uldci.m_cceIndex = 0;
uldci.m_aggrLevel = 1;
@@ -855,7 +857,7 @@ PfFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::Sched
if (itStats != m_flowStatsUl.end ())
{
(*itStats).second.lastTtiBytesTrasmitted = uldci.m_tbSize;
// NS_LOG_DEBUG (this << " UE bytes txed " << (*it).second.lastTtiBytesTrasmitted);
// NS_LOG_DEBUG (this << " UE bytes txed " << (*it).second.lastTtiBytesTrasmitted);
}
@@ -972,6 +974,7 @@ PfFfMacScheduler::DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::Sched
for (uint32_t i = 0; i < (*itMap).second.size (); i++)
{
// convert from fixed point notation Sxxxxxxxxxxx.xxx to double
NS_LOG_INFO (this << " i " << i << " size " << params.m_ulCqi.m_sinr.size () << " mapSIze " << (*itMap).second.size ());
double sinr = LteFfConverter::fpS11dot3toDouble (params.m_ulCqi.m_sinr.at (i));
//NS_LOG_DEBUG (this << " UE " << (*itMap).second.at (i) << " SINRfp " << params.m_ulCqi.m_sinr.at (i) << " sinrdb " << sinr);
itCqi = m_ueCqi.find ((*itMap).second.at (i));

View File

@@ -644,16 +644,11 @@ RrFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::Sched
// limit to physical resources last resource assignment
rbPerFlow = m_cschedCellConfig.m_ulBandwidth - rbAllocated;
}
// store info on allocation for managing ul-cqi interpretation
for (int i = 0; i < rbPerFlow; i++)
{
rbgAllocationMap.push_back ((*it).first);
}
UlDciListElement_s uldci;
uldci.m_rnti = (*it).first;
uldci.m_rbStart = rbAllocated;
uldci.m_rbLen = rbPerFlow;
rbAllocated += rbPerFlow;
std::map <uint16_t, std::vector <double> >::iterator itCqi = m_ueCqi.find ((*it).first);
int cqi = 0;
if (itCqi == m_ueCqi.end ())
@@ -695,6 +690,14 @@ RrFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::Sched
//NS_LOG_DEBUG (this << " UE " << (*it).first << " minsinr " << minSinr << " -> mcs " << (uint16_t)uldci.m_mcs);
}
rbAllocated += rbPerFlow;
// store info on allocation for managing ul-cqi interpretation
for (int i = 0; i < rbPerFlow; i++)
{
rbgAllocationMap.push_back ((*it).first);
}
uldci.m_tbSize = (LteAmc::GetTbSizeFromMcs (uldci.m_mcs, rbPerFlow) / 8); // MCS 0 -> UL-AMC TBD
// NS_LOG_DEBUG (this << " UE " << (*it).first << " startPRB " << (uint32_t)uldci.m_rbStart << " nPRB " << (uint32_t)uldci.m_rbLen << " CQI " << cqi << " MCS " << (uint32_t)uldci.m_mcs << " TBsize " << uldci.m_tbSize);
uldci.m_ndi = 1;

View File

@@ -0,0 +1,47 @@
#!/usr/bin/perl
use strict;
use IO::CaptureOutput qw(capture qxx qxy);
use Statistics::Descriptive;
use Cwd;
my $nIterations = 1;
open( FILE, '>times.csv' );
print FILE "#sTime\tnFloors\tnEnb\tnUe\trTime\trTDev\n";
my @nUe = ( 1, 5, 10, 15, 20, 25, 30 );
my @nEnb = ( 1, 2, 4, 6, 8, 12, 14, 18, 22 );
my @nFloors = ( 0, 1 );
#$my @simTime = ( 1, 5, 10, 20 );
my @simTime = ( 1 );
my $traceDirectory = ".";
my $traceDirectory = getcwd() . "/";
foreach my $time (@simTime)
{
foreach my $floor (@nFloors)
{
foreach my $enb (@nEnb)
{
foreach my $ue (@nUe)
{
my $timeStats = Statistics::Descriptive::Full->new();
for ( my $iteration = 0 ; $iteration < $nIterations ; $iteration++ )
{
my $launch = "time ./waf --run \'lena-runtime-profiler --simTime=$time --nUe=$ue --nEnb=$enb --nFloors=$floor --traceDirectory=$traceDirectory\'";
my $out, my $err;
print "$launch\n";
capture { system($launch ) } \$out, \$err;
$err =~ /real(.+)m(.+)s/;
my $minutes = $1;
my $seconds = $minutes * 60 + $2;
$timeStats->add_data($seconds);
}
print FILE "$time\t$floor\t$enb\t$ue\t";
print FILE $timeStats->mean() . "\t"
. $timeStats->standard_deviation() . "\n";
}
}
}
}

View File

@@ -18,6 +18,7 @@
* Author: Manuel Requena <manuel.requena@cttc.es>
*/
#include "ns3/log.h"
#include "ns3/lte-test-ue-phy.h"
NS_LOG_COMPONENT_DEFINE ("LteTestUePhy");

View File

@@ -21,6 +21,7 @@ def build(bld):
'model/lte-ue-net-device.cc',
'model/ideal-control-messages.cc',
'helper/lena-helper.cc',
'helper/lte-stats-calculator.cc',
'helper/rlc-stats-calculator.cc',
'helper/mac-stats-calculator.cc',
'model/ff-mac-csched-sap.cc',
@@ -79,6 +80,7 @@ def build(bld):
'model/lte-ue-net-device.h',
'model/ideal-control-messages.h',
'helper/lena-helper.h',
'helper/lte-stats-calculator.h',
'helper/mac-stats-calculator.h',
'helper/rlc-stats-calculator.h',
'model/ff-mac-common.h',

View File

@@ -21,11 +21,10 @@
#ifndef SPECTRUM_TYPE_H
#define SPECTRUM_TYPE_H
#include <ns3/log.h>
#include <iostream>
#include <vector>
#include <string>
#include <stdint.h>
namespace ns3 {