A Discrete-Event Network Simulator
API
lte-ue-power-control.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014 Piotr Gawlowicz
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Piotr Gawlowicz <gawlowicz.p@gmail.com>
19  *
20  */
21 
22 #include "lte-ue-power-control.h"
23 #include <ns3/log.h>
24 #include <ns3/boolean.h>
25 #include <ns3/double.h>
26 #include <ns3/integer.h>
27 #include <ns3/math.h>
28 
29 namespace ns3 {
30 
31 NS_LOG_COMPONENT_DEFINE ("LteUePowerControl");
32 
33 NS_OBJECT_ENSURE_REGISTERED (LteUePowerControl);
34 
36 {
37  NS_LOG_FUNCTION (this);
38  m_deltaTF = 0;
39  m_fc = 0;
40  m_pathLoss = 100; //initial value
41  m_curPuschTxPower = 10;
42  m_curPucchTxPower = 10;
43  m_curSrsTxPower = 10;
44  m_txPower = 10;
45 
46  m_cellId = 0;
47  m_rnti = 0;
48 
49  m_M_Pusch = 0;
50  m_rsrpSet = false;
51 }
52 
54 {
55  NS_LOG_FUNCTION (this);
56 }
57 
58 void
60 {
61  NS_LOG_FUNCTION (this);
62 }
63 
64 void
66 {
67  NS_LOG_FUNCTION (this);
68 }
69 
70 TypeId
72 {
73  static TypeId tid = TypeId ("ns3::LteUePowerControl")
74  .SetParent<Object> ()
75  .AddConstructor<LteUePowerControl> ()
76  .AddAttribute ("ClosedLoop",
77  "If true Closed Loop mode will be active, otherwise Open Loop",
78  BooleanValue (true),
81  .AddAttribute ("AccumulationEnabled",
82  "If true TCP accumulation mode will be active, otherwise absolute mode will be active",
83  BooleanValue (true),
86  .AddAttribute ("Alpha",
87  "Value of Alpha paramter",
88  DoubleValue (1.0),
90  MakeDoubleChecker<double> ())
91  .AddAttribute ("Pcmax",
92  "Max Transmission power in dBm, Default value 23 dBm"
93  "TS36.101 section 6.2.3",
94  DoubleValue (23.0),
96  MakeDoubleChecker<double> ())
97  .AddAttribute ("Pcmin",
98  "Min Transmission power in dBm, Default value -40 dBm"
99  "TS36.101 section 6.2.3",
100  DoubleValue (-40),
102  MakeDoubleChecker<double> ())
103  .AddAttribute ("PoNominalPusch",
104  "P_O_NOMINAL_PUSCH INT (-126 ... 24), Default value -80",
105  IntegerValue (-80),
107  MakeIntegerChecker<int16_t> ())
108  .AddAttribute ("PoUePusch",
109  "P_O_UE_PUSCH INT(-8...7), Default value 0",
110  IntegerValue (0),
112  MakeIntegerChecker<int16_t> ())
113  .AddAttribute ("PsrsOffset",
114  "P_SRS_OFFSET INT(0...15), Default value 7",
115  IntegerValue (7),
117  MakeIntegerChecker<int16_t> ())
118  .AddTraceSource ("ReportPuschTxPower",
119  "Report PUSCH TxPower in dBm",
121  "ns3::LteUePowerControl::TxPowerTracedCallback")
122  .AddTraceSource ("ReportPucchTxPower",
123  "Report PUCCH TxPower in dBm",
125  "ns3::LteUePowerControl::TxPowerTracedCallback")
126  .AddTraceSource ("ReportSrsTxPower",
127  "Report SRS TxPower in dBm",
129  "ns3::LteUePowerControl::TxPowerTracedCallback")
130  ;
131  return tid;
132 }
133 
134 void
136 {
137  NS_LOG_FUNCTION (this);
138  m_Pcmax = value;
139 }
140 
141 double
143 {
144  NS_LOG_FUNCTION (this);
145  return m_Pcmax;
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this);
152  m_txPower = value;
153  m_curPuschTxPower = value;
154  m_curPucchTxPower = value;
155  m_curSrsTxPower = value;
156 }
157 
158 void
160 {
161  NS_LOG_FUNCTION (this);
162  m_referenceSignalPower = referenceSignalPower;
163 }
164 
165 void
167 {
168  NS_LOG_FUNCTION (this);
169  m_cellId = cellId;
170 }
171 void
173 {
174  NS_LOG_FUNCTION (this);
175  m_rnti = rnti;
176 }
177 
178 void
180 {
181  NS_LOG_FUNCTION (this);
182 
183  if (m_PoNominalPusch.empty ())
184  {
185  m_PoNominalPusch.push_back (value);
186  m_PoNominalPusch.push_back (value);
187  m_PoNominalPusch.push_back (value);
188  }
189  else
190  {
191  m_PoNominalPusch[0] = value;
192  m_PoNominalPusch[1] = value;
193  m_PoNominalPusch[2] = value;
194  }
195 
196 }
197 void
199 {
200  NS_LOG_FUNCTION (this);
201  if (m_PoUePusch.empty ())
202  {
203  m_PoUePusch.push_back (value);
204  m_PoUePusch.push_back (value);
205  m_PoUePusch.push_back (0);
206  }
207  else
208  {
209  m_PoUePusch[0] = value;
210  m_PoUePusch[1] = value;
211  m_PoUePusch[2] = 0;
212  }
213 }
214 void
216 {
217  NS_LOG_FUNCTION (this);
218 
219  uint32_t temp = value * 10;
220  switch (temp)
221  {
222  case 0:
223  case 4:
224  case 5:
225  case 6:
226  case 7:
227  case 8:
228  case 9:
229  case 10:
230  break;
231  default:
232  NS_FATAL_ERROR ("Unexpected Alpha value");
233  }
234 
235  if (m_alpha.empty ())
236  {
237  m_alpha.push_back (value);
238  m_alpha.push_back (value);
239  m_alpha.push_back (0);
240  }
241  else
242  {
243  m_alpha[0] = value;
244  m_alpha[1] = value;
245  m_alpha[2] = 1;
246  }
247 
248 }
249 
250 void
252 {
253  NS_LOG_FUNCTION (this);
254 
255  if (!m_rsrpSet)
256  {
257  m_rsrp = value;
258  m_rsrpSet = true;
259  return;
260  }
261 
262  double coeff = 0.7;
263  m_rsrp = coeff * m_rsrp + (1 - coeff) * value;
265 }
266 
267 void
269 {
270  NS_LOG_FUNCTION (this);
271 
272  int delta = 0;
274  {
275  switch (tpc)
276  {
277  case 0:
278  delta = -1;
279  break;
280  case 1:
281  delta = 0;
282  break;
283  case 2:
284  delta = 1;
285  break;
286  case 3:
287  delta = 3;
288  break;
289  default:
290  NS_FATAL_ERROR ("Unexpected TPC value");
291  }
292  }
293  else
294  {
295  switch (tpc)
296  {
297  case 0:
298  delta = -4;
299  break;
300  case 1:
301  delta = -1;
302  break;
303  case 2:
304  delta = 1;
305  break;
306  case 3:
307  delta = 4;
308  break;
309  default:
310  NS_FATAL_ERROR ("Unexpected TPC value");
311  }
312  }
313 
314  m_deltaPusch.push_back (delta);
315 
316  if (m_closedLoop)
317  {
319  {
320  if (m_deltaPusch.size () == 4)
321  {
322  if ((m_curPuschTxPower <= m_Pcmin && m_deltaPusch.at (0) < 0)
323  || (m_curPuschTxPower >= m_Pcmax && m_deltaPusch.at (0) > 0))
324  {
325  //TPC commands for serving cell shall not be accumulated
326  m_deltaPusch.erase (m_deltaPusch.begin ());
327  }
328  else
329  {
330  m_fc = m_fc + m_deltaPusch.at (0);
331  m_deltaPusch.erase (m_deltaPusch.begin ());
332  }
333  }
334  else
335  {
336  m_fc = 0;
337  }
338  }
339  else
340  {
341  m_fc = m_deltaPusch.at (0);
342  m_deltaPusch.erase (m_deltaPusch.begin ());
343  }
344  }
345  else
346  {
347  m_fc = 0;
348  }
349 
350  NS_LOG_INFO ("ReportTpc: " << (int)tpc << " delta: " << delta << " Fc: " << m_fc);
351 }
352 
353 void
354 LteUePowerControl::SetSubChannelMask (std::vector <int> mask)
355 {
356  NS_LOG_FUNCTION (this);
357  m_M_Pusch = mask.size ();
358 }
359 
360 void
362 {
363  NS_LOG_FUNCTION (this);
364  int32_t j = 1;
365  int32_t PoPusch = m_PoNominalPusch[j] + m_PoUePusch[j];
366 
367  NS_LOG_INFO ("RB: " << m_M_Pusch << " m_PoPusch: " << PoPusch
368  << " Alpha: " << m_alpha[j] << " PathLoss: " << m_pathLoss
369  << " deltaTF: " << m_deltaTF << " fc: " << m_fc);
370 
371  if ( m_M_Pusch > 0 )
372  {
373  m_curPuschTxPower = 10 * log10 (1.0 * m_M_Pusch) + PoPusch + m_alpha[j] * m_pathLoss + m_deltaTF + m_fc;
374  m_M_Pusch = 0;
375  }
376  else
377  {
378  m_curPuschTxPower = PoPusch + m_alpha[j] * m_pathLoss + m_fc;
379  }
380 
381  NS_LOG_INFO ("CalcPower: " << m_curPuschTxPower << " MinPower: " << m_Pcmin << " MaxPower:" << m_Pcmax);
382 
385  NS_LOG_INFO ("PuschTxPower: " << m_curPuschTxPower);
386 }
387 
388 void
390 {
391  NS_LOG_FUNCTION (this);
393  NS_LOG_INFO ("PucchTxPower: " << m_curPucchTxPower);
394 }
395 
396 void
398 {
399  NS_LOG_FUNCTION (this);
400  int32_t j = 1;
401  int32_t PoPusch = m_PoNominalPusch[j] + m_PoUePusch[j];
402 
403  NS_LOG_INFO ("RB: " << m_M_Pusch << " m_PoPusch: " << PoPusch
404  << " Alpha: " << m_alpha[j] << " PathLoss: " << m_pathLoss
405  << " deltaTF: " << m_deltaTF << " fc: " << m_fc);
406 
407 
408  double pSrsOffsetValue = -10.5 + m_PsrsOffset * 1.5;
409 
410  m_curSrsTxPower = pSrsOffsetValue + 10 * log10 (m_srsBandwidth) + PoPusch + m_alpha[j] * m_pathLoss + m_fc;
411 
412  NS_LOG_INFO ("CalcPower: " << m_curSrsTxPower << " MinPower: " << m_Pcmin << " MaxPower:" << m_Pcmax);
413 
416  NS_LOG_INFO ("SrsTxPower: " << m_curSrsTxPower);
417 }
418 
419 
420 double
421 LteUePowerControl::GetPuschTxPower (std::vector <int> dlRb)
422 {
423  NS_LOG_FUNCTION (this);
424 
425  m_M_Pusch = dlRb.size ();
427 
429 
430  return m_curPuschTxPower;
431 }
432 
433 double
434 LteUePowerControl::GetPucchTxPower (std::vector <int> dlRb)
435 {
436  NS_LOG_FUNCTION (this);
437 
439 
441 
442  return m_curPucchTxPower;
443 }
444 
445 double
446 LteUePowerControl::GetSrsTxPower (std::vector <int> dlRb)
447 {
448  NS_LOG_FUNCTION (this);
449 
450  m_srsBandwidth = dlRb.size ();
452 
454 
455  return m_curSrsTxPower;
456 }
457 
458 } // namespace ns3
void SetTxPower(double value)
void SetSubChannelMask(std::vector< int > mask)
std::vector< int16_t > m_PoNominalPusch
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
AttributeValue implementation for Boolean.
Definition: boolean.h:34
void SetCellId(uint16_t cellId)
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
double GetPuschTxPower(std::vector< int > rb)
void SetPoUePusch(int16_t value)
Hold a signed integer type.
Definition: integer.h:44
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
std::vector< int8_t > m_deltaPusch
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
TracedCallback< uint16_t, uint16_t, double > m_reportPucchTxPower
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: integer.h:45
TracedCallback< uint16_t, uint16_t, double > m_reportSrsTxPower
virtual void DoInitialize(void)
Initialize() implementation.
TracedCallback< uint16_t, uint16_t, double > m_reportPuschTxPower
Trace information regarding Uplink TxPower uint16_t cellId, uint16_t rnti, double txPower...
static TypeId GetTypeId(void)
std::vector< int16_t > m_PoUePusch
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPoNominalPusch(int16_t value)
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
std::vector< double > m_alpha
void SetRnti(uint16_t rnti)
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: double.h:42
double GetPucchTxPower(std::vector< int > rb)
double GetSrsTxPower(std::vector< int > rb)
A base class which provides memory management and object aggregation.
Definition: object.h:87
void ConfigureReferenceSignalPower(int8_t referenceSignalPower)
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
a unique identifier for an interface.
Definition: type-id.h:51
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
virtual void DoDispose(void)
Destructor implementation.