--- a/doc/tutorial-pt-br/source/tracing.rst Tue May 22 16:40:24 2012 +0200
+++ b/doc/tutorial-pt-br/source/tracing.rst Tue May 22 16:41:05 2012 +0200
@@ -2996,10 +2996,10 @@
Mas os objetos internos são inteiramente diferentes. Por exemplo, o Ptr<PcapFileWrapper> é um ponteiro para um objeto |ns3| que suporta ``Attributes`` e é integrado dentro do sistema de configuração. O Ptr<OutputStreamWrapper>, por outro lado, é um ponteiro para uma referência para um simples objeto contado. Lembre-se sempre de analisar o objeto que você está referenciando antes de fazer suposições sobre os "poderes" que o objeto pode ter.
..
- For example, take a look at ``src/network/model/pcap-file-object.h`` in the
+ For example, take a look at ``src/network/utils/pcap-file-wrapper.h`` in the
distribution and notice,
-Por exemplo, acesse o arquivo ``src/network/model/pcap-file-object.h`` e observe,
+Por exemplo, acesse o arquivo ``src/network/utils/pcap-file-wrapper.h`` e observe,
::
@@ -3562,10 +3562,10 @@
uint32_t deviceid);
..
- You are encouraged to peruse the Doxygen for class ``TraceHelperForDevice``
+ You are encouraged to peruse the Doxygen for class ``AsciiTraceHelperForDevice``
to find the details of these methods; but to summarize ...
-Para maiores detalhes sobre os métodos é interessante consultar a documentação para a classe ``TraceHelperForDevice``; mas para resumir ...
+Para maiores detalhes sobre os métodos é interessante consultar a documentação para a classe ``AsciiTraceHelperForDevice``; mas para resumir ...
..
There are twice as many methods available for ascii tracing as there were for
--- a/doc/tutorial/source/tracing.rst Tue May 22 16:40:24 2012 +0200
+++ b/doc/tutorial/source/tracing.rst Tue May 22 16:41:05 2012 +0200
@@ -2168,7 +2168,7 @@
Remember to always look at the object you are referencing before making any
assumptions about the "powers" that object may have.
-For example, take a look at ``src/network/model/pcap-file-object.h`` in the
+For example, take a look at ``src/network/utils/pcap-file-wrapper.h`` in the
distribution and notice,
::
@@ -2566,7 +2566,7 @@
void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename);
void EnableAscii (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid);
-You are encouraged to peruse the Doxygen for class ``TraceHelperForDevice``
+You are encouraged to peruse the Doxygen for class ``AsciiTraceHelperForDevice``
to find the details of these methods; but to summarize ...
There are twice as many methods available for ascii tracing as there were for
--- a/src/buildings/bindings/modulegen__gcc_ILP32.py Tue May 22 16:40:24 2012 +0200
+++ b/src/buildings/bindings/modulegen__gcc_ILP32.py Tue May 22 16:41:05 2012 +0200
@@ -3989,14 +3989,6 @@
cls.add_method('IsOutdoor',
'bool',
[])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetFloorNumber(uint8_t nfloor) [member function]
- cls.add_method('SetFloorNumber',
- 'void',
- [param('uint8_t', 'nfloor')])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetIndoor(ns3::Ptr<ns3::Building> building) [member function]
- cls.add_method('SetIndoor',
- 'void',
- [param('ns3::Ptr< ns3::Building >', 'building')])
## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetIndoor(ns3::Ptr<ns3::Building> building, uint8_t nfloor, uint8_t nroomx, uint8_t nroomy) [member function]
cls.add_method('SetIndoor',
'void',
@@ -4005,14 +3997,6 @@
cls.add_method('SetOutdoor',
'void',
[])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetRoomNumberX(uint8_t nroomx) [member function]
- cls.add_method('SetRoomNumberX',
- 'void',
- [param('uint8_t', 'nroomx')])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetRoomNumberY(uint8_t nroomy) [member function]
- cls.add_method('SetRoomNumberY',
- 'void',
- [param('uint8_t', 'nroomy')])
## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::DoDispose() [member function]
cls.add_method('DoDispose',
'void',
--- a/src/buildings/bindings/modulegen__gcc_LP64.py Tue May 22 16:40:24 2012 +0200
+++ b/src/buildings/bindings/modulegen__gcc_LP64.py Tue May 22 16:41:05 2012 +0200
@@ -3989,14 +3989,6 @@
cls.add_method('IsOutdoor',
'bool',
[])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetFloorNumber(uint8_t nfloor) [member function]
- cls.add_method('SetFloorNumber',
- 'void',
- [param('uint8_t', 'nfloor')])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetIndoor(ns3::Ptr<ns3::Building> building) [member function]
- cls.add_method('SetIndoor',
- 'void',
- [param('ns3::Ptr< ns3::Building >', 'building')])
## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetIndoor(ns3::Ptr<ns3::Building> building, uint8_t nfloor, uint8_t nroomx, uint8_t nroomy) [member function]
cls.add_method('SetIndoor',
'void',
@@ -4005,14 +3997,6 @@
cls.add_method('SetOutdoor',
'void',
[])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetRoomNumberX(uint8_t nroomx) [member function]
- cls.add_method('SetRoomNumberX',
- 'void',
- [param('uint8_t', 'nroomx')])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetRoomNumberY(uint8_t nroomy) [member function]
- cls.add_method('SetRoomNumberY',
- 'void',
- [param('uint8_t', 'nroomy')])
## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::DoDispose() [member function]
cls.add_method('DoDispose',
'void',
--- a/src/dsr/bindings/modulegen__gcc_ILP32.py Tue May 22 16:40:24 2012 +0200
+++ b/src/dsr/bindings/modulegen__gcc_ILP32.py Tue May 22 16:41:05 2012 +0200
@@ -10281,6 +10281,8 @@
cls.add_constructor([param('ns3::dsr::RouteCache::Neighbor const &', 'arg0')])
## dsr-rcache.h (module 'dsr'): ns3::dsr::RouteCache::Neighbor::Neighbor(ns3::Ipv4Address ip, ns3::Mac48Address mac, ns3::Time t) [constructor]
cls.add_constructor([param('ns3::Ipv4Address', 'ip'), param('ns3::Mac48Address', 'mac'), param('ns3::Time', 't')])
+ ## dsr-rcache.h (module 'dsr'): ns3::dsr::RouteCache::Neighbor::Neighbor() [constructor]
+ cls.add_constructor([])
## dsr-rcache.h (module 'dsr'): ns3::dsr::RouteCache::Neighbor::close [variable]
cls.add_instance_attribute('close', 'bool', is_const=False)
## dsr-rcache.h (module 'dsr'): ns3::dsr::RouteCache::Neighbor::m_expireTime [variable]
--- a/src/dsr/bindings/modulegen__gcc_LP64.py Tue May 22 16:40:24 2012 +0200
+++ b/src/dsr/bindings/modulegen__gcc_LP64.py Tue May 22 16:41:05 2012 +0200
@@ -10281,6 +10281,8 @@
cls.add_constructor([param('ns3::dsr::RouteCache::Neighbor const &', 'arg0')])
## dsr-rcache.h (module 'dsr'): ns3::dsr::RouteCache::Neighbor::Neighbor(ns3::Ipv4Address ip, ns3::Mac48Address mac, ns3::Time t) [constructor]
cls.add_constructor([param('ns3::Ipv4Address', 'ip'), param('ns3::Mac48Address', 'mac'), param('ns3::Time', 't')])
+ ## dsr-rcache.h (module 'dsr'): ns3::dsr::RouteCache::Neighbor::Neighbor() [constructor]
+ cls.add_constructor([])
## dsr-rcache.h (module 'dsr'): ns3::dsr::RouteCache::Neighbor::close [variable]
cls.add_instance_attribute('close', 'bool', is_const=False)
## dsr-rcache.h (module 'dsr'): ns3::dsr::RouteCache::Neighbor::m_expireTime [variable]
--- a/src/dsr/model/dsr-rcache.h Tue May 22 16:40:24 2012 +0200
+++ b/src/dsr/model/dsr-rcache.h Tue May 22 16:41:05 2012 +0200
@@ -493,6 +493,8 @@
close (false)
{
}
+
+ Neighbor () {} // For Python bindings
};
// / Return expire time for neighbor node with address addr, if exists, else return 0.
Time GetExpireTime (Ipv4Address addr);
--- a/src/dsr/model/dsr-routing.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/dsr/model/dsr-routing.cc Tue May 22 16:41:05 2012 +0200
@@ -1527,7 +1527,7 @@
}
else
{
- uint32_t totalQueueSize;
+ uint32_t totalQueueSize = 0;
for (std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator j = m_priorityQueue.begin (); j != m_priorityQueue.end (); j++)
{
NS_LOG_DEBUG ("The size of the network queue for " << j->first << " is " << j->second->GetSize ());
--- a/src/lte/bindings/modulegen__gcc_ILP32.py Tue May 22 16:40:24 2012 +0200
+++ b/src/lte/bindings/modulegen__gcc_ILP32.py Tue May 22 16:41:05 2012 +0200
@@ -12574,14 +12574,6 @@
cls.add_method('IsOutdoor',
'bool',
[])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetFloorNumber(uint8_t nfloor) [member function]
- cls.add_method('SetFloorNumber',
- 'void',
- [param('uint8_t', 'nfloor')])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetIndoor(ns3::Ptr<ns3::Building> building) [member function]
- cls.add_method('SetIndoor',
- 'void',
- [param('ns3::Ptr< ns3::Building >', 'building')])
## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetIndoor(ns3::Ptr<ns3::Building> building, uint8_t nfloor, uint8_t nroomx, uint8_t nroomy) [member function]
cls.add_method('SetIndoor',
'void',
@@ -12590,14 +12582,6 @@
cls.add_method('SetOutdoor',
'void',
[])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetRoomNumberX(uint8_t nroomx) [member function]
- cls.add_method('SetRoomNumberX',
- 'void',
- [param('uint8_t', 'nroomx')])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetRoomNumberY(uint8_t nroomy) [member function]
- cls.add_method('SetRoomNumberY',
- 'void',
- [param('uint8_t', 'nroomy')])
## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::DoDispose() [member function]
cls.add_method('DoDispose',
'void',
--- a/src/lte/bindings/modulegen__gcc_LP64.py Tue May 22 16:40:24 2012 +0200
+++ b/src/lte/bindings/modulegen__gcc_LP64.py Tue May 22 16:41:05 2012 +0200
@@ -12574,14 +12574,6 @@
cls.add_method('IsOutdoor',
'bool',
[])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetFloorNumber(uint8_t nfloor) [member function]
- cls.add_method('SetFloorNumber',
- 'void',
- [param('uint8_t', 'nfloor')])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetIndoor(ns3::Ptr<ns3::Building> building) [member function]
- cls.add_method('SetIndoor',
- 'void',
- [param('ns3::Ptr< ns3::Building >', 'building')])
## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetIndoor(ns3::Ptr<ns3::Building> building, uint8_t nfloor, uint8_t nroomx, uint8_t nroomy) [member function]
cls.add_method('SetIndoor',
'void',
@@ -12590,14 +12582,6 @@
cls.add_method('SetOutdoor',
'void',
[])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetRoomNumberX(uint8_t nroomx) [member function]
- cls.add_method('SetRoomNumberX',
- 'void',
- [param('uint8_t', 'nroomx')])
- ## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::SetRoomNumberY(uint8_t nroomy) [member function]
- cls.add_method('SetRoomNumberY',
- 'void',
- [param('uint8_t', 'nroomy')])
## buildings-mobility-model.h (module 'buildings'): void ns3::BuildingsMobilityModel::DoDispose() [member function]
cls.add_method('DoDispose',
'void',
--- a/src/lte/examples/lena-dual-stripe.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/lte/examples/lena-dual-stripe.cc Tue May 22 16:41:05 2012 +0200
@@ -154,11 +154,66 @@
outFile << "set object " << index
<< " rect from " << box.xMin << "," << box.yMin
<< " to " << box.xMax << "," << box.yMax
- << " front"
+ << " front fs empty "
<< std::endl;
}
}
+void
+PrintGnuplottableUeListToFile (std::string filename)
+{
+ std::ofstream outFile;
+ outFile.open (filename.c_str ());
+ if (!outFile.is_open ())
+ {
+ NS_LOG_ERROR ("Can't open file " << filename);
+ return;
+ }
+ for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
+ {
+ Ptr<Node> node = *it;
+ int nDevs = node->GetNDevices ();
+ for (int j = 0; j < nDevs; j++)
+ {
+ Ptr<LteUeNetDevice> uedev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
+ if (uedev)
+ {
+ Vector pos = node->GetObject<MobilityModel> ()->GetPosition ();
+ outFile << "set label \"" << uedev->GetImsi ()
+ << "\" at "<< pos.x << "," << pos.y << " left font \"Helvetica,4\" textcolor rgb \"grey\" front point pt 1 ps 0.3 lc rgb \"grey\" offset 0,0"
+ << std::endl;
+ }
+ }
+ }
+}
+
+void
+PrintGnuplottableEnbListToFile (std::string filename)
+{
+ std::ofstream outFile;
+ outFile.open (filename.c_str ());
+ if (!outFile.is_open ())
+ {
+ NS_LOG_ERROR ("Can't open file " << filename);
+ return;
+ }
+ for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
+ {
+ Ptr<Node> node = *it;
+ int nDevs = node->GetNDevices ();
+ for (int j = 0; j < nDevs; j++)
+ {
+ Ptr<LteEnbNetDevice> enbdev = node->GetDevice (j)->GetObject <LteEnbNetDevice> ();
+ if (enbdev)
+ {
+ Vector pos = node->GetObject<MobilityModel> ()->GetPosition ();
+ outFile << "set label \"" << enbdev->GetCellId ()
+ << "\" at "<< pos.x << "," << pos.y << " left font \"Helvetica,4\" textcolor rgb \"white\" front point pt 2 ps 0.3 lc rgb \"white\" offset 0,0"
+ << std::endl;
+ }
+ }
+ }
+}
int
main (int argc, char *argv[])
@@ -193,7 +248,6 @@
bool epcUl = true;
bool useUdp = true;
bool generateRem = false;
- bool printBuildingList = false;
CommandLine cmd;
cmd.AddValue ("nBlocks", "Number of femtocell blocks", nBlocks);
@@ -222,8 +276,6 @@
cmd.AddValue ("simTime", "Total duration of the simulation [s]", simTime);
cmd.AddValue ("generateRem", "if true, will generate a REM and then abort the simulation;"
"if false, will run the simulation normally (without generating any REM)", generateRem);
- cmd.AddValue ("printBuildingList", "if true, will save a list of buildings with their positions to file;"
- "if false, will run the simulation normally (without generating any REM)", printBuildingList);
cmd.AddValue ("epc", "if true, will setup the EPC to simulate an end-to-end topology;"
"if false, only the LTE radio access will be simulated.", epc);
cmd.AddValue ("epcDl", "if true, will activate data flows in the downlink when EPC is being used. "
@@ -244,22 +296,32 @@
cmd.Parse (argc, argv);
- uint32_t currentSite = nMacroEnbSites -1;
- uint32_t biRowIndex = (currentSite / (nMacroEnbSitesX + nMacroEnbSitesX + 1));
- uint32_t biRowRemainder = currentSite % (nMacroEnbSitesX + nMacroEnbSitesX + 1);
- uint32_t rowIndex = biRowIndex*2 + 1;
- if (biRowRemainder >= nMacroEnbSitesX)
+ Box macroUeBox;
+
+ if (nMacroEnbSites > 0)
{
- ++rowIndex;
+ uint32_t currentSite = nMacroEnbSites -1;
+ uint32_t biRowIndex = (currentSite / (nMacroEnbSitesX + nMacroEnbSitesX + 1));
+ uint32_t biRowRemainder = currentSite % (nMacroEnbSitesX + nMacroEnbSitesX + 1);
+ uint32_t rowIndex = biRowIndex*2 + 1;
+ if (biRowRemainder >= nMacroEnbSitesX)
+ {
+ ++rowIndex;
+ }
+ uint32_t nMacroEnbSitesY = rowIndex;
+ NS_LOG_LOGIC ("nMacroEnbSitesY = " << nMacroEnbSitesY);
+
+ macroUeBox = Box (-areaMarginFactor*interSiteDistance,
+ (nMacroEnbSitesX + areaMarginFactor)*interSiteDistance,
+ -areaMarginFactor*interSiteDistance,
+ (nMacroEnbSitesY -1)*interSiteDistance*sqrt(0.75) + areaMarginFactor*interSiteDistance,
+ 1.0, 2.0);
}
- uint32_t nMacroEnbSitesY = rowIndex;
- NS_LOG_LOGIC ("nMacroEnbSitesY = " << nMacroEnbSitesY);
-
- Box macroUeBox (-areaMarginFactor*interSiteDistance,
- (nMacroEnbSitesX + areaMarginFactor)*interSiteDistance,
- -areaMarginFactor*interSiteDistance,
- (nMacroEnbSitesY -1)*interSiteDistance*sqrt(0.75) + areaMarginFactor*interSiteDistance,
- 1.0, 2.0);
+ else
+ {
+ // still need the box to place femtocell blocks
+ macroUeBox = Box (0, 150, 0, 150, 1.0, 2.0);
+ }
FemtocellBlockAllocator blockAllocator (macroUeBox, nApartmentsX, nFloors);
blockAllocator.Create (nBlocks);
@@ -353,7 +415,17 @@
mobility.SetPositionAllocator (positionAlloc);
mobility.Install (homeUes);
NetDeviceContainer homeUeDevs = lteHelper->InstallUeDevice (homeUes);
- lteHelper->AttachToClosestEnb (homeUeDevs, homeEnbDevs);
+
+ NetDeviceContainer::Iterator ueDevIt;
+ NetDeviceContainer::Iterator enbDevIt;
+ // attach explicitly each home UE to its home eNB
+ for (ueDevIt = homeUeDevs.Begin (),
+ enbDevIt = homeEnbDevs.Begin ();
+ ueDevIt != homeUeDevs.End () && enbDevIt != homeEnbDevs.End ();
+ ++ueDevIt, ++enbDevIt)
+ {
+ lteHelper->Attach (*ueDevIt, *enbDevIt);
+ }
if (epc)
@@ -478,6 +550,10 @@
Ptr<RadioEnvironmentMapHelper> remHelper;
if (generateRem)
{
+ PrintGnuplottableBuildingListToFile ("buildings.txt");
+ PrintGnuplottableEnbListToFile ("enbs.txt");
+ PrintGnuplottableUeListToFile ("ues.txt");
+
remHelper = CreateObject<RadioEnvironmentMapHelper> ();
remHelper->SetAttribute ("ChannelPath", StringValue ("/ChannelList/0"));
remHelper->SetAttribute ("OutputFile", StringValue ("lena-dual-stripe.rem"));
@@ -488,6 +564,8 @@
remHelper->SetAttribute ("Z", DoubleValue (1.5));
remHelper->Install ();
// simulation will stop right after the REM has been generated
+
+
}
else
{
@@ -501,11 +579,6 @@
lteHelper->EnablePdcpTraces ();
}
- if (printBuildingList)
- {
- PrintGnuplottableBuildingListToFile ("buildings.txt");
- }
-
Simulator::Run ();
//GtkConfigStore config;
--- a/src/lte/examples/lena-rem-sector-antenna.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/lte/examples/lena-rem-sector-antenna.cc Tue May 22 16:41:05 2012 +0200
@@ -164,12 +164,12 @@
vector < NetDeviceContainer > ueDevs;
// power setting in dBm for small cells
- Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (10.0));
+ Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (20.0));
enbDevs = lteHelper->InstallEnbDevice (oneSectorNodes);
// power setting for three-sector macrocell
- Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (30.0));
+ Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (43.0));
// Beam width is made quite narrow so sectors can be noticed in the REM
lteHelper->SetEnbAntennaModelType ("ns3::CosineAntennaModel");
--- a/src/lte/test/lte-test-phy-error-model.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/lte/test/lte-test-phy-error-model.cc Tue May 22 16:41:05 2012 +0200
@@ -46,6 +46,7 @@
#include <ns3/config.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
+#include <ns3/unused.h>
NS_LOG_COMPONENT_DEFINE ("LenaTestPhyErrorModel");
@@ -242,7 +243,10 @@
int lambda = (double)dlDataRxed.at (i) / m_tbSize;
double ber = 1.0 - ((double)dlDataRxed.at (i)/txed);
double np = n-n*m_berRef;
- NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " txed " << txed << " BER " << ber << " Err " << fabs (m_berRef - ber) << " lambda " << lambda << " np " << np << " difference " << abs(lambda - np) << " quantile " << m_bernQuantile);
+ NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " txed " << txed
+ << " BER " << ber << " Err " << fabs (m_berRef - ber) << " lambda " << lambda
+ << " np " << np << " difference " << abs(lambda - np) << " quantile " << m_bernQuantile);
+ NS_UNUSED (ber);
// the quantiles are evaluated offline according to a Bernoulli
// ditribution with n equal to the number of packet sent and p equal
// to the BER (see /reference/bernuolliDistribution.m for details)
--- a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc Tue May 22 16:41:05 2012 +0200
@@ -316,9 +316,8 @@
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
- double txed = rlcStats->GetUlTxData (imsi, lcId);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
- NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes txed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl << " txed " << txed / simulationTime);
+ NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes txed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl << " txed " << rlcStats->GetUlTxData (imsi, lcId) / simulationTime);
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
--- a/src/lte/test/test-epc-tft-classifier.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/lte/test/test-epc-tft-classifier.cc Tue May 22 16:41:05 2012 +0200
@@ -114,7 +114,7 @@
<< ", da = " << da
<< ", sp = " << sp
<< ", dp = " << dp
- << ", tos = 0x" << std::hex << tos
+ << ", tos = 0x" << std::hex << (int) tos
<< " --> tftId = " << tftId;
return oss.str ();
}
--- a/src/netanim/bindings/modulegen__gcc_ILP32.py Tue May 22 16:40:24 2012 +0200
+++ b/src/netanim/bindings/modulegen__gcc_ILP32.py Tue May 22 16:41:05 2012 +0200
@@ -516,14 +516,18 @@
cls.add_constructor([param('ns3::AnimationInterface const &', 'arg0')])
## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface() [constructor]
cls.add_constructor([])
- ## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(std::string const filename, bool usingXML=true) [constructor]
- cls.add_constructor([param('std::string const', 'filename'), param('bool', 'usingXML', default_value='true')])
+ ## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(std::string const filename, uint64_t maxPktsPerFile=100000, bool usingXML=true) [constructor]
+ cls.add_constructor([param('std::string const', 'filename'), param('uint64_t', 'maxPktsPerFile', default_value='100000'), param('bool', 'usingXML', default_value='true')])
## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(uint16_t port, bool usingXML=true) [constructor]
cls.add_constructor([param('uint16_t', 'port'), param('bool', 'usingXML', default_value='true')])
## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::EnablePacketMetadata(bool enable) [member function]
cls.add_method('EnablePacketMetadata',
'void',
[param('bool', 'enable')])
+ ## animation-interface.h (module 'netanim'): uint64_t ns3::AnimationInterface::GetTracePktCount() [member function]
+ cls.add_method('GetTracePktCount',
+ 'uint64_t',
+ [])
## animation-interface.h (module 'netanim'): static bool ns3::AnimationInterface::IsInitialized() [member function]
cls.add_method('IsInitialized',
'bool',
@@ -588,10 +592,10 @@
cls.add_method('ShowAll802_11',
'void',
[param('bool', 'showAll')])
- ## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::StartAnimation() [member function]
+ ## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::StartAnimation(bool restart=false) [member function]
cls.add_method('StartAnimation',
'void',
- [])
+ [param('bool', 'restart', default_value='false')])
## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::StopAnimation() [member function]
cls.add_method('StopAnimation',
'void',
--- a/src/netanim/bindings/modulegen__gcc_LP64.py Tue May 22 16:40:24 2012 +0200
+++ b/src/netanim/bindings/modulegen__gcc_LP64.py Tue May 22 16:41:05 2012 +0200
@@ -516,14 +516,18 @@
cls.add_constructor([param('ns3::AnimationInterface const &', 'arg0')])
## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface() [constructor]
cls.add_constructor([])
- ## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(std::string const filename, bool usingXML=true) [constructor]
- cls.add_constructor([param('std::string const', 'filename'), param('bool', 'usingXML', default_value='true')])
+ ## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(std::string const filename, uint64_t maxPktsPerFile=100000, bool usingXML=true) [constructor]
+ cls.add_constructor([param('std::string const', 'filename'), param('uint64_t', 'maxPktsPerFile', default_value='100000'), param('bool', 'usingXML', default_value='true')])
## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(uint16_t port, bool usingXML=true) [constructor]
cls.add_constructor([param('uint16_t', 'port'), param('bool', 'usingXML', default_value='true')])
## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::EnablePacketMetadata(bool enable) [member function]
cls.add_method('EnablePacketMetadata',
'void',
[param('bool', 'enable')])
+ ## animation-interface.h (module 'netanim'): uint64_t ns3::AnimationInterface::GetTracePktCount() [member function]
+ cls.add_method('GetTracePktCount',
+ 'uint64_t',
+ [])
## animation-interface.h (module 'netanim'): static bool ns3::AnimationInterface::IsInitialized() [member function]
cls.add_method('IsInitialized',
'bool',
@@ -588,10 +592,10 @@
cls.add_method('ShowAll802_11',
'void',
[param('bool', 'showAll')])
- ## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::StartAnimation() [member function]
+ ## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::StartAnimation(bool restart=false) [member function]
cls.add_method('StartAnimation',
'void',
- [])
+ [param('bool', 'restart', default_value='false')])
## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::StopAnimation() [member function]
cls.add_method('StopAnimation',
'void',
--- a/src/netanim/model/animation-interface.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/netanim/model/animation-interface.cc Tue May 22 16:41:05 2012 +0200
@@ -63,33 +63,36 @@
std::map <uint32_t, std::string> AnimationInterface::nodeDescriptions;
AnimationInterface::AnimationInterface ()
- : m_fHandle (STDOUT_FILENO), m_xml (false), mobilitypollinterval (Seconds(0.25)),
- usingSockets (false), mport (0), outputfilename (""),
- OutputFileSet (false), ServerPortSet (false), gAnimUid (0),randomPosition (true),
+ : m_fHandle (STDOUT_FILENO), m_xml (false), m_mobilityPollInterval (Seconds(0.25)),
+ m_usingSockets (false), m_port (0), m_outputFileName (""),
+ m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0),m_randomPosition (true),
m_writeCallback (0), m_started (false),
- m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
+ m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
+ m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE)
{
initialized = true;
StartAnimation ();
}
-AnimationInterface::AnimationInterface (const std::string fn, bool usingXML)
- : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)),
- usingSockets (false), mport (0), outputfilename (fn),
- OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true),
+AnimationInterface::AnimationInterface (const std::string fn, uint64_t maxPktsPerFile, bool usingXML)
+ : m_fHandle (STDOUT_FILENO), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)),
+ m_usingSockets (false), m_port (0), m_outputFileName (fn),
+ m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0), m_randomPosition (true),
m_writeCallback (0), m_started (false),
- m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
+ m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
+ m_maxPktsPerFile (maxPktsPerFile), m_originalFileName (fn)
{
initialized = true;
StartAnimation ();
}
AnimationInterface::AnimationInterface (const uint16_t port, bool usingXML)
- : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)),
- usingSockets (true), mport (port), outputfilename (""),
- OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true),
+ : m_fHandle (STDOUT_FILENO), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)),
+ m_usingSockets (true), m_port (port), m_outputFileName (""),
+ m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0), m_randomPosition (true),
m_writeCallback (0), m_started (false),
- m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
+ m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
+ m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE)
{
initialized = true;
StartAnimation ();
@@ -107,6 +110,22 @@
}
+void AnimationInterface::StartNewTraceFile ()
+{
+ static int i = 0;
+ std::ostringstream oss;
+ oss << i;
+ ++m_currentPktCount;
+ if (m_currentPktCount <= m_maxPktsPerFile)
+ {
+ return;
+ }
+ StopAnimation ();
+ m_outputFileName = m_originalFileName + "-" + oss.str ();
+ StartAnimation (true);
+ ++i;
+
+}
void AnimationInterface::SetStartTime (Time t)
{
m_startTime = t;
@@ -119,16 +138,17 @@
bool AnimationInterface::SetOutputFile (const std::string& fn)
{
- if (OutputFileSet)
+ if (m_outputFileSet)
{
return true;
}
if (fn == "")
{
m_fHandle = STDOUT_FILENO;
- OutputFileSet = true;
+ m_outputFileSet = true;
return true;
}
+ NS_LOG_INFO ("Creating new trace file:" << fn.c_str ());
FILE* f = fopen (fn.c_str (), "w");
if (!f)
{
@@ -136,9 +156,9 @@
return false; // Can't open
}
m_fHandle = fileno (f); // Set the file handle
- usingSockets = false;
- outputfilename = fn;
- OutputFileSet = true;
+ m_usingSockets = false;
+ m_outputFileName = fn;
+ m_outputFileSet = true;
return true;
}
@@ -182,7 +202,7 @@
bool AnimationInterface::SetServerPort (uint16_t port)
{
#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H)
- if (ServerPortSet)
+ if (m_serverPortSet)
{
return true;
}
@@ -204,8 +224,8 @@
// set the linger socket option
int t = 1;
setsockopt (s, SOL_SOCKET, SO_LINGER, &t, sizeof(t));
- usingSockets = true;
- ServerPortSet = true;
+ m_usingSockets = true;
+ m_serverPortSet = true;
return true;
#endif
return false; // never reached unless the above is disabled
@@ -214,33 +234,33 @@
bool AnimationInterface::WifiPacketIsPending (uint64_t AnimUid)
{
- return (pendingWifiPackets.find (AnimUid) != pendingWifiPackets.end ());
+ return (m_pendingWifiPackets.find (AnimUid) != m_pendingWifiPackets.end ());
}
bool AnimationInterface::CsmaPacketIsPending (uint64_t AnimUid)
{
- return (pendingCsmaPackets.find (AnimUid) != pendingCsmaPackets.end ());
+ return (m_pendingCsmaPackets.find (AnimUid) != m_pendingCsmaPackets.end ());
}
bool AnimationInterface::WimaxPacketIsPending (uint64_t AnimUid)
{
- return (pendingWimaxPackets.find (AnimUid) != pendingWimaxPackets.end ());
+ return (m_pendingWimaxPackets.find (AnimUid) != m_pendingWimaxPackets.end ());
}
bool AnimationInterface::LtePacketIsPending (uint64_t AnimUid)
{
- return (pendingLtePackets.find (AnimUid) != pendingLtePackets.end ());
+ return (m_pendingLtePackets.find (AnimUid) != m_pendingLtePackets.end ());
}
void AnimationInterface::SetMobilityPollInterval (Time t)
{
- mobilitypollinterval = t;
+ m_mobilityPollInterval = t;
}
void AnimationInterface::SetRandomPosition (bool setRandPos)
{
- randomPosition = setRandPos;
+ m_randomPosition = setRandPos;
}
Vector AnimationInterface::UpdatePosition (Ptr <Node> n)
@@ -248,49 +268,49 @@
Ptr<MobilityModel> loc = n->GetObject<MobilityModel> ();
if (loc)
{
- nodeLocation[n->GetId ()] = loc->GetPosition ();
+ m_nodeLocation[n->GetId ()] = loc->GetPosition ();
}
else
{
NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
Vector deterministicVector (100,100,0);
- Vector randomVector (UniformVariable (0, topo_maxX-topo_minX).GetValue (), UniformVariable (0, topo_maxY-topo_minY).GetValue (), 0);
- if (randomPosition)
+ Vector randomVector (UniformVariable (0, m_topoMaxX - m_topoMinX).GetValue (), UniformVariable (0, m_topoMaxY - m_topoMinY).GetValue (), 0);
+ if (m_randomPosition)
{
- nodeLocation[n->GetId ()] = randomVector;
+ m_nodeLocation[n->GetId ()] = randomVector;
}
else
{
- nodeLocation[n->GetId ()] = deterministicVector;
+ m_nodeLocation[n->GetId ()] = deterministicVector;
}
}
- return nodeLocation[n->GetId ()];
+ return m_nodeLocation[n->GetId ()];
}
Vector AnimationInterface::UpdatePosition (Ptr <Node> n, Vector v)
{
- nodeLocation[n->GetId ()] = v;
+ m_nodeLocation[n->GetId ()] = v;
return v;
}
Vector AnimationInterface::GetPosition (Ptr <Node> n)
{
#ifdef NS_LOG
- if (nodeLocation.find (n->GetId()) == nodeLocation.end ())
+ if (m_nodeLocation.find (n->GetId()) == m_nodeLocation.end ())
{
NS_FATAL_ERROR ("Node:" <<n->GetId() << " not found in Location table");
}
#endif
- return nodeLocation[n->GetId ()];
+ return m_nodeLocation[n->GetId ()];
}
void AnimationInterface::PurgePendingWifi ()
{
- if (pendingWifiPackets.empty ())
+ if (m_pendingWifiPackets.empty ())
return;
std::vector <uint64_t> purgeList;
- for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWifiPackets.begin ();
- i != pendingWifiPackets.end ();
+ for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWifiPackets.begin ();
+ i != m_pendingWifiPackets.end ();
++i)
{
@@ -306,18 +326,18 @@
i != purgeList.end ();
++i)
{
- pendingWifiPackets.erase (*i);
+ m_pendingWifiPackets.erase (*i);
}
}
void AnimationInterface::PurgePendingWimax ()
{
- if (pendingWimaxPackets.empty ())
+ if (m_pendingWimaxPackets.empty ())
return;
std::vector <uint64_t> purgeList;
- for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWimaxPackets.begin ();
- i != pendingWimaxPackets.end ();
+ for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWimaxPackets.begin ();
+ i != m_pendingWimaxPackets.end ();
++i)
{
@@ -333,7 +353,7 @@
i != purgeList.end ();
++i)
{
- pendingWimaxPackets.erase (*i);
+ m_pendingWimaxPackets.erase (*i);
}
}
@@ -341,11 +361,11 @@
void AnimationInterface::PurgePendingLte ()
{
- if (pendingLtePackets.empty ())
+ if (m_pendingLtePackets.empty ())
return;
std::vector <uint64_t> purgeList;
- for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingLtePackets.begin ();
- i != pendingLtePackets.end ();
+ for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingLtePackets.begin ();
+ i != m_pendingLtePackets.end ();
++i)
{
@@ -361,17 +381,17 @@
i != purgeList.end ();
++i)
{
- pendingLtePackets.erase (*i);
+ m_pendingLtePackets.erase (*i);
}
}
void AnimationInterface::PurgePendingCsma ()
{
- if (pendingCsmaPackets.empty ())
+ if (m_pendingCsmaPackets.empty ())
return;
std::vector <uint64_t> purgeList;
- for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingCsmaPackets.begin ();
- i != pendingCsmaPackets.end ();
+ for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingCsmaPackets.begin ();
+ i != m_pendingCsmaPackets.end ();
++i)
{
@@ -387,37 +407,38 @@
i != purgeList.end ();
++i)
{
- pendingCsmaPackets.erase (*i);
+ m_pendingCsmaPackets.erase (*i);
}
}
-void AnimationInterface::StartAnimation ()
+void AnimationInterface::StartAnimation (bool restart)
{
+ m_currentPktCount = 0;
m_started = true;
- if (usingSockets)
+ if (m_usingSockets)
{
- SetServerPort (mport);
+ SetServerPort (m_port);
}
else
{
- SetOutputFile (outputfilename);
+ SetOutputFile (m_outputFileName);
}
// Find the min/max x/y for the xml topology element
- topo_minX = -2;
- topo_minY = -2;
- topo_maxX = 2;
- topo_maxY = 2;
+ m_topoMinX = -2;
+ m_topoMinY = -2;
+ m_topoMaxX = 2;
+ m_topoMaxY = 2;
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
{
Ptr<Node> n = *i;
NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
Vector v = UpdatePosition (n);
- topo_minX = std::min (topo_minX, v.x);
- topo_minY = std::min (topo_minY, v.y);
- topo_maxX = std::max (topo_maxX, v.x);
- topo_maxY = std::max (topo_maxY, v.y);
+ m_topoMinX = std::min (m_topoMinX, v.x);
+ m_topoMinY = std::min (m_topoMinY, v.y);
+ m_topoMaxX = std::max (m_topoMaxX, v.x);
+ m_topoMaxY = std::max (m_topoMaxY, v.y);
}
AddMargin ();
@@ -426,7 +447,7 @@
std::ostringstream oss;
oss << GetXMLOpen_anim (0);
oss << GetPreamble ();
- oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
+ oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
WriteN (m_fHandle, oss.str ());
}
NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
@@ -497,13 +518,13 @@
}
}
}
- if (m_xml)
+ if (m_xml && !restart)
{
WriteN (m_fHandle, GetXMLClose ("topology"));
- Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
+ Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
}
-
- ConnectCallbacks ();
+ if (!restart)
+ ConnectCallbacks ();
}
void AnimationInterface::ConnectCallbacks ()
@@ -553,7 +574,7 @@
{
close (m_fHandle);
}
- OutputFileSet = false;
+ m_outputFileSet = false;
m_fHandle = -1;
}
}
@@ -575,14 +596,14 @@
void AnimationInterface::AddMargin ()
{
// Compute width/height, and add a small margin
- double w = topo_maxX - topo_minX;
- double h = topo_maxY - topo_minY;
- topo_minX -= w * 0.05;
- topo_minY -= h * 0.05;
- topo_maxX = topo_minX + w * 1.5;
- topo_maxY = topo_minY + h * 1.5;
- NS_LOG_INFO ("Added Canvas Margin:" << topo_minX << "," <<
- topo_minY << "," << topo_maxX << "," << topo_maxY);
+ double w = m_topoMaxX - m_topoMinX;
+ double h = m_topoMaxY - m_topoMinY;
+ m_topoMinX -= w * 0.05;
+ m_topoMinY -= h * 0.05;
+ m_topoMaxX = m_topoMinX + w * 1.5;
+ m_topoMaxY = m_topoMinY + h * 1.5;
+ NS_LOG_INFO ("Added Canvas Margin:" << m_topoMinX << "," <<
+ m_topoMinY << "," << m_topoMaxX << "," << m_topoMaxY);
}
std::vector <Ptr <Node> > AnimationInterface::RecalcTopoBounds ()
@@ -618,17 +639,17 @@
void AnimationInterface::RecalcTopoBounds (Vector v)
{
- double oldminX = topo_minX;
- double oldminY = topo_minY;
- double oldmaxX = topo_maxX;
- double oldmaxY = topo_maxY;
- topo_minX = std::min (topo_minX, v.x);
- topo_minY = std::min (topo_minY, v.y);
- topo_maxX = std::max (topo_maxX, v.x);
- topo_maxY = std::max (topo_maxY, v.y);
+ double oldminX = m_topoMinX;
+ double oldminY = m_topoMinY;
+ double oldmaxX = m_topoMaxX;
+ double oldmaxY = m_topoMaxY;
+ m_topoMinX = std::min (m_topoMinX, v.x);
+ m_topoMinY = std::min (m_topoMinY, v.y);
+ m_topoMaxX = std::max (m_topoMaxX, v.x);
+ m_topoMaxY = std::max (m_topoMaxY, v.y);
- if ((topo_minX != oldminX) || (topo_minY != oldminY) ||
- (topo_maxX != oldmaxX) || (topo_maxY != oldmaxY))
+ if ((m_topoMinX != oldminX) || (m_topoMinY != oldminY) ||
+ (m_topoMaxX != oldmaxX) || (m_topoMaxY != oldmaxY))
{
AddMargin ();
}
@@ -697,6 +718,8 @@
if (m_enablePacketMetadata)
oss << GetXMLOpenClose_meta (GetPacketMetadata (p));
oss << GetXMLClose ("packet");
+ StartNewTraceFile ();
+ ++m_currentPktCount;
}
else
{
@@ -727,25 +750,25 @@
void AnimationInterface::AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
- pendingWifiPackets[AnimUid] = pktinfo;
+ m_pendingWifiPackets[AnimUid] = pktinfo;
}
void AnimationInterface::AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
NS_ASSERT (pktinfo.m_txnd);
- pendingWimaxPackets[AnimUid] = pktinfo;
+ m_pendingWimaxPackets[AnimUid] = pktinfo;
}
void AnimationInterface::AddPendingLtePacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
NS_ASSERT (pktinfo.m_txnd);
- pendingLtePackets[AnimUid] = pktinfo;
+ m_pendingLtePackets[AnimUid] = pktinfo;
}
void AnimationInterface::AddPendingCsmaPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
NS_ASSERT (pktinfo.m_txnd);
- pendingCsmaPackets[AnimUid] = pktinfo;
+ m_pendingCsmaPackets[AnimUid] = pktinfo;
}
uint64_t AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
@@ -814,7 +837,7 @@
uint64_t AnimUid = GetAnimUidFromPacket (p);
NS_LOG_INFO ("TxDropTrace for packet:" << AnimUid);
NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
- pendingWifiPackets.erase (pendingWifiPackets.find (AnimUid));
+ m_pendingWifiPackets.erase (m_pendingWifiPackets.find (AnimUid));
}
@@ -851,9 +874,9 @@
NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
}
// TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
- pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
- pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
- OutputWirelessPacket (p, pendingWifiPackets[AnimUid], pendingWifiPackets[AnimUid].GetRxInfo (ndev));
+ m_pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
+ m_pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
+ OutputWirelessPacket (p, m_pendingWifiPackets[AnimUid], m_pendingWifiPackets[AnimUid].GetRxInfo (ndev));
}
@@ -874,7 +897,7 @@
AddPendingWifiPacket (AnimUid, pktinfo);
}
// TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
- AnimPacketInfo& pktInfo = pendingWifiPackets[AnimUid];
+ AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
if (pktrxInfo.IsPhyRxComplete ())
@@ -900,7 +923,7 @@
return;
}
// TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
- AnimPacketInfo& pktInfo = pendingWifiPackets[AnimUid];
+ AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
if (pktrxInfo.IsPhyRxComplete ())
{
@@ -944,7 +967,7 @@
uint64_t AnimUid = GetAnimUidFromPacket (p);
NS_LOG_INFO ("WimaxRxTrace for packet:" << AnimUid);
NS_ASSERT (WimaxPacketIsPending (AnimUid) == true);
- AnimPacketInfo& pktInfo = pendingWimaxPackets[AnimUid];
+ AnimPacketInfo& pktInfo = m_pendingWimaxPackets[AnimUid];
pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
//TODO 0.001 is used until Wimax implements RxBegin and RxEnd traces
@@ -986,7 +1009,7 @@
NS_LOG_WARN ("LteRxTrace: unknown Uid");
return;
}
- AnimPacketInfo& pktInfo = pendingLtePackets[AnimUid];
+ AnimPacketInfo& pktInfo = m_pendingLtePackets[AnimUid];
pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
//TODO 0.001 is used until Lte implements RxBegin and RxEnd traces
@@ -1031,7 +1054,7 @@
NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
}
// TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
- AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
+ AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
}
@@ -1050,8 +1073,8 @@
return;
}
// TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
- AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
- pendingCsmaPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
+ AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
+ m_pendingCsmaPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << AnimUid);
}
@@ -1074,7 +1097,7 @@
return;
}
// TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
- AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
+ AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
if (pktrxInfo.IsPhyRxComplete ())
{
@@ -1103,7 +1126,7 @@
UpdatePosition (n,v);
RecalcTopoBounds (v);
std::ostringstream oss;
- oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
+ oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y);
oss << GetXMLClose ("topology");
WriteN (m_fHandle, oss.str ());
@@ -1131,7 +1154,7 @@
return;
std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
std::ostringstream oss;
- oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
+ oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
for (uint32_t i = 0; i < MovedNodes.size (); i++)
{
Ptr <Node> n = MovedNodes [i];
@@ -1148,7 +1171,7 @@
PurgePendingWimax ();
PurgePendingLte ();
PurgePendingCsma ();
- Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
+ Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
}
}
@@ -1159,6 +1182,12 @@
return oss.str ();
}
+uint64_t AnimationInterface::GetTracePktCount ()
+{
+ return m_currentPktCount;
+}
+
+
// Helper to output a wireless packet.
// For now, only the XML interface is supported
@@ -1204,6 +1233,7 @@
void AnimationInterface::OutputWirelessPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
{
+ StartNewTraceFile ();
NS_ASSERT (m_xml);
std::ostringstream oss;
uint32_t nodeId = 0;
@@ -1226,6 +1256,7 @@
void AnimationInterface::OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
{
+ StartNewTraceFile ();
NS_ASSERT (m_xml);
std::ostringstream oss;
NS_ASSERT (pktInfo.m_txnd);
--- a/src/netanim/model/animation-interface.h Tue May 22 16:40:24 2012 +0200
+++ b/src/netanim/model/animation-interface.h Tue May 22 16:41:05 2012 +0200
@@ -52,6 +52,8 @@
namespace ns3 {
+#define MAX_PKTS_PER_TRACE_FILE 100000
+
/**
* \defgroup netanim Netanim
*
@@ -85,10 +87,16 @@
/**
* \brief Constructor
* \param filename The Filename for the trace file used by the Animator
+ * \param maxPktsPerFile The maximum number of packets per trace file.
+ AnimationInterface will create trace files with the following
+ filenames : filename, filename-1, filename-2..., filename-N
+ where each file contains packet info for 'maxPktPerFile' number of packets
* \param usingXML Set to true if XML output traces are required
*
*/
- AnimationInterface (const std::string filename, bool usingXML = true);
+ AnimationInterface (const std::string filename,
+ uint64_t maxPktsPerFile = MAX_PKTS_PER_TRACE_FILE,
+ bool usingXML = true);
/**
* \brief Constructor
@@ -169,9 +177,10 @@
* on prior calls to SetOutputFile, SetServerPort, or SetInternalAnimation.
* Then creates the callbacks needed for the animator to start processing
* packets.
- *
+ *
+ * \param restart True when restarting animation
*/
- void StartAnimation ();
+ void StartAnimation (bool restart = false);
/**
* \brief Closes the interface to the animator.
@@ -269,6 +278,15 @@
void EnablePacketMetadata (bool enable);
+ /**
+ *
+ * \brief Get trace file packet count (This used only for testing)
+ *
+ * returns Number of packets recorded in the current trace file
+ *
+ */
+ uint64_t GetTracePktCount ();
+
private:
#ifndef WIN32
@@ -280,12 +298,21 @@
int WriteN (SOCKET, const char*, uint32_t);
#endif
bool m_xml; // True if xml format desired
- Time mobilitypollinterval;
- bool usingSockets;
- uint16_t mport;
- std::string outputfilename;
- bool OutputFileSet;
- bool ServerPortSet;
+ Time m_mobilityPollInterval;
+ bool m_usingSockets;
+ uint16_t m_port;
+ std::string m_outputFileName;
+ bool m_outputFileSet;
+ bool m_serverPortSet;
+ uint64_t gAnimUid ; // Packet unique identifier used by Animtion
+ bool m_randomPosition;
+ AnimWriteCallback m_writeCallback;
+ bool m_started;
+ bool m_enablePacketMetadata;
+ Time m_startTime;
+ Time m_stopTime;
+ uint64_t m_maxPktsPerFile;
+ std::string m_originalFileName;
void DevTxTrace (std::string context,
Ptr<const Packet> p,
@@ -339,27 +366,26 @@
void OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo);
void MobilityAutoCheck ();
- uint64_t gAnimUid ; // Packet unique identifier used by Animtion
- std::map<uint64_t, AnimPacketInfo> pendingWifiPackets;
+ std::map<uint64_t, AnimPacketInfo> m_pendingWifiPackets;
void AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo&);
bool WifiPacketIsPending (uint64_t AnimUid);
- std::map<uint64_t, AnimPacketInfo> pendingWimaxPackets;
+ std::map<uint64_t, AnimPacketInfo> m_pendingWimaxPackets;
void AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo&);
bool WimaxPacketIsPending (uint64_t AnimUid);
- std::map<uint64_t, AnimPacketInfo> pendingLtePackets;
+ std::map<uint64_t, AnimPacketInfo> m_pendingLtePackets;
void AddPendingLtePacket (uint64_t AnimUid, AnimPacketInfo&);
bool LtePacketIsPending (uint64_t AnimUid);
- std::map<uint64_t, AnimPacketInfo> pendingCsmaPackets;
+ std::map<uint64_t, AnimPacketInfo> m_pendingCsmaPackets;
void AddPendingCsmaPacket (uint64_t AnimUid, AnimPacketInfo&);
bool CsmaPacketIsPending (uint64_t AnimUid);
uint64_t GetAnimUidFromPacket (Ptr <const Packet>);
- std::map<uint32_t, Vector> nodeLocation;
+ std::map<uint32_t, Vector> m_nodeLocation;
Vector GetPosition (Ptr <Node> n);
Vector UpdatePosition (Ptr <Node> n);
Vector UpdatePosition (Ptr <Node> n, Vector v);
@@ -376,14 +402,8 @@
void RecalcTopoBounds (Vector v);
std::vector < Ptr <Node> > RecalcTopoBounds ();
- bool randomPosition;
- AnimWriteCallback m_writeCallback;
void ConnectCallbacks ();
- bool m_started;
- bool m_enablePacketMetadata;
- Time m_startTime;
- Time m_stopTime;
std::map <std::string, uint32_t> m_macToNodeIdMap;
bool IsInTimeWindow ();
@@ -393,14 +413,17 @@
Ptr <NetDevice> GetNetDeviceFromContext (std::string context);
static std::map <uint32_t, std::string> nodeDescriptions;
+ uint64_t m_currentPktCount;
+
+ void StartNewTraceFile();
// XML helpers
std::string GetPreamble (void);
// Topology element dimensions
- double topo_minX;
- double topo_minY;
- double topo_maxX;
- double topo_maxY;
+ double m_topoMinX;
+ double m_topoMinY;
+ double m_topoMaxX;
+ double m_topoMaxY;
std::string GetPacketMetadata (Ptr<const Packet> p);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/netanim/test/examples-to-run.py Tue May 22 16:41:05 2012 +0200
@@ -0,0 +1,23 @@
+#! /usr/bin/env python
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+# A list of C++ examples to run in order to ensure that they remain
+# buildable and runnable over time. Each tuple in the list contains
+#
+# (example_name, do_run, do_valgrind_run).
+#
+# See test.py for more information.
+cpp_examples = [
+ ("dumbbell-animation", "True", "False"),
+ ("star-animation", "True", "False"),
+ ("grid-animation", "True", "False"),
+ ("wireless-animation", "True", "False"),
+]
+
+# A list of Python examples to run in order to ensure that they remain
+# runnable over time. Each tuple in the list contains
+#
+# (example_name, do_run).
+#
+# See test.py for more information.
+python_examples = []
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/netanim/test/netanim-test.cc Tue May 22 16:41:05 2012 +0200
@@ -0,0 +1,118 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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: John Abraham <john.abraham@gatech.edu>
+ */
+
+#include <iostream>
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/internet-module.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/netanim-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/point-to-point-layout-module.h"
+
+namespace ns3 {
+
+class AnimationInterfaceTestCase : public TestCase
+{
+public:
+ /**
+ * \brief Constructor.
+ */
+ AnimationInterfaceTestCase ();
+ /**
+ * \brief Destructor.
+ */
+ virtual
+ ~AnimationInterfaceTestCase ();
+ /**
+ * \brief Run unit tests for this class.
+ * \return false if all tests have passed, false otherwise
+ */
+ virtual void
+ DoRun (void);
+
+};
+
+AnimationInterfaceTestCase::AnimationInterfaceTestCase () :
+ TestCase ("Verify AnimationInterface")
+{
+}
+
+AnimationInterfaceTestCase::~AnimationInterfaceTestCase ()
+{
+}
+void
+AnimationInterfaceTestCase::DoRun (void)
+{
+ NodeContainer nodes;
+ nodes.Create (2);
+ AnimationInterface::SetConstantPosition (nodes.Get (0), 0 , 10);
+ AnimationInterface::SetConstantPosition (nodes.Get (1), 1 , 10);
+
+ PointToPointHelper pointToPoint;
+ pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+ pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+ NetDeviceContainer devices;
+ devices = pointToPoint.Install (nodes);
+
+ InternetStackHelper stack;
+ stack.Install (nodes);
+
+ Ipv4AddressHelper address;
+ address.SetBase ("10.1.1.0", "255.255.255.0");
+
+ Ipv4InterfaceContainer interfaces = address.Assign (devices);
+
+ UdpEchoServerHelper echoServer (9);
+
+ ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
+ serverApps.Start (Seconds (1.0));
+ serverApps.Stop (Seconds (10.0));
+
+ UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
+ echoClient.SetAttribute ("MaxPackets", UintegerValue (100));
+ echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
+ echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
+
+ ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
+ clientApps.Start (Seconds (2.0));
+ clientApps.Stop (Seconds (10.0));
+ std::string traceFileName = "netanim-test.xml";
+ AnimationInterface anim(traceFileName.c_str ());
+ Simulator::Run ();
+ NS_TEST_ASSERT_MSG_EQ (anim.GetTracePktCount (), 32, "Expected 32 packets traced");
+ FILE * fp = fopen (traceFileName.c_str (), "r");
+ NS_TEST_ASSERT_MSG_NE (fp, 0, "Trace file was not created");
+ fclose (fp);
+ unlink (traceFileName.c_str ());
+ Simulator::Destroy ();
+}
+
+static class AnimationInterfaceTestSuite : public TestSuite
+{
+public:
+ AnimationInterfaceTestSuite () :
+ TestSuite ("animation-interface", UNIT)
+ {
+ AddTestCase (new AnimationInterfaceTestCase ());
+ }
+} g_animationInterfaceTestSuite;
+
+} // namespace ns3
--- a/src/netanim/wscript Tue May 22 16:40:24 2012 +0200
+++ b/src/netanim/wscript Tue May 22 16:41:05 2012 +0200
@@ -14,6 +14,10 @@
'model/animation-interface.cc',
'helper/animation-interface-helper.cc',
]
+ netanim_test = bld.create_ns3_module_test_library('netanim')
+ netanim_test.source = [
+ 'test/netanim-test.cc',
+ ]
headers = bld.new_task_gen (features=['ns3header'])
headers.module = 'netanim'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/propagation/examples/jakes-propagation-model-example.cc Tue May 22 16:41:05 2012 +0200
@@ -0,0 +1,98 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Telum (www.telum.ru)
+ *
+ * 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: Kirill Andreev <andreev@telum.ru>
+ */
+#include "ns3/core-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/jakes-propagation-loss-model.h"
+#include <vector>
+#include <math.h>
+
+using namespace ns3;
+/**
+ * \ingroup propagation
+ * \brief Constructs a JakesPropagationlossModel and print the loss value as a function of time into std::cout.
+ * Distribution and correlation statistics is compared woth a theoretical ones using R package (http://www.r-project.org/).
+ * Scripts are presented within comments.
+ */
+class JakesPropagationExample
+{
+public:
+ JakesPropagationExample ();
+ ~JakesPropagationExample ();
+private:
+ Ptr<PropagationLossModel> m_loss;
+ Ptr<MobilityModel> m_firstMobility;
+ Ptr<MobilityModel> m_secondMobility;
+ Time m_step;
+ EventId m_nextEvent;
+ void Next ();
+
+};
+
+JakesPropagationExample::JakesPropagationExample () :
+ m_step (Seconds (0.0002)) //1/5000 part of the second
+{
+ m_loss = CreateObject<JakesPropagationLossModel> ();
+ m_firstMobility = CreateObject<ConstantPositionMobilityModel> ();
+ m_secondMobility = CreateObject<ConstantPositionMobilityModel> ();
+ m_firstMobility->SetPosition (Vector (0, 0, 0));
+ m_secondMobility->SetPosition (Vector (10, 0, 0));
+ m_nextEvent = Simulator::Schedule (m_step, &JakesPropagationExample::Next, this);
+}
+
+JakesPropagationExample::~JakesPropagationExample ()
+{
+}
+
+void JakesPropagationExample::Next ()
+{
+ m_nextEvent = Simulator::Schedule (m_step, &JakesPropagationExample::Next, this);
+ std::cout << Simulator::Now ().GetMilliSeconds () << " " << m_loss->CalcRxPower (0, m_firstMobility, m_secondMobility) << std::endl;
+}
+
+int main (int argc, char *argv[])
+{
+ Config::SetDefault ("ns3::JakesProcess::NumberOfOscillators", UintegerValue (100));
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+ JakesPropagationExample example;
+ Simulator::Stop (Seconds (1000));
+ Simulator::Run ();
+ Simulator::Destroy ();
+ /*
+ * R script for plotting a distribution:
+ data<-read.table ("data")
+ rayleigh<-(rnorm(1e6)^2+rnorm(1e6)^2)/2
+ qqplot(10*log10(rayleigh), data$V2, main="QQ-plot for improved Jakes model", xlab="Reference Rayleigh distribution [power, dB]", ylab="Sum-of-sinusoids distribution [power, dB]", xlim=c(-45, 10), ylim=c(-45, 10))
+ lines (c(-50, 50), c(-50, 50))
+ abline (v=-50:50*2, h=-50:50*2, col="light grey")
+ */
+
+ /*
+ * R script to plot autocorrelation function:
+ # Read amplitude distribution:
+ data<-10^(read.table ("data")$V2/20)
+ x<-1:2000/10
+ acf (data, lag.max=200, main="Autocorrelation function of the improved Jakes model", xlab="Time x200 microseconds ", ylab="Autocorrelation")
+ # If we have a delta T = 1/5000 part of the second and doppler freq = 80 Hz
+ lines (x, besselJ(x*80*2*pi/5000, 0)^2)
+ abline (h=0:10/10, col="light grey")
+ */
+ return 0;
+}
--- a/src/propagation/examples/main-propagation-loss.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/propagation/examples/main-propagation-loss.cc Tue May 22 16:41:05 2012 +0200
@@ -249,7 +249,7 @@
Ptr<JakesPropagationLossModel> jakes = CreateObject<JakesPropagationLossModel> ();
// doppler frequency shift for 5.15 GHz at 100 km/h
- jakes->SetAttribute ("DopplerFreq", DoubleValue (477.9));
+ Config::SetDefault ("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue (477.9));
Gnuplot plot = TestDeterministicByTime (jakes, Seconds (0.001), Seconds (1.0));
plot.SetTitle ("ns3::JakesPropagationLossModel (with 477.9 Hz shift and 1 millisec resolution)");
@@ -260,7 +260,7 @@
Ptr<JakesPropagationLossModel> jakes = CreateObject<JakesPropagationLossModel> ();
// doppler frequency shift for 5.15 GHz at 100 km/h
- jakes->SetAttribute ("DopplerFreq", DoubleValue (477.9));
+ Config::SetDefault ("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue (477.9));
Gnuplot plot = TestDeterministicByTime (jakes, Seconds (0.0001), Seconds (0.1));
plot.SetTitle ("ns3::JakesPropagationLossModel (with 477.9 Hz shift and 0.1 millisec resolution)");
--- a/src/propagation/examples/wscript Tue May 22 16:40:24 2012 +0200
+++ b/src/propagation/examples/wscript Tue May 22 16:41:05 2012 +0200
@@ -8,4 +8,9 @@
['core', 'mobility', 'config-store', 'tools', 'propagation'])
obj.source = 'main-propagation-loss.cc'
+ obj = bld.create_ns3_program('jakes-propagation-model-example',
+ ['core', 'propagation'])
+ obj.source = 'jakes-propagation-model-example.cc'
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/propagation/model/jakes-process.cc Tue May 22 16:41:05 2012 +0200
@@ -0,0 +1,134 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Telum (www.telum.ru)
+ *
+ * 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: Kirill Andreev <andreev@telum.ru>, Alexander Sofronov <sofronov@telum.ru>
+ */
+
+#include "jakes-process.h"
+#include "ns3/random-variable.h"
+#include "ns3/simulator.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+const double JakesProcess::PI = 3.14159265358979323846;
+
+/// Represents a single oscillator
+JakesProcess::Oscillator::Oscillator (std::complex<double> amplitude, double initialPhase, double omega) :
+ m_amplitude (amplitude),
+ m_phase (initialPhase),
+ m_omega (omega)
+{}
+
+std::complex<double>
+JakesProcess::Oscillator::GetValueAt (Time at) const
+{
+ return (m_amplitude * cos (at.GetSeconds () * m_omega + m_phase));
+}
+
+NS_OBJECT_ENSURE_REGISTERED (JakesProcess);
+
+TypeId
+JakesProcess::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::JakesProcess")
+ .SetParent<Object> ()
+ .AddConstructor<JakesProcess> ()
+ .AddAttribute ("DopplerFrequencyHz", "Corresponding doppler frequency[Hz]",
+ DoubleValue (80),
+ MakeDoubleAccessor (&JakesProcess::SetDopplerFrequencyHz),
+ MakeDoubleChecker<double> (0.0, 1e4))
+ .AddAttribute ("NumberOfOscillators", "The number of oscillators",
+ UintegerValue (20),
+ MakeUintegerAccessor (&JakesProcess::SetNOscillators),
+ MakeUintegerChecker<unsigned int> (4, 1000))
+ ;
+ return tid;
+}
+
+void
+JakesProcess::SetNOscillators (unsigned int nOscillators)
+{
+ m_nOscillators = nOscillators;
+ if (m_omegaDopplerMax != 0)
+ {
+ ConstructOscillators ();
+ }
+}
+
+void
+JakesProcess::SetDopplerFrequencyHz (double dopplerFrequencyHz)
+{
+ m_omegaDopplerMax = 2 * dopplerFrequencyHz * PI;
+ if (m_nOscillators != 0)
+ {
+ ConstructOscillators ();
+ }
+}
+
+void
+JakesProcess::ConstructOscillators ()
+{
+ // Initial phase is common for all oscillators:
+ double phi = UniformVariable (-PI, PI).GetValue ();
+ // Theta is common for all oscillatoer:
+ double theta = UniformVariable (-PI, PI).GetValue ();
+ for (unsigned int i = 0; i < m_nOscillators; i++)
+ {
+ unsigned int n = i + 1;
+ /// 1. Rotation speed
+ /// 1a. Initiate \f[ \alpha_n = \frac{2\pi n - \pi + \theta}{4M}, n=1,2, \ldots,M\f], n is oscillatorNumber, M is m_nOscillators
+ double alpha = (2.0 * PI * n - PI + theta) / (4.0 * m_nOscillators);
+ /// 1b. Initiate rotation speed:
+ double omega = m_omegaDopplerMax * cos (alpha);
+ /// 2. Initiate complex amplitude:
+ double psi = UniformVariable (-PI, PI).GetValue ();
+ std::complex<double> amplitude = std::complex<double> (cos (psi), sin (psi)) * 2.0 / sqrt (m_nOscillators);
+ /// 3. Construct oscillator:
+ m_oscillators.push_back (Oscillator (amplitude, phi, omega));
+ }
+}
+
+JakesProcess::JakesProcess () :
+ m_omegaDopplerMax (0),
+ m_nOscillators (0)
+{}
+
+JakesProcess::~JakesProcess()
+{
+ m_oscillators.clear ();
+}
+
+std::complex<double>
+JakesProcess::GetComplexGain () const
+{
+ std::complex<double> sumAplitude = std::complex<double> (0, 0);
+ for (unsigned int i = 0; i < m_oscillators.size (); i++)
+ {
+ sumAplitude += m_oscillators[i].GetValueAt (Now ());
+ }
+ return sumAplitude;
+}
+
+double
+JakesProcess::GetChannelGainDb () const
+{
+ std::complex<double> complexGain = GetComplexGain ();
+ return (10 * log10 ((pow (complexGain.real (), 2) + pow (complexGain.imag (), 2)) / 2));
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/propagation/model/jakes-process.h Tue May 22 16:41:05 2012 +0200
@@ -0,0 +1,92 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Telum (www.telum.ru)
+ *
+ * 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: Kirill Andreev <andreev@telum.ru>, Alexander Sofronov <sofronov@telum.ru>
+ */
+#ifndef DOPPLER_PROCESS_H
+#define DOPPLER_PROCESS_H
+
+#include "ns3/object.h"
+#include "ns3/nstime.h"
+#include <complex>
+
+namespace ns3
+{
+/**
+ * \ingroup fading
+ *
+ * \brief Implementation for a single path Stationary Jakes propagation loss model.
+ *
+ * The Jakes propagation loss model implemented here is
+ * described in [1].
+ *
+ * We consider one transmitter - receiver pair and calculate
+ * the complex coefficients for this case as follow:
+ * \f[ X(t)=X_c(t) + j X_s(t)\f]
+ * \f[ X_c(t) = \frac{2}{\sqrt{M}}\sum_{n=1}^{M}\cos(\psi_n)\cos(\omega_d t\cos(\alpha_n)+\phi_n)\f]
+ * \f[ X_s(t) = \frac{2}{\sqrt{M}}\sum_{n=1}^{M}\sin(\psi_n)\cos(\omega_d t\cos(\alpha_n)+\phi_n)\f]
+ * with
+ * \f[ \alpha_n = \frac{2\pi n - \pi + \theta}{4M}, n=1,2, \ldots,M\f]
+ * where
+ *\f$\theta\f$, \f$\phi\f$, and \f$\psi_n\f$ are statically independent and uniformly distributed over \f$[-\pi, \pi)\f$ for all \f$n\f$.
+ *
+ *
+ * [1] Y. R. Zheng and C. Xiao, "Simulation Models With Correct
+ * Statistical Properties for Rayleigh Fading Channel", IEEE
+ * Trans. on Communications, Vol. 51, pp 920-928, June 2003
+ */
+class JakesProcess : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+ JakesProcess ();
+ virtual ~JakesProcess();
+ std::complex<double> GetComplexGain () const;
+ /// Get Channel gain [dB]
+ double GetChannelGainDb () const;
+private:
+ /// Represents a single oscillator
+ struct Oscillator
+ {
+ /// Initiate oscillator with complex amplitude, initial phase and rotation speed
+ Oscillator (std::complex<double> amplitude, double initialPhase, double omega);
+ // Get the complex amplitude at moment \param t
+ std::complex<double> GetValueAt (Time t) const;
+ /// Complex number \f[Re=\cos(\psi_n), Im = i\sin(\psi_n)]
+ std::complex<double> m_amplitude;
+ /// Phase \f[\phi_n] of the oscillator
+ double m_phase;
+ /// Rotation speed of the oscillator \f[\omega_d \cos(\alpha_n)]
+ double m_omega;
+ };
+ /// PI Constant
+ static const double PI;
+private:
+ void SetNOscillators (unsigned int nOscillators);
+ void SetDopplerFrequencyHz (double dopplerFrequencyHz);
+ void ConstructOscillators ();
+private:
+ /// Vector of oscillators:
+ std::vector<Oscillator> m_oscillators;
+ ///\name Attributes:
+ ///\{
+ double m_omegaDopplerMax;
+ unsigned int m_nOscillators;
+ ///\}
+};
+} // namespace ns3
+#endif // DOPPLER_PROCESS_H
--- a/src/propagation/model/jakes-propagation-loss-model.cc Tue May 22 16:40:24 2012 +0200
+++ b/src/propagation/model/jakes-propagation-loss-model.cc Tue May 22 16:41:05 2012 +0200
@@ -1,9 +1,9 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2005,2006,2007 INRIA
+ * Copyright (c) 2012 Telum (www.telum.ru)
*
* 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
+ * 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,
@@ -15,246 +15,37 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Federico Maguolo <maguolof@dei.unipd.it>
+ * Author: Kirill Andreev <andreev@telum.ru>
*/
-#include "ns3/simulator.h"
-#include "ns3/uinteger.h"
-#include "ns3/double.h"
-#include "ns3/random-variable.h"
-#include "ns3/mobility-model.h"
-#include "ns3/log.h"
#include "jakes-propagation-loss-model.h"
-#include <math.h>
-NS_LOG_COMPONENT_DEFINE ("Jakes");
-
-namespace ns3 {
-
+namespace ns3
+{
NS_OBJECT_ENSURE_REGISTERED (JakesPropagationLossModel);
-class JakesPropagationLossModel::PathCoefficients
-{
-public:
- PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
- Ptr<MobilityModel> receiver,
- uint8_t nRays,
- uint8_t nOscillators);
- ~PathCoefficients ();
- double GetLoss (Ptr<const JakesPropagationLossModel> jakes);
- Ptr<MobilityModel> GetReceiver (void);
-private:
- void DoConstruct (Ptr<const JakesPropagationLossModel> jakes);
- Ptr<MobilityModel> m_receiver;
- uint8_t m_nOscillators;
- uint8_t m_nRays;
- double **m_phases;
- Time m_lastUpdate;
-};
-
-
-JakesPropagationLossModel::PathCoefficients::PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
- Ptr<MobilityModel> receiver,
- uint8_t nRays,
- uint8_t nOscillators)
- : m_receiver (receiver),
- m_nOscillators (nOscillators),
- m_nRays (nRays)
-{
- DoConstruct (jakes);
-}
-
-JakesPropagationLossModel::PathCoefficients::~PathCoefficients ()
-{
- for (uint8_t i = 0; i < m_nRays; i++)
- {
- delete [] m_phases[i];
- }
- delete [] m_phases;
-}
+JakesPropagationLossModel::JakesPropagationLossModel()
+{}
-void
-JakesPropagationLossModel::PathCoefficients::DoConstruct (Ptr<const JakesPropagationLossModel> jakes)
-{
- m_phases = new double*[m_nRays];
- for (uint8_t i = 0; i < m_nRays; i++)
- {
- m_phases[i] = new double[m_nOscillators + 1];
- for (uint8_t j = 0; j <= m_nOscillators; j++)
- {
- m_phases[i][j] = 2.0 * JakesPropagationLossModel::PI * jakes->m_variable.GetValue ();
- }
- }
- m_lastUpdate = Simulator::Now ();
-}
-
-Ptr<MobilityModel>
-JakesPropagationLossModel::PathCoefficients::GetReceiver ()
-{
- return m_receiver;
-}
-
-double
-JakesPropagationLossModel::PathCoefficients::GetLoss (Ptr<const JakesPropagationLossModel> jakes)
-{
- uint16_t N = 4 * m_nOscillators + 2;
- Time interval = Simulator::Now () - m_lastUpdate;
- ComplexNumber coef= { 0.0, 0.0};
- ComplexNumber fading;
- double norm = 0.0;
- for (uint8_t i = 0; i < m_nRays; i++)
- {
- fading.real = 0.0;
- fading.imag = 0.0;
- for (uint8_t j = 0; j <= m_nOscillators; j++)
- {
- m_phases[i][j] += 2.0 * JakesPropagationLossModel::PI *
- cos (2.0 * JakesPropagationLossModel::PI * j / N) * jakes->m_fd * interval.GetSeconds ();
- m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI *
- floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI);
- fading.real += jakes->m_amp[j].real * cos (m_phases[i][j]);
- fading.imag += jakes->m_amp[j].imag * cos (m_phases[i][j]);
- norm += sqrt (pow (jakes->m_amp[j].real, 2) + pow (jakes->m_amp[j].imag, 2));
- }
- coef.real += fading.real;
- coef.imag += fading.imag;
- }
- m_lastUpdate = Simulator::Now ();
- double k = sqrt (pow (coef.real, 2) + pow (coef.imag, 2)) / norm;
- NS_LOG_DEBUG ("Jakes coef "<< k << " (" << 10 * log10 (k) << "dB)");
- return 10 * log10 (k);
-}
-
-const double JakesPropagationLossModel::PI = 3.14159265358979323846;
+JakesPropagationLossModel::~JakesPropagationLossModel()
+{}
TypeId
-JakesPropagationLossModel::GetTypeId (void)
+JakesPropagationLossModel::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::JakesPropagationLossModel")
.SetParent<PropagationLossModel> ()
.AddConstructor<JakesPropagationLossModel> ()
- .AddAttribute ("NumberOfRaysPerPath",
- "The number of rays to use by default for compute the fading coeficent for a given path (default is 1)",
- UintegerValue (1),
- MakeUintegerAccessor (&JakesPropagationLossModel::SetNRays,
- &JakesPropagationLossModel::GetNRays),
- MakeUintegerChecker<uint8_t> ())
- .AddAttribute ("NumberOfOscillatorsPerRay",
- "The number of oscillators to use by default for compute the coeficent for a given ray of a given "
- "path (default is 4)",
- UintegerValue (4),
- MakeUintegerAccessor (&JakesPropagationLossModel::SetNOscillators,
- &JakesPropagationLossModel::GetNOscillators),
- MakeUintegerChecker<uint8_t> ())
- .AddAttribute ("DopplerFreq",
- "The doppler frequency in Hz (f_d = v / lambda = v * f / c), the default is 0)",
- DoubleValue (0.0),
- MakeDoubleAccessor (&JakesPropagationLossModel::m_fd),
- MakeDoubleChecker<double> ())
- .AddAttribute ("Distribution",
- "The distribution to choose the initial phases.",
- RandomVariableValue (ConstantVariable (1.0)),
- MakeRandomVariableAccessor (&JakesPropagationLossModel::m_variable),
- MakeRandomVariableChecker ())
;
return tid;
}
-JakesPropagationLossModel::JakesPropagationLossModel ()
- : m_amp (0),
- m_nRays (0),
- m_nOscillators (0)
-{
-}
-
-JakesPropagationLossModel::~JakesPropagationLossModel ()
-{
- delete [] m_amp;
- for (PathsList::reverse_iterator i = m_paths.rbegin (); i != m_paths.rend (); i++)
- {
- PathsSet *ps = *i;
- for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++)
- {
- PathCoefficients *pc = *r;
- delete pc;
- }
- ps->sender = 0;
- ps->receivers.clear ();
- delete ps;
- }
- m_paths.clear ();
-}
-
-void
-JakesPropagationLossModel::SetNRays (uint8_t nRays)
-{
- m_nRays = nRays;
-}
-
-void
-JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators)
-{
- m_nOscillators = nOscillators;
- delete [] m_amp;
- uint16_t N = 4 * m_nOscillators + 2;
- m_amp = new ComplexNumber[m_nOscillators + 1];
- m_amp[0].real = 2.0 * sqrt (2.0 / N) * cos (PI / 4.0);
- m_amp[0].imag = 2.0 * sqrt (2.0 / N) * sin (PI / 4.0);
- for (uint8_t i = 1; i <= m_nOscillators; i++)
- {
- double beta = PI * (double)i / m_nOscillators;
- m_amp[i].real = 4.0 * cos (beta) / sqrt (N);
- m_amp[i].imag = 4.0 * sin (beta) / sqrt (N);
- }
-}
-
-uint8_t
-JakesPropagationLossModel::GetNRays (void) const
-{
- return m_nRays;
-}
-uint8_t
-JakesPropagationLossModel::GetNOscillators (void) const
-{
- return m_nOscillators;
-}
-
-
-double
+double
JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
- PathsList::iterator i = m_paths.end ();
- while (i != m_paths.begin ())
- {
- i--;
- PathsSet *ps = *i;
- if (ps->sender == a)
- {
- m_paths.erase (i);
- m_paths.push_back (ps);
- for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++)
- {
- PathCoefficients *pc = *r;
- if (pc->GetReceiver () == b)
- {
- ps->receivers.erase (r);
- ps->receivers.push_back (pc);
- return txPowerDbm + pc->GetLoss (this);
- }
- }
- PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
- ps->receivers.push_back (pc);
- return txPowerDbm + pc->GetLoss (this);
- }
- }
- PathsSet *ps = new PathsSet;
- ps->sender = a;
- PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
- ps->receivers.push_back (pc);
- m_paths.push_back (ps);
- return txPowerDbm + pc->GetLoss (this);
+ return txPowerDbm + m_propagationCache.GetPathData (a, b, 0 /**Spectrum model uid is not used in PropagationLossModel*/)->GetChannelGainDb ();
}
} // namespace ns3
--- a/src/propagation/model/jakes-propagation-loss-model.h Tue May 22 16:40:24 2012 +0200
+++ b/src/propagation/model/jakes-propagation-loss-model.h Tue May 22 16:41:05 2012 +0200
@@ -1,9 +1,9 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2005,2006,2007 INRIA
+ * Copyright (c) 2012 Telum (www.telum.ru)
*
* 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
+ * 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,
@@ -15,125 +15,41 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Federico Maguolo <maguolof@dei.unipd.it>
+ * Author: Kirill Andreev <andreev@telum.ru>
*/
-#ifndef PROPAGATION_JAKES_MODEL_H
-#define PROPAGATION_JAKES_MODEL_H
+#ifndef JAKES_STATIONARY_LOSS_MODEL_H
+#define JAKES_STATIONARY_LOSS_MODEL_H
-#include "ns3/nstime.h"
-#include "propagation-loss-model.h"
+#include "ns3/propagation-loss-model.h"
+#include "ns3/propagation-cache.h"
+#include "ns3/jakes-process.h"
-namespace ns3 {
-
-
+namespace ns3
+{
/**
* \ingroup propagation
*
- * \brief a Jakes propagation loss model
- *
- * The Jakes propagation loss model implemented here is
- * described in [1].
- *
- *
- * We call path the set of rays that depart from a given
- * transmitter and arrive to a given receiver. For each ray
- * The complex coefficient is compute as follow:
- * \f[ u(t)=u_c(t) + j u_s(t)\f]
- * \f[ u_c(t) = \frac{2}{\sqrt{N}}\sum_{n=0}^{M}a_n\cos(\omega_n t+\phi_n)\f]
- * \f[ u_s(t) = \frac{2}{\sqrt{N}}\sum_{n=0}^{M}b_n\cos(\omega_n t+\phi_n)\f]
- * where
- * \f[ a_n=\left \{ \begin{array}{ll}
- * \sqrt{2}\cos\beta_0 & n=0 \\
- * 2\cos\beta_n & n=1,2,\ldots,M
- * \end{array}
- * \right .\f]
- * \f[ b_n=\left \{ \begin{array}{ll}
- * \sqrt{2}\sin\beta_0 & n=0 \\
- * 2\sin\beta_n & n=1,2,\ldots,M
- * \end{array}
- * \right .\f]
- * \f[ \beta_n=\left \{ \begin{array}{ll}
- * \frac{\pi}{4} & n=0 \\
- * \frac{\pi n}{M} & n=1,2,\ldots,M
- * \end{array}
- * \right .\f]
- * \f[ \omega_n=\left \{ \begin{array}{ll}
- * 2\pi f_d & n=0 \\
- * 2\pi f_d \cos\frac{2\pi n}{N} & n=1,2,\ldots,M
- * \end{array}
- * \right .\f]
- *
- * The parameter \f$f_d\f$ is the doppler frequency and \f$N=4M+2\f$ where
- * \f$M\f$ is the number of oscillators per ray.
- *
- * The attenuation coefficent of the path is the magnitude of the sum of
- * all the ray coefficients. This attenuation coefficient could be greater than
- * \f$1\f$, hence it is divide by \f$ \frac{2N_r}{\sqrt{N}} \sum_{n+0}^{M}\sqrt{a_n^2 +b_n^2}\f$
- * where \f$N_r\f$ is the number of rays.
- *
- * The initail phases \f$\phi_i\f$ are random and they are choosen according
- * to a given distribution.
- *
- * [1] Y. R. Zheng and C. Xiao, "Simulation Models With Correct
- * Statistical Properties for Rayleigh Fading Channel", IEEE
- * Trans. on Communications, Vol. 51, pp 920-928, June 2003
+ * \brief a jakes narrowband propagation model.
+ * Symmetrical cache for JakesProcess
*/
+
class JakesPropagationLossModel : public PropagationLossModel
{
public:
- static TypeId GetTypeId (void);
+ static TypeId GetTypeId ();
JakesPropagationLossModel ();
virtual ~JakesPropagationLossModel ();
- /**
- * \param nRays Number of rays per path
- *
- * Set the number of rays for each path
- */
- void SetNRays (uint8_t nRays);
- /**
- * \param nOscillators Number of oscillators
- *
- * Set the number of oscillators to use to compute the ray coefficient
- */
- void SetNOscillators (uint8_t nOscillators);
-
- uint8_t GetNRays (void) const;
- uint8_t GetNOscillators (void) const;
+private:
+ double DoCalcRxPower (double txPowerDbm,
+ Ptr<MobilityModel> a,
+ Ptr<MobilityModel> b) const;
private:
- JakesPropagationLossModel (const JakesPropagationLossModel &o);
- JakesPropagationLossModel & operator = (const JakesPropagationLossModel &o);
- void DoConstruct (void);
- virtual double DoCalcRxPower (double txPowerDbm,
- Ptr<MobilityModel> a,
- Ptr<MobilityModel> b) const;
-
- class PathCoefficients;
- struct ComplexNumber {
- double real;
- double imag;
- };
- friend class PathCoefficents;
- typedef std::vector<PathCoefficients *> DestinationList;
- struct PathsSet {
- Ptr<MobilityModel> sender;
- DestinationList receivers;
- };
- typedef std::vector<PathsSet *> PathsList;
-
-
- static const double PI;
- ComplexNumber* m_amp;
- RandomVariable m_variable;
- double m_fd;
- mutable PathsList m_paths;
- uint8_t m_nRays;
- uint8_t m_nOscillators;
+ mutable PropagationCache<JakesProcess> m_propagationCache;
};
} // namespace ns3
-#endif /* PROPAGATION_JAKES_MODEL_H */
+#endif /* JAKES_STATIONARY_LOSS_MODEL_H */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/propagation/model/propagation-cache.h Tue May 22 16:41:05 2012 +0200
@@ -0,0 +1,86 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Telum (www.telum.ru)
+ *
+ * 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: Kirill Andreev <andreev@telum.ru>
+ */
+#ifndef PROPAGATION_CACHE_H_
+#define PROPAGATION_CACHE_H_
+
+#include "ns3/mobility-model.h"
+#include <map>
+
+namespace ns3
+{
+/**
+ * \ingroup propagation
+ * \brief Constructs a cache of objects, where each obect is responsible for a single propagation path loss calculations.
+ * Propagation path a-->b and b-->a is the same thing. Propagation path is identified by
+ * a couple of MobilityModels and a spectrum model UID
+ */
+template<class T>
+class PropagationCache
+{
+public:
+ PropagationCache () {};
+ ~PropagationCache () {};
+ Ptr<T> GetPathData (Ptr<const MobilityModel> a, Ptr<const MobilityModel> b, uint32_t modelUid)
+ {
+ PropagationPathIdentifier key = PropagationPathIdentifier (a, b, modelUid);
+ typename PathCache::iterator it = m_pathCache.find (key);
+ if (it == m_pathCache.end ())
+ {
+ Ptr<T> newPath = CreateObject<T> ();
+ m_pathCache.insert (std::make_pair (key, newPath));
+ return newPath;
+ }
+ return it->second;
+ };
+private:
+ /// Each path is identified by
+ struct PropagationPathIdentifier
+ {
+ PropagationPathIdentifier (Ptr<const MobilityModel> a, Ptr<const MobilityModel> b, uint32_t modelUid) :
+ m_srcMobility (a), m_dstMobility (b), m_spectrumModelUid (modelUid)
+ {};
+ Ptr<const MobilityModel> m_srcMobility;
+ Ptr<const MobilityModel> m_dstMobility;
+ uint32_t m_spectrumModelUid;
+ bool operator < (const PropagationPathIdentifier & other) const
+ {
+ if (m_spectrumModelUid != other.m_spectrumModelUid)
+ {
+ return m_spectrumModelUid < other.m_spectrumModelUid;
+ }
+ /// Links are supposed to be symmetrical!
+ if (std::min (m_dstMobility, m_srcMobility) != std::min (other.m_dstMobility, other.m_srcMobility))
+ {
+ return std::min (m_dstMobility, m_srcMobility) < std::min (other.m_dstMobility, other.m_srcMobility);
+ }
+ if (std::max (m_dstMobility, m_srcMobility) != std::max (other.m_dstMobility, other.m_srcMobility))
+ {
+ return std::max (m_dstMobility, m_srcMobility) < std::max (other.m_dstMobility, other.m_srcMobility);
+ }
+ return false;
+ }
+ };
+ typedef std::map<PropagationPathIdentifier, Ptr<T> > PathCache;
+private:
+ PathCache m_pathCache;
+};
+} // namespace ns3
+
+#endif // PROPAGATION_CACHE_H_
--- a/src/propagation/wscript Tue May 22 16:40:24 2012 +0200
+++ b/src/propagation/wscript Tue May 22 16:41:05 2012 +0200
@@ -7,6 +7,7 @@
'model/propagation-delay-model.cc',
'model/propagation-loss-model.cc',
'model/jakes-propagation-loss-model.cc',
+ 'model/jakes-process.cc',
'model/cost231-propagation-loss-model.cc',
'model/okumura-hata-propagation-loss-model.cc',
'model/itu-r-1411-los-propagation-loss-model.cc',
@@ -29,6 +30,8 @@
'model/propagation-delay-model.h',
'model/propagation-loss-model.h',
'model/jakes-propagation-loss-model.h',
+ 'model/jakes-process.h',
+ 'model/propagation-cache.h',
'model/cost231-propagation-loss-model.h',
'model/propagation-environment.h',
'model/okumura-hata-propagation-loss-model.h',