QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GeoFenceManager.cc
Go to the documentation of this file.
1#include "GeoFenceManager.h"
2#include "Vehicle.h"
5
6QGC_LOGGING_CATEGORY(GeoFenceManagerLog, "PlanManager.GeoFenceManager")
7
9 : PlanManager (vehicle, MAV_MISSION_TYPE_FENCE)
10{
12 connect(this, &PlanManager::error, this, &GeoFenceManager::error);
14 connect(this, &PlanManager::sendComplete, this, &GeoFenceManager::_sendComplete);
15 connect(this, &PlanManager::newMissionItemsAvailable, this, &GeoFenceManager::_planManagerLoadComplete);
16}
17
22
23void GeoFenceManager::sendToVehicle(const QGeoCoordinate& breachReturn,
24 QmlObjectListModel& polygons,
25 QmlObjectListModel& circles)
26{
27 QList<MissionItem*> fenceItems;
28
29 _sendPolygons.clear();
30 _sendCircles.clear();
31
32 for (int i=0; i<polygons.count(); i++) {
33 _sendPolygons.append(*polygons.value<QGCFencePolygon*>(i));
34 }
35 for (int i=0; i<circles.count(); i++) {
36 _sendCircles.append(*circles.value<QGCFenceCircle*>(i));
37 }
38 _breachReturnPoint = breachReturn;
39
40 for (int i=0; i<_sendPolygons.count(); i++) {
41 const QGCFencePolygon& polygon = _sendPolygons[i];
42
43 for (int j=0; j<polygon.count(); j++) {
44 const QGeoCoordinate& vertex = polygon.path()[j].value<QGeoCoordinate>();
45
46 MissionItem* item = new MissionItem(0,
47 polygon.inclusion() ? MAV_CMD_NAV_FENCE_POLYGON_VERTEX_INCLUSION : MAV_CMD_NAV_FENCE_POLYGON_VERTEX_EXCLUSION,
48 MAV_FRAME_GLOBAL,
49 polygon.count(), // vertex count
50 0, 0, 0, // param 2-4 unused
51 vertex.latitude(),
52 vertex.longitude(),
53 0, // param 7 unused
54 false, // autocontinue
55 false, // isCurrentItem
56 this); // parent
57 fenceItems.append(item);
58 }
59 }
60
61 for (int i=0; i<_sendCircles.count(); i++) {
62 QGCFenceCircle& circle = _sendCircles[i];
63
64 MissionItem* item = new MissionItem(0,
65 circle.inclusion() ? MAV_CMD_NAV_FENCE_CIRCLE_INCLUSION : MAV_CMD_NAV_FENCE_CIRCLE_EXCLUSION,
66 MAV_FRAME_GLOBAL,
67 circle.radius()->rawValue().toDouble(),
68 0, 0, 0, // param 2-4 unused
69 circle.center().latitude(),
70 circle.center().longitude(),
71 0, // param 7 unused
72 false, // autocontinue
73 false, // isCurrentItem
74 this); // parent
75 fenceItems.append(item);
76 }
77
78 if (_breachReturnPoint.isValid()) {
79 MissionItem* item = new MissionItem(0,
80 MAV_CMD_NAV_FENCE_RETURN_POINT,
81 MAV_FRAME_GLOBAL_RELATIVE_ALT,
82 0, 0, 0, 0, // param 1-4 unused
83 breachReturn.latitude(),
84 breachReturn.longitude(),
85 breachReturn.altitude(),
86 false, // autocontinue
87 false, // isCurrentItem
88 this); // parent
89 fenceItems.append(item);
90 }
91
92 // Plan manager takes control of MissionItems, so no need to delete
93 writeMissionItems(fenceItems);
94}
95
97{
98 _polygons.clear();
99 _circles.clear();
100 _breachReturnPoint = QGeoCoordinate();
101
103}
104
105void GeoFenceManager::_sendComplete(bool error)
106{
107 if (error) {
108 _polygons.clear();
109 _circles.clear();
110 _breachReturnPoint = QGeoCoordinate();
111 } else {
112 _polygons = _sendPolygons;
113 _circles = _sendCircles;
114 }
115 _sendPolygons.clear();
116 _sendCircles.clear();
117 emit sendComplete(error);
118}
119
120void GeoFenceManager::_planManagerLoadComplete(bool removeAllRequested)
121{
122 bool loadFailed = false;
123
124 Q_UNUSED(removeAllRequested);
125
126 _polygons.clear();
127 _circles.clear();
128
129 MAV_CMD expectedCommand = (MAV_CMD)0;
130 int expectedVertexCount = 0;
131 QGCFencePolygon nextPolygon(true /* inclusion */);
132 const QList<MissionItem*>& fenceItems = missionItems();
133
134 for (int i=0; i<fenceItems.count(); i++) {
135 MissionItem* item = fenceItems[i];
136
137 MAV_CMD command = item->command();
138
139 if (command == MAV_CMD_NAV_FENCE_POLYGON_VERTEX_INCLUSION || command == MAV_CMD_NAV_FENCE_POLYGON_VERTEX_EXCLUSION) {
140 if (nextPolygon.count() == 0) {
141 // Starting a new polygon
142 expectedVertexCount = item->param1();
143 expectedCommand = command;
144 } else if (expectedVertexCount != item->param1()){
145 // In the middle of a polygon, but count suddenly changed
146 emit error(BadPolygonItemFormat, tr("GeoFence load: Vertex count change mid-polygon - actual:expected") + QString(" %1:%2").arg(item->param1()).arg(expectedVertexCount));
147 break;
148 } else if (expectedCommand != command) {
149 // Command changed before last polygon was completely loaded
150 emit error(BadPolygonItemFormat, tr("GeoFence load: Polygon type changed before last load complete - actual:expected") + QString(" %1:%2").arg(command).arg(expectedCommand));
151 break;
152 }
153 nextPolygon.appendVertex(QGeoCoordinate(item->param5(), item->param6()));
154 if (nextPolygon.count() == expectedVertexCount) {
155 // Polygon is complete
156 nextPolygon.setInclusion(command == MAV_CMD_NAV_FENCE_POLYGON_VERTEX_INCLUSION);
157 _polygons.append(nextPolygon);
158 nextPolygon.clear();
159 }
160 } else if (command == MAV_CMD_NAV_FENCE_CIRCLE_INCLUSION || command == MAV_CMD_NAV_FENCE_CIRCLE_EXCLUSION) {
161 if (nextPolygon.count() != 0) {
162 // Incomplete polygon
163 emit error(IncompletePolygonLoad, tr("GeoFence load: Incomplete polygon loaded"));
164 break;
165 }
166 QGCFenceCircle circle(QGeoCoordinate(item->param5(), item->param6()), item->param1(), command == MAV_CMD_NAV_FENCE_CIRCLE_INCLUSION /* inclusion */);
167 _circles.append(circle);
168 } else if (command == MAV_CMD_NAV_FENCE_RETURN_POINT) {
169 _breachReturnPoint = QGeoCoordinate(item->param5(), item->param6(), item->param7());
170 } else {
171 emit error(UnsupportedCommand, tr("GeoFence load: Unsupported command %1").arg(item->command()));
172 break;
173 }
174 }
175
176 if (loadFailed) {
177 _polygons.clear();
178 _circles.clear();
179 _breachReturnPoint = QGeoCoordinate();
180 }
181
182 emit loadComplete();
183}
184
186{
187 return _vehicle->capabilityBits() & MAV_PROTOCOL_CAPABILITY_MISSION_FENCE;
188}
Error error
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void removeAll(void)
Signals removeAllComplete when done.
void sendToVehicle(const QGeoCoordinate &breachReturn, QmlObjectListModel &polygons, QmlObjectListModel &circles)
Signals sendComplete when done.
void error(int errorCode, const QString &errorMsg)
void inProgressChanged(bool inProgress)
const QList< QGCFencePolygon > & polygons(void)
@ BadPolygonItemFormat
Error re-creating polygons from mission items.
@ UnsupportedCommand
Usupported command in mission type.
@ IncompletePolygonLoad
Incomplete polygon loaded.
void loadComplete(void)
bool supported(void) const
void removeAllComplete(bool error)
void sendComplete(bool error)
const QList< QGCFenceCircle > & circles(void)
MAV_CMD command(void) const
Definition MissionItem.h:49
double param5(void) const
Definition MissionItem.h:58
double param7(void) const
Definition MissionItem.h:60
double param6(void) const
Definition MissionItem.h:59
double param1(void) const
Definition MissionItem.h:54
void sendComplete(bool error)
void removeAll(void)
void newMissionItemsAvailable(bool removeAllRequested)
void removeAllComplete(bool error)
void writeMissionItems(const QList< MissionItem * > &missionItems)
void inProgressChanged(bool inProgress)
const QList< MissionItem * > & missionItems(void)
Definition PlanManager.h:25
Vehicle * _vehicle
void error(int errorCode, const QString &errorMsg)
The QGCFenceCircle class provides a cicle used by GeoFence support.
bool inclusion(void) const
The QGCFencePolygon class provides a polygon used by GeoFence support.
bool inclusion(void) const
Fact * radius(void)
QGeoCoordinate center(void) const
QVariantList path(void) const
int count(void) const
uint64_t capabilityBits() const
Definition Vehicle.h:738