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 
35 NS_LOG_COMPONENT_DEFINE("SatHandoverModule");
36 
37 namespace ns3
38 {
39 
40 NS_OBJECT_ENSURE_REGISTERED(SatHandoverModule);
41 
42 TypeId
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 
73 TypeId
75 {
76  NS_LOG_FUNCTION(this);
77 
78  return GetTypeId();
79 }
80 
81 void
83 {
84  NS_LOG_FUNCTION(this);
85 
86  m_handoverCallback.Nullify();
87  m_antennaGainPatterns = nullptr;
88 
89  Object::DoDispose();
90 }
91 
93  : m_antennaGainPatterns(nullptr),
94  m_lastMessageSentAt(0),
95  m_repeatRequestTimeout(600),
96  m_hasPendingRequest(false),
97  m_askedSatId(0),
98  m_askedBeamId(0)
99 {
100  NS_LOG_FUNCTION(this);
101 
102  NS_FATAL_ERROR("SatHandoverModule default constructor should not be used!");
103 }
104 
106  NodeContainer satellites,
107  Ptr<SatAntennaGainPatternContainer> agpContainer)
108  : m_handoverDecisionAlgorithm(SAT_N_CLOSEST_SAT),
109  m_numberClosestSats(1),
110  m_utNode(utNode),
111  m_satellites(satellites),
112  m_antennaGainPatterns(agpContainer),
113  m_lastMessageSentAt(0),
114  m_repeatRequestTimeout(600),
115  m_hasPendingRequest(false),
116  m_askedSatId(0),
117  m_askedBeamId(0)
118 {
119  NS_LOG_FUNCTION(this << agpContainer);
120 }
121 
123 {
124  NS_LOG_FUNCTION(this);
125 }
126 
127 void
129 {
130  NS_LOG_FUNCTION(this << &cb);
131 
132  m_handoverCallback = cb;
133 }
134 
135 uint32_t
137 {
138  return m_askedSatId;
139 }
140 
141 uint32_t
143 {
144  return m_askedBeamId;
145 }
146 
147 void
149 {
150  NS_LOG_FUNCTION(this);
151 
152  m_hasPendingRequest = false;
153 }
154 
155 bool
157 {
158  NS_LOG_FUNCTION(this << satId << beamId);
159 
160  Time now = Simulator::Now();
162  {
163  m_hasPendingRequest = false;
164  }
165 
166  Ptr<SatMobilityModel> mobilityModel = GetObject<SatMobilityModel>();
167  if (!mobilityModel)
168  {
169  NS_LOG_FUNCTION("Bailing out for lack of mobility model");
170  return false;
171  }
172 
173  // If current beam is still valid, do nothing
174  GeoCoordinate coords = mobilityModel->GetGeoPosition();
175  Ptr<SatAntennaGainPattern> agp = m_antennaGainPatterns->GetAntennaGainPattern(beamId);
176  Ptr<SatMobilityModel> mobility = m_antennaGainPatterns->GetAntennaMobility(satId);
177  if (agp->IsValidPosition(coords, m_antennaGainTrace, mobility))
178  {
179  NS_LOG_FUNCTION("Current beam is good, do nothing");
180  // m_hasPendingRequest = false;
181  return false;
182  }
183 
184  // Current beam ID is no longer valid, check for better beam and ask for handover
185  uint32_t bestSatId = m_askedSatId;
186  uint32_t bestBeamId = m_askedBeamId;
187 
189  {
191  {
192  case SAT_N_CLOSEST_SAT: {
193  std::pair<uint32_t, uint32_t> bestSatAndBeam = AlgorithmNClosest(coords);
194  bestSatId = bestSatAndBeam.first;
195  bestBeamId = bestSatAndBeam.second;
196  break;
197  }
198  default:
199  NS_FATAL_ERROR("Incorrect handover decision algorithm");
200  }
201  }
202 
203  if ((bestSatId != satId || bestBeamId != beamId) &&
205  {
206  NS_LOG_FUNCTION("Sending handover recommendation for beam " << bestBeamId << " on sat "
207  << bestSatId);
208 
209  m_handoverCallback(bestSatId, bestBeamId);
210  m_lastMessageSentAt = now;
211  m_hasPendingRequest = true;
212  m_askedSatId = bestSatId;
213  m_askedBeamId = bestBeamId;
214  return true;
215  }
216 
217  return false;
218 }
219 
220 std::vector<uint32_t>
222 {
223  NS_LOG_FUNCTION(this << numberOfSats);
224 
225  std::map<double, uint32_t> satellites;
226 
227  Ptr<SatMobilityModel> utMobility = m_utNode->GetObject<SatMobilityModel>();
228  Ptr<SatMobilityModel> satMobility;
229  double distance;
230 
231  for (uint32_t i = 0; i < m_satellites.GetN(); i++)
232  {
233  satMobility = m_satellites.Get(i)->GetObject<SatMobilityModel>();
234  distance = utMobility->GetDistanceFrom(satMobility);
235  satellites.emplace(distance, i);
236  }
237 
238  std::vector<uint32_t> closest;
239  uint32_t i = 0;
240  for (auto&& [dist, satId] : satellites)
241  {
242  if (i++ < numberOfSats)
243  {
244  closest.push_back(satId);
245  }
246  else
247  {
248  break;
249  }
250  }
251 
252  return closest;
253 }
254 
255 std::pair<uint32_t, uint32_t>
257 {
258  NS_LOG_FUNCTION(this << coords);
259 
260  std::vector<uint32_t> satellites = GetNClosestSats(m_numberClosestSats);
261 
262  uint32_t bestSatId = satellites[0];
263  uint32_t bestBeamId = m_antennaGainPatterns->GetBestBeamId(bestSatId, coords, true);
264  double bestGain = m_antennaGainPatterns->GetBeamGain(bestSatId, bestBeamId, coords);
265 
266  uint32_t beamId;
267  double gain;
268  for (uint32_t i = 1; i < satellites.size(); i++)
269  {
270  beamId = m_antennaGainPatterns->GetBestBeamId(satellites[i], coords, true);
271  gain = m_antennaGainPatterns->GetBeamGain(satellites[i], beamId, coords);
272 
273  if (beamId != 0)
274  {
275  if (gain > bestGain)
276  {
277  bestGain = gain;
278  bestSatId = satellites[i];
279  bestBeamId = beamId;
280  }
281  }
282  }
283 
284  return std::make_pair(bestSatId, bestBeamId);
285 }
286 
287 } // 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
virtual TypeId GetInstanceTypeId(void) const
Derived from Object.
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