Loading...
Searching...
No Matches
satellite-handover-module.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2018 CNES
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: Mathias Ettinger <mettinger@toulouse.viveris.fr>
19 */
20
22
23#include "geo-coordinate.h"
25
26#include "ns3/enum.h"
27#include "ns3/log.h"
28#include "ns3/simulator.h"
29#include "ns3/uinteger.h"
30
31#include <map>
32#include <utility>
33#include <vector>
34
35NS_LOG_COMPONENT_DEFINE("SatHandoverModule");
36
37namespace ns3
38{
39
40NS_OBJECT_ENSURE_REGISTERED(SatHandoverModule);
41
42TypeId
44{
45 static TypeId tid =
46 TypeId("ns3::SatHandoverModule")
47 .SetParent<Object>()
48 .AddConstructor<SatHandoverModule>()
49 .AddAttribute("Timeout",
50 "Amount of time to wait before sending a new handover recommendation if "
51 "no TIM-U is received",
52 TimeValue(MilliSeconds(1000)),
54 MakeTimeChecker())
55 .AddAttribute("HandoverDecisionAlgorithm",
56 "Algorithm to use for handovers",
58 MakeEnumAccessor<SatHandoverModule::HandoverDecisionAlgorithm_t>(
60 MakeEnumChecker(SatHandoverModule::SAT_N_CLOSEST_SAT, "NClosestSats"))
61 .AddAttribute("NumberClosestSats",
62 "Number of satellites to consider when using algorithm SAT_N_CLOSEST_SAT",
63 UintegerValue(1),
64 MakeUintegerAccessor(&SatHandoverModule::m_numberClosestSats),
65 MakeUintegerChecker<uint32_t>())
66 .AddTraceSource("AntennaGainTrace",
67 "Trace antenna gains when checking for beam compliance",
68 MakeTraceSourceAccessor(&SatHandoverModule::m_antennaGainTrace),
69 "ns3::SatAntennaGainPattern::AntennaGainTrace");
70 return tid;
71}
72
73void
75{
76 NS_LOG_FUNCTION(this);
77
78 m_handoverCallback.Nullify();
79 m_antennaGainPatterns = nullptr;
80
81 Object::DoDispose();
82}
83
85 : m_antennaGainPatterns(nullptr),
89 m_askedSatId(0),
91{
92 NS_LOG_FUNCTION(this);
93
94 NS_FATAL_ERROR("SatHandoverModule default constructor should not be used!");
95}
96
98 NodeContainer satellites,
99 Ptr<SatAntennaGainPatternContainer> agpContainer)
102 m_utNode(utNode),
103 m_satellites(satellites),
104 m_antennaGainPatterns(agpContainer),
107 m_hasPendingRequest(false),
108 m_askedSatId(0),
110{
111 NS_LOG_FUNCTION(this << agpContainer);
112}
113
115{
116 NS_LOG_FUNCTION(this);
117}
118
119void
121{
122 NS_LOG_FUNCTION(this << &cb);
123
125}
126
127uint32_t
132
133uint32_t
138
139void
141{
142 NS_LOG_FUNCTION(this);
143
144 m_hasPendingRequest = false;
145}
146
147bool
149{
150 NS_LOG_FUNCTION(this << satId << beamId);
151
152 Time now = Simulator::Now();
154 {
155 m_hasPendingRequest = false;
156 }
157
158 Ptr<SatMobilityModel> mobilityModel = GetObject<SatMobilityModel>();
159 if (!mobilityModel)
160 {
161 NS_LOG_FUNCTION("Bailing out for lack of mobility model");
162 return false;
163 }
164
165 // If current beam is still valid, do nothing
166 GeoCoordinate coords = mobilityModel->GetGeoPosition();
167 Ptr<SatAntennaGainPattern> agp = m_antennaGainPatterns->GetAntennaGainPattern(beamId);
168 Ptr<SatMobilityModel> mobility = m_antennaGainPatterns->GetAntennaMobility(satId);
169 if (agp->IsValidPosition(coords, m_antennaGainTrace, mobility))
170 {
171 NS_LOG_FUNCTION("Current beam is good, do nothing");
172 // m_hasPendingRequest = false;
173 return false;
174 }
175
176 // Current beam ID is no longer valid, check for better beam and ask for handover
177 uint32_t bestSatId = m_askedSatId;
178 uint32_t bestBeamId = m_askedBeamId;
179
181 {
183 {
184 case SAT_N_CLOSEST_SAT: {
185 std::pair<uint32_t, uint32_t> bestSatAndBeam = AlgorithmNClosest(coords);
186 bestSatId = bestSatAndBeam.first;
187 bestBeamId = bestSatAndBeam.second;
188 break;
189 }
190 default:
191 NS_FATAL_ERROR("Incorrect handover decision algorithm");
192 }
193 }
194
195 if ((bestSatId != satId || bestBeamId != beamId) &&
197 {
198 NS_LOG_FUNCTION("Sending handover recommendation for beam " << bestBeamId << " on sat "
199 << bestSatId);
200
201 m_handoverCallback(bestSatId, bestBeamId);
203 m_hasPendingRequest = true;
204 m_askedSatId = bestSatId;
205 m_askedBeamId = bestBeamId;
206 return true;
207 }
208
209 return false;
210}
211
212std::vector<uint32_t>
214{
215 NS_LOG_FUNCTION(this << numberOfSats);
216
217 std::map<double, uint32_t> satellites;
218
219 Ptr<SatMobilityModel> utMobility = m_utNode->GetObject<SatMobilityModel>();
220 Ptr<SatMobilityModel> satMobility;
221 double distance;
222
223 for (uint32_t i = 0; i < m_satellites.GetN(); i++)
224 {
225 satMobility = m_satellites.Get(i)->GetObject<SatMobilityModel>();
226 distance = utMobility->GetDistanceFrom(satMobility);
227 satellites.emplace(distance, i);
228 }
229
230 std::vector<uint32_t> closest;
231 uint32_t i = 0;
232 for (auto&& [dist, satId] : satellites)
233 {
234 if (i++ < numberOfSats)
235 {
236 closest.push_back(satId);
237 }
238 else
239 {
240 break;
241 }
242 }
243
244 return closest;
245}
246
247std::pair<uint32_t, uint32_t>
249{
250 NS_LOG_FUNCTION(this << coords);
251
252 std::vector<uint32_t> satellites = GetNClosestSats(m_numberClosestSats);
253
254 uint32_t bestSatId = satellites[0];
255 uint32_t bestBeamId = m_antennaGainPatterns->GetBestBeamId(bestSatId, coords, true);
256 double bestGain = m_antennaGainPatterns->GetBeamGain(bestSatId, bestBeamId, coords);
257
258 uint32_t beamId;
259 double gain;
260 for (uint32_t i = 1; i < satellites.size(); i++)
261 {
262 beamId = m_antennaGainPatterns->GetBestBeamId(satellites[i], coords, true);
263 gain = m_antennaGainPatterns->GetBeamGain(satellites[i], beamId, coords);
264
265 if (beamId != 0)
266 {
267 if (gain > bestGain)
268 {
269 bestGain = gain;
270 bestSatId = satellites[i];
271 bestBeamId = beamId;
272 }
273 }
274 }
275
276 return std::make_pair(bestSatId, bestBeamId);
277}
278
279} // namespace ns3
GeoCoordinate class is used to store and operate with geodetic coordinates.
void HandoverFinished()
Method to call when a handover has been performed.
HandoverDecisionAlgorithm_t m_handoverDecisionAlgorithm
Algorithm used to detect if handover is needed.
uint32_t GetAskedBeamId()
Get the best beam ID.
~SatHandoverModule()
Destroy a SatHandoverModule.
void SetHandoverRequestCallback(SatHandoverModule::HandoverRequestCallback cb)
Set the handover recommendation message sending callback.
HandoverRequestCallback m_handoverCallback
SatHandoverModule()
Default constructor, which is not used.
bool CheckForHandoverRecommendation(uint32_t satId, uint32_t beamId)
Inspect whether or not the given beam is still suitable for the underlying mobility model.
virtual void DoDispose()
Dispose of this class instance.
std::pair< uint32_t, uint32_t > AlgorithmNClosest(GeoCoordinate coords)
Handover algorithm choosing best beam between N closest satellites.
TracedCallback< double > m_antennaGainTrace
Ptr< SatAntennaGainPatternContainer > m_antennaGainPatterns
uint32_t GetAskedSatId()
Get the best sat ID.
uint32_t m_numberClosestSats
Number of satellites to consider when using algorithm SAT_N_CLOSEST_SAT.
std::vector< uint32_t > GetNClosestSats(uint32_t numberOfSats)
Get the N closest satellites to the UT node.
static TypeId GetTypeId(void)
Derived from Object.
Callback< void, uint32_t, uint32_t > HandoverRequestCallback
Handover recommendation message sending callback.
Keep track of the current position and velocity of an object in satellite network.
double GetDistanceFrom(Ptr< const SatMobilityModel > position) const
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
Ptr< SatMobilityModel > satMobility