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.
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"
37 class SearchPointVector
;
38 class OrderedTaskPoint
;
41 class AbstractTaskFactory
;
42 class TaskDijkstraMin
;
43 class TaskDijkstraMax
;
47 class FlatBoundingBox
;
50 struct TaskFactoryConstraints
;
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.
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
66 typedef std::vector
<OrderedTaskPoint
*> OrderedTaskPointVector
; /**< Storage type of task points */
68 typedef DereferenceContainerAdapter
<const OrderedTaskPointVector
,
69 const OrderedTaskPoint
> ConstTaskPointList
;
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
;
90 * maintains a list of Turnpoints from the waypoint file for MAT tasks
99 * - default values in constructor
101 * @param tb Task behaviour
103 * @return Initialised object
105 OrderedTask(const TaskBehaviour
&tb
);
109 * Accessor for factory system for constructing tasks
114 AbstractTaskFactory
& GetFactory() const {
115 return *active_factory
;
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
);
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
136 std::vector
<TaskFactoryType
> GetFactoryTypes(bool all
= true) const;
138 void SetTaskBehaviour(const TaskBehaviour
&tb
);
141 * Removes all task points.
143 void RemoveAllPoints();
146 * Clear all points and restore default ordered task behaviour
147 * for the active factory
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
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
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
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
202 bool HasStart() const {
203 return taskpoint_start
!= NULL
;
207 * Check if task has a single FinishPoint
209 * @return True if task has finish
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.
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
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
);
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
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
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
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.
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
355 * Accessor for task projection, for use when creating task points
357 * @return Task global projection
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.
382 FlatBoundingBox
GetBoundingBox(const GeoBounds
&bounds
) const;
385 * Update summary task statistics (progress along path)
387 void UpdateSummary(TaskSummary
&summary
) const;
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;
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
);
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
);
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
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
);
487 bool DistanceIsSignificant(const GeoPoint
&location
,
488 const GeoPoint
&location_last
) const;
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
,
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
,
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
,
519 void SelectOptionalStart(unsigned pos
);
523 * Retrieve TaskAdvance mechanism
525 * @return Reference to TaskAdvance used by this task
527 const TaskAdvance
&GetTaskAdvance() const {
532 * Retrieve TaskAdvance mechanism
534 * @return Reference to TaskAdvance used by this task
536 TaskAdvance
&SetTaskAdvance() {
541 * Retrieve the factory type used by this task
543 * @return Factory type
545 TaskFactoryType
GetFactoryType() const {
550 * Retrieve (const) the OrderedTaskBehaviour used by this task
552 * @return Read-only OrderedTaskBehaviour
554 const OrderedTaskBehaviour
&GetOrderedTaskBehaviour() const {
555 return ordered_behaviour
;
559 * Copy OrderedTaskBehaviour to this task
561 * @param ob Value to set
563 void SetOrderedTaskBehaviour(const OrderedTaskBehaviour
&ob
);
565 ConstTaskPointList
GetPoints() const {
570 OrderedTaskPoint
&GetPoint(const unsigned i
) {
571 assert(i
< task_points
.size());
572 assert(task_points
[i
] != NULL
);
574 return *task_points
[i
];
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
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
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 */
612 bool HasTargets() const;
615 * Find location of center of task (for rendering purposes)
617 * @return Location of center of task or GeoPoint::Invalid()
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
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;
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
;
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
,
737 DistanceStat
&total_remaining_effective
,
738 DistanceStat
&leg_remaining_effective
,
739 const GlideResult
&solution_remaining_total
,
740 const GlideResult
&solution_remaining_leg
) override
;
742 virtual bool IsScored() const override
;
744 virtual void AcceptTaskPointVisitor(TaskPointConstVisitor
&visitor
) const override
;
747 #endif //ORDEREDTASK_H