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  .SetGroupName("Lte")
76  .AddConstructor<LteUePowerControl> ()
77  .AddAttribute ("ClosedLoop",
78  "If true Closed Loop mode will be active, otherwise Open Loop",
79  BooleanValue (true),
82  .AddAttribute ("AccumulationEnabled",
83  "If true TCP accumulation mode will be active, otherwise absolute mode will be active",
84  BooleanValue (true),
87  .AddAttribute ("Alpha",
88  "Value of Alpha paramter",
89  DoubleValue (1.0),
91  MakeDoubleChecker<double> ())
92  .AddAttribute ("Pcmax",
93  "Max Transmission power in dBm, Default value 23 dBm"
94  "TS36.101 section 6.2.3",
95  DoubleValue (23.0),
97  MakeDoubleChecker<double> ())
98  .AddAttribute ("Pcmin",
99  "Min Transmission power in dBm, Default value -40 dBm"
100  "TS36.101 section 6.2.3",
101  DoubleValue (-40),
103  MakeDoubleChecker<double> ())
104  .AddAttribute ("PoNominalPusch",
105  "P_O_NOMINAL_PUSCH INT (-126 ... 24), Default value -80",
106  IntegerValue (-80),
108  MakeIntegerChecker<int16_t> ())
109  .AddAttribute ("PoUePusch",
110  "P_O_UE_PUSCH INT(-8...7), Default value 0",
111  IntegerValue (0),
113  MakeIntegerChecker<int16_t> ())
114  .AddAttribute ("PsrsOffset",
115  "P_SRS_OFFSET INT(0...15), Default value 7",
116  IntegerValue (7),
118  MakeIntegerChecker<int16_t> ())
119  .AddTraceSource ("ReportPuschTxPower",
120  "Report PUSCH TxPower in dBm",
122  "ns3::LteUePowerControl::TxPowerTracedCallback")
123  .AddTraceSource ("ReportPucchTxPower",
124  "Report PUCCH TxPower in dBm",
126  "ns3::LteUePowerControl::TxPowerTracedCallback")
127  .AddTraceSource ("ReportSrsTxPower",
128  "Report SRS TxPower in dBm",
130  "ns3::LteUePowerControl::TxPowerTracedCallback")
131  ;
132  return tid;
133 }
134 
135 void
137 {
138  NS_LOG_FUNCTION (this);
139  m_Pcmax = value;
140 }
141 
142 double
144 {
145  NS_LOG_FUNCTION (this);
146  return m_Pcmax;
147 }
148 
149 void
151 {
152  NS_LOG_FUNCTION (this);
153  m_txPower = value;
154  m_curPuschTxPower = value;
155  m_curPucchTxPower = value;
156  m_curSrsTxPower = value;
157 }
158 
159 void
161 {
162  NS_LOG_FUNCTION (this);
163  m_referenceSignalPower = referenceSignalPower;
164 }
165 
166 void
168 {
169  NS_LOG_FUNCTION (this);
170  m_cellId = cellId;
171 }
172 void
174 {
175  NS_LOG_FUNCTION (this);
176  m_rnti = rnti;
177 }
178 
179 void
181 {
182  NS_LOG_FUNCTION (this);
183 
184  if (m_PoNominalPusch.empty ())
185  {
186  m_PoNominalPusch.push_back (value);
187  m_PoNominalPusch.push_back (value);
188  m_PoNominalPusch.push_back (value);
189  }
190  else
191  {
192  m_PoNominalPusch[0] = value;
193  m_PoNominalPusch[1] = value;
194  m_PoNominalPusch[2] = value;
195  }
196 
197 }
198 void
200 {
201  NS_LOG_FUNCTION (this);
202  if (m_PoUePusch.empty ())
203  {
204  m_PoUePusch.push_back (value);
205  m_PoUePusch.push_back (value);
206  m_PoUePusch.push_back (0);
207  }
208  else
209  {
210  m_PoUePusch[0] = value;
211  m_PoUePusch[1] = value;
212  m_PoUePusch[2] = 0;
213  }
214 }
215 void
217 {
218  NS_LOG_FUNCTION (this);
219 
220  uint32_t temp = value * 10;
221  switch (temp)
222  {
223  case 0:
224  case 4:
225  case 5:
226  case 6:
227  case 7:
228  case 8:
229  case 9:
230  case 10:
231  break;
232  default:
233  NS_FATAL_ERROR ("Unexpected Alpha value");
234  }
235 
236  if (m_alpha.empty ())
237  {
238  m_alpha.push_back (value);
239  m_alpha.push_back (value);
240  m_alpha.push_back (0);
241  }
242  else
243  {
244  m_alpha[0] = value;
245  m_alpha[1] = value;
246  m_alpha[2] = 1;
247  }
248 
249 }
250 
251 void
253 {
254  NS_LOG_FUNCTION (this);
255 
256  if (!m_rsrpSet)
257  {
258  m_rsrp = value;
259  m_rsrpSet = true;
260  return;
261  }
262 
263  double coeff = 0.7;
264  m_rsrp = coeff * m_rsrp + (1 - coeff) * value;
266 }
267 
268 void
270 {
271  NS_LOG_FUNCTION (this);
272 
273  int delta = 0;
275  {
276  switch (tpc)
277  {
278  case 0:
279  delta = -1;
280  break;
281  case 1:
282  delta = 0;
283  break;
284  case 2:
285  delta = 1;
286  break;
287  case 3:
288  delta = 3;
289  break;
290  default:
291  NS_FATAL_ERROR ("Unexpected TPC value");
292  }
293  }
294  else
295  {
296  switch (tpc)
297  {
298  case 0:
299  delta = -4;
300  break;
301  case 1:
302  delta = -1;
303  break;
304  case 2:
305  delta = 1;
306  break;
307  case 3:
308  delta = 4;
309  break;
310  default:
311  NS_FATAL_ERROR ("Unexpected TPC value");
312  }
313  }
314 
315  m_deltaPusch.push_back (delta);
316 
317  if (m_closedLoop)
318  {
320  {
321  if (m_deltaPusch.size () == 4)
322  {
323  if ((m_curPuschTxPower <= m_Pcmin && m_deltaPusch.at (0) < 0)
324  || (m_curPuschTxPower >= m_Pcmax && m_deltaPusch.at (0) > 0))
325  {
326  //TPC commands for serving cell shall not be accumulated
327  m_deltaPusch.erase (m_deltaPusch.begin ());
328  }
329  else
330  {
331  m_fc = m_fc + m_deltaPusch.at (0);
332  m_deltaPusch.erase (m_deltaPusch.begin ());
333  }
334  }
335  else
336  {
337  m_fc = 0;
338  }
339  }
340  else
341  {
342  m_fc = m_deltaPusch.at (0);
343  m_deltaPusch.erase (m_deltaPusch.begin ());
344  }
345  }
346  else
347  {
348  m_fc = 0;
349  }
350 
351  NS_LOG_INFO ("ReportTpc: " << (int)tpc << " delta: " << delta << " Fc: " << m_fc);
352 }
353 
354 void
355 LteUePowerControl::SetSubChannelMask (std::vector <int> mask)
356 {
357  NS_LOG_FUNCTION (this);
358  m_M_Pusch = mask.size ();
359 }
360 
361 void
363 {
364  NS_LOG_FUNCTION (this);
365  int32_t j = 1;
366  int32_t PoPusch = m_PoNominalPusch[j] + m_PoUePusch[j];
367 
368  NS_LOG_INFO ("RB: " << m_M_Pusch << " m_PoPusch: " << PoPusch
369  << " Alpha: " << m_alpha[j] << " PathLoss: " << m_pathLoss
370  << " deltaTF: " << m_deltaTF << " fc: " << m_fc);
371 
372  if ( m_M_Pusch > 0 )
373  {
374  m_curPuschTxPower = 10 * log10 (1.0 * m_M_Pusch) + PoPusch + m_alpha[j] * m_pathLoss + m_deltaTF + m_fc;
375  m_M_Pusch = 0;
376  }
377  else
378  {
379  m_curPuschTxPower = PoPusch + m_alpha[j] * m_pathLoss + m_fc;
380  }
381 
382  NS_LOG_INFO ("CalcPower: " << m_curPuschTxPower << " MinPower: " << m_Pcmin << " MaxPower:" << m_Pcmax);
383 
386  NS_LOG_INFO ("PuschTxPower: " << m_curPuschTxPower);
387 }
388 
389 void
391 {
392  NS_LOG_FUNCTION (this);
394  NS_LOG_INFO ("PucchTxPower: " << m_curPucchTxPower);
395 }
396 
397 void
399 {
400  NS_LOG_FUNCTION (this);
401  int32_t j = 1;
402  int32_t PoPusch = m_PoNominalPusch[j] + m_PoUePusch[j];
403 
404  NS_LOG_INFO ("RB: " << m_M_Pusch << " m_PoPusch: " << PoPusch
405  << " Alpha: " << m_alpha[j] << " PathLoss: " << m_pathLoss
406  << " deltaTF: " << m_deltaTF << " fc: " << m_fc);
407 
408 
409  double pSrsOffsetValue = -10.5 + m_PsrsOffset * 1.5;
410 
411  m_curSrsTxPower = pSrsOffsetValue + 10 * log10 (m_srsBandwidth) + PoPusch + m_alpha[j] * m_pathLoss + m_fc;
412 
413  NS_LOG_INFO ("CalcPower: " << m_curSrsTxPower << " MinPower: " << m_Pcmin << " MaxPower:" << m_Pcmax);
414 
417  NS_LOG_INFO ("SrsTxPower: " << m_curSrsTxPower);
418 }
419 
420 
421 double
422 LteUePowerControl::GetPuschTxPower (std::vector <int> dlRb)
423 {
424  NS_LOG_FUNCTION (this);
425 
426  m_M_Pusch = dlRb.size ();
428 
430 
431  return m_curPuschTxPower;
432 }
433 
434 double
435 LteUePowerControl::GetPucchTxPower (std::vector <int> dlRb)
436 {
437  NS_LOG_FUNCTION (this);
438 
440 
442 
443  return m_curPucchTxPower;
444 }
445 
446 double
447 LteUePowerControl::GetSrsTxPower (std::vector <int> dlRb)
448 {
449  NS_LOG_FUNCTION (this);
450 
451  m_srsBandwidth = dlRb.size ();
453 
455 
456  return m_curSrsTxPower;
457 }
458 
459 } // 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)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
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
This class realizes Uplink Power Control functionality.
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:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
virtual void DoDispose(void)
Destructor implementation.