FlightGear next
rnav_waypt_controller.hxx
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0+
3 * SPDX-FileCopyrightText: 2009 (C) Curtis L. Olson
4 *
5 * rnav_waypt_controller.hxx - Waypoint-specific behaviours for RNAV systems
6 * Written by James Turner, started 2009.
7 *
8 * Copyright (C) 2009 Curtis L. Olson
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23*/
24
25#pragma once
26
27#include <optional>
28
29#include <Navaids/waypoint.hxx>
30
31namespace flightgear
32{
33
38class RNAV
39{
40public:
41 virtual SGGeod position() = 0;
42
46 virtual double trackDeg() = 0;
47
51 virtual double groundSpeedKts() = 0;
52
56 virtual double vspeedFPM()= 0;
57
61 virtual double magvarDeg() = 0;
62
66 virtual double selectedMagCourse() = 0;
67
68 virtual bool canFlyBy() const
69 {
70 return false;
71 }
72
78 virtual double maxFlyByTurnAngleDeg() const
79 {
80 return 90.0;
81 }
82
86 virtual double overflightDistanceM() = 0;
90 virtual double overflightArmDistanceM() = 0;
94 virtual double overflightArmAngleDeg() = 0;
95
96 struct LegData {
97 SGGeod position;
98 bool didFlyBy = false;
100 double flyByRadius = 0.0;
101 double turnAngle = 0.0;
102 };
103
107 virtual std::optional<LegData> previousLegData()
108 {
109 return std::optional<LegData>();
110 }
111
112 virtual std::optional<double> nextLegTrack()
113 {
114 return std::optional<double>{};
115 }
116
120
122 {
124 }
125
130 virtual double turnRadiusNm(const double groundSpeedKnots) = 0;
131};
132
134{
135public:
136 virtual ~WayptController();
137
138 virtual bool init();
139
140 virtual void update(double dt) = 0;
141
145 virtual double timeToWaypt() const;
146
150 virtual double distanceToWayptM() const = 0;
151
156 virtual double trueBearingDeg() const;
157
158 virtual double targetTrackDeg() const;
159
160 virtual double xtrackErrorNm() const;
161
162 virtual double courseDeviationDeg() const;
163
169 virtual SGGeod position() const = 0;
170
174 bool isDone() const;
175
181 virtual bool toFlag() const
182 { return true; }
183
189 virtual std::string status() const;
190
191 virtual std::optional<RNAV::LegData> legData() const
192 {
193 // defer to our subcontroller if it exists
194 if (_subController)
195 return _subController->legData();
196
197 return std::optional<RNAV::LegData>();
198 }
199
204 static WayptController* createForWaypt(RNAV* rnav, const WayptRef& aWpt);
205
207 { return _waypt; }
208
209protected:
210 WayptController(RNAV* aRNAV, const WayptRef& aWpt) :
211 _waypt(aWpt),
212 _targetTrack(0),
213 _rnav(aRNAV),
214 _isDone(false)
215 { }
216
220
221 void setDone();
222
223 // take asubcontroller ref (will be destroyed automatically)
224 // pass nullptr to clear any activ esubcontroller
225 // the subcontroller will be initialised
227
228 // if a subcontroller exists, we can delegate to it automatically
229 std::unique_ptr<WayptController> _subController;
230private:
231 bool _isDone;
232};
233
242{
243public:
244 DirectToController(RNAV* aRNAV, const WayptRef& aWpt, const SGGeod& aOrigin);
245
246 bool init() override;
247 virtual void update(double dt);
248 virtual double distanceToWayptM() const;
249 virtual double xtrackErrorNm() const;
250 virtual double courseDeviationDeg() const;
251 virtual double trueBearingDeg() const;
252 virtual SGGeod position() const;
253private:
254 SGGeod _origin;
255 double _distanceAircraftTargetMeter;
256 double _courseDev;
257 double _courseAircraftToTarget;
258};
259
264{
265public:
266 OBSController(RNAV* aRNAV, const WayptRef& aWpt);
267
268 bool init() override;
269 virtual void update(double dt);
270 virtual double distanceToWayptM() const;
271 virtual double xtrackErrorNm() const;
272 virtual double courseDeviationDeg() const;
273 virtual double trueBearingDeg() const;
274 virtual bool toFlag() const;
275 virtual SGGeod position() const;
276private:
277 double _distanceAircraftTargetMeter;
278 double _courseDev;
279 double _courseAircraftToTarget;
280};
281
283{
284 enum HoldState {
285 HOLD_INIT,
286 LEG_TO_HOLD,
287 ENTRY_DIRECT,
288 ENTRY_PARALLEL, // flying the outbound part of a parallel entry
289 ENTRY_PARALLEL_OUTBOUND,
290 ENTRY_PARALLEL_INBOUND,
291 ENTRY_TEARDROP, // flying the outbound leg of teardrop entry
292 HOLD_OUTBOUND,
293 HOLD_INBOUND,
294 HOLD_EXITING, // we are going to exit the hold
295 };
296
297 HoldState _state = HOLD_INIT;
298 double _holdCourse = 0.0;
299 double _holdLegTime = 60.0;
300 double _holdLegDistance = 0.0;
301 double _holdCount = 0;
302 bool _leftHandTurns = false;
303
304 bool _inTurn = false;
305 SGGeod _turnCenter;
306 double _turnEndAngle, _turnRadius;
307 SGGeod _segmentEnd;
308
309 bool checkOverHold();
310 void checkInitialEntry(double dNm);
311
312 void startInboundTurn();
313 void startOutboundTurn();
314 void startParallelEntryTurn();
315 void exitTurn();
316
317 SGGeod outboundEndPoint();
318 SGGeod outboundTurnCenter();
319 SGGeod inboundTurnCenter();
320
321 double holdLegLengthNm() const;
322
327 bool inLeftTurn() const;
328
329 void computeEntry();
330public:
331 HoldCtl(RNAV* aRNAV, const WayptRef& aWpt);
332
333 void setHoldCount(int count);
334 void exitHold();
335
336 bool init() override;
337 void update(double) override;
338
339 double distanceToWayptM() const override;
340 SGGeod position() const override;
341 double xtrackErrorNm() const override;
342 double courseDeviationDeg() const override;
343
344 std::string status() const override;
345};
346
347} // of namespace flightgear
virtual double distanceToWayptM() const
Compute distance until the waypoint is done.
virtual SGGeod position() const
Position associated with the waypt.
DirectToController(RNAV *aRNAV, const WayptRef &aWpt, const SGGeod &aOrigin)
virtual double trueBearingDeg() const
Bearing to the waypoint, if this value is meaningful.
double xtrackErrorNm() const override
double courseDeviationDeg() const override
double distanceToWayptM() const override
Compute distance until the waypoint is done.
void update(double) override
SGGeod position() const override
Position associated with the waypt.
std::string status() const override
Allow waypoints to indicate a status value as a string.
HoldCtl(RNAV *aRNAV, const WayptRef &aWpt)
OBSController(RNAV *aRNAV, const WayptRef &aWpt)
virtual double courseDeviationDeg() const
virtual double trueBearingDeg() const
Bearing to the waypoint, if this value is meaningful.
virtual double xtrackErrorNm() const
virtual SGGeod position() const
Position associated with the waypt.
virtual double distanceToWayptM() const
Compute distance until the waypoint is done.
virtual bool toFlag() const
to/from flag - true = to, false = from.
Abstract RNAV interface, for devices which implement an RNAV system - INS / GPS / FMS.
virtual double magvarDeg()=0
Magnetic variation at current position.
virtual double vspeedFPM()=0
Vertical speed in ft/minute.
virtual bool canFlyBy() const
double turnRadiusNm()
compute turn radius based on current ground-speed
virtual std::optional< LegData > previousLegData()
device leg previous waypoint position(eg, from route manager)
virtual SGGeod position()=0
virtual double overflightArmAngleDeg()=0
angle for overflight sequencing.
virtual double maxFlyByTurnAngleDeg() const
maximum angle in degrees where flyBy is permitted.
virtual double overflightDistanceM()=0
minimum distance to switch next waypoint.
virtual double groundSpeedKts()=0
Ground speed (along the track) in knots.
virtual double trackDeg()=0
True track in degrees.
virtual double overflightArmDistanceM()=0
minimum distance to a waypoint for overflight sequencing.
virtual std::optional< double > nextLegTrack()
virtual double turnRadiusNm(const double groundSpeedKnots)=0
compute the turn radius (based on standard rate turn) for a given ground speed in knots.
virtual double selectedMagCourse()=0
device selected course (eg, from autopilot / MCP / OBS) in degrees
virtual double trueBearingDeg() const
Bearing to the waypoint, if this value is meaningful.
virtual double courseDeviationDeg() const
virtual bool toFlag() const
to/from flag - true = to, false = from.
WayptController(RNAV *aRNAV, const WayptRef &aWpt)
virtual double targetTrackDeg() const
std::unique_ptr< WayptController > _subController
void setSubController(WayptController *sub)
bool isDone() const
Is this controller finished?
virtual double distanceToWayptM() const =0
Compute distance until the waypoint is done.
virtual SGGeod position() const =0
Position associated with the waypt.
virtual std::string status() const
Allow waypoints to indicate a status value as a string.
virtual void update(double dt)=0
virtual double timeToWaypt() const
Compute time until the waypoint is done.
virtual std::optional< RNAV::LegData > legData() const
static WayptController * createForWaypt(RNAV *rnav, const WayptRef &aWpt)
Static factory method, given a waypoint, return a controller bound to it, of the appropriate type.
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
Definition Addon.cxx:53
SGSharedPtr< Waypt > WayptRef