Loading...
Searching...
No Matches
satellite-mobility-observer.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014 Magister Solutions Ltd
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: Sami Rantanen <sami.rantanen@magister.fi>
19 */
20
22
23#include "satellite-utils.h"
24
25#include "ns3/boolean.h"
26#include "ns3/double.h"
27#include "ns3/log.h"
28#include "ns3/pointer.h"
29#include "ns3/trace-source-accessor.h"
30
31#include <cmath>
32#include <stdint.h>
33#include <string>
34
35NS_LOG_COMPONENT_DEFINE("SatMobilityObserver");
36
37namespace ns3
38{
39
40NS_OBJECT_ENSURE_REGISTERED(SatMobilityObserver);
41
42TypeId
44{
45 static TypeId tid =
46 TypeId("ns3::SatMobilityObserver")
47 .SetParent<Object>()
48 .AddAttribute("OwnMobility",
49 "Own mobility.",
50 PointerValue(),
51 MakePointerAccessor(&SatMobilityObserver::m_ownMobility),
52 MakePointerChecker<SatMobilityModel>())
53 .AddAttribute("SatelliteMobility",
54 "The mobility of the satellite.",
55 PointerValue(),
56 MakePointerAccessor(&SatMobilityObserver::m_geoSatMobility),
57 MakePointerChecker<SatMobilityModel>())
58 .AddAttribute("AnotherMobility",
59 "The mobility of the another end node.",
60 PointerValue(),
61 MakePointerAccessor(&SatMobilityObserver::m_anotherMobility),
62 MakePointerChecker<SatMobilityModel>())
63 .AddAttribute("OwnPropagation",
64 "Own propagation delay model.",
65 PointerValue(),
66 MakePointerAccessor(&SatMobilityObserver::m_ownProgDelayModel),
67 MakePointerChecker<SatMobilityModel>())
68 .AddAttribute("AnotherPropagation",
69 "The propagation delay model of the another end node.",
70 PointerValue(),
72 MakePointerChecker<SatMobilityModel>())
73 .AddAttribute("MinAltitude",
74 "The minimum altitude accepted for own position.",
75 DoubleValue(0),
76 MakeDoubleAccessor(&SatMobilityObserver::m_minAltitude),
77 MakeDoubleChecker<double>())
78 .AddAttribute("MaxAltitude",
79 "The maximum altitude accepted for own position.",
80 DoubleValue(500.00),
81 MakeDoubleAccessor(&SatMobilityObserver::m_maxAltitude),
82 MakeDoubleChecker<double>())
83 .AddTraceSource("PropertyChanged",
84 "The value of the some property has changed",
85 MakeTraceSourceAccessor(&SatMobilityObserver::m_propertyChangeTrace),
86 "ns3::SatMobilityObserver::PropertyChangedCallback");
87 return tid;
88}
89
91{
92 NS_LOG_FUNCTION(this);
93
94 // this constructor version should not be used
95 NS_ASSERT(false);
96}
97
98SatMobilityObserver::SatMobilityObserver(Ptr<SatMobilityModel> ownMobility,
99 Ptr<SatMobilityModel> geoSatMobility,
100 bool isRegenerative)
101 : m_ownMobility(ownMobility),
102 m_anotherMobility(nullptr),
103 m_geoSatMobility(geoSatMobility),
104 m_ownProgDelayModel(nullptr),
106 m_initialized(false),
107 m_isRegenerative(isRegenerative)
108{
109 NS_LOG_FUNCTION(this << ownMobility << geoSatMobility);
110
111 GeoCoordinate satellitePosition = m_geoSatMobility->GetGeoPosition();
112 GeoCoordinate ownPosition = m_ownMobility->GetGeoPosition();
113
114 // same reference ellipsoide must be used by mobilities
115 NS_ASSERT(satellitePosition.GetRefEllipsoid() == ownPosition.GetRefEllipsoid());
116
117 double satelliteAltitude = satellitePosition.GetAltitude();
118
119 // satellite is expected to be in the sky
120 NS_ASSERT(satelliteAltitude > 0.0);
121
122 // calculate radius of the earth using satellite information
124 CalculateDistance(satellitePosition.ToVector(), Vector(0, 0, 0)) - satelliteAltitude;
125
129 m_timingAdvance_s = Seconds(0);
130
131 m_geoSatMobility->TraceConnect("SatCourseChange",
132 "Satellite",
133 MakeCallback(&SatMobilityObserver::PositionChanged, this));
134 m_ownMobility->TraceConnect("SatCourseChange",
135 "Own",
136 MakeCallback(&SatMobilityObserver::PositionChanged, this));
137
138 m_velocity = 0.0;
139
140 m_initialized = true;
141}
142
143void
145{
146 NS_LOG_FUNCTION(this);
147
148 m_ownMobility = nullptr;
149 m_anotherMobility = nullptr;
150 m_geoSatMobility = nullptr;
151 m_ownProgDelayModel = nullptr;
152 m_anotherProgDelayModel = nullptr;
153}
154
156{
157 NS_LOG_FUNCTION(this);
158}
159
160void
161SatMobilityObserver::ObserveTimingAdvance(Ptr<PropagationDelayModel> ownDelayModel,
162 Ptr<PropagationDelayModel> anotherDelayModel,
163 Ptr<SatMobilityModel> anotherMobility)
164{
165 NS_LOG_FUNCTION(this << ownDelayModel << anotherDelayModel << anotherMobility);
166
167 NS_ASSERT(ownDelayModel != nullptr);
168 NS_ASSERT(anotherDelayModel != nullptr);
169 NS_ASSERT(anotherMobility != nullptr);
170
171 auto cb = MakeCallback(&SatMobilityObserver::PositionChanged, this);
172 if (m_anotherMobility != nullptr)
173 {
174 m_anotherMobility->TraceDisconnect("SatCourseChange", "Another", cb);
175 }
176
177 m_ownProgDelayModel = ownDelayModel;
178 m_anotherProgDelayModel = anotherDelayModel;
179 m_anotherMobility = anotherMobility;
180
181 // same reference ellipsoide must be used by mobilities
182 NS_ASSERT(m_anotherMobility->GetGeoPosition().GetRefEllipsoid() ==
183 m_ownMobility->GetGeoPosition().GetRefEllipsoid());
184
185 m_anotherMobility->TraceConnect("SatCourseChange", "Another", cb);
186}
187
188double
190{
191 NS_LOG_FUNCTION(this);
192
193 if (m_updateElevationAngle == true)
194 {
195 // same reference ellipsoide must be used by mobilities
196 NS_ASSERT(m_geoSatMobility->GetGeoPosition().GetRefEllipsoid() ==
197 m_ownMobility->GetGeoPosition().GetRefEllipsoid());
198
201 }
202
203 return m_elevationAngle;
204}
205
206double
208{
209 NS_LOG_FUNCTION(this);
210
211 Vector velocity = m_ownMobility->GetVelocity();
212 m_velocity = std::sqrt((velocity.x * velocity.x) + (velocity.y * velocity.y) +
213 (velocity.z * velocity.z));
214
215 return m_velocity;
216}
217
218Time
220{
221 NS_LOG_FUNCTION(this);
222
223 // update timing advance, if another end is given and update needed
224 if ((m_anotherMobility != nullptr) && (m_updateTimingAdvance == true))
225 {
226 // another propagation delay is expected to be given
227 NS_ASSERT(m_anotherProgDelayModel != nullptr);
228
229 // same reference ellipsoide must be used by mobilities
230 NS_ASSERT(m_geoSatMobility->GetGeoPosition().GetRefEllipsoid() ==
231 m_ownMobility->GetGeoPosition().GetRefEllipsoid());
232
233 // same reference ellipsoide must be used by mobilities
234 NS_ASSERT(m_anotherMobility->GetGeoPosition().GetRefEllipsoid() ==
235 m_ownMobility->GetGeoPosition().GetRefEllipsoid());
236
238 m_updateTimingAdvance = false;
239 }
240
241 return m_timingAdvance_s;
242}
243
244void
246{
247 NS_LOG_FUNCTION(this);
248
249 if (m_initialized)
250 {
252 }
253}
254
255void
256SatMobilityObserver::PositionChanged(std::string context, Ptr<const SatMobilityModel> position)
257{
258 NS_LOG_FUNCTION(this << context << position);
259
260 // set flag on to idicate that elevation angle is needed to update,
261 // when its status is requested with method GetElevationAngle
263
264 // set flag on to idicate that timing advance is needed to update,
265 // when its status is requested with method GetTimingAdvance
267
268 // call satellite statis updated routine to update needed variables
269 if (context == "Satellite")
270 {
272 }
273
275}
276
277void
279{
280 NS_LOG_FUNCTION(this);
281
282 m_elevationAngle = NAN;
283
284 GeoCoordinate ownPosition = m_ownMobility->GetGeoPosition();
285 GeoCoordinate satellitePosition = m_geoSatMobility->GetGeoPosition();
286
287 NS_ASSERT(ownPosition.GetAltitude() >= m_minAltitude &&
288 ownPosition.GetAltitude() <= m_maxAltitude);
289
290 // elevation angle is always calculated at earth surface, so set altitude to zero
291 ownPosition.SetAltitude(0);
292
293 // calculate distance from Earth location to satellite
294 double distanceToSatellite =
295 CalculateDistance(ownPosition.ToVector(), satellitePosition.ToVector());
296
297 // calculate elevation angle only, if satellite can be seen from own position
298 if (distanceToSatellite <= m_maxDistanceToSatellite)
299 {
300 double earthLatitude = SatUtils::DegreesToRadians(ownPosition.GetLatitude());
301 double satLatitude = SatUtils::DegreesToRadians(satellitePosition.GetLatitude());
302
303 double earthLongitude = SatUtils::DegreesToRadians(ownPosition.GetLongitude());
304 double satLongitude = SatUtils::DegreesToRadians(satellitePosition.GetLongitude());
305
306 double longitudeDelta = satLongitude - earthLongitude;
307
308 // Calculate cosini of the central angle
309 // TODO: Currently we have assumed that the reference ellipsoide is a sphere.
310 // This should be accurate enough for elevation angle calculation with also other
311 // reference ellipsoides. But, if more accurate calculation is needed, then the used
312 // reference ellipsoide is needed to be take into account.
313 double centralAngleCos =
314 (std::cos(earthLatitude) * std::cos(satLatitude) * std::cos(longitudeDelta)) +
315 (std::sin(earthLatitude) * std::sin(satLatitude));
316
317 // Calculate cosini of the elavation angle
318 double elCos =
319 std::sin(std::acos(centralAngleCos)) /
320 std::sqrt(1 + std::pow(m_radiusRatio, 2) - 2 * m_radiusRatio * centralAngleCos);
321
323 }
324}
325
326void
328{
329 NS_LOG_FUNCTION(this);
330
331 NS_ASSERT(m_ownProgDelayModel != nullptr);
332 NS_ASSERT(m_anotherProgDelayModel != nullptr);
333
335 {
337 }
338 else
339 {
342 }
343}
344
345void
347{
348 NS_LOG_FUNCTION(this);
349
350 double satelliteAltitude = m_geoSatMobility->GetGeoPosition().GetAltitude();
351
352 // satellite is expected to be in the sky
353 NS_ASSERT(satelliteAltitude > 0.0);
354
355 // calculate maximum distance where UT or GW can be on the Earth.
356 double satelliteRadius = satelliteAltitude + m_earthRadius;
358 std::sqrt((satelliteRadius * satelliteRadius) - (m_earthRadius * m_earthRadius));
359
360 // calculate ratio of the earth and satellite radius
361 m_radiusRatio = m_earthRadius / satelliteRadius;
362}
363
364} // namespace ns3
GeoCoordinate class is used to store and operate with geodetic coordinates.
void SetAltitude(double altitude)
Sets altitude value of coordinate.
double GetAltitude() const
Gets altitude value of coordinate.
double GetLatitude() const
Gets latitude value of coordinate.
ReferenceEllipsoid_t GetRefEllipsoid()
Gets reference ellipsoid used by GeoCoordinate object.
double GetLongitude() const
Gets longitude value of coordinate.
Vector ToVector() const
Converts Geodetic coordinates to Cartesian coordinates.
Observes given mobilities and keeps track of certain wanted properties.
Ptr< SatMobilityModel > m_geoSatMobility
virtual ~SatMobilityObserver()
Destructor of the mobility observer.
virtual void DoDispose(void)
Dispose of this class instance.
void UpdateElevationAngle()
Update elevation angle.
SatMobilityObserver()
Default constructor of the mobility observer (should not be called).
void ObserveTimingAdvance(Ptr< PropagationDelayModel > ownDelayModel, Ptr< PropagationDelayModel > anotherDelayModel, Ptr< SatMobilityModel > anotherMobility)
Enable observing of the timing advance.
Time GetTimingAdvance(void)
Get timing advance.
void PositionChanged(std::string context, Ptr< const SatMobilityModel > position)
Listener (callback) for mobility position changes.
void SatelliteStatusChanged()
Do actions needed when satellite position is changed.
void UpdateTimingAdvance()
Update timing advance.
double GetVelocity(void)
Get velocity of own movement (speed).
static TypeId GetTypeId(void)
Get the type ID.
Ptr< SatMobilityModel > m_anotherMobility
void NotifyPropertyChange(void) const
Notify listeners about some property is changed.
double GetElevationAngle(void)
Get elevation angle.
TracedCallback< Ptr< const SatMobilityObserver > > m_propertyChangeTrace
Used to alert subscribers that a change in some observed property has occurred.
Ptr< PropagationDelayModel > m_anotherProgDelayModel
Ptr< PropagationDelayModel > m_ownProgDelayModel
Ptr< SatMobilityModel > m_ownMobility
static T RadiansToDegrees(T radian)
Converts radians to degrees.
static T DegreesToRadians(T degree)
Converts degrees to radians.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.