QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
TakeoffMissionItem.cc
Go to the documentation of this file.
4#include "SettingsManager.h"
5#include "PlanViewSettings.h"
9#include "Vehicle.h"
10
11TakeoffMissionItem::TakeoffMissionItem(PlanMasterController* masterController, bool flyView, MissionSettingsItem* settingsItem, bool forLoad)
12 : SimpleMissionItem(masterController, flyView, forLoad)
13 , _settingsItem(settingsItem)
14{
15 _init(forLoad);
16}
17
18TakeoffMissionItem::TakeoffMissionItem(MAV_CMD takeoffCmd, PlanMasterController* masterController, bool flyView, MissionSettingsItem* settingsItem, bool forLoad)
19 : SimpleMissionItem(masterController, flyView, false /* forLoad */)
20 , _settingsItem(settingsItem)
21{
22 setCommand(takeoffCmd);
23 _init(forLoad);
24}
25
26TakeoffMissionItem::TakeoffMissionItem(const MissionItem& missionItem, PlanMasterController* masterController, bool flyView, MissionSettingsItem* settingsItem, bool forLoad)
27 : SimpleMissionItem(masterController, flyView, missionItem)
28 , _settingsItem(settingsItem)
29{
30 _init(forLoad);
31}
32
37
38void TakeoffMissionItem::_init(bool forLoad)
39{
40 _editorQml = QStringLiteral("qrc:/qml/QGroundControl/Controls/SimpleItemEditor.qml");
41
43
44 if (_flyView) {
45 _initLaunchTakeoffAtSameLocation();
46 return;
47 }
48
49 QGeoCoordinate homePosition = _settingsItem->coordinate();
50 if (!homePosition.isValid()) {
51 Vehicle* activeVehicle = MultiVehicleManager::instance()->activeVehicle();
52 if (activeVehicle) {
53 homePosition = activeVehicle->homePosition();
54 if (homePosition.isValid()) {
55 _settingsItem->setCoordinate(homePosition);
56 }
57 }
58 }
59
60 if (forLoad) {
61 // Load routines will set the rest up after load
62 return;
63 }
64
65 _initLaunchTakeoffAtSameLocation();
66 if (_launchTakeoffAtSameLocation && homePosition.isValid()) {
68 }
69
70 // Wizard mode is set if:
71 // - Launch position is missing - requires prompt to user to click to set launch
72 // - Fixed wing - warn about climb out position adjustment
73 if (!homePosition.isValid() || _controllerVehicle->fixedWing()) {
74 _wizardMode = true;
75 }
76
77 setDirty(false);
78}
79
80void TakeoffMissionItem::_setLaunchTakeoffAtSameLocation(bool launchTakeoffAtSameLocation)
81{
82 if (launchTakeoffAtSameLocation != _launchTakeoffAtSameLocation) {
83 _launchTakeoffAtSameLocation = launchTakeoffAtSameLocation;
84 if (_launchTakeoffAtSameLocation) {
85 _setLaunchCoordinate(coordinate());
86 }
87 emit launchTakeoffAtSameLocationChanged(_launchTakeoffAtSameLocation);
88 setDirty(true);
89 }
90}
91
92QGeoCoordinate TakeoffMissionItem::launchCoordinate(void) const
93{
94 return _settingsItem->coordinate();
95}
96
97void TakeoffMissionItem::setCoordinate(const QGeoCoordinate& coordinate)
98{
99 if (coordinate != this->coordinate()) {
101 if (_launchTakeoffAtSameLocation) {
102 _settingsItem->setCoordinate(coordinate);
103 }
104 }
105}
106
111
112void TakeoffMissionItem::_initLaunchTakeoffAtSameLocation(void)
113{
114 if (specifiesCoordinate()) {
116 _setLaunchTakeoffAtSameLocation(false);
117 } else {
118 // PX4 specifies a coordinate for takeoff even for multi-rotor. But it makes more sense to not have a coordinate
119 // from and end user standpoint. So even for PX4 we try to keep launch and takeoff at the same position. Unless the
120 // user has moved/loaded launch at a different location than takeoff.
121 if (coordinate().isValid() && _settingsItem->coordinate().isValid()) {
122 _setLaunchTakeoffAtSameLocation(coordinate().latitude() == _settingsItem->coordinate().latitude() && coordinate().longitude() == _settingsItem->coordinate().longitude());
123 } else {
124 _setLaunchTakeoffAtSameLocation(true);
125 }
126
127 }
128 } else {
129 _setLaunchTakeoffAtSameLocation(true);
130 }
131}
132
133bool TakeoffMissionItem::load(QTextStream &loadStream)
134{
135 bool success = SimpleMissionItem::load(loadStream);
136 if (success) {
137 _initLaunchTakeoffAtSameLocation();
138 }
139 _wizardMode = false; // Always be off for loaded items
140 return success;
141}
142
143bool TakeoffMissionItem::load(const QJsonObject& json, int sequenceNumber, QString& errorString)
144{
146 if (success) {
147 _initLaunchTakeoffAtSameLocation();
148 }
149 _wizardMode = false; // Always be off for loaded items
150 return success;
151}
152
153void TakeoffMissionItem::_setLaunchCoordinate(const QGeoCoordinate& launchCoordinate)
154{
155 if (!launchCoordinate.isValid()) {
156 return;
157 }
158
159 _settingsItem->setCoordinate(launchCoordinate);
160
161 if (!coordinate().isValid()) {
162 QGeoCoordinate takeoffCoordinate;
163 if (_launchTakeoffAtSameLocation) {
164 takeoffCoordinate = launchCoordinate;
165 } else {
166 double distance = SettingsManager::instance()->planViewSettings()->vtolTransitionDistance()->rawValue().toDouble(); // Default distance is VTOL transition to takeoff point distance
168 double altitude = this->altitude()->rawValue().toDouble();
169
171 // Offset for fixed wing climb out of 30 degrees to specified altitude
172 if (altitude != 0.0) {
173 distance = altitude / tan(qDegreesToRadians(30.0));
174 }
175 } else {
176 distance = altitude * 1.5;
177 }
178 }
179 takeoffCoordinate = launchCoordinate.atDistanceAndAzimuth(distance, 0);
180 }
181 SimpleMissionItem::setCoordinate(takeoffCoordinate);
182 }
183}
QString errorString
bool isTakeoffCommand(MAV_CMD command) const
static MissionCommandTree * instance()
QGeoCoordinate coordinate(void) const final
void setCoordinate(const QGeoCoordinate &coordinate) final
Master controller for mission, fence, rally.
Fact *vtolTransitionDistance READ vtolTransitionDistance CONSTANT Fact * vtolTransitionDistance()
A SimpleMissionItem is used to represent a single MissionItem to the ui.
bool specifiesCoordinate(void) const final
int sequenceNumber(void) const final
QGroundControlQmlGlobal::AltMode altitudeMode(void) const
QGeoCoordinate coordinate(void) const final
virtual bool load(QTextStream &loadStream)
void setCoordinate(const QGeoCoordinate &coordinate) override
void setCommand(int command)
int command(void) const
void setDirty(bool dirty) final
static bool isTakeoffCommand(MAV_CMD command)
QGeoCoordinate launchCoordinate READ launchCoordinate WRITE _setLaunchCoordinate NOTIFY launchCoordinateChanged(bool launchTakeoffAtSameLocation READ launchTakeoffAtSameLocation WRITE _setLaunchTakeoffAtSameLocation NOTIFY launchTakeoffAtSameLocationChanged) QGeoCoordinate launchCoordinate(void) const
bool launchTakeoffAtSameLocation(void) const
void setCoordinate(const QGeoCoordinate &coordinate) override
bool load(QTextStream &loadStream) final
TakeoffMissionItem(PlanMasterController *masterController, bool flyView, MissionSettingsItem *settingsItem, bool forLoad)
void launchTakeoffAtSameLocationChanged(bool launchTakeoffAtSameLocation)
bool vtol() const
Definition Vehicle.cc:1869
QGeoCoordinate homePosition()
Definition Vehicle.cc:1515
bool fixedWing() const
Definition Vehicle.cc:1844
QString _editorQml
Qml resource for editing item.
void coordinateChanged(const QGeoCoordinate &coordinate)
double distance(void) const
bool _wizardMode
true: Item editor is showing wizard completion panel