3 XCSoar Glide Computer - http://www.xcsoar.org/
4 Copyright (C) 2000-2013 The XCSoar Project
5 A detailed list of copyright holders can be found in the file "AUTHORS".
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "Engine/GlideSolvers/GlidePolar.hpp"
24 #include "Engine/Task/Ordered/OrderedTask.hpp"
25 #include "Engine/Task/Ordered/OrderedTaskBehaviour.hpp"
26 #include "Engine/Task/Ordered/Points/AATPoint.hpp"
27 #include "Engine/Task/Ordered/Points/StartPoint.hpp"
28 #include "Engine/Task/Ordered/Points/FinishPoint.hpp"
29 #include "Engine/Task/ObservationZones/CylinderZone.hpp"
30 #include "Geo/Flat/TaskProjection.hpp"
31 #include "TestUtil.hpp"
33 static TaskBehaviour task_behaviour
;
34 static OrderedTaskBehaviour ordered_task_behaviour
;
35 static GlidePolar
glide_polar(fixed(0));
38 MakeGeoPoint(double longitude
, double latitude
)
40 return GeoPoint(Angle::Degrees(longitude
),
41 Angle::Degrees(latitude
));
45 MakeWaypoint(Waypoint wp
, double altitude
)
47 wp
.elevation
= fixed(altitude
);
52 MakeWaypoint(double longitude
, double latitude
, double altitude
)
54 return MakeWaypoint(Waypoint(MakeGeoPoint(longitude
, latitude
)), altitude
);
57 static const Waypoint wp1
= MakeWaypoint(0, 45, 50);
58 static const Waypoint wp2
= MakeWaypoint(0, 45.3, 50);
59 static const Waypoint wp3
= MakeWaypoint(0, 46, 50);
64 OrderedTask
task(task_behaviour
);
65 task
.Append(StartPoint(new CylinderZone(wp1
.location
, fixed(500)), wp1
,
67 ordered_task_behaviour
.start_constraints
));
68 task
.Append(AATPoint(new CylinderZone(wp2
.location
, fixed(10000)), wp2
,
70 task
.Append(FinishPoint(new CylinderZone(wp3
.location
, fixed(500)), wp3
,
72 ordered_task_behaviour
.finish_constraints
));
73 task
.SetActiveTaskPoint(1);
74 ok1(task
.CheckTask());
76 AircraftState aircraft
;
78 aircraft
.location
= wp1
.location
;
79 aircraft
.altitude
= fixed(2500);
80 task
.Update(aircraft
, aircraft
, glide_polar
);
82 AATPoint
&ap
= (AATPoint
&)task
.GetPoint(1);
84 ok1(!ap
.IsTargetLocked());
85 ok1(equals(ap
.GetTargetLocation(), wp2
.location
));
87 ok1(ap
.IsTargetLocked());
88 ok1(equals(ap
.GetTargetLocation(), wp2
.location
));
90 GeoPoint target
= MakeGeoPoint(0, 45.31);
92 ok1(ap
.IsTargetLocked());
93 ok1(equals(ap
.GetTargetLocation(), wp2
.location
));
95 ap
.SetTarget(target
, true);
96 ok1(ap
.IsTargetLocked());
97 ok1(equals(ap
.GetTargetLocation(), target
));
99 RangeAndRadial rar
= ap
.GetTargetRangeRadial();
100 ok1(equals(rar
.range
, fixed(0.1112), 1000));
101 ok1(equals(rar
.radial
.Degrees(), fixed(0), 200));
103 target
= MakeGeoPoint(0, 45.29);
104 ap
.SetTarget(target
, true);
105 rar
= ap
.GetTargetRangeRadial();
106 ok1(equals(rar
.range
, fixed(-0.1112), 1000));
107 ok1(equals(rar
.radial
.Degrees(), fixed(180), 200) ||
108 equals(rar
.radial
.Degrees(), fixed(-180), 200));
110 target
= MakeGeoPoint(-0.05, 45.3);
111 ap
.SetTarget(target
, true);
112 rar
= ap
.GetTargetRangeRadial();
113 ok1(equals(rar
.range
, 0.39107));
114 ok1(equals(rar
.radial
.Degrees(), -89.98));
116 target
= MakeGeoPoint(0.05, 45.3);
117 ap
.SetTarget(target
, true);
118 rar
= ap
.GetTargetRangeRadial();
119 ok1(equals(rar
.range
, 0.39107));
120 ok1(equals(rar
.radial
.Degrees(), 89.98));
122 for (int radial
= -170; radial
<= 170; radial
+= 10) {
123 const Angle radial2
= Angle::Degrees(radial
);
125 for (int range
= 10; range
<= 100; range
+= 10) {
126 const fixed
range2(fixed(radial
>= -90 && radial
<= 90
127 ? range
: -range
) / 100);
129 ap
.SetTarget(RangeAndRadial
{range2
, radial2
}, task
.GetTaskProjection());
130 rar
= ap
.GetTargetRangeRadial();
131 ok1(equals(rar
.range
, range2
, 100));
132 ok1(equals(rar
.radial
.Degrees(), radial2
.Degrees(), 100));
143 int main(int argc
, char **argv
)
147 task_behaviour
.SetDefaults();
148 ordered_task_behaviour
.SetDefaults();
152 return exit_status();