--- a/src/buildings/doc/source/buildings-design.rst Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/doc/source/buildings-design.rst Mon Jan 16 20:32:45 2012 +0100
@@ -10,7 +10,8 @@
++++++++
The Buildings module provides:
-
+
+ #. a new class (Building) that models the presence of a building in a simulation scenario;
#. 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.
@@ -18,16 +19,17 @@
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 Building class
+++++++++++++++++++
-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:
+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 supports the following attributes:
* building type:
* Residential (default value)
* Office
* Commercial
+
* external walls type
* Wood
@@ -37,7 +39,7 @@
* number of floors (default value 1, which means only ground-floor)
* number of rooms in x-axis (default value 1)
- * number of rooms in x-axis (default value 1)
+ * number of rooms in y-axis (default value 1)
By means of the number of rooms in x and y axis it is possible the definition of buildings where rooms are organized in grids, typical reference scenario for femto-cells in 3GPP called dual-strip.
@@ -45,7 +47,10 @@
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.).
-In the following we present the link pathloss models included.
+Pathloss models used in BuildingsPropagationLossModel
++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+In the following we present the pathloss models that are included in the BuildingsPropagationLossModel
Okumura Hata (OH)
-----------------
@@ -133,7 +138,7 @@
Short Range Communications ITU-R P.1411 (I1411)
----------------------------------------
+-----------------------------------------------
This model is designed for short range outdoor communication in the frequency range 300 MHz to 100 GHz. It is divided in LOS and NLoS models and NLoS is split in roof-tops and canyons. The model implemented considers the LoS propagation for short distances according to a tunable threshold (``m_itu1411NlosThreshold``). In case on NLoS propagation, the over the roof-top model is taken in consideration for modeling both macro BS and SC. In case on NLoS several parameters scenario dependent have been included, such as average street width, orientation, etc. The values of such parameters have to be properly set according to the scenario implemented, the model does not calculate natively their values. In case any values is provided, the standard ones are used, apart for the height of the mobile and BS, which instead their integrity is tested directly in the code (i.e., they have to be greater then zero). In the following we give the expressions of the components of the model.
@@ -328,11 +333,10 @@
-Pathloss Logic Model
-++++++++++++++++++++
+Pathloss Model Logic of BuildingsPropagationLossModel
++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-In the following the pseudo-code of the model is presented::
+The following pseudo-code illustrates how the different pathloss models described above are integrated in the BuildingsPropagationLossModel::
if (txNode is outdoor)
then
@@ -376,12 +380,7 @@
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).
+We note that, for the case of communication between two nodes below rooftop level with distance is greater then 1 km, we still consider the I1411 model, since OH is specifically designed for macro cells and therefore for antennas above the roof-top level. Finally, we introduced a threshold called ``m_itu1411DistanceThreshold``) for pruning the communications between nodes below rooftop when the distance is too large (the default values is 2 km).
Shadowing Model
--- a/src/buildings/doc/source/buildings-testing.rst Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/doc/source/buildings-testing.rst Mon Jan 16 20:32:45 2012 +0100
@@ -6,13 +6,12 @@
Overview
********
-To test and validate the ns-3 Building Pathloss module, a test suites is provided which are integrated with the ns-3 test framework in the lte module.
-To run them, you need to have configured the build of the simulator in this way::
+To test and validate the ns-3 Building Pathloss module, some test suites is provided which are integrated with the ns-3 test framework. To run them, you need to have configured the build of the simulator in this way::
- ./waf configure --enable-tests --enable-modules=lte --enable-examples
+ ./waf configure --enable-tests --enable-modules=buildings
./test.py
-The above will run not only the test suites belonging to the LTE module, but also those belonging to all the other ns-3 modules on which the LTE module depends. See the ns-3 manual for generic information on the testing framework.
+The above will run not only the test suites belonging to the buildings module, but also those belonging to all the other ns-3 modules on which the buildings module depends. See the ns-3 manual for generic information on the testing framework.
You can get a more detailed report in HTML format in this way::
@@ -28,16 +27,20 @@
-Description of the test suite
-*****************************
+Description of the test suites
+******************************
+
+
+BuildingsHelper test
+~~~~~~~~~~~~~~~~~~~~
-The test suite ``lte-pathloss-model`` creates different test cases with
-both unit and system tests. The formers validate the single component model and the pathloss logic behavior. The latter proof the integration of the pathloss model in the ns3 framework and more in specifically in the lte module. Finally. a unit test is provided in order to test the shadowing characterization.
+The test suite ``buildings-helper`` checks that the method ``BuildingsHelper::MakeAllInstancesConsistent ()`` works properly, i.e., that the BuildingsHelper is successful in locating if nodes are outdoor or indoor, and if indoor that they are located in the correct building, room and floor. Several test cases are provided with different buildings (having different size, position, rooms and floors) and different node positions. The test passes if each every node is located correctly.
+
-Unit Tests
-~~~~~~~~~~
+Pathloss tests
+~~~~~~~~~~~~~~
-The unit tests are carried out by comparing the expected results of the pathloss module in specific scenarios with pre calculated values obtained offline with an Octave script (/test/reference/lte-pathloss.m). The tests are considered passed if the two values differs only for a predefined tolerance (0.1) that accounts for the approximations due to floating point arithmetics.
+The test suite ``buildings-pathloss-model`` provides different unit tests that compare the expected results of the buildings pathloss module in specific scenarios with pre calculated values obtained offline with an Octave script (test/reference/buildings-pathloss.m). The tests are considered passed if the two values are equal up to a tolerance of 0.1, which is deemed appropriate for the typical usage of pathloss values (which are in dB).
In the following we detailed the scenarios considered, their selection has been done for covering the wide set of possible pathloss logic combinations. The pathloss logic results therefore implicitly tested.
@@ -96,6 +99,6 @@
Shadowing Test
~~~~~~~~~~~~~~
-This unit test is intended to verify the statistics distribution characteristics of the shadowing are the one expected. The shadowing is modeled according to a normal distribution with mean 0 and variable standard deviation (usually called sigma), according to the standard models used in literature.
+The test suite ``buildings-shadowing-test`` is a unit test intended to verify the statistics distribution characteristics of the shadowing are the one expected. The shadowing is modeled according to a normal distribution with mean :math:`\mu = 0` and variable standard deviation :math:`\sigma`, according to models commonly used in literature.
The test generates 10,000 samples of shadowing by subtracting the deterministic component from the total loss returned by the ``BuildingPathlossModel``. The mean and variance of the shadowing samples are then used to verify whether the 99% confidence interval is respected by the sequence generated by the simulator.
--- a/src/buildings/doc/source/buildings-user.rst Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/doc/source/buildings-user.rst Mon Jan 16 20:32:45 2012 +0100
@@ -6,37 +6,6 @@
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-Background
-**********
-
-
-
-We assume the reader is already familiar with how to use the ns-3
-simulator to run generic simulation programs. If this is not the case,
-we strongly recommend the reader to consult [ns3tutorial]_.
-
-
-Usage Overview
-**************
-
-The ns-3 LTE model is a software library that allows the simulation of
-LTE networks. The process of performing such simulations typically involves the following
-steps:
-
- 1. *Define the scenario* to be simulated
- 2. *Write a simulation program* that recreates the desired scenario
- topology/architecture. This is done accessing the ns-3 LTE model
- libraryusing the ``ns3::LenaHelper`` API defined in ``src/lte/helper/lena-helper.h``.
- 3. *Specify configuration parameters* of the objects that are being
- used for the simulation. This can be done using input files (via the
- ``ns3::ConfigStore``) or directly within the simulation program.
- 4. *Configure the desired output* to be produced by the simulator
- 5. *Run* the simulation.
-
-All these aspects will be explained in the following sections by means
-of practical examples.
-
-
Main configurable parameters
----------------------------
@@ -70,82 +39,6 @@
* ``CitySize``: the dimension of the city among Small, Medium, Large (default Large).
-Basic simulation program
-------------------------
-
-In what following, a few guidelines for the usage of the ``BuildingMobilityModel`` and the ``BuildingPropagationModel`` classes with an example based on the lte module.
-
-.. highlight:: none
-
-#. Inheritance::
-
- #include <ns3/buildings-mobility-model.h>
- #include <ns3/buildings-propagation-loss-model.h>
- #include <ns3/building.h>
-
-#. Propagation model selection::
-
- Ptr<LenaHelper> lena = CreateObject<LenaHelper> ();
-
- lena->SetAttribute ("PropagationModel", StringValue ("ns3::BuildingsPropagationLossModel"));
-
-#. EUTRA Band Selection
-
-The selection of the working frequency of the propagation model has to be done with the standard ns-3 attribute system as described in the correspond section ("Configuration of LTE model parameters") by means of the DlEarfcn and UlEarfcn parameters, for instance::
-
- lena->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (100));
- lena->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (18100));
-
-It is to be noted that any other configuration (i.e., with BuildingsPropagationLossModel attributes) might generates conflicts in the frequencies definition in the modules during the simulation.
-
-#. Mobility model selection::
-
- MobilityHelper mobility;
- mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
-
-#. Node creation and positioning::
-
- ueNodes.Create (1);
- mobility.Install (ueNodes);
- NetDeviceContainer ueDevs;
- ueDevs = lena->InstallUeDevice (ueNodes);
- Ptr<BuildingsMobilityModel> mm = enbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
- double x_axis = 0.0;
- double y_axis = 0.0;
- double z_axis = 0.0;
- mm->SetPosition (Vector (x_axis, y_axis, z_axis));
-
-#. Building creation::
-
- double x_min = 0.0;
- double x_max = 10.0;
- double y_min = 0.0;
- double y_max = 20.0;
- double z_min = 0.0;
- double z_max = 10.0;
- Ptr<Building> building = Create<Building> (x_min, x_max, y_min, y_max, z_min, z_max);
- building->SetBuildingType (Building::Residential);
- building->SetExtWallsType (Building::ConcreteWithWindows);
- building->SetFloorsNumber (3);
- building->SetNumberRoomX (3);
- building->SetNumberRoomY (2);
-
- This will instantiate a residential building with base of 10 x 20 meters and height of 10 meters with concrete with windows as external walls, three floors and a grid of rooms of 3 x 2.
-
-#. Building and nodes interactions::
-
- mm->SetIndoor (building, 2, 1, 1);
-
-which is equivalent to the form::
-
- mm->SetIndoor (building);
- mm->SetFloorNumber (2);
- mm->SetRoomNumberX (1);
- mm->SetRoomNumberY (1);
-
-This informs node's mobility model the fact that the node is inside the building at the second floor in the corner room of the 3 x 2 grid.
-We suggest the usage of the first form since it performs a consistency check of the node position with the building bounds.
-It has to be noted that the simulator does not check the consistence between the node's position (x,y,z coordinates) and the building position and size for outdoor nodes. The responsibility of this consistency is completely left to the user.
@@ -153,6 +46,3 @@
-
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/buildings-helper.cc Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,67 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "buildings-helper.h"
+
+#include <ns3/node-list.h>
+#include <ns3/building.h>
+#include <ns3/building-list.h>
+#include <ns3/mobility-model.h>
+#include <ns3/buildings-mobility-model.h>
+#include <ns3/abort.h>
+#include <ns3/log.h>
+
+
+NS_LOG_COMPONENT_DEFINE ("BuildingsHelper");
+
+namespace ns3 {
+
+void
+BuildingsHelper::MakeAllInstancesConsistent ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (NodeList::Iterator nit = NodeList::Begin (); nit != NodeList::End (); ++nit)
+ {
+ Ptr<BuildingsMobilityModel> bmm = (*nit)->GetObject<BuildingsMobilityModel> ();
+ NS_ABORT_MSG_UNLESS (0 != bmm, "node " << (*nit)->GetId () << " does not have a BuildingsMobilityModel");
+ bool found = false;
+ for (BuildingList::Iterator bit = BuildingList::Begin (); bit != BuildingList::End (); ++bit)
+ {
+ Vector pos = bmm->GetPosition ();
+ if ((*bit)->IsInside (pos))
+ {
+ NS_LOG_LOGIC ("node " << (*nit)->GetId () << " falls inside building " << (*bit)->GetId ());
+ NS_ABORT_MSG_UNLESS (found == false, "node already inside another building!");
+ found = true;
+ uint16_t floor = (*bit)->GetFloor (pos);
+ uint16_t roomX = (*bit)->GetRoomX (pos);
+ uint16_t roomY = (*bit)->GetRoomY (pos);
+ bmm->SetIndoor (*bit, floor, roomX, roomY);
+ }
+ }
+ if (!found)
+ {
+ NS_LOG_LOGIC ("node " << (*nit)->GetId () << " is outdoor");
+ bmm->SetOutdoor ();
+ }
+ }
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/buildings-helper.h Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,43 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef BUILDINGS_HELPER_H
+#define BUILDINGS_HELPER_H
+
+#include <string>
+#include <ns3/attribute.h>
+#include <ns3/object-factory.h>
+#include <ns3/node-container.h>
+
+
+namespace ns3 {
+
+
+class BuildingsHelper
+{
+public:
+ static void MakeAllInstancesConsistent ();
+
+};
+
+
+}
+
+#endif /* BUILDINGS_HELPER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/model/building-list.cc Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,192 @@
+/* -*- 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 <jaume.nin@cttc,cat>
+ * Based on BuildingList implemenation by Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ *
+ */
+#include "building-list.h"
+#include "ns3/simulator.h"
+#include "ns3/object-vector.h"
+#include "ns3/config.h"
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "building-list.h"
+#include "building.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("BuildingList");
+
+/**
+ * \brief private implementation detail of the BuildingList API.
+ */
+class BuildingListPriv : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+ BuildingListPriv ();
+ ~BuildingListPriv ();
+
+ uint32_t Add (Ptr<Building> building);
+ BuildingList::Iterator Begin (void) const;
+ BuildingList::Iterator End (void) const;
+ Ptr<Building> GetBuilding (uint32_t n);
+ uint32_t GetNBuildings (void);
+
+ static Ptr<BuildingListPriv> Get (void);
+
+private:
+ virtual void DoDispose (void);
+ static Ptr<BuildingListPriv> *DoGet (void);
+ static void Delete (void);
+ std::vector<Ptr<Building> > m_buildings;
+};
+
+NS_OBJECT_ENSURE_REGISTERED (BuildingListPriv);
+
+TypeId
+BuildingListPriv::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::BuildingListPriv")
+ .SetParent<Object> ()
+ .AddAttribute ("BuildingList", "The list of all buildings created during the simulation.",
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&BuildingListPriv::m_buildings),
+ MakeObjectVectorChecker<Building> ())
+ ;
+ return tid;
+}
+
+Ptr<BuildingListPriv>
+BuildingListPriv::Get (void)
+{
+ return *DoGet ();
+}
+Ptr<BuildingListPriv> *
+BuildingListPriv::DoGet (void)
+{
+ static Ptr<BuildingListPriv> ptr = 0;
+ if (ptr == 0)
+ {
+ ptr = CreateObject<BuildingListPriv> ();
+ Config::RegisterRootNamespaceObject (ptr);
+ Simulator::ScheduleDestroy (&BuildingListPriv::Delete);
+ }
+ return &ptr;
+}
+void
+BuildingListPriv::Delete (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Config::UnregisterRootNamespaceObject (Get ());
+ (*DoGet ()) = 0;
+}
+
+
+BuildingListPriv::BuildingListPriv ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+BuildingListPriv::~BuildingListPriv ()
+{
+}
+void
+BuildingListPriv::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (std::vector<Ptr<Building> >::iterator i = m_buildings.begin ();
+ i != m_buildings.end (); i++)
+ {
+ Ptr<Building> building = *i;
+ building->Dispose ();
+ *i = 0;
+ }
+ m_buildings.erase (m_buildings.begin (), m_buildings.end ());
+ Object::DoDispose ();
+}
+
+
+uint32_t
+BuildingListPriv::Add (Ptr<Building> building)
+{
+ uint32_t index = m_buildings.size ();
+ m_buildings.push_back (building);
+ Simulator::ScheduleWithContext (index, TimeStep (0), &Building::Start, building);
+ return index;
+
+}
+BuildingList::Iterator
+BuildingListPriv::Begin (void) const
+{
+ return m_buildings.begin ();
+}
+BuildingList::Iterator
+BuildingListPriv::End (void) const
+{
+ return m_buildings.end ();
+}
+uint32_t
+BuildingListPriv::GetNBuildings (void)
+{
+ return m_buildings.size ();
+}
+
+Ptr<Building>
+BuildingListPriv::GetBuilding (uint32_t n)
+{
+ NS_ASSERT_MSG (n < m_buildings.size (), "Building index " << n <<
+ " is out of range (only have " << m_buildings.size () << " buildings).");
+ return m_buildings[n];
+}
+
+}
+
+/**
+ * The implementation of the public static-based API
+ * which calls into the private implementation through
+ * the simulation singleton.
+ */
+namespace ns3 {
+
+uint32_t
+BuildingList::Add (Ptr<Building> building)
+{
+ return BuildingListPriv::Get ()->Add (building);
+}
+BuildingList::Iterator
+BuildingList::Begin (void)
+{
+ return BuildingListPriv::Get ()->Begin ();
+}
+BuildingList::Iterator
+BuildingList::End (void)
+{
+ return BuildingListPriv::Get ()->End ();
+}
+Ptr<Building>
+BuildingList::GetBuilding (uint32_t n)
+{
+ return BuildingListPriv::Get ()->GetBuilding (n);
+}
+uint32_t
+BuildingList::GetNBuildings (void)
+{
+ return BuildingListPriv::Get ()->GetNBuildings ();
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/model/building-list.h Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,71 @@
+/* -*- 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 <jaume.nin@cttc,cat>
+ * Based on NodeList implementation by Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ *
+ */
+
+#ifndef BUILDING_LIST_H_
+#define BUILDING_LIST_H_
+
+#include <vector>
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Building;
+
+class BuildingList
+{
+public:
+ typedef std::vector< Ptr<Building> >::const_iterator Iterator;
+
+ /**
+ * \param building building to add
+ * \returns index of building in list.
+ *
+ * This method is called automatically from Building::Building so
+ * the user has little reason to call it himself.
+ */
+ static uint32_t Add (Ptr<Building> building);
+ /**
+ * \returns a C++ iterator located at the beginning of this
+ * list.
+ */
+ static Iterator Begin (void);
+ /**
+ * \returns a C++ iterator located at the end of this
+ * list.
+ */
+ static Iterator End (void);
+ /**
+ * \param n index of requested building.
+ * \returns the Building associated to index n.
+ */
+ static Ptr<Building> GetBuilding (uint32_t n);
+ /**
+ * \returns the number of buildings currently in the list.
+ */
+ static uint32_t GetNBuildings (void);
+};
+
+} // namespace ns3
+
+#endif /* BUILDING_LIST_H_ */
+
+
--- a/src/buildings/model/building.cc Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/model/building.cc Mon Jan 16 20:32:45 2012 +0100
@@ -15,109 +15,244 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Marco Miozzo <marco.miozzo@cttc.es>
+ * Authors: Marco Miozzo <marco.miozzo@cttc.es>
+ * Nicola Baldo <nbaldo@cttc.es>
*
*/
+#include "building.h"
+#include "building-list.h"
-#include <ns3/building.h>
#include <ns3/enum.h>
+#include <ns3/uinteger.h>
+#include <ns3/log.h>
+#include <ns3/assert.h>
+#include <math.h>
+NS_LOG_COMPONENT_DEFINE ("Building");
namespace ns3 {
-Building::Building (double _xMin, double _xMax,
- double _yMin, double _yMax,
- double _zMin, double _zMax/*,
- uint8_t _nFloors, uint8_t _nRoomX, uint8_t _nRoomY*/)
- : m_floor (1),
- m_roomX (1),
- m_roomY (1),
+TypeId
+Building::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Building")
+ .SetParent<Object> ()
+ .AddConstructor<Building> ()
+ .AddAttribute ("roomX", "The number of rooms in the X axis.",
+ TypeId::ATTR_GET, // allow only getting it.
+ UintegerValue (4),
+ MakeUintegerAccessor (&Building::m_roomsX),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("roomY", "The number of rooms in the Y axis.",
+ TypeId::ATTR_GET, // allow only getting it.
+ UintegerValue (1),
+ MakeUintegerAccessor (&Building::m_roomsY),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("nFloor", "The number of floors of this building.",
+ TypeId::ATTR_GET, // allow only getting it.
+ UintegerValue (1),
+ MakeUintegerAccessor (&Building::m_floors),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("Id", "The id (unique integer) of this Building.",
+ TypeId::ATTR_GET, // allow only getting it.
+ UintegerValue (0),
+ MakeUintegerAccessor (&Building::m_buildingId),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+
+Building::Building (double xMin,
+ double xMax,
+ double yMin,
+ double yMax,
+ double zMin,
+ double zMax)
+ : m_buildingBounds (xMin, xMax, yMin, yMax, zMin, zMax),
+ m_floors (1),
+ m_roomsX (1),
+ m_roomsY (1),
m_buildingType (Residential),
m_externalWalls (ConcreteWithWindows)
-
{
- m_buldingBounds = Box (_xMin, _xMax, _yMin, _yMax, _zMin, _zMax);
+ NS_LOG_FUNCTION (this);
+ Construct();
}
Building::Building ()
- : m_floor (1),
- m_roomX (1),
- m_roomY (1),
+ : m_floors (1),
+ m_roomsX (1),
+ m_roomsY (1),
m_buildingType (Residential),
m_externalWalls (ConcreteWithWindows)
{
- m_buldingBounds = Box ();
+ NS_LOG_FUNCTION (this);
+ m_buildingBounds = Box ();
+ Construct();
+}
+
+Building::~Building ()
+{
+ NS_LOG_FUNCTION (this);
}
+void
+Building::DoDispose ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+Building::Construct ()
+{
+ NS_LOG_FUNCTION (this);
+ m_buildingId = BuildingList::Add(this);
+}
+
+uint32_t
+Building::GetId (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_buildingId;
+}
void
Building::SetBuildingType (Building::BuildingType_t t)
{
+ NS_LOG_FUNCTION (this << t);
m_buildingType = t;
}
void
Building::SetExtWallsType (Building::ExtWallsType_t t)
{
+ NS_LOG_FUNCTION (this << t);
m_externalWalls = t;
}
void
-Building::SetFloorsNumber (uint8_t nfloors)
+Building::SetNFloors (uint16_t nfloors)
{
- m_floor = nfloors;
+ NS_LOG_FUNCTION (this << nfloors);
+ m_floors = nfloors;
}
void
-Building::SetNumberRoomX (uint8_t nroomx)
+Building::SetNRoomsX (uint16_t nroomx)
{
- m_roomX = nroomx;
+ NS_LOG_FUNCTION (this << nroomx);
+ m_roomsX = nroomx;
}
void
-Building::SetNumberRoomY (uint8_t nroomy)
+Building::SetNRoomsY (uint16_t nroomy)
{
- m_roomY = nroomy;
+ NS_LOG_FUNCTION (this << nroomy);
+ m_roomsY = nroomy;
}
Building::BuildingType_t
-Building::GetBuildingType ()
+Building::GetBuildingType () const
{
return (m_buildingType);
}
Building::ExtWallsType_t
-Building::GetExtWallsType ()
+Building::GetExtWallsType () const
{
return (m_externalWalls);
}
-uint8_t
-Building::GetNumberFloors ()
+uint16_t
+Building::GetNFloors () const
+{
+ return (m_floors);
+}
+
+uint16_t
+Building::GetNRoomsX () const
{
- return (m_floor);
+ return (m_roomsX);
+}
+
+uint16_t
+Building::GetNRoomsY () const
+{
+ return (m_roomsY);
+}
+
+bool
+Building::IsInside (Vector position) const
+{
+ return m_buildingBounds.IsInside (position);
}
-uint8_t
-Building::GetNumberRoomX ()
+
+uint16_t
+Building::GetRoomX (Vector position) const
{
- return (m_roomX);
+ NS_ASSERT (IsInside (position));
+ uint16_t n;
+
+ if (position.x == m_buildingBounds.xMax)
+ {
+ n = m_roomsX;
+ }
+ else
+ {
+ double xLength = m_buildingBounds.xMax - m_buildingBounds.xMin;
+ double x = position.x - m_buildingBounds.xMin;
+ n = floor (m_roomsX * x/xLength) + 1;
+ NS_LOG_LOGIC ("xLength=" << xLength << ", x=" << x << ", m_roomsX=" << m_roomsX);
+ }
+ NS_LOG_LOGIC ("RoomX: " << n);
+ return n;
}
-uint8_t
-Building::GetNumberRoomY ()
+uint16_t
+Building::GetRoomY (Vector position) const
{
- return (m_roomY);
+ NS_ASSERT (IsInside (position));
+ uint16_t n;
+
+ if (position.y == m_buildingBounds.yMax)
+ {
+ n = m_roomsY;
+ }
+ else
+ {
+ double yLength = m_buildingBounds.yMax - m_buildingBounds.yMin;
+ double y = position.y - m_buildingBounds.yMin;
+ n = floor (m_roomsY * y/yLength) + 1;
+ NS_LOG_LOGIC ("yLength=" << yLength << ", y=" << y << ", m_roomsY=" << m_roomsY);
+ }
+ NS_LOG_LOGIC ("RoomY: " << n);
+ return n;
}
-Box
-Building::GetBuildingBounds ()
+uint16_t
+Building::GetFloor (Vector position) const
{
- return (m_buldingBounds);
+ NS_ASSERT (IsInside (position));
+ uint16_t n;
+
+ if (position.z == m_buildingBounds.zMax)
+ {
+ n = m_floors;
+ }
+ else
+ {
+ double zLength = m_buildingBounds.zMax - m_buildingBounds.zMin;
+ double z = position.z - m_buildingBounds.zMin;
+ n = floor (m_floors * z/zLength) + 1;
+ NS_LOG_LOGIC ("zLength=" << zLength << ", z=" << z << ", m_floors=" << m_floors);
+ }
+ NS_LOG_LOGIC ("floor: " << n);
+ return n;
}
--- a/src/buildings/model/building.h Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/model/building.h Mon Jan 16 20:32:45 2012 +0100
@@ -26,7 +26,7 @@
#include <ns3/vector.h>
#include <ns3/box.h>
#include <ns3/simple-ref-count.h>
-
+#include <ns3/object.h>
namespace ns3 {
@@ -34,132 +34,180 @@
* \ingroup mobility
* \brief a 3d building block
*/
-class Building : public SimpleRefCount<Building>
+class Building : public Object
{
public:
+
+ // inherited from Object
+ static TypeId GetTypeId (void);
+ virtual void DoDispose ();
+
+
enum BuildingType_t
- {
- Residential, Office, Commercial
- };
+ {
+ Residential, Office, Commercial
+ };
enum ExtWallsType_t
- {
- Wood, ConcreteWithWindows, ConcreteWithoutWindows, StoneBlocks
- };
+ {
+ Wood, ConcreteWithWindows, ConcreteWithoutWindows, StoneBlocks
+ };
+
/**
- * \param _xMin x coordinates of left boundary.
- * \param _xMax x coordinates of right boundary.
- * \param _yMin y coordinates of bottom boundary.
- * \param _yMax y coordinates of top boundary.
- * \param _zMin z coordinates of down boundary.
- * \param _zMax z coordinates of up boundary.
- * \param _nFloors number of floors
- * \param _nRoomX number of rooms in the x axis
- * \param _nRoomY number of rooms in the y axis
- *
- * Create a building.
- */
- Building (double _xMin, double _xMax,
- double _yMin, double _yMax,
- double _zMin, double _zMax/*,
- uint8_t _nFloors, uint8_t _nRoomX, uint8_t _nRoomY*/);
+ * Construct a simple building with 1 room and 1 floor
+ *
+ * \param xMin x coordinates of left boundary.
+ * \param xMax x coordinates of right boundary.
+ * \param yMin y coordinates of bottom boundary.
+ * \param yMax y coordinates of top boundary.
+ * \param zMin z coordinates of down boundary.
+ * \param zMax z coordinates of up boundary.
+ *
+ */
+ Building (double xMin,
+ double xMax,
+ double yMin,
+ double yMax,
+ double zMin,
+ double zMax);
/**
- * Create a zero-sized building located at coordinates (0.0,0.0,0.0)
- * and with no floors and 1 room.
- */
+ * Create a zero-sized building located at coordinates (0.0,0.0,0.0)
+ * and with 1 floors and 1 room.
+ */
Building ();
+ /**
+ * Destructor
+ *
+ */
+ virtual ~Building ();
/**
- * \param t the type of building (i.e., Residential, Office, Commercial)
- *
- * This method allows to set building type (default is Residential)
- */
+ * \return the unique id of this Building. This unique id happens to
+ * be also the index of the Building into the BuildingList.
+ */
+ uint32_t GetId (void) const;
+
+ /**
+ * \param t the type of building (i.e., Residential, Office, Commercial)
+ *
+ * This method allows to set building type (default is Residential)
+ */
void SetBuildingType (Building::BuildingType_t t);
/**
- * \param t the type of external walls (i.e., Wood, ConcreteWithWindows,
- * ConcreteWithoutWindows and StoneBlocks), used for evaluating the loss
- * due to the penetration of external walls in outdoor <-> indoor comm.
- *
- * This method allows to set external walls type (default is Residential)
- */
+ * \param t the type of external walls (i.e., Wood, ConcreteWithWindows,
+ * ConcreteWithoutWindows and StoneBlocks), used for evaluating the loss
+ * due to the penetration of external walls in outdoor <-> indoor comm.
+ *
+ * This method allows to set external walls type (default is Residential)
+ */
void SetExtWallsType (Building::ExtWallsType_t t);
/**
- * \param nfloors the number of floors in the building
- *
- * This method allows to set the number of floors in the building
- * (default is 1)
- */
- void SetFloorsNumber (uint8_t nfloors);
+ * \param nfloors the number of floors in the building
+ *
+ * This method allows to set the number of floors in the building
+ * (default is 1)
+ */
+ void SetNFloors (uint16_t nfloors);
/**
- * \param nroomx the number of rooms in the x axis
- *
- * This method allows to set the number of room in x-axis (default is 1)
- * The rooms are disposed as a grid of nº of rooms in X per nº of rooms in Y
- */
- void SetNumberRoomX (uint8_t nroomx);
+ * \param nroomx the number of rooms along the x axis
+ *
+ * This method allows to set the number of rooms along the x-axis
+ */
+ void SetNRoomsX (uint16_t nroomx);
/**
- * \param nroomy the number of floors in the building
- *
- * This method allows to set the number of floors in the building
- * (default is 1)
- */
- void SetNumberRoomY (uint8_t nroomy);
+ * \param nroomy the number of floors in the building
+ *
+ * This method allows to set the number of rooms along the y-axis
+ */
+ void SetNRoomsY (uint16_t nroomy);
/**
- * \return the type of building
- * Return the type of building (i.e., Residential, Office, Commercial)
- */
- BuildingType_t GetBuildingType ();
+ * \return the type of building
+ * Return the type of building (i.e., Residential, Office, Commercial)
+ */
+ BuildingType_t GetBuildingType () const;
/**
- * \return the type of external walls
- * Return the type of external walls (i.e., Wood, ConcreteWithWindows,
- * ConcreteWithoutWindows)
- */
- ExtWallsType_t GetExtWallsType ();
+ * \return the type of external walls of the building
+ */
+ ExtWallsType_t GetExtWallsType () const;
+
+ /**
+ * \return the number of floors of the building
+ */
+ uint16_t GetNFloors () const;
+
+ /**
+ * \return the number of rooms along the x-axis of the building
+ */
+ uint16_t GetNRoomsX () const;
/**
- * \return the number of floors
- * Return the number of floors
- */
- uint8_t GetNumberFloors ();
-
- /**
- * \return the number of room in x-axis
- * Return the number of room in x-axis
- */
- uint8_t GetNumberRoomX ();
+ * \return the number of rooms along the y-axis
+ */
+ uint16_t GetNRoomsY () const;
+
+ /**
+ *
+ *
+ * \param position some position
+ *
+ * \return true if the position fall inside the building, false otherwise
+ */
+ bool IsInside (Vector position) const;
+
+ /**
+ *
+ *
+ * \param position a position inside the building
+ *
+ * \return the number of the room along the X axis where the
+ * position falls
+ */
+ uint16_t GetRoomX (Vector position) const;
- /**
- * \return the number of room in y-axis
- * Return the number of room in y-axis
- */
- uint8_t GetNumberRoomY ();
-
- /**
- * \return the bounds of the building
- * Return the bounds of the building as Box class
- */
- Box GetBuildingBounds ();
+ /**
+ *
+ *
+ * \param position a position inside the building
+ *
+ * \return the number of the room along the Y axis where the
+ * position falls
+ */
+ uint16_t GetRoomY (Vector position) const;
+
+ /**
+ *
+ * \param position a position inside the building
+ *
+ * \return the floor where the position falls
+ */
+ uint16_t GetFloor (Vector position) const;
+
+
private:
- Box m_buldingBounds;
+
+ void Construct ();
+
+ Box m_buildingBounds;
+
/**
- * number of floors must be greater then 0 and 1 means only one floor
- * (i.e., groundfloor)
- */
- uint8_t m_floor;
- uint8_t m_roomX;
- uint8_t m_roomY;
+ * number of floors, must be greater than 0, and 1 means only one floor
+ * (i.e., groundfloor)
+ */
+ uint16_t m_floors;
+ uint16_t m_roomsX;
+ uint16_t m_roomsY;
- uint8_t m_buildingId;
+ uint32_t m_buildingId;
BuildingType_t m_buildingType;
ExtWallsType_t m_externalWalls;
@@ -169,7 +217,7 @@
//std::istream &operator >> (std::istream &is, Box &box);
-ATTRIBUTE_HELPER_HEADER (Building);
+//ATTRIBUTE_HELPER_HEADER (Building);
} // namespace ns3
--- a/src/buildings/model/buildings-mobility-model.cc Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/model/buildings-mobility-model.cc Mon Jan 16 20:32:45 2012 +0100
@@ -22,8 +22,10 @@
#include <ns3/simulator.h>
#include <ns3/position-allocator.h>
#include <ns3/buildings-mobility-model.h>
-#include "ns3/pointer.h"
+#include <ns3/pointer.h>
+#include <ns3/log.h>
+NS_LOG_COMPONENT_DEFINE ("BuildingsMobilityModel");
namespace ns3 {
@@ -35,12 +37,7 @@
static TypeId tid = TypeId ("ns3::BuildingsMobilityModel")
.SetParent<MobilityModel> ()
.SetGroupName ("Mobility")
- .AddConstructor<BuildingsMobilityModel> ()
- .AddAttribute ("Bounds",
- "Bounds of the area to cruise.",
- BoxValue (Box (-100.0, 100.0, -100.0, 100.0, 0.0, 100.0)),
- MakeBoxAccessor (&BuildingsMobilityModel::m_bounds),
- MakeBoxChecker ());
+ .AddConstructor<BuildingsMobilityModel> ();
return tid;
}
@@ -48,6 +45,7 @@
BuildingsMobilityModel::BuildingsMobilityModel ()
{
+ NS_LOG_FUNCTION (this);
m_indoor = false;
m_nFloor = 0;
m_roomX = 1;
@@ -57,43 +55,48 @@
void
BuildingsMobilityModel::DoDispose (void)
{
- // chain up
- m_surroudingBuildings.clear ();
+ NS_LOG_FUNCTION (this);
MobilityModel::DoDispose ();
}
Vector
BuildingsMobilityModel::DoGetPosition (void) const
{
+ NS_LOG_FUNCTION (this);
m_helper.Update ();
return m_helper.GetCurrentPosition ();
}
void
BuildingsMobilityModel::DoSetPosition (const Vector &position)
{
+ NS_LOG_FUNCTION (this);
m_helper.SetPosition (position);
}
Vector
BuildingsMobilityModel::DoGetVelocity (void) const
{
+ NS_LOG_FUNCTION (this);
return m_helper.GetVelocity ();
}
bool
BuildingsMobilityModel::IsIndoor (void)
{
+ NS_LOG_FUNCTION (this);
return (m_indoor);
}
bool
BuildingsMobilityModel::IsOutdoor (void)
{
+ NS_LOG_FUNCTION (this);
return (!m_indoor);
}
void
BuildingsMobilityModel::SetIndoor (Ptr<Building> building)
{
+ NS_LOG_FUNCTION (this);
m_indoor = true;
m_myBuilding = building;
}
@@ -101,13 +104,14 @@
void
BuildingsMobilityModel::SetIndoor (Ptr<Building> building, uint8_t nfloor, uint8_t nroomx, uint8_t nroomy)
{
+ NS_LOG_FUNCTION (this);
m_indoor = true;
m_myBuilding = building;
m_nFloor = nfloor;
m_roomX = nroomx;
m_roomY = nroomy;
- if (!building->GetBuildingBounds ().IsInside (m_helper.GetCurrentPosition ()))
+ if (!building->IsInside (m_helper.GetCurrentPosition ()))
{
NS_FATAL_ERROR ("Position of the node is inconsistent with building bounds");
}
@@ -117,12 +121,14 @@
void
BuildingsMobilityModel::SetOutdoor (void)
{
+ NS_LOG_FUNCTION (this);
m_indoor = false;
}
void
BuildingsMobilityModel::SetFloorNumber (uint8_t nfloor)
{
+ NS_LOG_FUNCTION (this);
m_nFloor = nfloor;
}
@@ -135,31 +141,28 @@
void
BuildingsMobilityModel::SetRoomNumberY (uint8_t nroomy)
{
+ NS_LOG_FUNCTION (this);
m_roomY = nroomy;
}
-
-void
-BuildingsMobilityModel::SetSurroudingBuilding (Ptr<Building> building)
-{
- m_surroudingBuildings.push_back (building);
-}
-
uint8_t
BuildingsMobilityModel::GetFloorNumber (void)
{
+ NS_LOG_FUNCTION (this);
return (m_nFloor);
}
uint8_t
BuildingsMobilityModel::GetRoomNumberX (void)
{
+ NS_LOG_FUNCTION (this);
return (m_roomX);
}
uint8_t
BuildingsMobilityModel::GetRoomNumberY (void)
{
+ NS_LOG_FUNCTION (this);
return (m_roomY);
}
@@ -167,8 +170,9 @@
Ptr<Building>
BuildingsMobilityModel::GetBuilding ()
{
+ NS_LOG_FUNCTION (this);
return (m_myBuilding);
}
-} // namespace
\ No newline at end of file
+} // namespace
--- a/src/buildings/model/buildings-mobility-model.h Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/model/buildings-mobility-model.h Mon Jan 16 20:32:45 2012 +0100
@@ -59,8 +59,6 @@
void SetIndoor (Ptr<Building> building, uint8_t nfloor, uint8_t nroomx, uint8_t nroomy);
void SetOutdoor (void);
- void SetSurroudingBuilding (Ptr<Building> building);
-
void SetFloorNumber (uint8_t nfloor);
void SetRoomNumberX (uint8_t nroomx);
void SetRoomNumberY (uint8_t nroomy);
@@ -79,8 +77,7 @@
virtual void DoSetPosition (const Vector &position);
virtual Vector DoGetVelocity (void) const;
ConstantVelocityHelper m_helper;
- Box m_bounds; // bounds of the simulation field (if needed)
- std::list < Ptr<Building> > m_surroudingBuildings; // buildings blocks
+
Ptr<Building> m_myBuilding;
bool m_indoor;
/**
--- a/src/buildings/model/buildings-propagation-loss-model.cc Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/model/buildings-propagation-loss-model.cc Mon Jan 16 20:32:45 2012 +0100
@@ -29,9 +29,6 @@
#include "ns3/buildings-mobility-model.h"
#include "ns3/enum.h"
-//#include <ns3/shadowing-loss-model.h>
-//#include <ns3/jakes-fading-loss-model.h>
-
NS_LOG_COMPONENT_DEFINE ("BuildingsPropagationLossModel");
@@ -624,7 +621,9 @@
double
BuildingsPropagationLossModel::GetLoss (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
{
+ NS_ASSERT_MSG ((a->GetPosition ().z > 0) && (b->GetPosition ().z > 0), "BuildingsPropagationLossModel does not support underground nodes (placed at z < 0)");
+
double distance = a->GetDistanceFrom (b);
if (distance <= m_minDistance)
{
@@ -634,6 +633,7 @@
// get the BuildingsMobilityModel pointers
Ptr<BuildingsMobilityModel> a1 = DynamicCast<BuildingsMobilityModel> (a);
Ptr<BuildingsMobilityModel> b1 = DynamicCast<BuildingsMobilityModel> (b);
+ NS_ASSERT_MSG ((a1 != 0) && (b1 != 0), "BuildingsPropagationLossModel only works with BuildingsMobilityModel");
double loss = 0.0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/test/buildings-helper-test.cc Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,324 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011, 2012 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+
+#include "ns3/log.h"
+#include "ns3/test.h"
+#include <ns3/buildings-mobility-model.h>
+#include <ns3/building.h>
+#include <ns3/buildings-helper.h>
+#include <ns3/mobility-helper.h>
+#include <ns3/simulator.h>
+
+NS_LOG_COMPONENT_DEFINE ("BuildingsHelperTest");
+
+using namespace ns3;
+
+
+struct PositionInBuilding
+{
+ PositionInBuilding ();
+ Vector pos; // coordinates of the mobility model instance
+ bool indoor; // true if indoor, false otherwise
+ uint32_t bid; // building id
+ uint16_t rx; // room x
+ uint16_t ry; // room y
+ uint16_t fn; // floor number
+};
+
+PositionInBuilding::PositionInBuilding ()
+ : pos (0,0,0),
+ indoor (false),
+ bid (0xffffffff),
+ rx (0),
+ ry (0),
+ fn (0)
+{
+}
+
+/**
+ * data to construct a Building object. We don't want to pass Building
+ * objects to the TestCase constructor because otherwise BuildingList
+ * would contain all of them (even if only one is meant to be in the
+ * test case).
+ *
+ */
+struct BuildingData
+{
+ BuildingData ();
+ double xmin;
+ double xmax;
+ double ymin;
+ double ymax;
+ double zmin;
+ double zmax;
+ uint16_t nrx;
+ uint16_t nry;
+ uint16_t nf;
+};
+
+BuildingData::BuildingData ()
+ : xmin (0),
+ xmax (0),
+ ymin (0),
+ ymax (0),
+ zmin (0),
+ zmax (0),
+ nrx (0),
+ nry (0),
+ nf (0)
+{
+}
+
+class BuildingsHelperOneTestCase : public TestCase
+{
+public:
+ static std::string BuildNameString (PositionInBuilding pib, BuildingData bd);
+ BuildingsHelperOneTestCase (PositionInBuilding pib, BuildingData bd);
+
+private:
+ virtual void DoRun (void);
+
+ PositionInBuilding m_pib;
+ BuildingData m_bd;
+
+};
+
+std::string BuildingsHelperOneTestCase::BuildNameString (PositionInBuilding pib, BuildingData bd)
+{
+ std::ostringstream oss;
+ oss << "pos=" << pib.pos;
+ if (pib.indoor)
+ {
+ oss << ", bid=" << pib.bid
+ << ", rx=" << pib.rx
+ << ", ry=" << pib.ry
+ << ", fn=" << pib.fn;
+ }
+ else
+ {
+ oss << ", outdoor";
+ }
+ return oss.str ();
+}
+
+
+BuildingsHelperOneTestCase::BuildingsHelperOneTestCase (PositionInBuilding pib, BuildingData bd)
+ : TestCase (BuildNameString (pib, bd)),
+ m_pib (pib),
+ m_bd (bd)
+{
+}
+
+void
+BuildingsHelperOneTestCase::DoRun ()
+{
+ NS_LOG_FUNCTION (this << BuildNameString (m_pib, m_bd));
+ MobilityHelper mobility;
+ mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
+
+ NodeContainer nodes;
+ nodes.Create (1);
+ mobility.Install (nodes);
+
+ Ptr<BuildingsMobilityModel> bmm = nodes.Get (0)->GetObject<BuildingsMobilityModel> ();
+ bmm->SetPosition (m_pib.pos);
+
+ NS_LOG_LOGIC ("create building");
+ Ptr<Building> b = CreateObject<Building> (m_bd.xmin, m_bd.xmax, m_bd.ymin, m_bd.ymax, m_bd.zmin, m_bd.zmax);
+ b->SetNFloors (m_bd.nf);
+ b->SetNRoomsX (m_bd.nrx);
+ b->SetNRoomsY (m_bd.nry);
+
+ BuildingsHelper::MakeAllInstancesConsistent ();
+
+
+ NS_TEST_ASSERT_MSG_EQ (bmm->IsIndoor (), m_pib.indoor, "indoor/outdoor mismatch");
+ if (m_pib.indoor)
+ {
+ NS_LOG_LOGIC (" got bid=" << bmm->GetBuilding ()->GetId () << ", f=" << (uint32_t) bmm->GetFloorNumber () << ", rx=" << (uint32_t) bmm->GetRoomNumberX () << ", roomY=" << (uint32_t) bmm->GetRoomNumberY ());
+ // only one building in this test, so Id will be 0
+ NS_TEST_ASSERT_MSG_EQ (bmm->GetBuilding ()->GetId (), 0, "Building ID mismatch");
+ NS_TEST_ASSERT_MSG_EQ ((uint32_t) bmm->GetFloorNumber (), m_pib.fn, "floor number mismatch");
+ NS_TEST_ASSERT_MSG_EQ ((uint32_t) bmm->GetRoomNumberX (), m_pib.rx, "x room number mismatch");
+ NS_TEST_ASSERT_MSG_EQ ((uint32_t) bmm->GetRoomNumberY (), m_pib.ry, "y room number mismatch");
+ }
+
+ Simulator::Destroy ();
+}
+
+
+
+
+
+
+
+class BuildingsHelperTestSuite : public TestSuite
+{
+public:
+ BuildingsHelperTestSuite ();
+};
+
+
+BuildingsHelperTestSuite::BuildingsHelperTestSuite ()
+ : TestSuite ("buildings-helper", UNIT)
+{
+ NS_LOG_FUNCTION (this);
+
+ BuildingData b1;
+ b1.xmin = 1;
+ b1.xmax = 3;
+ b1.ymin = 1;
+ b1.ymax = 2;
+ b1.zmin = 0;
+ b1.zmax = 4;
+ b1.nrx = 1;
+ b1.nry = 1;
+ b1.nf = 1;
+
+ Vector vp1 (1.5, 1.5, 0.5);
+ PositionInBuilding p1;
+ p1.pos = vp1;
+ p1.indoor = true;
+ p1.bid = 0;
+ p1.rx = 1;
+ p1.ry = 1;
+ p1.fn = 1;
+ AddTestCase (new BuildingsHelperOneTestCase (p1, b1));
+
+ Vector vp2 (1.5, 0.5, 0.5);
+ PositionInBuilding p2;
+ p2.pos = vp2;
+ p2.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (p2, b1));
+
+ Vector vp3 (1.5, 2.5, 0.5);
+ PositionInBuilding p3;
+ p3.pos = vp3;
+ p3.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (p3, b1));
+
+ Vector vp4 (1.5, 1.5, 5);
+ PositionInBuilding p4;
+ p4.pos = vp4;
+ p4.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (p4, b1));
+
+ Vector vp5 (2.5, 1.6, 3.5);
+ PositionInBuilding p5;
+ p5.pos = vp5;
+ p5.indoor = true;
+ p5.bid = 0;
+ p5.rx = 1;
+ p5.ry = 1;
+ p5.fn = 1;
+ AddTestCase (new BuildingsHelperOneTestCase (p5, b1));
+
+ Vector vp6 (0.9999, 1.5, 1.5);
+ PositionInBuilding p6;
+ p6.pos = vp6;
+ p6.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (p6, b1));
+
+ Vector vp7 (3.0001, 1.5, 2.5);
+ PositionInBuilding p7;
+ p7.pos = vp7;
+ p7.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (p7, b1));
+
+ Vector vp8 (1.001, 1.001, -0.01);
+ PositionInBuilding p8;
+ p8.pos = vp8;
+ p8.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (p8, b1));
+
+ Vector vp9 (1.5, 1.5, 4.001);
+ PositionInBuilding p9;
+ p9.pos = vp9;
+ p9.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (p9, b1));
+
+
+
+
+ BuildingData b2;
+ b2.xmin = -1;
+ b2.xmax = 0.5;
+ b2.ymin = -2;
+ b2.ymax = 0.5;
+ b2.zmin = 0;
+ b2.zmax = 2;
+ b2.nrx = 3;
+ b2.nry = 5;
+ b2.nf = 4;
+
+ Vector vq1 (-0.7, -1.1, 1.2);
+ PositionInBuilding q1;
+ q1.pos = vq1;
+ q1.indoor = true;
+ q1.bid = 1;
+ q1.rx = 1;
+ q1.ry = 2;
+ q1.fn = 3;
+ AddTestCase (new BuildingsHelperOneTestCase (q1, b2));
+
+ Vector vq2 (0.2, 0.3, 0.2);
+ PositionInBuilding q2;
+ q2.pos = vq2;
+ q2.indoor = true;
+ q2.bid = 1;
+ q2.rx = 3;
+ q2.ry = 5;
+ q2.fn = 1;
+ AddTestCase (new BuildingsHelperOneTestCase (q2, b2));
+
+ Vector vq3 (0.6, -1.75, 1.5);
+ PositionInBuilding q3;
+ q3.pos = vq3;
+ q3.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (q3, b2));
+
+ Vector vq4 (-1.01, 0.3, 1.99);
+ PositionInBuilding q4;
+ q4.pos = vq4;
+ q4.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (q4, b2));
+
+ Vector vq5 (-0.8, 0.7, 0.01);
+ PositionInBuilding q5;
+ q5.pos = vq5;
+ q5.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (q5, b2));
+
+ Vector vq6 (0.2, 0.3, -0.2);
+ PositionInBuilding q6;
+ q6.pos = vq6;
+ q6.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (q6, b2));
+
+ Vector vq7 (0.2, 0.3, 2.001);
+ PositionInBuilding q7;
+ q7.pos = vq7;
+ q7.indoor = false;
+ AddTestCase (new BuildingsHelperOneTestCase (q7, b2));
+}
+
+static BuildingsHelperTestSuite buildingsHelperAntennaTestSuiteInstance;
--- a/src/buildings/wscript Mon Jan 16 14:25:21 2012 +0100
+++ b/src/buildings/wscript Mon Jan 16 20:32:45 2012 +0100
@@ -5,12 +5,15 @@
module = bld.create_ns3_module('buildings', ['mobility', 'propagation'])
module.source = [
'model/building.cc',
+ 'model/building-list.cc',
'model/buildings-mobility-model.cc',
'model/buildings-propagation-loss-model.cc',
+ 'helper/buildings-helper.cc',
]
module_test = bld.create_ns3_module_test_library('buildings')
module_test.source = [
+ 'test/buildings-helper-test.cc',
'test/buildings-pathloss-test.cc',
'test/buildings-shadowing-test.cc',
]
@@ -19,8 +22,10 @@
headers.module = 'buildings'
headers.source = [
'model/building.h',
+ 'model/building-list.h',
'model/buildings-mobility-model.h',
'model/buildings-propagation-loss-model.h',
+ 'helper/buildings-helper.h',
'test/buildings-pathloss-test.h',
'test/buildings-shadowing-test.h',
]
--- a/src/lte/doc/source/lte-user.rst Mon Jan 16 14:25:21 2012 +0100
+++ b/src/lte/doc/source/lte-user.rst Mon Jan 16 20:32:45 2012 +0100
@@ -403,18 +403,6 @@
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
-#. Node creation and positioning::
-
- ueNodes.Create (1);
- mobility.Install (ueNodes);
- NetDeviceContainer ueDevs;
- ueDevs = lteHelper->InstallUeDevice (ueNodes);
- Ptr<BuildingsMobilityModel> mm = enbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
- double x_axis = 0.0;
- double y_axis = 0.0;
- double z_axis = 0.0;
- mm->SetPosition (Vector (x_axis, y_axis, z_axis));
-
#. Building creation::
double x_min = 0.0;
@@ -423,29 +411,33 @@
double y_max = 20.0;
double z_min = 0.0;
double z_max = 10.0;
- Ptr<Building> building = Create<Building> (x_min, x_max, y_min, y_max, z_min, z_max);
+ Ptr<Building> building = CreateObject <Building> (x_min, x_max, y_min, y_max, z_min, z_max);
building->SetBuildingType (Building::Residential);
building->SetExtWallsType (Building::ConcreteWithWindows);
- building->SetFloorsNumber (3);
- building->SetNumberRoomX (3);
- building->SetNumberRoomY (2);
+ building->SetNFloors (3);
+ building->SetNRoomsX (3);
+ building->SetNRoomsY (2);
This will instantiate a residential building with base of 10 x 20 meters and height of 10 meters whose external walls are of concrete with windows; the building has three floors and has an internal 3 x 2 grid of rooms of equal size.
-#. Building and nodes interactions::
-
- mm->SetIndoor (building, 2, 1, 1);
-
- which is equivalent to the form::
+#. Node creation and positioning::
- mm->SetIndoor (building);
- mm->SetFloorNumber (2);
- mm->SetRoomNumberX (1);
- mm->SetRoomNumberY (1);
+ ueNodes.Create (2);
+ mobility.Install (ueNodes);
+ NetDeviceContainer ueDevs;
+ ueDevs = lteHelper->InstallUeDevice (ueNodes);
+ Ptr<BuildingsMobilityModel> mm0 = enbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
+ Ptr<BuildingsMobilityModel> mm1 = enbNodes.Get (1)->GetObject<BuildingsMobilityModel> ();
+ mm0->SetPosition (Vector (5.0, 5.0, 1.5));
+ mm1->SetPosition (Vector (30.0, 40.0, 1.5));
- This informs the node's mobility model that the node is located inside the building on the second floor in the corner room of the 3 x 2 grid.
- We suggest the usage of the first form since it performs a consistency check of the node position with the building bounds.
- It has to be noted that the simulator does not check the consistence between the node's position (x,y,z coordinates) and the building position and size for outdoor nodes. The responsibility of this consistency is completely left to the user.
+This positions the node on the scenario. Note that, in this example, node 0 will be in the building, and node 1 will be out of the building. Note that this alone is not sufficient to setup the topology correctly. What is left to be done is to issue the following command after we have placed all nodes in the simulation::
+
+ BuildingsHelper::MakeAllInstancesConsistent ();
+
+This command will go through the lists of all nodes and of all buildings, determine for each user if it is indoor or outdoor, and if indoor it will also determine the building in which the user is located and the corresponding floor and number inside the building.
+
+
@@ -477,6 +469,54 @@
with different antenna orientations to be installed on each node.
+Radio Environment Maps
+----------------------
+
+By using the class RadioEnvironmentMapHelper it is possible to output
+to a file a Radio Environment Map (REM), i.e., a uniform 2D grid of values
+that represent the Signal-to-noise ratio in the downlink with respect
+to the eNB that has the strongest signal at each point.
+
+To do this, you just need to add the following code to your simulation
+program towards the end, right before the call to Simulator::Run ()::
+
+ Ptr<RadioEnvironmentMapHelper> remHelper = CreateObject<RadioEnvironmentMapHelper> ();
+ remHelper->SetAttribute ("ChannelPath", StringValue ("/ChannelList/0"));
+ remHelper->SetAttribute ("OutputFile", StringValue ("rem.out"));
+ remHelper->SetAttribute ("XMin", DoubleValue (-400.0));
+ remHelper->SetAttribute ("XMax", DoubleValue (400.0));
+ remHelper->SetAttribute ("XRes", UintegerValue (100));
+ remHelper->SetAttribute ("YMin", DoubleValue (-300.0));
+ remHelper->SetAttribute ("YMax", DoubleValue (300.0));
+ remHelper->SetAttribute ("YRes", UintegerValue (75));
+ remHelper->SetAttribute ("Z", DoubleValue (0.0));
+ remHelper->Install ();
+
+By configuring the attributes of the RadioEnvironmentMapHelper object
+as shown above, you can tune the parameters of the REM to be
+generated. Note that each RadioEnvironmentMapHelper instance can
+generate only one REM; if you want to generate more REMs, you need to
+create one separate instance for each REM.
+
+The REM is stored in an ASCII file in the following format:
+
+ * column 1 is the x coordinate
+ * column 2 is the y coordinate
+ * column 3 is the z coordinate
+ * column 4 is the SINR in linear units
+
+A minimal gnuplot script that allows you to plot the REM is given
+below::
+
+ set view map;
+ set xlabel "X"
+ set ylabel "Y"
+ set cblabel "SINR (dB)"
+ plot "rem.out" using ($1):($2):(10*log10($4)) with image
+
+
+
+
Evolved Packet Core (EPC)
-------------------------
--- a/src/lte/examples/lena-profiling.cc Mon Jan 16 14:25:21 2012 +0100
+++ b/src/lte/examples/lena-profiling.cc Mon Jan 16 20:32:45 2012 +0100
@@ -138,9 +138,9 @@
0.0, nFloors* roomHeight);
building->SetBuildingType (Building::Residential);
building->SetExtWallsType (Building::ConcreteWithWindows);
- building->SetFloorsNumber (nFloors);
- building->SetNumberRoomX (nRooms);
- building->SetNumberRoomY (nRooms);
+ building->SetNFloors (nFloors);
+ building->SetNRoomsX (nRooms);
+ building->SetNRoomsY (nRooms);
mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
mobility.Install (enbNodes);
uint32_t plantedEnb = 0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/examples/lena-rem.cc Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,121 @@
+/* -*- 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/spectrum-module.h"
+//#include "ns3/gtk-config-store.h"
+
+using namespace ns3;
+
+int main (int argc, char *argv[])
+{
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ // to save a template default attribute file run it like this:
+ // ./waf --command-template="%s --ns3::ConfigStore::Filename=input-defaults.txt --ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=RawText" --run src/lte/examples/lena-first-sim
+ //
+ // to load a previously created default attribute file
+ // ./waf --command-template="%s --ns3::ConfigStore::Filename=input-defaults.txt --ns3::ConfigStore::Mode=Load --ns3::ConfigStore::FileFormat=RawText" --run src/lte/examples/lena-first-sim
+
+ ConfigStore inputConfig;
+ inputConfig.ConfigureDefaults ();
+
+ // Parse again so you can override default values from the command line
+ cmd.Parse (argc, argv);
+
+ Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
+
+ // Uncomment to enable logging
+ //lteHelper->EnableLogComponents ();
+
+ // Create Nodes: eNodeB and UE
+ NodeContainer enbNodes;
+ NodeContainer ueNodes;
+ enbNodes.Create (1);
+ ueNodes.Create (1);
+
+ // Install Mobility Model
+ MobilityHelper mobility;
+ mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
+ mobility.Install (enbNodes);
+ mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
+ mobility.Install (ueNodes);
+
+ // Create Devices and install them in the Nodes (eNB and UE)
+ NetDeviceContainer enbDevs;
+ NetDeviceContainer ueDevs;
+ // Default scheduler is PF, uncomment to use RR
+ //lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
+
+ enbDevs = lteHelper->InstallEnbDevice (enbNodes);
+ ueDevs = lteHelper->InstallUeDevice (ueNodes);
+
+ // Attach a UE to a eNB
+ lteHelper->Attach (ueDevs, enbDevs.Get (0));
+
+ // Activate an EPS bearer
+ enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
+ EpsBearer bearer (q);
+ lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+
+
+ // Configure Radio Environment Map (REM) output
+ // for LTE-only simulations always use /ChannelList/0 which is the downlink channel
+ Ptr<RadioEnvironmentMapHelper> remHelper = CreateObject<RadioEnvironmentMapHelper> ();
+ remHelper->SetAttribute ("ChannelPath", StringValue ("/ChannelList/0"));
+ remHelper->SetAttribute ("OutputFile", StringValue ("rem.out"));
+ remHelper->SetAttribute ("XMin", DoubleValue (-400.0));
+ remHelper->SetAttribute ("XMax", DoubleValue (400.0));
+ remHelper->SetAttribute ("XRes", UintegerValue (100));
+ remHelper->SetAttribute ("YMin", DoubleValue (-300.0));
+ remHelper->SetAttribute ("YMax", DoubleValue (300.0));
+ remHelper->SetAttribute ("YRes", UintegerValue (75));
+ remHelper->SetAttribute ("Z", DoubleValue (0.0));
+ remHelper->Install ();
+
+ // here's a minimal gnuplot script that will plot the above:
+ //
+ // set view map;
+ // set term x11;
+ // set xlabel "X"
+ // set ylabel "Y"
+ // set cblabel "SINR (dB)"
+ // plot "rem.out" using ($1):($2):(10*log10($4)) with image
+
+
+
+
+ Simulator::Stop (Seconds (0.020));
+
+ Simulator::Run ();
+
+ //GtkConfigStore config;
+ //config.ConfigureAttributes ();
+
+ Simulator::Destroy ();
+ return 0;
+}
--- a/src/lte/examples/wscript Mon Jan 16 14:25:21 2012 +0100
+++ b/src/lte/examples/wscript Mon Jan 16 20:32:45 2012 +0100
@@ -28,4 +28,6 @@
obj = bld.create_ns3_program('lena-simple-epc',
['lte'])
obj.source = 'lena-simple-epc.cc'
-
+ obj = bld.create_ns3_program('lena-rem',
+ ['lte'])
+ obj.source = 'lena-rem.cc'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/helper/radio-environment-map-helper.cc Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,203 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#include "radio-environment-map-helper.h"
+
+#include <ns3/abort.h>
+#include <ns3/log.h>
+#include <ns3/double.h>
+#include <ns3/uinteger.h>
+#include <ns3/string.h>
+#include <ns3/spectrum-channel.h>
+#include <ns3/config.h>
+#include <ns3/rem-spectrum-phy.h>
+#include <ns3/buildings-mobility-model.h>
+#include <ns3/simulator.h>
+#include <ns3/node.h>
+
+#include <fstream>
+
+
+NS_LOG_COMPONENT_DEFINE ("RadioEnvironmentMapHelper");
+
+namespace ns3 {
+
+
+
+NS_OBJECT_ENSURE_REGISTERED (RadioEnvironmentMapHelper);
+
+RadioEnvironmentMapHelper::RadioEnvironmentMapHelper ()
+{
+}
+
+
+RadioEnvironmentMapHelper::~RadioEnvironmentMapHelper ()
+{
+}
+
+
+
+void
+RadioEnvironmentMapHelper::DoDispose ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+TypeId
+RadioEnvironmentMapHelper::GetTypeId (void)
+{
+ NS_LOG_FUNCTION ("RadioEnvironmentMapHelper::GetTypeId");
+ static TypeId tid = TypeId ("ns3::RadioEnvironmentMapHelper")
+ .SetParent<Object> ()
+ .AddConstructor<RadioEnvironmentMapHelper> ()
+ .AddAttribute ("ChannelPath", "The path to the channel for which the Radio Environment Map is to be generated",
+ StringValue ("/ChannelList/0"),
+ MakeStringAccessor (&RadioEnvironmentMapHelper::m_channelPath),
+ MakeStringChecker ())
+ .AddAttribute ("OutputFile", "the filename to which the Radio Environment Map is saved",
+ StringValue ("rem.out"),
+ MakeStringAccessor (&RadioEnvironmentMapHelper::m_outputFile),
+ MakeStringChecker ())
+ .AddAttribute ("XMin", "The min x coordinate of the map.",
+ DoubleValue (0.0),
+ MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_xMin),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("YMin", "The min y coordinate of the map.",
+ DoubleValue (0.0),
+ MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_yMin),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("XMax", "The max x coordinate of the map.",
+ DoubleValue (1.0),
+ MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_xMax),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("YMax", "The max y coordinate of the map.",
+ DoubleValue (1.0),
+ MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_yMax),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("XRes", "The resolution (number of points) of the map along the x axis.",
+ UintegerValue (100),
+ MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_xRes),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("YRes", "The resolution (number of points) of the map along the y axis.",
+ UintegerValue (100),
+ MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_yRes),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("Z", "The value of the z coordinate for which the map is to be generated",
+ DoubleValue (0.0),
+ MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_z),
+ MakeDoubleChecker<double> ())
+
+ ;
+ return tid;
+}
+
+
+
+
+void
+RadioEnvironmentMapHelper::Install ()
+{
+ NS_LOG_FUNCTION (this);
+ if (!m_rem.empty ())
+ {
+ NS_FATAL_ERROR ("only one REM supported per instance of RadioEnvironmentMapHelper");
+ }
+ Config::MatchContainer match = Config::LookupMatches (m_channelPath);
+ if (match.GetN () != 1)
+ {
+ NS_FATAL_ERROR ("Lookup " << m_channelPath << " should have exactly one match");
+ }
+ m_channel = match.Get (0)->GetObject<SpectrumChannel> ();
+ NS_ABORT_MSG_IF (m_channel == 0, "object at " << m_channelPath << "is not of type SpectrumChannel");
+
+ double xStep = (m_xMax - m_xMin)/m_xRes;
+ double yStep = (m_yMax - m_yMin)/m_yRes;
+
+ for (double x = m_xMin; x <= m_xMax ; x += xStep)
+ {
+ m_rem.push_back (std::list<RemPoint> ());
+ for (double y = m_yMin; y <= m_yMax ; y += yStep)
+ {
+ RemPoint p;
+ p.phy = CreateObject<RemSpectrumPhy> ();
+ p.bmm = CreateObject<BuildingsMobilityModel> ();
+ p.phy->SetMobility (p.bmm);
+ p.bmm->SetPosition (Vector (x, y, m_z));
+ m_rem.back ().push_back (p);
+ }
+ }
+ Simulator::Schedule (Seconds (0.0055), &RadioEnvironmentMapHelper::Connect, this);
+ Simulator::Schedule (Seconds (0.0065), &RadioEnvironmentMapHelper::PrintAndDisconnect, this);
+
+}
+
+void
+RadioEnvironmentMapHelper::Connect ()
+{
+ NS_LOG_FUNCTION (this);
+ for (std::list<std::list<RemPoint> >::iterator it1 = m_rem.begin ();
+ it1 != m_rem.end ();
+ ++it1)
+ {
+ for (std::list<RemPoint>::iterator it2 = it1->begin ();
+ it2 != it1->end ();
+ ++it2)
+ {
+ NS_LOG_LOGIC ("adding phy " << it2->phy);
+ m_channel->AddRx (it2->phy);
+ }
+ }
+}
+
+void
+RadioEnvironmentMapHelper::PrintAndDisconnect ()
+{
+ NS_LOG_FUNCTION (this);
+ std::ofstream outFile;
+ outFile.open (m_outputFile.c_str ());
+ if (!outFile.is_open ())
+ {
+ NS_FATAL_ERROR ("Can't open file " << (m_outputFile));
+ return;
+ }
+
+ for (std::list<std::list<RemPoint> >::iterator it1 = m_rem.begin ();
+ it1 != m_rem.end ();
+ ++it1)
+ {
+ for (std::list<RemPoint>::iterator it2 = it1->begin ();
+ it2 != it1->end ();
+ ++it2)
+ {
+ Vector pos = it2->bmm->GetPosition ();
+ outFile << pos.x << "\t"
+ << pos.y << "\t"
+ << pos.z << "\t"
+ << it2->phy->GetSinr ()
+ << std::endl;
+ m_channel->RemoveRx (it2->phy);
+ }
+ }
+ outFile.close ();
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/helper/radio-environment-map-helper.h Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#ifndef RADIO_ENVIRONMENT_MAP_HELPER_H
+#define RADIO_ENVIRONMENT_MAP_HELPER_H
+
+
+#include <ns3/object.h>
+
+
+
+namespace ns3 {
+
+class RemSpectrumPhy;
+class Node;
+class NetDevice;
+class SpectrumChannel;
+class BuildingsMobilityModel;
+
+/**
+ * Generates a 2D map of the SINR from the strongest transmitter.
+ *
+ */
+class RadioEnvironmentMapHelper : public Object
+{
+public:
+
+ RadioEnvironmentMapHelper ();
+
+ virtual ~RadioEnvironmentMapHelper ();
+
+ // inherited from Object
+ virtual void DoDispose (void);
+ static TypeId GetTypeId (void);
+
+ void Install ();
+
+private:
+
+ void Connect ();
+ void PrintAndDisconnect ();
+
+
+ struct RemPoint
+ {
+ Ptr<RemSpectrumPhy> phy;
+ Ptr<Node> node;
+ Ptr<NetDevice> dev;
+ Ptr<BuildingsMobilityModel> bmm;
+ };
+
+ std::list<std::list<RemPoint> > m_rem;
+
+ double m_xMin;
+ double m_xMax;
+ uint32_t m_xRes;
+
+ double m_yMin;
+ double m_yMax;
+ uint32_t m_yRes;
+
+ double m_z;
+
+ std::string m_channelPath;
+ std::string m_outputFile;
+
+ Ptr<SpectrumChannel> m_channel;
+};
+
+
+}
+
+#endif /* RADIO_ENVIRONMENT_MAP_HELPER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/rem-spectrum-phy.cc Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,159 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#include <ns3/object-factory.h>
+#include <ns3/log.h>
+#include <ns3/double.h>
+#include <ns3/simulator.h>
+#include <ns3/trace-source-accessor.h>
+#include <ns3/antenna-model.h>
+
+#include "rem-spectrum-phy.h"
+
+NS_LOG_COMPONENT_DEFINE ("RemSpectrumPhy");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (RemSpectrumPhy);
+
+RemSpectrumPhy::RemSpectrumPhy ()
+ : m_mobility (0),
+ m_netDevice (0),
+ m_channel (0),
+ m_referenceSignalPower (0),
+ m_sumPower (0)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+
+
+RemSpectrumPhy::~RemSpectrumPhy ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+RemSpectrumPhy::DoDispose ()
+{
+ NS_LOG_FUNCTION (this);
+ m_mobility = 0;
+ m_netDevice = 0;
+ m_channel = 0;
+ SpectrumPhy::DoDispose ();
+}
+
+TypeId
+RemSpectrumPhy::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::RemSpectrumPhy")
+ .SetParent<SpectrumPhy> ()
+ .AddConstructor<RemSpectrumPhy> ()
+ .AddAttribute ("NoisePower",
+ "the power of the measuring instrument noise, in Watts. Default to a kT of -174 dBm with a noise figure of 9 dB and a bandwidth of 25 LTE Resource Blocks",
+ DoubleValue (1.4230e-10),
+ MakeDoubleAccessor (&RemSpectrumPhy::m_noisePower),
+ MakeDoubleChecker<double> ())
+ ;
+ return tid;
+}
+
+
+
+Ptr<NetDevice>
+RemSpectrumPhy::GetDevice ()
+{
+ return m_netDevice;
+}
+
+
+Ptr<MobilityModel>
+RemSpectrumPhy::GetMobility ()
+{
+ return m_mobility;
+}
+
+
+Ptr<const SpectrumModel>
+RemSpectrumPhy::GetRxSpectrumModel () const
+{
+ return m_spectrumModel;
+}
+
+void
+RemSpectrumPhy::SetDevice (Ptr<NetDevice> d)
+{
+ NS_LOG_FUNCTION (this << d);
+ m_netDevice = d;
+}
+
+
+void
+RemSpectrumPhy::SetMobility (Ptr<MobilityModel> m)
+{
+ NS_LOG_FUNCTION (this << m);
+ m_mobility = m;
+}
+
+
+void
+RemSpectrumPhy::SetChannel (Ptr<SpectrumChannel> c)
+{
+ NS_LOG_FUNCTION (this << c);
+ m_channel = c;
+}
+
+void
+RemSpectrumPhy::SetRxSpectrumModel (Ptr<SpectrumModel> m)
+{
+ NS_LOG_FUNCTION (this << m);
+ m_spectrumModel = m;
+}
+
+Ptr<AntennaModel>
+RemSpectrumPhy::GetRxAntenna ()
+{
+ return 0;
+}
+
+
+void
+RemSpectrumPhy::StartRx (Ptr<SpectrumSignalParameters> params)
+{
+ NS_LOG_FUNCTION ( this << params);
+ double power = Integral (*(params->psd));
+ NS_ASSERT_MSG (params->duration.GetMilliSeconds () == 1,
+ "RemSpectrumPhy works only for LTE signals with duration of 1 ms");
+ m_sumPower += power;
+ if (power > m_referenceSignalPower)
+ {
+ m_referenceSignalPower = power;
+ }
+}
+
+double
+RemSpectrumPhy::GetSinr ()
+{
+ return m_referenceSignalPower / (m_sumPower + m_noisePower);
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/rem-spectrum-phy.h Mon Jan 16 20:32:45 2012 +0100
@@ -0,0 +1,105 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef REM_SPECTRUM_PHY_H
+#define REM_SPECTRUM_PHY_H
+
+
+#include <ns3/spectrum-value.h>
+#include <ns3/mobility-model.h>
+#include <ns3/packet.h>
+#include <ns3/nstime.h>
+#include <ns3/net-device.h>
+#include <ns3/spectrum-phy.h>
+#include <ns3/spectrum-channel.h>
+#include <string>
+#include <fstream>
+
+namespace ns3 {
+
+
+/**
+ *
+ * This minimal SpectrumPhy implemetation calculates the SINR with
+ * respect to the strongest signal for a given point. The original
+ * purpose of this class is to be used to generate a
+ * Radio Environment Map (REM) by locating several instances in a grid
+ * fashion, and connecting them to the channel only for a very short
+ * amount of time.
+ *
+ * The assumption on which this class works is that the system
+ * being considered is an infrastructured radio access network using
+ * FDD, hence all signals will be transmitted simultaneously.
+ */
+class RemSpectrumPhy : public SpectrumPhy
+{
+
+public:
+ RemSpectrumPhy ();
+ virtual ~RemSpectrumPhy ();
+
+ static TypeId GetTypeId (void);
+
+// inherited from SpectrumPhy
+ void SetChannel (Ptr<SpectrumChannel> c);
+ void SetMobility (Ptr<MobilityModel> m);
+ void SetDevice (Ptr<NetDevice> d);
+ Ptr<MobilityModel> GetMobility ();
+ Ptr<NetDevice> GetDevice ();
+ Ptr<const SpectrumModel> GetRxSpectrumModel () const;
+ Ptr<AntennaModel> GetRxAntenna ();
+ void StartRx (Ptr<SpectrumSignalParameters> params);
+
+ void SetRxSpectrumModel (Ptr<SpectrumModel>);
+
+ /**
+ *
+ *
+ * \return the Signal to Noise Ratio calculated
+ */
+ double GetSinr ();
+
+protected:
+ void DoDispose ();
+
+private:
+ Ptr<MobilityModel> m_mobility;
+ Ptr<NetDevice> m_netDevice;
+ Ptr<SpectrumChannel> m_channel;
+ Ptr<SpectrumModel> m_spectrumModel;
+
+ double m_referenceSignalPower;
+ double m_sumPower;
+ double m_noisePower;
+
+};
+
+
+
+
+
+
+}
+
+
+
+
+
+#endif /* REM_SPECTRUM_PHY_H */
--- a/src/lte/wscript Mon Jan 16 14:25:21 2012 +0100
+++ b/src/lte/wscript Mon Jan 16 20:32:45 2012 +0100
@@ -38,6 +38,8 @@
'helper/epc-helper.cc',
'helper/radio-bearer-stats-calculator.cc',
'helper/mac-stats-calculator.cc',
+ 'helper/radio-environment-map-helper.cc',
+ 'model/rem-spectrum-phy.cc',
'model/ff-mac-csched-sap.cc',
'model/ff-mac-sched-sap.cc',
'model/lte-mac-sap.cc',
@@ -127,6 +129,8 @@
'helper/epc-helper.h',
'helper/mac-stats-calculator.h',
'helper/radio-bearer-stats-calculator.h',
+ 'helper/radio-environment-map-helper.h',
+ 'model/rem-spectrum-phy.h',
'model/ff-mac-common.h',
'model/ff-mac-csched-sap.h',
'model/ff-mac-sched-sap.h',
--- a/src/spectrum/model/multi-model-spectrum-channel.cc Mon Jan 16 14:25:21 2012 +0100
+++ b/src/spectrum/model/multi-model-spectrum-channel.cc Mon Jan 16 20:32:45 2012 +0100
@@ -181,6 +181,43 @@
}
+void
+MultiModelSpectrumChannel::RemoveRx (Ptr<SpectrumPhy> phy)
+{
+ NS_LOG_FUNCTION (this << phy);
+
+ bool found = false;
+ for (std::vector<Ptr<SpectrumPhy> >::iterator it = m_phyVector.begin (); it != m_phyVector.end (); ++it)
+ {
+ if (*it == phy)
+ {
+ m_phyVector.erase (it);
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ NS_LOG_WARN ("phy instance " << phy << " not found");
+ }
+ else
+ {
+
+ Ptr<const SpectrumModel> rxSpectrumModel = phy->GetRxSpectrumModel ();
+
+ NS_ASSERT_MSG ((0 != rxSpectrumModel), "phy->GetRxSpectrumModel () returned 0. Please check that the RxSpectrumModel is already set for the phy before calling MultiModelSpectrumChannel::AddRx (phy)");
+
+ SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid ();
+ RxSpectrumModelInfoMap_t::iterator rxInfoIterator = m_rxSpectrumModelInfoMap.find (rxSpectrumModelUid);
+ NS_ASSERT (rxInfoIterator != m_rxSpectrumModelInfoMap.end ());
+ rxInfoIterator->second.m_rxPhyList.remove (phy);
+ if (rxInfoIterator->second.m_rxPhyList.empty ())
+ {
+ // no more PHY instances with this spectrum model, so we can remove the converter
+ m_rxSpectrumModelInfoMap.erase (rxInfoIterator);
+ }
+ }
+}
TxSpectrumModelInfoMap_t::const_iterator
MultiModelSpectrumChannel::FindAndEventuallyAddTxSpectrumModel (Ptr<const SpectrumModel> txSpectrumModel)
--- a/src/spectrum/model/multi-model-spectrum-channel.h Mon Jan 16 14:25:21 2012 +0100
+++ b/src/spectrum/model/multi-model-spectrum-channel.h Mon Jan 16 20:32:45 2012 +0100
@@ -92,6 +92,7 @@
virtual void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss);
virtual void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay);
virtual void AddRx (Ptr<SpectrumPhy> phy);
+ virtual void RemoveRx (Ptr<SpectrumPhy> phy);
virtual void StartTx (Ptr<SpectrumSignalParameters> params);
--- a/src/spectrum/model/single-model-spectrum-channel.cc Mon Jan 16 14:25:21 2012 +0100
+++ b/src/spectrum/model/single-model-spectrum-channel.cc Mon Jan 16 20:32:45 2012 +0100
@@ -106,6 +106,27 @@
void
+SingleModelSpectrumChannel::RemoveRx (Ptr<SpectrumPhy> phy)
+{
+ NS_LOG_FUNCTION (this << phy);
+ bool found = false;
+ for (std::vector<Ptr<SpectrumPhy> >::iterator it = m_phyList.begin (); it != m_phyList.end (); ++it)
+ {
+ if (*it == phy)
+ {
+ m_phyList.erase (it);
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ NS_LOG_WARN ("phy instance " << phy << " not found");
+ }
+}
+
+
+void
SingleModelSpectrumChannel::StartTx (Ptr<SpectrumSignalParameters> txParams)
{
NS_LOG_FUNCTION (this << txParams->psd << txParams->duration << txParams->txPhy);
--- a/src/spectrum/model/single-model-spectrum-channel.h Mon Jan 16 14:25:21 2012 +0100
+++ b/src/spectrum/model/single-model-spectrum-channel.h Mon Jan 16 20:32:45 2012 +0100
@@ -51,6 +51,7 @@
virtual void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss);
virtual void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay);
virtual void AddRx (Ptr<SpectrumPhy> phy);
+ virtual void RemoveRx (Ptr<SpectrumPhy> phy);
virtual void StartTx (Ptr<SpectrumSignalParameters> params);
--- a/src/spectrum/model/spectrum-channel.h Mon Jan 16 14:25:21 2012 +0100
+++ b/src/spectrum/model/spectrum-channel.h Mon Jan 16 20:32:45 2012 +0100
@@ -79,7 +79,8 @@
virtual void StartTx (Ptr<SpectrumSignalParameters> params) = 0;
/**
- * @brief add a SpectrumPhy to a channel, so it can receive packets
+ * @brief add a SpectrumPhy to a channel, so it can receive signals
+ * transmitted over the channel
*
* This method is used to attach a SpectrumPhy instance to a
* SpectrumChannel instance, so that the SpectrumPhy can receive
@@ -95,6 +96,15 @@
*/
virtual void AddRx (Ptr<SpectrumPhy> phy) = 0;
+ /**
+ * @brief remove a previously added SpectrumPhy from the channel, so
+ * that it will not receive any more signals transmitted on the channel
+ *
+ *
+ * @param phy the SpectrumPhy instance to be removed from the channel
+ */
+ virtual void RemoveRx (Ptr<SpectrumPhy> phy) = 0;
+
};