A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lora-radio-energy-model.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 University of Padova
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Romagnolo Stefano <romagnolostefano93@gmail.com>
18 */
19
21
22#include "ns3/energy-source.h"
23#include "ns3/log.h"
24#include "ns3/pointer.h"
25#include "ns3/simulator.h"
26
27namespace ns3
28{
29namespace lorawan
30{
31
32NS_LOG_COMPONENT_DEFINE("LoraRadioEnergyModel");
33
34NS_OBJECT_ENSURE_REGISTERED(LoraRadioEnergyModel);
35
36TypeId
38{
39 static TypeId tid =
40 TypeId("ns3::LoraRadioEnergyModel")
42 .SetGroupName("Energy")
43 .AddConstructor<LoraRadioEnergyModel>()
44 .AddAttribute("StandbyCurrentA",
45 "The default radio Standby current in Ampere.",
46 DoubleValue(0.0014), // idle mode = 1.4mA
49 MakeDoubleChecker<double>())
50 .AddAttribute("TxCurrentA",
51 "The radio Tx current in Ampere.",
52 DoubleValue(0.028), // transmit at 0dBm = 28mA
55 MakeDoubleChecker<double>())
56 .AddAttribute("RxCurrentA",
57 "The radio Rx current in Ampere.",
58 DoubleValue(0.0112), // receive mode = 11.2mA
61 MakeDoubleChecker<double>())
62 .AddAttribute("SleepCurrentA",
63 "The radio Sleep current in Ampere.",
64 DoubleValue(0.0000015), // sleep mode = 1.5microA
67 MakeDoubleChecker<double>())
68 .AddAttribute("TxCurrentModel",
69 "A pointer to the attached tx current model.",
72 MakePointerChecker<LoraTxCurrentModel>())
73 .AddTraceSource(
74 "TotalEnergyConsumption",
75 "Total energy consumption of the radio device.",
77 "ns3::TracedValueCallback::Double");
78 return tid;
79}
80
82{
83 NS_LOG_FUNCTION(this);
84 m_currentState = EndDeviceLoraPhy::SLEEP; // initially STANDBY
89 m_source = nullptr;
90 // set callback for EndDeviceLoraPhy listener
93 // set callback for updating the tx current
96}
97
99{
100 NS_LOG_FUNCTION(this);
101 delete m_listener;
102}
103
104void
106{
107 NS_LOG_FUNCTION(this << source);
108 NS_ASSERT(source);
109 m_source = source;
110}
111
112double
114{
115 NS_LOG_FUNCTION(this);
117}
118
119double
121{
122 NS_LOG_FUNCTION(this);
123 return m_idleCurrentA;
124}
125
126void
128{
129 NS_LOG_FUNCTION(this << idleCurrentA);
130 m_idleCurrentA = idleCurrentA;
131}
132
133double
135{
136 NS_LOG_FUNCTION(this);
137 return m_txCurrentA;
138}
139
140void
142{
143 NS_LOG_FUNCTION(this << txCurrentA);
144 m_txCurrentA = txCurrentA;
145}
146
147double
149{
150 NS_LOG_FUNCTION(this);
151 return m_rxCurrentA;
152}
153
154void
156{
157 NS_LOG_FUNCTION(this << rxCurrentA);
158 m_rxCurrentA = rxCurrentA;
159}
160
161double
163{
164 NS_LOG_FUNCTION(this);
165 return m_sleepCurrentA;
166}
167
168void
170{
171 NS_LOG_FUNCTION(this << sleepCurrentA);
172 m_sleepCurrentA = sleepCurrentA;
173}
174
177{
178 NS_LOG_FUNCTION(this);
179 return m_currentState;
180}
181
182void
184{
185 NS_LOG_FUNCTION(this);
186 if (callback.IsNull())
187 {
188 NS_LOG_DEBUG("LoraRadioEnergyModel:Setting NULL energy depletion callback!");
189 }
190 m_energyDepletionCallback = callback;
191}
192
193void
195{
196 NS_LOG_FUNCTION(this);
197 if (callback.IsNull())
198 {
199 NS_LOG_DEBUG("LoraRadioEnergyModel:Setting NULL energy recharged callback!");
200 }
201 m_energyRechargedCallback = callback;
202}
203
204void
206{
207 m_txCurrentModel = model;
208}
209
210void
212{
214 {
215 m_txCurrentA = m_txCurrentModel->CalcTxCurrent(txPowerDbm);
216 }
217}
218
219void
221{
222 NS_LOG_FUNCTION(this << newState);
223
224 Time duration = Simulator::Now() - m_lastUpdateTime;
225 NS_ASSERT(duration.GetNanoSeconds() >= 0); // check if duration is valid
226
227 // energy to decrease = current * voltage * time
228 double energyToDecrease = 0.0;
229 double supplyVoltage = m_source->GetSupplyVoltage();
230 switch (m_currentState)
231 {
233 energyToDecrease = duration.GetSeconds() * m_idleCurrentA * supplyVoltage;
234 break;
236 energyToDecrease = duration.GetSeconds() * m_txCurrentA * supplyVoltage;
237 break;
239 energyToDecrease = duration.GetSeconds() * m_rxCurrentA * supplyVoltage;
240 break;
242 energyToDecrease = duration.GetSeconds() * m_sleepCurrentA * supplyVoltage;
243 break;
244 default:
245 NS_FATAL_ERROR("LoraRadioEnergyModel:Undefined radio state: " << m_currentState);
246 }
247
248 // update total energy consumption
249 m_totalEnergyConsumption += energyToDecrease;
250
251 // update last update time stamp
253
255
256 // notify energy source
257 m_source->UpdateEnergySource();
258
259 // in case the energy source is found to be depleted during the last update, a callback might be
260 // invoked that might cause a change in the Lora PHY state (e.g., the PHY is put into SLEEP
261 // mode). This in turn causes a new call to this member function, with the consequence that the
262 // previous instance is resumed after the termination of the new instance. In particular, the
263 // state set by the previous instance is erroneously the final state stored in m_currentState.
264 // The check below ensures that previous instances do not change m_currentState.
265
267 {
268 // update current state & last update time stamp
270
271 // some debug message
272 NS_LOG_DEBUG("LoraRadioEnergyModel:Total energy consumption is " << m_totalEnergyConsumption
273 << "J");
274 }
275
277
279}
280
281void
283{
284 NS_LOG_FUNCTION(this);
285 NS_LOG_DEBUG("LoraRadioEnergyModel:Energy is depleted!");
286 // invoke energy depletion callback, if set.
288 {
290 }
291}
292
293void
295{
296 NS_LOG_FUNCTION(this);
297 NS_LOG_DEBUG("LoraRadioEnergyModel:Energy changed!");
298}
299
300void
302{
303 NS_LOG_FUNCTION(this);
304 NS_LOG_DEBUG("LoraRadioEnergyModel:Energy is recharged!");
305 // invoke energy recharged callback, if set.
307 {
309 }
310}
311
314{
315 NS_LOG_FUNCTION(this);
316 return m_listener;
317}
318
319/*
320 * Private functions start here.
321 */
322
323void
325{
326 NS_LOG_FUNCTION(this);
327 m_source = nullptr;
329}
330
331double
333{
334 NS_LOG_FUNCTION(this);
335 switch (m_currentState)
336 {
338 return m_idleCurrentA;
340 return m_txCurrentA;
342 return m_rxCurrentA;
344 return m_sleepCurrentA;
345 default:
346 NS_FATAL_ERROR("LoraRadioEnergyModel:Undefined radio state:" << m_currentState);
347 }
348}
349
350void
352{
353 NS_LOG_FUNCTION(this << state);
354 m_currentState = state;
355 std::string stateName;
356 switch (state)
357 {
359 stateName = "STANDBY";
360 break;
362 stateName = "TX";
363 break;
365 stateName = "RX";
366 break;
368 stateName = "SLEEP";
369 break;
370 }
371 NS_LOG_DEBUG("LoraRadioEnergyModel:Switching to state: "
372 << stateName << " at time = " << Simulator::Now().GetSeconds() << " s");
373}
374
375// -------------------------------------------------------------------------- //
376
378{
379 NS_LOG_FUNCTION(this);
382}
383
385{
386 NS_LOG_FUNCTION(this);
387}
388
389void
392{
393 NS_LOG_FUNCTION(this << &callback);
394 NS_ASSERT(!callback.IsNull());
395 m_changeStateCallback = callback;
396}
397
398void
400{
401 NS_LOG_FUNCTION(this << &callback);
402 NS_ASSERT(!callback.IsNull());
403 m_updateTxCurrentCallback = callback;
404}
405
406void
408{
409 NS_LOG_FUNCTION(this);
411 {
412 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
413 }
415}
416
417void
419{
420 NS_LOG_FUNCTION(this << txPowerDbm);
422 {
423 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Update tx current callback not set!");
424 }
425 m_updateTxCurrentCallback(txPowerDbm);
427 {
428 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
429 }
431}
432
433void
435{
436 NS_LOG_FUNCTION(this);
438 {
439 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
440 }
442}
443
444void
446{
447 NS_LOG_FUNCTION(this);
449 {
450 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
451 }
453}
454
455/*
456 * Private function state here.
457 */
458
459void
461{
462 NS_LOG_FUNCTION(this);
464 {
465 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
466 }
468}
469
470} // namespace lorawan
471} // namespace ns3
void Nullify()
Discard the implementation, set it to null.
Definition: callback.h:577
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:418
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Base class for device energy models.
virtual void ChangeState(int newState)=0
State
An enumeration of the possible states of an EndDeviceLoraPhy.
@ RX
The PHY layer is receiving a packet.
@ TX
The PHY layer is sending a packet.
@ SLEEP
The PHY layer is sleeping.
@ STANDBY
The PHY layer is in STANDBY.
LoraRadioEnergyModelPhyListener * m_listener
EndDeviceLoraPhy listener.
LoraRadioEnergyModelPhyListener * GetPhyListener()
void HandleEnergyChanged() override
Handles energy recharged.
uint8_t m_nPendingChangeState
pending state change
void SetEnergySource(Ptr< EnergySource > source) override
Sets pointer to EnergySouce installed on node.
double GetTxCurrentA() const
Gets transmit current.
void ChangeState(int newState) override
Changes state of the LoraRadioEnergyMode.
double GetTotalEnergyConsumption() const override
double GetRxCurrentA() const
Gets receive current.
void SetStandbyCurrentA(double idleCurrentA)
Sets idle current.
void SetTxCurrentFromModel(double txPowerDbm)
Calls the CalcTxCurrent method of the tx current model to compute the tx current based on such model.
LoraRadioEnergyDepletionCallback m_energyDepletionCallback
Energy depletion callback.
void DoDispose() override
Destructor implementation.
EndDeviceLoraPhy::State m_currentState
current state the radio is in
bool m_isSupersededChangeState
superseded change state
void HandleEnergyRecharged() override
Handles energy recharged.
void HandleEnergyDepletion() override
Handles energy depletion.
void SetEnergyRechargedCallback(LoraRadioEnergyRechargedCallback callback)
void SetLoraRadioState(const EndDeviceLoraPhy::State state)
Time m_lastUpdateTime
time stamp of previous energy update
double GetStandbyCurrentA() const
Gets idle current.
Ptr< LoraTxCurrentModel > m_txCurrentModel
current model
void SetEnergyDepletionCallback(LoraRadioEnergyDepletionCallback callback)
void SetSleepCurrentA(double sleepCurrentA)
Sets sleep current.
void SetRxCurrentA(double rxCurrentA)
Sets receive current.
Ptr< EnergySource > m_source
energy source
void SetTxCurrentA(double txCurrentA)
Sets transmit current.
double GetSleepCurrentA() const
Gets sleep current.
void SetTxCurrentModel(Ptr< LoraTxCurrentModel > model)
static TypeId GetTypeId()
Register this type.
EndDeviceLoraPhy::State GetCurrentState() const
LoraRadioEnergyRechargedCallback m_energyRechargedCallback
Energy recharged callback.
TracedValue< double > m_totalEnergyConsumption
This variable keeps track of the total energy consumed by this model.
Installable listener for LoRa physiscal layer state changes.
void NotifyTxStart(double txPowerDbm) override
Switches the LoraRadioEnergyModel to TX state and switches back to STANDBY after TX duration.
DeviceEnergyModel::ChangeStateCallback m_changeStateCallback
Change state callback used to notify the LoraRadioEnergyModel of a state change.
void NotifyStandby() override
Defined in ns3::LoraEndDevicePhyListener.
void NotifySleep() override
Defined in ns3::LoraEndDevicePhyListener.
void SetChangeStateCallback(DeviceEnergyModel::ChangeStateCallback callback)
Sets the change state callback.
void SetUpdateTxCurrentCallback(UpdateTxCurrentCallback callback)
Sets the update tx current callback.
void SwitchToStandby()
A helper function that makes scheduling m_changeStateCallback possible.
void NotifyRxStart() override
Switches the LoraRadioEnergyModel to RX state.
UpdateTxCurrentCallback m_updateTxCurrentCallback
Callback used to update the tx current stored in LoraRadioEnergyModel based on the nominal tx power u...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:700
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43