diff --git a/src/buildings/helper/buildings-helper.cc b/src/buildings/helper/buildings-helper.cc index 5b4bbfe19..9dc7caa84 100644 --- a/src/buildings/helper/buildings-helper.cc +++ b/src/buildings/helper/buildings-helper.cc @@ -41,27 +41,35 @@ BuildingsHelper::MakeMobilityModelConsistent () { Ptr bmm = (*nit)->GetObject (); 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 (); - } + MakeConsistent (bmm); } } + +void +BuildingsHelper::MakeConsistent (Ptr bmm) +{ + bool found = false; + for (BuildingList::Iterator bit = BuildingList::Begin (); bit != BuildingList::End (); ++bit) + { + Vector pos = bmm->GetPosition (); + if ((*bit)->IsInside (pos)) + { + NS_LOG_LOGIC ("BuildingsMobilityModel " << bmm << " falls inside building " << (*bit)->GetId ()); + NS_ABORT_MSG_UNLESS (found == false, " BuildingsMobilityModel 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 ("BuildingsMobilityModel " << bmm << " is outdoor"); + bmm->SetOutdoor (); + } + +} + } // namespace ns3 diff --git a/src/buildings/helper/buildings-helper.h b/src/buildings/helper/buildings-helper.h index 4f639aa1c..3304ed4d9 100644 --- a/src/buildings/helper/buildings-helper.h +++ b/src/buildings/helper/buildings-helper.h @@ -25,15 +25,18 @@ #include #include #include +#include namespace ns3 { +class BuildingsMobilityModel; class BuildingsHelper { public: static void MakeMobilityModelConsistent (); + static void MakeConsistent (Ptr bmm); }; diff --git a/src/lte/doc/source/lte-user.rst b/src/lte/doc/source/lte-user.rst index 209310339..90f0bfda6 100644 --- a/src/lte/doc/source/lte-user.rst +++ b/src/lte/doc/source/lte-user.rst @@ -498,6 +498,21 @@ 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. +Note that the REM generation is very demanding, in particular: + + * the run-time memory consumption is approximately 5KB per pixel. For example, + a REM with a resolution of 500x500 needs about 1.25 GB of memory, and + a resolution of 1000x1000 needs about 5 GB (too much for a + regular PC at the time of this writing). + * if you generate a REM at the beginning of a simulation, it will + slow down the execution of the rest of the simulation. If you want + to generate a REM for a program and also use the same program to + get simulation result, it is recommended to add a command-line + switch that allows to either generate the REM or run the complete + simulation. For this purpose, note that there is an attribute + ``RadioEnvironmentMapHelper::StopWhenDone`` (default: true) that + will force the simulation to stop right after the REM has been generated. + The REM is stored in an ASCII file in the following format: * column 1 is the x coordinate @@ -512,6 +527,7 @@ below:: set xlabel "X" set ylabel "Y" set cblabel "SINR (dB)" + unset key plot "rem.out" using ($1):($2):(10*log10($4)) with image diff --git a/src/lte/examples/lena-rem-sector-antenna.cc b/src/lte/examples/lena-rem-sector-antenna.cc index 35dd5a9f1..8bf890b69 100644 --- a/src/lte/examples/lena-rem-sector-antenna.cc +++ b/src/lte/examples/lena-rem-sector-antenna.cc @@ -174,8 +174,6 @@ main (int argc, char *argv[]) } mobility.Install (ueNodes.at(i)); } - BuildingsHelper::MakeMobilityModelConsistent (); - // Create Devices and install them in the Nodes (eNB and UE) NetDeviceContainer enbDevs; @@ -218,6 +216,9 @@ main (int argc, char *argv[]) lteHelper->ActivateEpsBearer (ueDev, bearer, EpcTft::Default ()); } + + BuildingsHelper::MakeMobilityModelConsistent (); + // by default, simulation will anyway stop right after the REM has been generated Simulator::Stop (Seconds (0.0069)); @@ -231,9 +232,6 @@ main (int argc, char *argv[]) remHelper->SetAttribute ("Z", DoubleValue (1.5)); remHelper->Install (); - - - BuildingsHelper::MakeMobilityModelConsistent (); Simulator::Run (); // GtkConfigStore config; diff --git a/src/lte/helper/radio-environment-map-helper.cc b/src/lte/helper/radio-environment-map-helper.cc index 35fc20b11..a858f3fd6 100644 --- a/src/lte/helper/radio-environment-map-helper.cc +++ b/src/lte/helper/radio-environment-map-helper.cc @@ -33,9 +33,10 @@ #include #include #include +#include #include - +#include NS_LOG_COMPONENT_DEFINE ("RadioEnvironmentMapHelper"); @@ -96,20 +97,24 @@ RadioEnvironmentMapHelper::GetTypeId (void) .AddAttribute ("XRes", "The resolution (number of points) of the map along the x axis.", UintegerValue (100), MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_xRes), - MakeUintegerChecker ()) + MakeUintegerChecker (2,std::numeric_limits::max ())) .AddAttribute ("YRes", "The resolution (number of points) of the map along the y axis.", UintegerValue (100), MakeUintegerAccessor (&RadioEnvironmentMapHelper::m_yRes), - MakeUintegerChecker ()) + MakeUintegerChecker (2,std::numeric_limits::max ())) .AddAttribute ("Z", "The value of the z coordinate for which the map is to be generated", DoubleValue (0.0), MakeDoubleAccessor (&RadioEnvironmentMapHelper::m_z), MakeDoubleChecker ()) - .AddAttribute ("ExitWhenDone", "If true, Simulator::Stop () will be called as soon as the REM has been generated", + .AddAttribute ("StopWhenDone", "If true, Simulator::Stop () will be called as soon as the REM has been generated", BooleanValue (true), - MakeBooleanAccessor (&RadioEnvironmentMapHelper::m_exitWhenDone), + MakeBooleanAccessor (&RadioEnvironmentMapHelper::m_stopWhenDone), MakeBooleanChecker ()) - + .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 (&RadioEnvironmentMapHelper::m_noisePower), + MakeDoubleChecker ()) ; return tid; } @@ -133,22 +138,21 @@ RadioEnvironmentMapHelper::Install () m_channel = match.Get (0)->GetObject (); 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; + double xStep = (m_xMax - m_xMin)/(m_xRes-1); + double yStep = (m_yMax - m_yMin)/(m_yRes-1); - for (double x = m_xMin; x <= m_xMax ; x += xStep) + + for (double x = m_xMin; x < m_xMax + 0.5*xStep; x += xStep) { - m_rem.push_back (std::list ()); - for (double y = m_yMin; y <= m_yMax ; y += yStep) + for (double y = m_yMin; y < m_yMax + 0.5*yStep ; y += yStep) { RemPoint p; p.phy = CreateObject (); p.bmm = CreateObject (); - p.node = CreateObject (); - p.node->AggregateObject (p.bmm); p.phy->SetMobility (p.bmm); p.bmm->SetPosition (Vector (x, y, m_z)); - m_rem.back ().push_back (p); + BuildingsHelper::MakeConsistent (p.bmm); + m_rem.push_back (p); } } Simulator::Schedule (Seconds (0.0055), &RadioEnvironmentMapHelper::Connect, this); @@ -160,18 +164,13 @@ void RadioEnvironmentMapHelper::Connect () { NS_LOG_FUNCTION (this); - for (std::list >::iterator it1 = m_rem.begin (); - it1 != m_rem.end (); - ++it1) + for (std::list::iterator it = m_rem.begin (); + it != m_rem.end (); + ++it) { - for (std::list::iterator it2 = it1->begin (); - it2 != it1->end (); - ++it2) - { - NS_LOG_LOGIC ("adding phy " << it2->phy); - m_channel->AddRx (it2->phy); - } - } + NS_LOG_LOGIC ("adding phy " << it->phy); + m_channel->AddRx (it->phy); + } } void @@ -186,25 +185,20 @@ RadioEnvironmentMapHelper::PrintAndDeactivate () return; } - for (std::list >::iterator it1 = m_rem.begin (); - it1 != m_rem.end (); - ++it1) + for (std::list::iterator it = m_rem.begin (); + it != m_rem.end (); + ++it) { - for (std::list::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; - it2->phy->Deactivate (); - } + Vector pos = it->bmm->GetPosition (); + outFile << pos.x << "\t" + << pos.y << "\t" + << pos.z << "\t" + << it->phy->GetSinr (m_noisePower) + << std::endl; + it->phy->Deactivate (); } outFile.close (); - if (m_exitWhenDone) + if (m_stopWhenDone) { Simulator::Stop (); } diff --git a/src/lte/helper/radio-environment-map-helper.h b/src/lte/helper/radio-environment-map-helper.h index 27ca17906..66e2f35e6 100644 --- a/src/lte/helper/radio-environment-map-helper.h +++ b/src/lte/helper/radio-environment-map-helper.h @@ -62,29 +62,29 @@ private: struct RemPoint { Ptr phy; - Ptr node; - Ptr dev; Ptr bmm; }; - std::list > m_rem; + std::list m_rem; double m_xMin; double m_xMax; - uint32_t m_xRes; + uint16_t m_xRes; double m_yMin; double m_yMax; - uint32_t m_yRes; + uint16_t m_yRes; double m_z; std::string m_channelPath; std::string m_outputFile; - bool m_exitWhenDone; + bool m_stopWhenDone; Ptr m_channel; + + double m_noisePower; }; diff --git a/src/lte/model/rem-spectrum-phy.cc b/src/lte/model/rem-spectrum-phy.cc index bff9696ed..fd34d4e70 100644 --- a/src/lte/model/rem-spectrum-phy.cc +++ b/src/lte/model/rem-spectrum-phy.cc @@ -35,9 +35,7 @@ namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (RemSpectrumPhy); RemSpectrumPhy::RemSpectrumPhy () - : m_mobility (0), - m_netDevice (0), - m_channel (0), + : m_mobility (0), m_referenceSignalPower (0), m_sumPower (0), m_active (true) @@ -57,8 +55,6 @@ RemSpectrumPhy::DoDispose () { NS_LOG_FUNCTION (this); m_mobility = 0; - m_netDevice = 0; - m_channel = 0; SpectrumPhy::DoDispose (); } @@ -68,45 +64,18 @@ RemSpectrumPhy::GetTypeId (void) static TypeId tid = TypeId ("ns3::RemSpectrumPhy") .SetParent () .AddConstructor () - .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 ()) ; return tid; } -Ptr -RemSpectrumPhy::GetDevice () -{ - return m_netDevice; -} - - -Ptr -RemSpectrumPhy::GetMobility () -{ - return m_mobility; -} - - -Ptr -RemSpectrumPhy::GetRxSpectrumModel () const -{ - return m_spectrumModel; -} - void -RemSpectrumPhy::SetDevice (Ptr d) +RemSpectrumPhy::SetChannel (Ptr c) { - NS_LOG_FUNCTION (this << d); - m_netDevice = d; + // this is a no-op, RemSpectrumPhy does not transmit hence it does not need a reference to the channel } - void RemSpectrumPhy::SetMobility (Ptr m) { @@ -114,19 +83,30 @@ RemSpectrumPhy::SetMobility (Ptr m) m_mobility = m; } - void -RemSpectrumPhy::SetChannel (Ptr c) +RemSpectrumPhy::SetDevice (Ptr d) { - NS_LOG_FUNCTION (this << c); - m_channel = c; + NS_LOG_FUNCTION (this << d); + // this is a no-op, RemSpectrumPhy does not handle any data hence it does not support the use of a NetDevice } -void -RemSpectrumPhy::SetRxSpectrumModel (Ptr m) +Ptr +RemSpectrumPhy::GetMobility () { - NS_LOG_FUNCTION (this << m); - m_spectrumModel = m; + return m_mobility; +} + +Ptr +RemSpectrumPhy::GetDevice () +{ + return 0; +} + +Ptr +RemSpectrumPhy::GetRxSpectrumModel () const +{ + // supports any SpectrumModel + return 0; } Ptr @@ -154,9 +134,9 @@ RemSpectrumPhy::StartRx (Ptr params) } double -RemSpectrumPhy::GetSinr () +RemSpectrumPhy::GetSinr (double noisePower) { - return m_referenceSignalPower / (m_sumPower + m_noisePower); + return m_referenceSignalPower / (m_sumPower + noisePower); } void diff --git a/src/lte/model/rem-spectrum-phy.h b/src/lte/model/rem-spectrum-phy.h index 0230220a3..a22ba7336 100644 --- a/src/lte/model/rem-spectrum-phy.h +++ b/src/lte/model/rem-spectrum-phy.h @@ -55,9 +55,11 @@ public: RemSpectrumPhy (); virtual ~RemSpectrumPhy (); + // inherited from Object + void DoDispose (); static TypeId GetTypeId (void); -// inherited from SpectrumPhy + // inherited from SpectrumPhy void SetChannel (Ptr c); void SetMobility (Ptr m); void SetDevice (Ptr d); @@ -67,19 +69,12 @@ public: Ptr GetRxAntenna (); void StartRx (Ptr params); - - /** - * set the SpectrumModel to be used for reception - * - */ - void SetRxSpectrumModel (Ptr); - /** * * * \return the Signal to Noise Ratio calculated */ - double GetSinr (); + double GetSinr (double noisePower); /** * make StartRx a no-op from now on @@ -87,18 +82,12 @@ public: */ void Deactivate (); -protected: - void DoDispose (); private: Ptr m_mobility; - Ptr m_netDevice; - Ptr m_channel; - Ptr m_spectrumModel; double m_referenceSignalPower; double m_sumPower; - double m_noisePower; bool m_active;