Loading...
Searching...
No Matches
satellite-per-packet-interference.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013 Magister Solutions Ltd.
4 * Copyright (c) 2018 CNES
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Author: Jani Puttonen <jani.puttonen@magister.fi>
20 * Author: Mathias Ettinger <mettinger@toulouse.viveris.fr>
21 */
22
24
25#include "ns3/log.h"
26#include "ns3/simulator.h"
27#include "ns3/singleton.h"
28
29#include <algorithm>
30#include <cmath>
31#include <istream>
32#include <limits>
33#include <set>
34#include <tuple>
35#include <utility>
36#include <vector>
37
38NS_LOG_COMPONENT_DEFINE("SatPerPacketInterference");
39
40namespace ns3
41{
42
43NS_OBJECT_ENSURE_REGISTERED(SatPerPacketInterference);
44
45TypeId
47{
48 static TypeId tid = TypeId("ns3::SatPerPacketInterference")
49 .SetParent<SatInterference>()
50 .AddConstructor<SatPerPacketInterference>();
51
52 return tid;
53}
54
56 : m_residualPowerW(0.0),
57 m_rxing(false),
62{
63 NS_LOG_FUNCTION(this);
64}
65
67 double rxBandwidthHz)
68 : m_residualPowerW(0.0),
69 m_rxing(false),
72 m_channelType(channelType),
73 m_rxBandwidth_Hz(rxBandwidthHz)
74{
75 NS_LOG_FUNCTION(this << channelType << rxBandwidthHz);
76
77 if (m_rxBandwidth_Hz <= std::numeric_limits<double>::epsilon())
78 {
79 NS_FATAL_ERROR("SatPerPacketInterference::SatPerPacketInterference - Invalid value");
80 }
81}
82
84{
85 NS_LOG_FUNCTION(this);
86
87 Reset();
88}
89
90Ptr<SatInterference::InterferenceChangeEvent>
91SatPerPacketInterference::DoAdd(Time duration, double power, Address rxAddress)
92{
93 NS_LOG_FUNCTION(this << duration << power << rxAddress);
94
95 Ptr<SatInterference::InterferenceChangeEvent> event;
96 event = Create<SatInterference::InterferenceChangeEvent>(m_nextEventId++,
97 duration,
98 power,
99 rxAddress);
100 Time now = event->GetStartTime();
101
102 NS_LOG_INFO("Add change: Duration= " << duration << ", Power= " << power << ", Time: " << now);
103
104 // do update and clean-ups, if we are not receiving
105 if (!m_rxing)
106 {
107 InterferenceChanges::iterator nowIterator = m_interferenceChanges.upper_bound(now);
108
109 for (InterferenceChanges::iterator i = m_interferenceChanges.begin(); i != nowIterator; i++)
110 {
111 uint32_t eventID;
112 long double powerValue;
113 std::tie(eventID, powerValue, std::ignore) = i->second;
114
115 NS_LOG_INFO("Change to erase: Time= " << i->first << ", Id= " << eventID
116 << ", PowerValue= " << powerValue);
117
118 m_residualPowerW += powerValue;
119
120 NS_LOG_INFO("First power after erase: " << m_residualPowerW);
121 }
122 m_interferenceChanges.erase(m_interferenceChanges.begin(), nowIterator);
123 }
124
125 NS_LOG_INFO("Change count before addition: " << m_interferenceChanges.size());
126
127 // if no changes in future, first power should be zero
128 if (m_interferenceChanges.size() == 0)
129 {
130 if ((m_residualPowerW != 0) &&
131 std::fabs(m_residualPowerW) < std::numeric_limits<long double>::epsilon())
132 {
133 // if we end up here,
134 // reset first power (this probably due to roundin problem with very small values)
136 }
137 }
138
140 std::make_pair(now, InterferenceChange(event->GetId(), power, false)));
142 std::make_pair(event->GetEndTime(), InterferenceChange(event->GetId(), -power, true)));
143
144 NS_LOG_INFO("Change count after addition: " << m_interferenceChanges.size());
145
146 if (m_residualPowerW < 0)
147 {
148 // First power should never leak negative
149 NS_FATAL_ERROR("First power negative!!!");
150 }
151
152 return event;
153}
154
155std::vector<std::pair<double, double>>
156SatPerPacketInterference::DoCalculate(Ptr<SatInterference::InterferenceChangeEvent> event)
157{
158 NS_LOG_FUNCTION(this);
159
160 if (m_rxing == false)
161 {
162 NS_FATAL_ERROR("Receiving is not set on!!!");
163 }
164
165 double ifPowerW = m_residualPowerW;
166 double rxDuration = event->GetDuration().GetDouble();
167 double rxEndTime = event->GetEndTime().GetDouble();
168 bool ownStartReached = false;
169
170 NS_LOG_INFO("Calculate: IfPower (W)= " << ifPowerW << ", Event ID= " << event->GetId()
171 << ", Duration= " << event->GetDuration()
172 << ", StartTime= " << event->GetStartTime()
173 << ", EndTime= " << event->GetEndTime());
174
175 InterferenceChanges::iterator currentItem = m_interferenceChanges.begin();
176
177 // calculate power values until own "stop" event found (own negative power event)
178 while (currentItem != m_interferenceChanges.end())
179 {
180 uint32_t eventID;
181 long double powerValue;
182 bool isEndEvent;
183 std::tie(eventID, powerValue, isEndEvent) = currentItem->second;
184
185 if (event->GetId() == eventID)
186 {
187 if (isEndEvent)
188 {
189 NS_LOG_INFO("IfPower after end event: " << ifPowerW);
190 break;
191 }
192 // stop increasing power value fully, when own 'start' event is reached
193 // needed to support multiple simultaneous receiving (currently not supported)
194 // own event is not updated to ifPower
195 ownStartReached = true;
196 onOwnStartReached(ifPowerW);
197 }
198 else if (ownStartReached)
199 {
200 // increase/decrease interference power with relative part of duration of power change
201 // in list
202 double itemTime = currentItem->first.GetDouble();
203 onInterferentEvent(((rxEndTime - itemTime) / rxDuration), powerValue, ifPowerW);
204
205 NS_LOG_INFO("Update (partial): ID: " << eventID << ", Power (W)= " << powerValue
206 << ", Time= " << currentItem->first
207 << ", DeltaTime= " << (rxEndTime - itemTime));
208
209 NS_LOG_INFO("IfPower after update: " << ifPowerW);
210 }
211 else
212 {
213 // increase/decrease interference power with full power change in list
214 ifPowerW += powerValue;
215
216 NS_LOG_INFO("Update (full): ID: " << eventID << ", Power (W)= " << powerValue);
217 NS_LOG_INFO("IfPower after update: " << ifPowerW);
218 }
219
220 currentItem++;
221 }
222
224 {
225 std::vector<double> tempVector;
226 tempVector.push_back(Now().GetSeconds());
227 tempVector.push_back(ifPowerW / m_rxBandwidth_Hz);
228 Singleton<SatInterferenceOutputTraceContainer>::Get()->AddToContainer(
229 std::make_pair(event->GetSatEarthStationAddress(), m_channelType),
230 tempVector);
231 }
232
233 std::vector<std::pair<double, double>> ifPowerPerFragment;
234 ifPowerPerFragment.emplace_back(1.0, ifPowerW);
235
236 return ifPowerPerFragment;
237}
238
239void
241{
242 // do nothing, meant for subclasses to override
243}
244
245void
247 double interferenceValue,
248 double& ifPowerW)
249{
250 ifPowerW += timeRatio * interferenceValue;
251}
252
253void
255{
256 NS_LOG_FUNCTION(this);
257
258 m_interferenceChanges.clear();
259 m_rxing = false;
260 m_residualPowerW = 0.0;
261}
262
263void
264SatPerPacketInterference::DoNotifyRxStart(Ptr<SatInterference::InterferenceChangeEvent> event)
265{
266 NS_LOG_FUNCTION(this);
267
268 std::pair<std::set<uint32_t>::iterator, bool> result = m_rxEventIds.insert(event->GetId());
269
270 NS_ASSERT(result.second);
271 m_rxing = true;
272}
273
274void
275SatPerPacketInterference::DoNotifyRxEnd(Ptr<SatInterference::InterferenceChangeEvent> event)
276{
277 NS_LOG_FUNCTION(this);
278
279 m_rxEventIds.erase(event->GetId());
280
281 if (m_rxEventIds.empty())
282 {
283 m_rxing = false;
284 }
285}
286
287void
289{
290 NS_LOG_FUNCTION(this);
291
292 SatInterference::DoDispose();
293}
294
295void
297{
298 NS_LOG_FUNCTION(this << rxBandwidth);
299
300 if (rxBandwidth <= std::numeric_limits<double>::epsilon())
301 {
302 NS_FATAL_ERROR("SatPerPacketInterference::SetRxBandwidth - Invalid value");
303 }
304
305 m_rxBandwidth_Hz = rxBandwidth;
306}
307
308} // namespace ns3
309
310// namespace ns3
ChannelType_t
Types of channel.
void Reset(void)
Resets current interference.
SatInterference()
Constructor for Satellite interference base class.
virtual void DoReset(void)
Resets current interference.
bool m_rxing
flag to indicate that at least one receiving is on
long double m_residualPowerW
Residual power value for interference.
virtual void DoNotifyRxEnd(Ptr< SatInterference::InterferenceChangeEvent > event)
Notifies that RX is ended by a receiver.
InterferenceChanges m_interferenceChanges
interference change list
virtual void DoNotifyRxStart(Ptr< SatInterference::InterferenceChangeEvent > event)
Notifies that RX is started by a receiver.
std::set< uint32_t > m_rxEventIds
notified interference event IDs
virtual void onInterferentEvent(long double timeRatio, double interferenceValue, double &ifPowerW)
Helper function meant for subclasses to override.
std::tuple< uint32_t, long double, bool > InterferenceChange
virtual std::vector< std::pair< double, double > > DoCalculate(Ptr< SatInterference::InterferenceChangeEvent > event)
Calculates interference power for the given reference Sets final power at end time to finalPower.
virtual void onOwnStartReached(double ifPowerW)
Helper function meant for subclasses to override.
virtual Ptr< SatInterference::InterferenceChangeEvent > DoAdd(Time rxDuration, double rxPower, Address rxAddress)
Adds interference power to interference object.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.