A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("LteUePowerControl");
30 
31 namespace ns3 {
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),
79  MakeBooleanAccessor (&LteUePowerControl::m_closedLoop),
80  MakeBooleanChecker ())
81  .AddAttribute ("AccumulationEnabled",
82  "If true TCP accumulation mode will be active, otherwise absolute mode will be active",
83  BooleanValue (true),
84  MakeBooleanAccessor (&LteUePowerControl::m_accumulationEnabled),
85  MakeBooleanChecker ())
86  .AddAttribute ("Alpha",
87  "Value of Alpha paramter",
88  DoubleValue (1.0),
89  MakeDoubleAccessor (&LteUePowerControl::SetAlpha),
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),
95  MakeDoubleAccessor (&LteUePowerControl::m_Pcmax),
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),
101  MakeDoubleAccessor (&LteUePowerControl::m_Pcmin),
102  MakeDoubleChecker<double> ())
103  .AddAttribute ("PoNominalPusch",
104  "P_O_NOMINAL_PUSCH INT (-126 ... 24), Default value -80",
105  IntegerValue (-80),
106  MakeIntegerAccessor (&LteUePowerControl::SetPoNominalPusch),
107  MakeIntegerChecker<int16_t> ())
108  .AddAttribute ("PoUePusch",
109  "P_O_UE_PUSCH INT(-8...7), Default value 0",
110  IntegerValue (0),
111  MakeIntegerAccessor (&LteUePowerControl::SetPoUePusch),
112  MakeIntegerChecker<int16_t> ())
113  .AddAttribute ("PsrsOffset",
114  "P_SRS_OFFSET INT(0...15), Default value 7",
115  IntegerValue (7),
116  MakeIntegerAccessor (&LteUePowerControl::m_PsrsOffset),
117  MakeIntegerChecker<int16_t> ())
118  .AddTraceSource ("ReportPuschTxPower",
119  "Report PUSCH TxPower in dBm",
121  .AddTraceSource ("ReportPucchTxPower",
122  "Report PUCCH TxPower in dBm",
124  .AddTraceSource ("ReportSrsTxPower",
125  "Report SRS TxPower in dBm",
127  ;
128  return tid;
129 }
130 
131 void
133 {
134  NS_LOG_FUNCTION (this);
135  m_Pcmax = value;
136 }
137 
138 double
140 {
141  NS_LOG_FUNCTION (this);
142  return m_Pcmax;
143 }
144 
145 void
147 {
148  NS_LOG_FUNCTION (this);
149  m_txPower = value;
150  m_curPuschTxPower = value;
151  m_curPucchTxPower = value;
152  m_curSrsTxPower = value;
153 }
154 
155 void
157 {
158  NS_LOG_FUNCTION (this);
159  m_referenceSignalPower = referenceSignalPower;
160 }
161 
162 void
164 {
165  NS_LOG_FUNCTION (this);
166  m_cellId = cellId;
167 }
168 void
170 {
171  NS_LOG_FUNCTION (this);
172  m_rnti = rnti;
173 }
174 
175 void
177 {
178  NS_LOG_FUNCTION (this);
179 
180  if (m_PoNominalPusch.empty ())
181  {
182  m_PoNominalPusch.push_back (value);
183  m_PoNominalPusch.push_back (value);
184  m_PoNominalPusch.push_back (value);
185  }
186  else
187  {
188  m_PoNominalPusch[0] = value;
189  m_PoNominalPusch[1] = value;
190  m_PoNominalPusch[2] = value;
191  }
192 
193 }
194 void
196 {
197  NS_LOG_FUNCTION (this);
198  if (m_PoUePusch.empty ())
199  {
200  m_PoUePusch.push_back (value);
201  m_PoUePusch.push_back (value);
202  m_PoUePusch.push_back (0);
203  }
204  else
205  {
206  m_PoUePusch[0] = value;
207  m_PoUePusch[1] = value;
208  m_PoUePusch[2] = 0;
209  }
210 }
211 void
213 {
214  NS_LOG_FUNCTION (this);
215 
216  uint32_t temp = value * 10;
217  switch (temp)
218  {
219  case 0:
220  case 4:
221  case 5:
222  case 6:
223  case 7:
224  case 8:
225  case 9:
226  case 10:
227  break;
228  default:
229  NS_FATAL_ERROR ("Unexpected Alpha value");
230  }
231 
232  if (m_alpha.empty ())
233  {
234  m_alpha.push_back (value);
235  m_alpha.push_back (value);
236  m_alpha.push_back (0);
237  }
238  else
239  {
240  m_alpha[0] = value;
241  m_alpha[1] = value;
242  m_alpha[2] = 1;
243  }
244 
245 }
246 
247 void
249 {
250  NS_LOG_FUNCTION (this);
251 
252  if (!m_rsrpSet)
253  {
254  m_rsrp = value;
255  m_rsrpSet = true;
256  return;
257  }
258 
259  double coeff = 0.7;
260  m_rsrp = coeff * m_rsrp + (1 - coeff) * value;
262 }
263 
264 void
266 {
267  NS_LOG_FUNCTION (this);
268 
269  int delta = 0;
271  {
272  switch (tpc)
273  {
274  case 0:
275  delta = -1;
276  break;
277  case 1:
278  delta = 0;
279  break;
280  case 2:
281  delta = 1;
282  break;
283  case 3:
284  delta = 3;
285  break;
286  default:
287  NS_FATAL_ERROR ("Unexpected TPC value");
288  }
289  }
290  else
291  {
292  switch (tpc)
293  {
294  case 0:
295  delta = -4;
296  break;
297  case 1:
298  delta = -1;
299  break;
300  case 2:
301  delta = 1;
302  break;
303  case 3:
304  delta = 4;
305  break;
306  default:
307  NS_FATAL_ERROR ("Unexpected TPC value");
308  }
309  }
310 
311  m_deltaPusch.push_back (delta);
312 
313  if (m_closedLoop)
314  {
316  {
317  if (m_deltaPusch.size () == 4)
318  {
319  if ((m_curPuschTxPower <= m_Pcmin && m_deltaPusch.at (0) < 0)
320  || (m_curPuschTxPower >= m_Pcmax && m_deltaPusch.at (0) > 0))
321  {
322  //TPC commands for serving cell shall not be accumulated
323  m_deltaPusch.erase (m_deltaPusch.begin ());
324  }
325  else
326  {
327  m_fc = m_fc + m_deltaPusch.at (0);
328  m_deltaPusch.erase (m_deltaPusch.begin ());
329  }
330  }
331  else
332  {
333  m_fc = 0;
334  }
335  }
336  else
337  {
338  m_fc = m_deltaPusch.at (0);
339  m_deltaPusch.erase (m_deltaPusch.begin ());
340  }
341  }
342  else
343  {
344  m_fc = 0;
345  }
346 
347  NS_LOG_INFO ("ReportTpc: " << (int)tpc << " delta: " << delta << " Fc: " << m_fc);
348 }
349 
350 void
351 LteUePowerControl::SetSubChannelMask (std::vector <int> mask)
352 {
353  NS_LOG_FUNCTION (this);
354  m_M_Pusch = mask.size ();
355 }
356 
357 void
359 {
360  NS_LOG_FUNCTION (this);
361  int32_t j = 1;
362  int32_t PoPusch = m_PoNominalPusch[j] + m_PoUePusch[j];
363 
364  NS_LOG_INFO ("RB: " << m_M_Pusch << " m_PoPusch: " << PoPusch
365  << " Alpha: " << m_alpha[j] << " PathLoss: " << m_pathLoss
366  << " deltaTF: " << m_deltaTF << " fc: " << m_fc);
367 
368  if ( m_M_Pusch > 0 )
369  {
370  m_curPuschTxPower = 10 * log10 (1.0 * m_M_Pusch) + PoPusch + m_alpha[j] * m_pathLoss + m_deltaTF + m_fc;
371  m_M_Pusch = 0;
372  }
373  else
374  {
375  m_curPuschTxPower = PoPusch + m_alpha[j] * m_pathLoss + m_fc;
376  }
377 
378  NS_LOG_INFO ("CalcPower: " << m_curPuschTxPower << " MinPower: " << m_Pcmin << " MaxPower:" << m_Pcmax);
379 
382  NS_LOG_INFO ("PuschTxPower: " << m_curPuschTxPower);
383 }
384 
385 void
387 {
388  NS_LOG_FUNCTION (this);
390  NS_LOG_INFO ("PucchTxPower: " << m_curPucchTxPower);
391 }
392 
393 void
395 {
396  NS_LOG_FUNCTION (this);
397  int32_t j = 1;
398  int32_t PoPusch = m_PoNominalPusch[j] + m_PoUePusch[j];
399 
400  NS_LOG_INFO ("RB: " << m_M_Pusch << " m_PoPusch: " << PoPusch
401  << " Alpha: " << m_alpha[j] << " PathLoss: " << m_pathLoss
402  << " deltaTF: " << m_deltaTF << " fc: " << m_fc);
403 
404 
405  double pSrsOffsetValue = -10.5 + m_PsrsOffset * 1.5;
406 
407  m_curSrsTxPower = pSrsOffsetValue + 10 * log10 (m_srsBandwidth) + PoPusch + m_alpha[j] * m_pathLoss + m_fc;
408 
409  NS_LOG_INFO ("CalcPower: " << m_curSrsTxPower << " MinPower: " << m_Pcmin << " MaxPower:" << m_Pcmax);
410 
413  NS_LOG_INFO ("SrsTxPower: " << m_curSrsTxPower);
414 }
415 
416 
417 double
418 LteUePowerControl::GetPuschTxPower (std::vector <int> dlRb)
419 {
420  NS_LOG_FUNCTION (this);
421 
422  m_M_Pusch = dlRb.size ();
424 
426 
427  return m_curPuschTxPower;
428 }
429 
430 double
431 LteUePowerControl::GetPucchTxPower (std::vector <int> dlRb)
432 {
433  NS_LOG_FUNCTION (this);
434 
436 
438 
439  return m_curPucchTxPower;
440 }
441 
442 double
443 LteUePowerControl::GetSrsTxPower (std::vector <int> dlRb)
444 {
445  NS_LOG_FUNCTION (this);
446 
447  m_srsBandwidth = dlRb.size ();
449 
451 
452  return m_curSrsTxPower;
453 }
454 
455 } // 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 "...
Hold a bool native type.
Definition: boolean.h:38
void SetCellId(uint16_t cellId)
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
double GetPuschTxPower(std::vector< int > rb)
void SetPoUePusch(int16_t value)
Hold a signed integer type.
Definition: integer.h:45
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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:223
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
TracedCallback< uint16_t, uint16_t, double > m_reportPucchTxPower
TracedCallback< uint16_t, uint16_t, double > m_reportSrsTxPower
virtual void DoInitialize(void)
This method is called only once by Object::Initialize.
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
void SetPoNominalPusch(int16_t value)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
std::vector< double > m_alpha
void SetRnti(uint16_t rnti)
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:64
void ConfigureReferenceSignalPower(int8_t referenceSignalPower)
Hold a floating point type.
Definition: double.h:41
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...