5#include "cc-bwp-helper.h"
8#include <ns3/spectrum-channel.h>
9#include <ns3/three-gpp-propagation-loss-model.h>
10#include <ns3/three-gpp-spectrum-propagation-loss-model.h>
18NS_LOG_COMPONENT_DEFINE(
"CcBwpHelper");
23 NS_LOG_FUNCTION(
this);
30 m_bwp.emplace_back(std::move(bwp));
33 while (i <
m_bwp.size() - 1)
35 auto& bwp =
m_bwp.at(i);
36 auto& nextBwp =
m_bwp.at(i + 1);
37 if (bwp->m_higherFrequency > nextBwp->m_lowerFrequency)
39 NS_LOG_ERROR(
"BWP ID "
40 << +bwp->m_bwpId <<
" has higher freq = " << bwp->m_higherFrequency / 1e6
41 <<
"MHz while BWP ID " << +nextBwp->m_bwpId
42 <<
" has lower freq = " << nextBwp->m_lowerFrequency / 1e6 <<
" MHz.");
48 for (
auto& bwp :
m_bwp)
50 NS_LOG_INFO(
"Create BWP with bwpId: "
51 << +bwp->m_bwpId <<
" lower: " << bwp->m_lowerFrequency / 1e6
52 <<
" with central freq: " << bwp->m_centralFrequency / 1e6
53 <<
" higher: " << bwp->m_higherFrequency / 1e6
54 <<
" BW: " << bwp->m_channelBandwidth / 1e6 <<
" MHz");
63 NS_LOG_FUNCTION(
this);
69 m_cc.emplace_back(std::move(cc));
72 while (i <
m_cc.size() - 1)
74 auto& cc =
m_cc.at(i);
75 auto& nextCc =
m_cc.at(i + 1);
76 if (cc->m_higherFrequency > nextCc->m_lowerFrequency)
78 NS_LOG_WARN(
"Cc at " << i <<
" has higher freq " << cc->m_higherFrequency / 1e6
79 <<
" while Cc at " << i + 1 <<
" has freq at "
88 NS_LOG_INFO(
"Create CC with ccId: "
89 << +cc->m_ccId <<
" lower: " << cc->m_lowerFrequency / 1e6
90 <<
" with central freq: " << cc->m_centralFrequency / 1e6
91 <<
" higher: " << cc->m_higherFrequency / 1e6
92 <<
" BW: " << cc->m_channelBandwidth / 1e6 <<
" MHz");
101 return m_cc.at(ccId)->m_bwp.at(bwpId);
107 std::vector<std::reference_wrapper<BandwidthPartInfoPtr>> ret;
109 for (
const auto& cc :
m_cc)
111 for (
auto& bwp : cc->m_bwp)
113 ret.emplace_back(bwp);
125CcBwpCreator::InitializeCc(std::unique_ptr<ComponentCarrierInfo>& cc,
131 NS_LOG_FUNCTION(
this);
132 cc->m_centralFrequency = lowerFreq + ccPosition * ccBandwidth + ccBandwidth / 2;
133 cc->m_lowerFrequency = lowerFreq + ccPosition * ccBandwidth;
134 cc->m_higherFrequency = lowerFreq + (ccPosition + 1) * ccBandwidth - 1;
135 cc->m_channelBandwidth = ccBandwidth;
137 NS_LOG_INFO(
"Initialize the op band "
138 << +ccPosition <<
"st (or nd) CC of BW " << ccBandwidth / 1e6 <<
" MHz "
139 <<
" from " << lowerFreq / 1e6 <<
"MHz, resulting in: " << *cc);
143CcBwpCreator::InitializeBwp(std::unique_ptr<BandwidthPartInfo>& bwp,
149 NS_LOG_FUNCTION(
this);
150 bwp->m_centralFrequency = lowerFreq + bwpPosition * bwOfBwp + bwOfBwp / 2;
151 bwp->m_lowerFrequency = lowerFreq + bwpPosition * bwOfBwp;
152 bwp->m_higherFrequency = lowerFreq + (bwpPosition + 1) * bwOfBwp - 1;
153 bwp->m_channelBandwidth = bwOfBwp;
154 bwp->m_bwpId = bwpId;
155 NS_LOG_INFO(
"Initialize the " << +bwpPosition <<
"st (or nd) BWP of BW " << bwOfBwp / 1e6
156 <<
" MHz, from " << lowerFreq / 1e6
157 <<
"MHz, resulting in: " << *bwp);
160std::unique_ptr<ComponentCarrierInfo>
161CcBwpCreator::CreateCc(
double ccBandwidth,
169 std::unique_ptr<ComponentCarrierInfo> cc(
new ComponentCarrierInfo());
170 InitializeCc(cc, ccBandwidth, lowerFreq, ccPosition, ccId);
172 double bwpBandwidth = ccBandwidth / bwpNumber;
174 for (uint8_t i = 0; i < bwpNumber; ++i)
176 std::unique_ptr<BandwidthPartInfo> bwp(
new BandwidthPartInfo());
177 InitializeBwp(bwp, bwpBandwidth, cc->m_lowerFrequency, i, m_bandwidthPartCounter++);
178 bwp->m_scenario = scenario;
179 bool ret = cc->AddBwp(std::move(bwp));
190 NS_LOG_FUNCTION(
this);
191 NS_LOG_INFO(
"Creating an op band formed by " << +conf.
m_numCc <<
" contiguous CC"
197 band.
m_bandId = m_operationBandCounter++;
203 NS_LOG_INFO(
"Resulting OpBand: " << band);
205 uint32_t maxCcBandwidth = 198e6;
209 maxCcBandwidth = 396e6;
212 double ccBandwidth = std::min(
static_cast<double>(maxCcBandwidth),
215 for (uint8_t ccPosition = 0; ccPosition < conf.
m_numCc; ++ccPosition)
217 bool ret = band.
AddCc(CreateCc(ccBandwidth,
220 m_componentCarrierCounter++,
232 const std::vector<SimpleOperationBandConf>& configuration)
235 band.
m_bandId = m_operationBandCounter++;
237 for (
const auto& conf : configuration)
239 NS_ASSERT(conf.m_numBwp == 1);
240 band.
AddCc(CreateCc(conf.m_channelBandwidth,
243 m_componentCarrierCounter++,
253 const std::vector<std::reference_wrapper<OperationBandInfo>>& operationBands)
257 for (
const auto& operationBand : operationBands)
259 auto v = operationBand.get().
GetBwps();
260 ret.insert(ret.end(), std::make_move_iterator(v.begin()), std::make_move_iterator(v.end()));
268 const std::string& filename)
270 std::ofstream outFile;
271 outFile.open(filename.c_str(), std::ios_base::out | std::ios_base::trunc);
272 if (!outFile.is_open())
274 NS_LOG_ERROR(
"Can't open file " << filename);
283 double minFreq = 100e9;
285 for (
const auto& band : bands)
287 if (band->m_lowerFrequency < minFreq)
289 minFreq = band->m_lowerFrequency;
291 if (band->m_higherFrequency > maxFreq)
293 maxFreq = band->m_higherFrequency;
297 outFile <<
"set term eps" << std::endl;
298 outFile <<
"set output \"" << filename <<
".eps\"" << std::endl;
299 outFile <<
"set grid" << std::endl;
301 outFile <<
"set xrange [";
302 outFile << minFreq * 1e-6 - 1;
304 outFile << maxFreq * 1e-6 + 1;
306 outFile << std::endl;
308 outFile <<
"set yrange [1:100]" << std::endl;
309 outFile <<
"set xlabel \"f [MHz]\"" << std::endl;
312 for (
const auto& band : bands)
314 std::string label =
"n";
315 uint16_t bandId =
static_cast<uint16_t
>(band->m_bandId);
316 label += std::to_string(bandId);
317 PlotFrequencyBand(outFile,
319 band->m_lowerFrequency * 1e-6,
320 band->m_higherFrequency * 1e-6,
325 for (
auto& cc : band->m_cc)
327 uint16_t ccId =
static_cast<uint16_t
>(cc->m_ccId);
328 label =
"CC" + std::to_string(ccId);
329 PlotFrequencyBand(outFile,
331 cc->m_lowerFrequency * 1e-6,
332 cc->m_higherFrequency * 1e-6,
337 for (
auto& bwp : cc->m_bwp)
339 uint16_t bwpId =
static_cast<uint16_t
>(bwp->m_bwpId);
340 label =
"BWP" + std::to_string(bwpId);
341 PlotFrequencyBand(outFile,
343 bwp->m_lowerFrequency * 1e-6,
344 bwp->m_higherFrequency * 1e-6,
353 outFile <<
"unset key" << std::endl;
354 outFile <<
"plot -x" << std::endl;
359 const std::string& filename)
361 std::ofstream outFile;
362 outFile.open(filename.c_str(), std::ios_base::out | std::ios_base::trunc);
363 if (!outFile.is_open())
365 NS_LOG_ERROR(
"Can't open file " << filename);
372 double minFreq = 100e9;
374 for (
const auto& band : bands)
376 if (band->m_lowerFrequency < minFreq)
378 minFreq = band->m_lowerFrequency;
380 if (band->m_higherFrequency > maxFreq)
382 maxFreq = band->m_higherFrequency;
386 outFile <<
"set term eps" << std::endl;
387 outFile <<
"set output \"" << filename <<
".eps\"" << std::endl;
388 outFile <<
"set grid" << std::endl;
390 outFile <<
"set xrange [";
391 outFile << minFreq * 1e-6 - 1;
393 outFile << maxFreq * 1e-6 + 1;
395 outFile << std::endl;
397 outFile <<
"set yrange [1:100]" << std::endl;
398 outFile <<
"set xlabel \"f [MHz]\"" << std::endl;
401 for (
const auto& band : bands)
403 std::string label =
"n";
404 uint16_t bandId =
static_cast<uint16_t
>(band->m_bandId);
405 label += std::to_string(bandId);
406 PlotFrequencyBand(outFile,
408 band->m_lowerFrequency * 1e-6,
409 band->m_higherFrequency * 1e-6,
414 for (
auto& cc : band->m_cc)
416 uint16_t ccId =
static_cast<uint16_t
>(cc->m_ccId);
417 label =
"CC" + std::to_string(ccId);
418 PlotFrequencyBand(outFile,
420 cc->m_lowerFrequency * 1e-6,
421 cc->m_higherFrequency * 1e-6,
429 outFile <<
"unset key" << std::endl;
430 outFile <<
"plot -x" << std::endl;
434CcBwpCreator::PlotFrequencyBand(std::ofstream& outFile,
440 const std::string& label)
442 outFile <<
"set object " << index <<
" rect from " << xmin <<
"," << ymin <<
" to " << xmax
443 <<
"," << ymax <<
" front fs empty " << std::endl;
445 outFile <<
"LABEL" << index <<
" = \"" << label <<
"\"" << std::endl;
447 outFile <<
"set label " << index <<
" at " << xmin <<
"," << (ymin + ymax) / 2 <<
" LABEL"
448 << index << std::endl;
451BandwidthPartInfo::BandwidthPartInfo(uint8_t bwpId,
452 double centralFrequency,
453 double channelBandwidth,
456 m_centralFrequency(centralFrequency),
457 m_channelBandwidth(channelBandwidth),
460 NS_ASSERT_MSG(centralFrequency > channelBandwidth / 2,
461 "Configuration error with channel bandwidth");
469 NS_LOG_FUNCTION(
this);
470 static std::unordered_map<Scenario, std::string, std::hash<int>> lookupTable{
493 return lookupTable[m_scenario];
503 for (
const auto& bwp : item.m_bwp)
505 os <<
"\t\t" << *bwp << std::endl;
511operator<<(std::ostream& os,
const OperationBandInfo& item)
513 os <<
"id: " << +item.m_bandId <<
" lower freq " << item.m_lowerFrequency / 1e6
514 <<
" MHz central freq " << item.m_centralFrequency / 1e6 <<
" MHz higher freq "
515 << item.m_higherFrequency / 1e6 <<
" MHz bw " << item.m_channelBandwidth / 1e6 <<
" MHz."
517 for (
const auto& cc : item.m_cc)
519 os <<
"\t" << *cc << std::endl;
525operator<<(std::ostream& os,
const BandwidthPartInfo& item)
527 os <<
"id: " << +item.m_bwpId <<
" lower freq " << item.m_lowerFrequency / 1e6
528 <<
" MHz central freq " << item.m_centralFrequency / 1e6 <<
" MHz higher freq "
529 << item.m_higherFrequency / 1e6 <<
" MHz bw " << item.m_channelBandwidth / 1e6 <<
" MHz.";
OperationBandInfo CreateOperationBandContiguousCc(const SimpleOperationBandConf &conf)
Create an operation band with the CC specified.
static BandwidthPartInfoPtrVector GetAllBwps(const std::vector< std::reference_wrapper< OperationBandInfo > > &operationBands)
Get all the BWP pointers from the specified vector of operation bands.
static void PlotLteCaConfiguration(const std::vector< OperationBandInfo * > &bands, const std::string &filename)
Plots the CA/BWP configuration using GNUPLOT. There must be a valid configuration.
static void PlotNrCaBwpConfiguration(const std::vector< OperationBandInfo * > &bands, const std::string &filename)
Plots the CA/BWP configuration using GNUPLOT. There must be a valid configuration.
OperationBandInfo CreateOperationBandNonContiguousCc(const std::vector< SimpleOperationBandConf > &configuration)
Creates an operation band with non-contiguous CC.
std::unique_ptr< BandwidthPartInfo > BandwidthPartInfoPtr
unique_ptr of BandwidthPartInfo
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
std::unique_ptr< ComponentCarrierInfo > ComponentCarrierInfoPtr
unique_ptr of ComponentCarrierInfo
double m_lowerFrequency
BWP lower frequency.
std::string GetScenario() const
Retrieve a string version of the scenario.
double m_higherFrequency
BWP higher frequency.
Scenario
Different types for the propagation loss model of this bandwidth part.
@ UMi_Buildings
UMi_StreetCanyon with buildings.
@ Custom
User-defined custom scenario.
@ UMa_LoS
UMa where all the nodes will be in Line-of-Sight.
@ RMa_LoS
RMa where all the nodes will be in Line-of-Sight.
@ InH_OfficeOpen
InH_OfficeOpen.
@ InH_OfficeOpen_nLoS
indoor office where all the nodes will not be in Line-of-Sight
@ V2V_Highway
V2V_Highway.
@ RMa_nLoS
RMA where all the nodes will not be in Line-of-Sight.
@ InH_OfficeMixed_nLoS
indoor office where all the nodes will not be in Line-of-Sight
@ UMa_Buildings
UMa with buildings.
@ InH_OfficeOpen_LoS
indoor office where all the nodes will be in Line-of-Sight
@ UMa_nLoS
UMa where all the nodes will not be in Line-of-Sight.
@ UMi_StreetCanyon_LoS
UMi_StreetCanyon where all the nodes will be in Line-of-Sight.
@ InH_OfficeMixed
InH_OfficeMixed.
@ UMi_StreetCanyon
UMi_StreetCanyon.
@ InH_OfficeMixed_LoS
indoor office where all the nodes will be in Line-of-Sight
Minimum configuration requirements for a OperationBand.
uint8_t m_numCc
Number of CC in this OpBand.
uint8_t m_numBwp
Number of BWP per CC.
double m_centralFrequency
Central Freq.
double m_channelBandwidth
Total Bandwidth of the operation band.
BandwidthPartInfo::Scenario m_scenario
Scenario.
Component carrier configuration element.
double m_higherFrequency
BWP higher frequency.
bool AddBwp(BandwidthPartInfoPtr &&bwp)
Adds a bandwidth part configuration to the carrier.
double m_lowerFrequency
BWP lower frequency.
std::vector< BandwidthPartInfoPtr > m_bwp
Space for BWP.
double m_channelBandwidth
BWP bandwidth.
double m_centralFrequency
BWP central frequency.
Operation band information structure.
double m_channelBandwidth
Operation band bandwidth.
BandwidthPartInfoPtr & GetBwpAt(uint32_t ccId, uint32_t bwpId) const
Get the BWP at the cc/bwp specified.
std::vector< ComponentCarrierInfoPtr > m_cc
Operation band component carriers.
BandwidthPartInfoPtrVector GetBwps() const
Get the list of all the BWPs to pass to NrHelper.
bool AddCc(ComponentCarrierInfoPtr &&cc)
Adds the component carrier definition given as an input reference to the current operation band confi...
double m_lowerFrequency
Operation band lower frequency.
double m_centralFrequency
Operation band central frequency.
double m_higherFrequency
Operation band higher frequency.
uint8_t m_bandId
Operation band id.