AbstractTask: eliminate GetFinishHeight()
[xcsoar.git] / src / Engine / Task / Ordered / OrderedTask.hpp
blobc5634f3ada8e8aeab01a8e03db5cc3f1aaa687dc
1 /* Copyright_License {
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 #ifndef ORDEREDTASK_H
24 #define ORDEREDTASK_H
26 #include "Geo/Flat/TaskProjection.hpp"
27 #include "Task/AbstractTask.hpp"
28 #include "Task/TaskBehaviour.hpp"
29 #include "SmartTaskAdvance.hpp"
30 #include "Util/DereferenceIterator.hpp"
31 #include "MatPoints.hpp"
33 #include <assert.h>
34 #include <vector>
36 class SearchPoint;
37 class SearchPointVector;
38 class OrderedTaskPoint;
39 class StartPoint;
40 class FinishPoint;
41 class AbstractTaskFactory;
42 class TaskDijkstraMin;
43 class TaskDijkstraMax;
44 struct Waypoint;
45 class Waypoints;
46 class AATPoint;
47 class FlatBoundingBox;
48 class GeoBounds;
49 struct TaskSummary;
50 struct TaskFactoryConstraints;
52 /**
53 * A task comprising an ordered sequence of task points, each with
54 * observation zones. A valid OrderedTask has a StartPoint, zero or more
55 * IntermediatePoints and a FinishPoint.
57 * \todo
58 * - better handling of removal of start/finish point
59 * - allow for TakeOffPoint and LandingPoint
60 * - have a method to check if a potential taskpoint is distinct from its neighbours?
61 * - multiple start points
63 class OrderedTask final : public AbstractTask
65 public:
66 typedef std::vector<OrderedTaskPoint*> OrderedTaskPointVector; /**< Storage type of task points */
68 typedef DereferenceContainerAdapter<const OrderedTaskPointVector,
69 const OrderedTaskPoint> ConstTaskPointList;
71 private:
72 OrderedTaskPointVector task_points;
73 OrderedTaskPointVector optional_start_points;
75 StartPoint *taskpoint_start;
76 FinishPoint *taskpoint_finish;
78 TaskProjection task_projection;
80 GeoPoint last_min_location;
82 TaskFactoryType factory_mode;
83 AbstractTaskFactory* active_factory;
84 OrderedTaskBehaviour ordered_behaviour;
85 SmartTaskAdvance task_advance;
86 TaskDijkstraMin *dijkstra_min;
87 TaskDijkstraMax *dijkstra_max;
89 /**
90 * maintains a list of Turnpoints from the waypoint file for MAT tasks
92 MatPoints mat_points;
94 public:
95 /**
96 * Constructor.
98 * \todo
99 * - default values in constructor
101 * @param tb Task behaviour
103 * @return Initialised object
105 OrderedTask(const TaskBehaviour &tb);
106 ~OrderedTask();
109 * Accessor for factory system for constructing tasks
111 * @return Factory
113 gcc_pure
114 AbstractTaskFactory& GetFactory() const {
115 return *active_factory;
118 gcc_pure
119 const TaskFactoryConstraints &GetFactoryConstraints() const;
122 * Set type of task factory to be used for constructing tasks
124 * @param _factory Type of task
126 void SetFactory(const TaskFactoryType _factory);
128 /**
129 * Return list of factory types
131 * @param all If true, return all types, otherwise only valid transformable ones
133 * @return Vector of factory types
135 gcc_pure
136 std::vector<TaskFactoryType> GetFactoryTypes(bool all = true) const;
138 void SetTaskBehaviour(const TaskBehaviour &tb);
141 * Removes all task points.
143 void RemoveAllPoints();
145 /**
146 * Clear all points and restore default ordered task behaviour
147 * for the active factory
149 void Clear();
152 * Create a clone of the task.
153 * Caller is responsible for destruction.
155 * @param te Task events
156 * @param tb Task behaviour
158 * @return Initialised object
160 gcc_malloc
161 OrderedTask *Clone(const TaskBehaviour &tb) const;
164 * Copy task into this task
166 * @param other OrderedTask to copy
167 * @param waypoints. const reference to the waypoint file
168 * @return True if this task changed
170 bool Commit(const OrderedTask& other);
173 * Retrieves the active task point index.
175 * @return Index of active task point sequence
177 gcc_pure
178 unsigned GetActiveIndex() const {
179 return active_task_point;
183 * Retrieve task point by sequence index
185 * @param index Index of task point sequence
187 * @return OrderedTaskPoint at index
189 gcc_pure
190 const OrderedTaskPoint &GetTaskPoint(const unsigned index) const {
191 assert(index < task_points.size());
193 return *task_points[index];
197 * Check if task has a single StartPoint
199 * @return True if task has start
201 gcc_pure
202 bool HasStart() const {
203 return taskpoint_start != NULL;
207 * Check if task has a single FinishPoint
209 * @return True if task has finish
211 gcc_pure
212 bool HasFinish() const {
213 return taskpoint_finish != NULL;
217 * Cycle through optional start points, replacing actual task start point
218 * with top item in optional starts.
220 void RotateOptionalStarts();
223 * Returns true if there are optional start points.
225 gcc_pure
226 bool HasOptionalStarts() const {
227 return !optional_start_points.empty();
231 * Insert taskpoint before specified index in task. May fail if the candidate
232 * is the wrong type (e.g. if it is a StartPoint and the task already
233 * has one).
234 * Ownership is transferred to this object.
236 * @param tp Taskpoint to insert
237 * @param position Index in task sequence, before which to insert
239 * @return True on success
241 bool Insert(const OrderedTaskPoint &tp, const unsigned position);
244 * Replace taskpoint.
245 * May fail if the candidate is the wrong type.
246 * Does nothing (but returns true) if replacement is equivalent
247 * Ownership is transferred to this object.
249 * @param tp Taskpoint to become replacement
250 * @param position Index in task sequence of task point to replace
252 * @return True on success
254 bool Replace(const OrderedTaskPoint &tp, const unsigned position);
257 * Replace optional start point.
258 * May fail if the candidate is the wrong type.
259 * Does nothing (but returns true) if replacement is equivalent
260 * Ownership is transferred to this object.
262 * @param tp Taskpoint to become replacement
263 * @param position Index in task sequence of task point to replace
265 * @return True on success
267 bool ReplaceOptionalStart(const OrderedTaskPoint &tp, const unsigned position);
270 * Append taskpoint to end of task. May fail if the candidate
271 * is the wrong type (e.g. if it is a StartPoint and the task already
272 * has one).
273 * Ownership is transferred to this object.
275 * @param tp Taskpoint to append to task
277 * @return True on success
279 bool Append(const OrderedTaskPoint &tp);
282 * Append optional start point. May fail if the candidate
283 * is the wrong type.
284 * Ownership is transferred to this object.
286 * @param tp Taskpoint to append to task
288 * @return True on success
290 bool AppendOptionalStart(const OrderedTaskPoint &tp);
293 * Remove task point at specified position. Note that
294 * currently start/finish points can't be removed.
296 * @param position Index in task sequence of task point to remove
298 * @return True on success
300 bool Remove(const unsigned position);
303 * Remove optional start point at specified position.
305 * @param position Index in sequence of optional start point to remove
307 * @return True on success
309 bool RemoveOptionalStart(const unsigned position);
312 * Change the waypoint of an optional start point
313 * @param position valid index to optional start point
314 * @param waypoint
315 * @return true if succeeded
317 bool RelocateOptionalStart(const unsigned position, const Waypoint& waypoint);
320 * Relocate a task point to a new location
322 * @param position Index in task sequence of task point to replace
323 * @param waypoint Waypoint of replacement
325 * @return True on success
327 bool Relocate(const unsigned position, const Waypoint& waypoint);
330 * returns pointer to AATPoint accessed via TPIndex if exist
332 * @param TPindex index of taskpoint
334 * @return pointer to tp if valid, else NULL
336 AATPoint* GetAATTaskPoint(unsigned index) const;
339 * Check whether the task point with the specified index exists.
341 gcc_pure
342 bool IsValidIndex(unsigned i) const {
343 return i < task_points.size();
347 * Determine whether the task is full according to the factory in use
349 * @return True if task is full
351 gcc_pure
352 bool IsFull() const;
355 * Accessor for task projection, for use when creating task points
357 * @return Task global projection
359 gcc_pure
360 const TaskProjection&
361 GetTaskProjection() const {
362 return task_projection;
365 void CheckDuplicateWaypoints(Waypoints& waypoints);
368 * Update internal geometric state of task points.
369 * Typically called after task geometry or observation zones are modified.
372 * This also updates planned/nominal distances so clients can use that
373 * data during task construction.
375 void UpdateGeometry();
378 * Convert a GeoBounds into a flat bounding box projected
379 * according to the task projection.
381 gcc_pure
382 FlatBoundingBox GetBoundingBox(const GeoBounds &bounds) const;
385 * Update summary task statistics (progress along path)
387 void UpdateSummary(TaskSummary &summary) const;
389 public:
391 * Retrieve vector of search points to be used in max/min distance
392 * scans (by TaskDijkstra).
394 * @param tp Index of task point of query
396 * @return Vector of search point candidates
398 const SearchPointVector &GetPointSearchPoints(unsigned tp) const;
400 protected:
402 * Set task point's minimum distance value (by TaskDijkstra).
404 * @param tp Index of task point to set min
405 * @param sol Search point found to be minimum distance
407 void SetPointSearchMin(unsigned tp, const SearchPoint &sol);
410 * Set task point's maximum distance value (by TaskDijkstra).
412 * @param tp Index of task point to set max
413 * @param sol Search point found to be maximum distance
415 void SetPointSearchMax(unsigned tp, const SearchPoint &sol);
418 * Set task point's minimum distance achieved value
420 * @param tp Index of task point to set min
421 * @param sol Search point found to be minimum distance
423 void set_tp_search_achieved(unsigned tp, const SearchPoint &sol);
425 public:
427 * Scan task for valid start/finish points
429 * @return True if start and finish found
431 bool ScanStartFinish();
434 * checks if the aircraft has entered the Mat cylinder
435 * updates transition state of point
436 * @return true if enter transition occurs
438 bool CheckTransitionPointMat(OrderedTaskPoint &point,
439 const AircraftState &state,
440 const AircraftState &state_last,
441 const FlatBoundingBox &bb_now,
442 const FlatBoundingBox &bb_last);
443 private:
445 fixed ScanDistanceMin(const GeoPoint &ref, bool full);
446 fixed ScanDistanceMax();
449 * Optimise target ranges (for adjustable tasks) to produce an estimated
450 * time remaining with the current glide polar, equal to a target value.
452 * @param state_now Aircraft state
453 * @param t_target Desired time for remainder of task (s)
455 * @return Target range parameter (0-1)
457 fixed CalcMinTarget(const AircraftState &state_now,
458 const GlidePolar &glide_polar,
459 const fixed t_target);
462 * Sets previous/next taskpoint pointers for task point at specified
463 * index in sequence.
465 * @param position Index of task point
467 void SetNeighbours(unsigned position);
470 * Erase taskpoint in sequence (for internal use)
472 * @param i index of task point in sequence
474 void ErasePoint(unsigned i);
477 * Erase optional start point (for internal use)
479 * @param i index of optional start point in sequence
481 void EraseOptionalStartPoint(unsigned i);
483 void UpdateStartTransition(const AircraftState &state,
484 OrderedTaskPoint &start);
486 gcc_pure
487 bool DistanceIsSignificant(const GeoPoint &location,
488 const GeoPoint &location_last) const;
490 gcc_pure
491 bool AllowIncrementalBoundaryStats(const AircraftState &state) const;
493 bool CheckTransitionPoint(OrderedTaskPoint &point,
494 const AircraftState &state_now,
495 const AircraftState &state_last,
496 const FlatBoundingBox &bb_now,
497 const FlatBoundingBox &bb_last,
498 bool &transition_enter, bool &transition_exit,
499 bool &last_started,
500 const bool is_start);
502 bool CheckTransitionOptionalStart(const AircraftState &state_now,
503 const AircraftState &state_last,
504 const FlatBoundingBox& bb_now,
505 const FlatBoundingBox& bb_last,
506 bool &transition_enter,
507 bool &transition_exit,
508 bool &last_started);
511 * @param waypoints Active waypoint database
512 * @param points Vector of points to confirm in active waypoint database
513 * @param is_task True if task point. False if optional start point
515 void CheckDuplicateWaypoints(Waypoints& waypoints,
516 OrderedTaskPointVector& points,
517 const bool is_task);
519 void SelectOptionalStart(unsigned pos);
521 public:
523 * Retrieve TaskAdvance mechanism
525 * @return Reference to TaskAdvance used by this task
527 const TaskAdvance &GetTaskAdvance() const {
528 return task_advance;
531 /**
532 * Retrieve TaskAdvance mechanism
534 * @return Reference to TaskAdvance used by this task
536 TaskAdvance &SetTaskAdvance() {
537 return task_advance;
540 /**
541 * Retrieve the factory type used by this task
543 * @return Factory type
545 TaskFactoryType GetFactoryType() const {
546 return factory_mode;
549 /**
550 * Retrieve (const) the OrderedTaskBehaviour used by this task
552 * @return Read-only OrderedTaskBehaviour
554 const OrderedTaskBehaviour &GetOrderedTaskBehaviour() const {
555 return ordered_behaviour;
558 /**
559 * Copy OrderedTaskBehaviour to this task
561 * @param ob Value to set
563 void SetOrderedTaskBehaviour(const OrderedTaskBehaviour &ob);
565 ConstTaskPointList GetPoints() const {
566 return task_points;
569 gcc_pure
570 OrderedTaskPoint &GetPoint(const unsigned i) {
571 assert(i < task_points.size());
572 assert(task_points[i] != NULL);
574 return *task_points[i];
577 gcc_pure
578 const OrderedTaskPoint &GetPoint(const unsigned i) const {
579 assert(i < task_points.size());
580 assert(task_points[i] != NULL);
582 return *task_points[i];
585 ConstTaskPointList GetOptionalStartPoints() const {
586 return optional_start_points;
590 * @return number of optional start poitns
592 gcc_pure
593 unsigned GetOptionalStartPointCount() const {
594 return optional_start_points.size();
598 * returns optional start point
600 * @param pos optional start point index
601 * @return NULL if index out of range, else optional start point
603 gcc_pure
604 const OrderedTaskPoint &GetOptionalStartPoint(unsigned i) const {
605 assert(i < optional_start_points.size());
607 return *optional_start_points[i];
610 /** Determines whether the task has adjustable targets */
611 gcc_pure
612 bool HasTargets() const;
615 * Find location of center of task (for rendering purposes)
617 * @return Location of center of task or GeoPoint::Invalid()
619 gcc_pure
620 GeoPoint GetTaskCenter() const;
623 * Find approximate radius of task from center to edge (for rendering purposes)
625 * @return Radius (m) from center to edge of task
627 gcc_pure
628 fixed GetTaskRadius() const;
631 * returns the index of the highest intermediate TP that has been entered.
632 * if none have been entered, returns zero
633 * If start has exited, returns zero
634 * Does not consider whether Finish has been achieved
635 * @return index of last intermediate point achieved or 0 if none
637 unsigned GetLastIntermediateAchieved() const;
640 * returns const reference to mat_points
642 const MatPoints::MatVector& GetMatPoints() const {
643 return mat_points.GetMatPoints();
647 * returns reference mat_points
649 MatPoints::MatVector& SetMatPoints() {
650 return mat_points.SetMatPoints();
654 * this is called automatically by Commit
655 * or if the waypoint file changes.
656 * If a client wants to use the Mat Points on an Uncommitted task,
657 * he must Call FillMatPoints himself
658 * The MatPoints will be deleted when the task is deleted
659 * It is the client's responsibility to lock the task manager if
660 * this is called on the active task
661 * @param wps. Reference to the waypoint file
662 * @param update_geometry. If true (default) will update the task's geometry
664 void FillMatPoints(const Waypoints &wps, bool update_geometry = true);
667 * removes all points from mat_points
669 void ClearMatPoints() {
670 mat_points.ClearMatPoints();
674 * Should we add this WP to the Mat
675 * after the last achieved Intermediate point?
676 * @param mat_wp the wp to test
677 * @return true if this should be added after the last achieved intermediate tp
679 bool ShouldAddToMat(const Waypoint &mat_wp) const;
681 public:
682 /* virtual methods from class TaskInterface */
683 virtual unsigned TaskSize() const override {
684 return task_points.size();
687 virtual void SetActiveTaskPoint(unsigned desired) override;
688 virtual TaskWaypoint *GetActiveTaskPoint() const override;
689 virtual bool IsValidTaskPoint(const int index_offset=0) const override;
690 virtual bool UpdateIdle(const AircraftState& state_now,
691 const GlidePolar &glide_polar) override;
693 /* virtual methods from class AbstractTask */
694 virtual void Reset() override;
695 virtual bool TaskFinished() const override;
696 virtual bool TaskStarted(bool soft=false) const override;
697 virtual bool CheckTask() const override;
699 protected:
700 /* virtual methods from class AbstractTask */
701 virtual bool UpdateSample(const AircraftState &state_now,
702 const GlidePolar &glide_polar,
703 const bool full_update) override;
704 virtual bool CheckTransitions(const AircraftState &state_now,
705 const AircraftState &state_last) override;
706 virtual bool CalcBestMC(const AircraftState &state_now,
707 const GlidePolar &glide_polar,
708 fixed& best) const override;
709 virtual fixed CalcRequiredGlide(const AircraftState &state_now,
710 const GlidePolar &glide_polar) const override;
711 virtual bool CalcCruiseEfficiency(const AircraftState &state_now,
712 const GlidePolar &glide_polar,
713 fixed &value) const override;
714 virtual bool CalcEffectiveMC(const AircraftState &state_now,
715 const GlidePolar &glide_polar,
716 fixed &value) const override;
717 virtual fixed CalcGradient(const AircraftState &state_now) const override;
718 virtual fixed ScanTotalStartTime(const AircraftState &state_now) override;
719 virtual fixed ScanLegStartTime(const AircraftState &state_now) override;
720 virtual fixed ScanDistanceNominal() override;
721 virtual fixed ScanDistancePlanned() override;
722 virtual fixed ScanDistanceRemaining(const GeoPoint &ref) override;
723 virtual fixed ScanDistanceScored(const GeoPoint &ref) override;
724 virtual fixed ScanDistanceTravelled(const GeoPoint &ref) override;
725 virtual void ScanDistanceMinMax(const GeoPoint &ref, bool full,
726 fixed *dmin, fixed *dmax) override;
727 virtual void GlideSolutionRemaining(const AircraftState &state_now,
728 const GlidePolar &polar,
729 GlideResult &total, GlideResult &leg) override;
730 virtual void GlideSolutionTravelled(const AircraftState &state_now,
731 const GlidePolar &glide_polar,
732 GlideResult &total, GlideResult &leg) override;
733 virtual void GlideSolutionPlanned(const AircraftState &state_now,
734 const GlidePolar &glide_polar,
735 GlideResult &total,
736 GlideResult &leg,
737 DistanceStat &total_remaining_effective,
738 DistanceStat &leg_remaining_effective,
739 const GlideResult &solution_remaining_total,
740 const GlideResult &solution_remaining_leg) override;
741 protected:
742 virtual bool IsScored() const override;
743 public:
744 virtual void AcceptTaskPointVisitor(TaskPointConstVisitor &visitor) const override;
747 #endif //ORDEREDTASK_H