PX4 Firmware
PX4 Autopilot Software http://px4.io
geofence.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2013,2017 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 /**
34  * @file geofence.cpp
35  * Provides functions for handling the geofence
36  *
37  * @author Jean Cyr <jean.m.cyr@gmail.com>
38  * @author Thomas Gubler <thomasgubler@gmail.com>
39  * @author Beat Küng <beat-kueng@gmx.net>
40  */
41 #include "geofence.h"
42 #include "navigator.h"
43 
44 #include <ctype.h>
45 
46 #include <dataman/dataman.h>
47 #include <drivers/drv_hrt.h>
48 #include <lib/ecl/geo/geo.h>
49 #include <systemlib/mavlink_log.h>
50 
51 #include "navigator.h"
52 
53 #define GEOFENCE_RANGE_WARNING_LIMIT 5000000
54 
56  ModuleParams(navigator),
57  _navigator(navigator),
58  _sub_airdata(ORB_ID(vehicle_air_data))
59 {
60  // we assume there's no concurrent fence update on startup
61  _updateFence();
62 }
63 
65 {
66  if (_polygons) {
67  delete[](_polygons);
68  }
69 }
70 
72 {
73  // Note: be aware that when calling this, it can block for quite some time, the duration of a geofence transfer.
74  // However this is currently not used
75  int ret = dm_lock(DM_KEY_FENCE_POINTS);
76 
77  if (ret != 0) {
78  PX4_ERR("lock failed");
79  return;
80  }
81 
82  _updateFence();
84 }
85 
87 {
88 
89  // initialize fence points count
91  int ret = dm_read(DM_KEY_FENCE_POINTS, 0, &stats, sizeof(mission_stats_entry_s));
92  int num_fence_items = 0;
93 
94  if (ret == sizeof(mission_stats_entry_s)) {
95  num_fence_items = stats.num_items;
97  }
98 
99  // iterate over all polygons and store their starting vertices
100  _num_polygons = 0;
101  int current_seq = 1;
102 
103  while (current_seq <= num_fence_items) {
104  mission_fence_point_s mission_fence_point;
105  bool is_circle_area = false;
106 
107  if (dm_read(DM_KEY_FENCE_POINTS, current_seq, &mission_fence_point, sizeof(mission_fence_point_s)) !=
108  sizeof(mission_fence_point_s)) {
109  PX4_ERR("dm_read failed");
110  break;
111  }
112 
113  switch (mission_fence_point.nav_cmd) {
115  // TODO: do we need to store this?
116  ++current_seq;
117  break;
118 
121  is_circle_area = true;
122 
123  /* FALLTHROUGH */
126  if (!is_circle_area && mission_fence_point.vertex_count == 0) {
127  ++current_seq; // avoid endless loop
128  PX4_ERR("Polygon with 0 vertices. Skipping");
129 
130  } else {
131  if (_polygons) {
132  // resize: this is somewhat inefficient, but we do not expect there to be many polygons
133  PolygonInfo *new_polygons = new PolygonInfo[_num_polygons + 1];
134 
135  if (new_polygons) {
136  memcpy(new_polygons, _polygons, sizeof(PolygonInfo) * _num_polygons);
137  }
138 
139  delete[](_polygons);
140  _polygons = new_polygons;
141 
142  } else {
143  _polygons = new PolygonInfo[1];
144  }
145 
146  if (!_polygons) {
147  _num_polygons = 0;
148  PX4_ERR("alloc failed");
149  return;
150  }
151 
152  PolygonInfo &polygon = _polygons[_num_polygons];
153  polygon.dataman_index = current_seq;
154  polygon.fence_type = mission_fence_point.nav_cmd;
155 
156  if (is_circle_area) {
157  polygon.circle_radius = mission_fence_point.circle_radius;
158  current_seq += 1;
159 
160  } else {
161  polygon.vertex_count = mission_fence_point.vertex_count;
162  current_seq += mission_fence_point.vertex_count;
163  }
164 
165  ++_num_polygons;
166  }
167 
168  break;
169 
170  default:
171  PX4_ERR("unhandled Fence command: %i", (int)mission_fence_point.nav_cmd);
172  ++current_seq;
173  break;
174  }
175 
176  }
177 
178 }
179 
180 bool Geofence::checkAll(const struct vehicle_global_position_s &global_position)
181 {
182  return checkAll(global_position.lat, global_position.lon, global_position.alt);
183 }
184 
185 bool Geofence::checkAll(const struct vehicle_global_position_s &global_position, const float alt)
186 {
187  return checkAll(global_position.lat, global_position.lon, alt);
188 }
189 
190 bool Geofence::check(const vehicle_global_position_s &global_position, const vehicle_gps_position_s &gps_position,
191  const home_position_s home_pos, bool home_position_set)
192 {
195  return checkAll(global_position);
196 
197  } else {
198  return checkAll((double)gps_position.lat * 1.0e-7, (double)gps_position.lon * 1.0e-7,
199  (double)gps_position.alt * 1.0e-3);
200  }
201 
202  } else {
203  // get baro altitude
204  _sub_airdata.update();
205  const float baro_altitude_amsl = _sub_airdata.get().baro_alt_meter;
206 
208  return checkAll(global_position, baro_altitude_amsl);
209 
210  } else {
211  return checkAll((double)gps_position.lat * 1.0e-7, (double)gps_position.lon * 1.0e-7, baro_altitude_amsl);
212  }
213  }
214 }
215 
216 bool Geofence::check(const struct mission_item_s &mission_item)
217 {
218  return checkAll(mission_item.lat, mission_item.lon, mission_item.altitude);
219 }
220 
221 bool Geofence::checkAll(double lat, double lon, float altitude)
222 {
223  bool inside_fence = true;
224 
226 
227  const float max_horizontal_distance = _param_gf_max_hor_dist.get();
228  const float max_vertical_distance = _param_gf_max_ver_dist.get();
229 
230  const double home_lat = _navigator->get_home_position()->lat;
231  const double home_lon = _navigator->get_home_position()->lon;
232  const float home_alt = _navigator->get_home_position()->alt;
233 
234  float dist_xy = -1.0f;
235  float dist_z = -1.0f;
236 
237  get_distance_to_point_global_wgs84(lat, lon, altitude, home_lat, home_lon, home_alt, &dist_xy, &dist_z);
238 
239  if (max_vertical_distance > FLT_EPSILON && (dist_z > max_vertical_distance)) {
241  mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Maximum altitude above home exceeded by %.1f m",
242  (double)(dist_z - max_vertical_distance));
244  }
245 
246  inside_fence = false;
247  }
248 
249  if (max_horizontal_distance > FLT_EPSILON && (dist_xy > max_horizontal_distance)) {
251  mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Maximum distance from home exceeded by %.1f m",
252  (double)(dist_xy - max_horizontal_distance));
254  }
255 
256  inside_fence = false;
257  }
258  }
259 
260  // to be inside the geofence both fences have to report being inside
261  // as they both report being inside when not enabled
262  inside_fence = inside_fence && checkPolygons(lat, lon, altitude);
263 
264  if (inside_fence) {
265  _outside_counter = 0;
266  return inside_fence;
267 
268  } else {
270 
271  if (_outside_counter > _param_gf_count.get()) {
272  return inside_fence;
273 
274  } else {
275  return true;
276  }
277  }
278 }
279 
280 
281 bool Geofence::checkPolygons(double lat, double lon, float altitude)
282 {
283  // the following uses dm_read, so first we try to lock all items. If that fails, it (most likely) means
284  // the data is currently being updated (via a mavlink geofence transfer), and we do not check for a violation now
285  if (dm_trylock(DM_KEY_FENCE_POINTS) != 0) {
286  return true;
287  }
288 
289  // we got the lock, now check if the fence data got updated
290  mission_stats_entry_s stats;
291  int ret = dm_read(DM_KEY_FENCE_POINTS, 0, &stats, sizeof(mission_stats_entry_s));
292 
293  if (ret == sizeof(mission_stats_entry_s) && _update_counter != stats.update_counter) {
294  _updateFence();
295  }
296 
297  if (isEmpty()) {
299  /* Empty fence -> accept all points */
300  return true;
301  }
302 
303  /* Vertical check */
304  if (_altitude_max > _altitude_min) { // only enable vertical check if configured properly
305  if (altitude > _altitude_max || altitude < _altitude_min) {
307  return false;
308  }
309  }
310 
311 
312  /* Horizontal check: iterate all polygons & circles */
313  bool outside_exclusion = true;
314  bool inside_inclusion = false;
315  bool had_inclusion_areas = false;
316 
317  for (int polygon_idx = 0; polygon_idx < _num_polygons; ++polygon_idx) {
318  if (_polygons[polygon_idx].fence_type == NAV_CMD_FENCE_CIRCLE_INCLUSION) {
319  bool inside = insideCircle(_polygons[polygon_idx], lat, lon, altitude);
320 
321  if (inside) {
322  inside_inclusion = true;
323  }
324 
325  had_inclusion_areas = true;
326 
327  } else if (_polygons[polygon_idx].fence_type == NAV_CMD_FENCE_CIRCLE_EXCLUSION) {
328  bool inside = insideCircle(_polygons[polygon_idx], lat, lon, altitude);
329 
330  if (inside) {
331  outside_exclusion = false;
332  }
333 
334  } else { // it's a polygon
335  bool inside = insidePolygon(_polygons[polygon_idx], lat, lon, altitude);
336 
337  if (_polygons[polygon_idx].fence_type == NAV_CMD_FENCE_POLYGON_VERTEX_INCLUSION) {
338  if (inside) {
339  inside_inclusion = true;
340  }
341 
342  had_inclusion_areas = true;
343 
344  } else { // exclusion
345  if (inside) {
346  outside_exclusion = false;
347  }
348  }
349  }
350  }
351 
353 
354  return (!had_inclusion_areas || inside_inclusion) && outside_exclusion;
355 }
356 
357 bool Geofence::insidePolygon(const PolygonInfo &polygon, double lat, double lon, float altitude)
358 {
359 
360  /* Adaptation of algorithm originally presented as
361  * PNPOLY - Point Inclusion in Polygon Test
362  * W. Randolph Franklin (WRF)
363  * Only supports non-complex polygons (not self intersecting)
364  */
365 
366  mission_fence_point_s temp_vertex_i;
367  mission_fence_point_s temp_vertex_j;
368  bool c = false;
369 
370  for (unsigned i = 0, j = polygon.vertex_count - 1; i < polygon.vertex_count; j = i++) {
371  if (dm_read(DM_KEY_FENCE_POINTS, polygon.dataman_index + i, &temp_vertex_i,
372  sizeof(mission_fence_point_s)) != sizeof(mission_fence_point_s)) {
373  break;
374  }
375 
376  if (dm_read(DM_KEY_FENCE_POINTS, polygon.dataman_index + j, &temp_vertex_j,
377  sizeof(mission_fence_point_s)) != sizeof(mission_fence_point_s)) {
378  break;
379  }
380 
381  if (temp_vertex_i.frame != NAV_FRAME_GLOBAL && temp_vertex_i.frame != NAV_FRAME_GLOBAL_INT
382  && temp_vertex_i.frame != NAV_FRAME_GLOBAL_RELATIVE_ALT
383  && temp_vertex_i.frame != NAV_FRAME_GLOBAL_RELATIVE_ALT_INT) {
384  // TODO: handle different frames
385  PX4_ERR("Frame type %i not supported", (int)temp_vertex_i.frame);
386  break;
387  }
388 
389  if (((double)temp_vertex_i.lon >= lon) != ((double)temp_vertex_j.lon >= lon) &&
390  (lat <= (double)(temp_vertex_j.lat - temp_vertex_i.lat) * (lon - (double)temp_vertex_i.lon) /
391  (double)(temp_vertex_j.lon - temp_vertex_i.lon) + (double)temp_vertex_i.lat)) {
392  c = !c;
393  }
394  }
395 
396  return c;
397 }
398 
399 bool Geofence::insideCircle(const PolygonInfo &polygon, double lat, double lon, float altitude)
400 {
401 
402  mission_fence_point_s circle_point;
403 
404  if (dm_read(DM_KEY_FENCE_POINTS, polygon.dataman_index, &circle_point,
405  sizeof(mission_fence_point_s)) != sizeof(mission_fence_point_s)) {
406  PX4_ERR("dm_read failed");
407  return false;
408  }
409 
410  if (circle_point.frame != NAV_FRAME_GLOBAL && circle_point.frame != NAV_FRAME_GLOBAL_INT
411  && circle_point.frame != NAV_FRAME_GLOBAL_RELATIVE_ALT
412  && circle_point.frame != NAV_FRAME_GLOBAL_RELATIVE_ALT_INT) {
413  // TODO: handle different frames
414  PX4_ERR("Frame type %i not supported", (int)circle_point.frame);
415  return false;
416  }
417 
420  }
421 
422  float x1, y1, x2, y2;
423  map_projection_project(&_projection_reference, lat, lon, &x1, &y1);
424  map_projection_project(&_projection_reference, circle_point.lat, circle_point.lon, &x2, &y2);
425  float dx = x1 - x2, dy = y1 - y2;
426  return dx * dx + dy * dy < circle_point.circle_radius * circle_point.circle_radius;
427 }
428 
429 bool
431 {
432  return true; // always valid
433 }
434 
435 int
436 Geofence::loadFromFile(const char *filename)
437 {
438  FILE *fp;
439  char line[120];
440  int pointCounter = 0;
441  bool gotVertical = false;
442  const char commentChar = '#';
443  int rc = PX4_ERROR;
444 
445  /* Make sure no data is left in the datamanager */
446  clearDm();
447 
448  /* open the mixer definition file */
449  fp = fopen(GEOFENCE_FILENAME, "r");
450 
451  if (fp == nullptr) {
452  return PX4_ERROR;
453  }
454 
455  /* create geofence points from valid lines and store in DM */
456  for (;;) {
457  /* get a line, bail on error/EOF */
458  if (fgets(line, sizeof(line), fp) == nullptr) {
459  break;
460  }
461 
462  /* Trim leading whitespace */
463  size_t textStart = 0;
464 
465  while ((textStart < sizeof(line) / sizeof(char)) && isspace(line[textStart])) { textStart++; }
466 
467  /* if the line starts with #, skip */
468  if (line[textStart] == commentChar) {
469  continue;
470  }
471 
472  /* if there is only a linefeed, skip it */
473  if (line[0] == '\n') {
474  continue;
475  }
476 
477  if (gotVertical) {
478  /* Parse the line as a geofence point */
479  mission_fence_point_s vertex;
480  vertex.frame = NAV_FRAME_GLOBAL;
482  vertex.vertex_count = 0; // this will be filled in a second pass
483  vertex.alt = 0; // alt is not used
484 
485  /* if the line starts with DMS, this means that the coordinate is given as degree minute second instead of decimal degrees */
486  if (line[textStart] == 'D' && line[textStart + 1] == 'M' && line[textStart + 2] == 'S') {
487  /* Handle degree minute second format */
488  double lat_d, lat_m, lat_s, lon_d, lon_m, lon_s;
489 
490  if (sscanf(line, "DMS %lf %lf %lf %lf %lf %lf", &lat_d, &lat_m, &lat_s, &lon_d, &lon_m, &lon_s) != 6) {
491  PX4_ERR("Scanf to parse DMS geofence vertex failed.");
492  goto error;
493  }
494 
495 // PX4_INFO("Geofence DMS: %.5lf %.5lf %.5lf ; %.5lf %.5lf %.5lf", lat_d, lat_m, lat_s, lon_d, lon_m, lon_s);
496 
497  vertex.lat = lat_d + lat_m / 60.0 + lat_s / 3600.0;
498  vertex.lon = lon_d + lon_m / 60.0 + lon_s / 3600.0;
499 
500  } else {
501  /* Handle decimal degree format */
502  if (sscanf(line, "%lf %lf", &vertex.lat, &vertex.lon) != 2) {
503  PX4_ERR("Scanf to parse geofence vertex failed.");
504  goto error;
505  }
506  }
507 
508  if (dm_write(DM_KEY_FENCE_POINTS, pointCounter + 1, DM_PERSIST_POWER_ON_RESET, &vertex,
509  sizeof(vertex)) != sizeof(vertex)) {
510  goto error;
511  }
512 
513  PX4_INFO("Geofence: point: %d, lat %.5lf: lon: %.5lf", pointCounter, vertex.lat, vertex.lon);
514 
515  pointCounter++;
516 
517  } else {
518  /* Parse the line as the vertical limits */
519  if (sscanf(line, "%f %f", &_altitude_min, &_altitude_max) != 2) {
520  goto error;
521  }
522 
523  PX4_INFO("Geofence: alt min: %.4f, alt_max: %.4f", (double)_altitude_min, (double)_altitude_max);
524  gotVertical = true;
525  }
526  }
527 
528 
529  /* Check if import was successful */
530  if (gotVertical && pointCounter > 2) {
531  mavlink_log_info(_navigator->get_mavlink_log_pub(), "Geofence imported");
532  rc = PX4_OK;
533 
534  /* do a second pass, now that we know the number of vertices */
535  for (int seq = 1; seq <= pointCounter; ++seq) {
536  mission_fence_point_s mission_fence_point;
537 
538  if (dm_read(DM_KEY_FENCE_POINTS, seq, &mission_fence_point, sizeof(mission_fence_point_s)) ==
539  sizeof(mission_fence_point_s)) {
540  mission_fence_point.vertex_count = pointCounter;
541  dm_write(DM_KEY_FENCE_POINTS, seq, DM_PERSIST_POWER_ON_RESET, &mission_fence_point,
542  sizeof(mission_fence_point_s));
543  }
544  }
545 
546  mission_stats_entry_s stats;
547  stats.num_items = pointCounter;
549 
550  } else {
551  PX4_ERR("Geofence: import error");
552  mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Geofence import error");
553  }
554 
555  updateFence();
556 
557 error:
558  fclose(fp);
559  return rc;
560 }
561 
563 {
565  updateFence();
566  return PX4_OK;
567 }
568 
570 {
571  bool max_horizontal_enabled = (_param_gf_max_hor_dist.get() > FLT_EPSILON);
572  bool max_vertical_enabled = (_param_gf_max_ver_dist.get() > FLT_EPSILON);
573  bool geofence_action_rtl = (getGeofenceAction() == geofence_result_s::GF_ACTION_RTL);
574 
575  return max_horizontal_enabled || max_vertical_enabled || geofence_action_rtl;
576 }
577 
579 {
580  int num_inclusion_polygons = 0, num_exclusion_polygons = 0, total_num_vertices = 0;
581  int num_inclusion_circles = 0, num_exclusion_circles = 0;
582 
583  for (int i = 0; i < _num_polygons; ++i) {
584  total_num_vertices += _polygons[i].vertex_count;
585 
586  if (_polygons[i].fence_type == NAV_CMD_FENCE_POLYGON_VERTEX_INCLUSION) {
587  ++num_inclusion_polygons;
588  }
589 
590  if (_polygons[i].fence_type == NAV_CMD_FENCE_POLYGON_VERTEX_EXCLUSION) {
591  ++num_exclusion_polygons;
592  }
593 
594  if (_polygons[i].fence_type == NAV_CMD_FENCE_CIRCLE_INCLUSION) {
595  ++num_inclusion_circles;
596  }
597 
598  if (_polygons[i].fence_type == NAV_CMD_FENCE_CIRCLE_EXCLUSION) {
599  ++num_exclusion_circles;
600  }
601  }
602 
603  PX4_INFO("Geofence: %i inclusion, %i exclusion polygons, %i inclusion, %i exclusion circles, %i total vertices",
604  num_inclusion_polygons, num_exclusion_polygons, num_inclusion_circles, num_exclusion_circles,
605  total_num_vertices);
606 }
void _updateFence()
implementation of updateFence(), but without locking
Definition: geofence.cpp:86
bool insideCircle(const PolygonInfo &polygon, double lat, double lon, float altitude)
Check if a single point is within a circle.
Definition: geofence.cpp:399
bool home_position_valid()
Definition: navigator.h:166
Global position setpoint in WGS84 coordinates.
Definition: navigation.h:145
float get_distance_to_point_global_wgs84(double lat_now, double lon_now, float alt_now, double lat_next, double lon_next, float alt_next, float *dist_xy, float *dist_z)
Definition: geo.cpp:523
float _altitude_max
Definition: geofence.h:145
Definition of geo / math functions to perform geodesic calculations.
float altitude
altitude in meters (AMSL)
Definition: navigation.h:160
bool map_projection_initialized(const struct map_projection_reference_s *ref)
Checks if projection given as argument was initialized.
Definition: geo.cpp:68
hrt_abstime _last_vertical_range_warning
Definition: geofence.h:142
__EXPORT int dm_lock(dm_item_t item)
Lock all items of a type.
Definition: dataman.cpp:1157
bool valid()
Definition: geofence.cpp:430
bool checkAll(double lat, double lon, float altitude)
Check if a point passes the Geofence test.
Definition: geofence.cpp:221
PolygonInfo * _polygons
Definition: geofence.h:155
int getAltitudeMode()
Definition: geofence.h:127
struct home_position_s * get_home_position()
Getters.
Definition: navigator.h:151
bool isEmpty()
Definition: geofence.h:125
bool insidePolygon(const PolygonInfo &polygon, double lat, double lon, float altitude)
Check if a single point is within a polygon.
Definition: geofence.cpp:357
hrt_abstime _last_horizontal_range_warning
Definition: geofence.h:141
uint16_t fence_type
one of MAV_CMD_NAV_FENCE_* (can also be a circular region)
Definition: geofence.h:148
uint16_t vertex_count
number of vertices in this polygon
Definition: navigation.h:209
void updateFence()
update the geofence from dataman.
Definition: geofence.cpp:71
#define GEOFENCE_FILENAME
Definition: geofence.h:55
void printStatus()
print Geofence status to the console
Definition: geofence.cpp:578
#define FLT_EPSILON
float circle_radius
geofence circle radius in meters (only used for NAV_CMD_NAV_FENCE_CIRCLE*)
Definition: navigation.h:210
High-resolution timer with callouts and timekeeping.
double lon
longitude in degrees
Definition: navigation.h:147
int getGeofenceAction()
Definition: geofence.h:129
Provides functions for handling the geofence.
Geofence(Navigator *navigator)
Definition: geofence.cpp:55
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
__EXPORT ssize_t dm_read(dm_item_t item, unsigned index, void *buf, size_t count)
Retrieve from the data manager file.
Definition: dataman.cpp:1104
Geofence vertex point.
Definition: navigation.h:203
map_projection_reference_s _projection_reference
reference to convert (lon, lat) to local [m]
Definition: geofence.h:158
DEFINE_PARAMETERS((ParamInt< px4::params::GF_ACTION >) _param_gf_action,(ParamInt< px4::params::GF_ALTMODE >) _param_gf_altmode,(ParamInt< px4::params::GF_SOURCE >) _param_gf_source,(ParamInt< px4::params::GF_COUNT >) _param_gf_count,(ParamFloat< px4::params::GF_MAX_HOR_DIST >) _param_gf_max_hor_dist,(ParamFloat< px4::params::GF_MAX_VER_DIST >) _param_gf_max_ver_dist) uORB int _outside_counter
Definition: geofence.h:171
Navigator * _navigator
Definition: geofence.h:139
bool check(const vehicle_global_position_s &global_position, const vehicle_gps_position_s &gps_position, const home_position_s home_pos, bool home_position_set)
Return whether the system obeys the geofence.
Definition: geofence.cpp:190
int clearDm()
Definition: geofence.cpp:562
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
Definition: drv_hrt.h:102
DATAMANAGER driver.
dataman housekeeping information for a specific item.
Definition: navigation.h:194
__EXPORT int dm_trylock(dm_item_t item)
Try to lock all items of a type (.
Definition: dataman.cpp:1179
bool checkPolygons(double lat, double lon, float altitude)
Check if a point passes the Geofence test.
Definition: geofence.cpp:281
~Geofence()
Definition: geofence.cpp:64
int _num_polygons
Definition: geofence.h:156
__EXPORT void dm_unlock(dm_item_t item)
Unlock a data Item.
Definition: dataman.cpp:1202
uint16_t nav_cmd
navigation command (one of MAV_CMD_NAV_FENCE_*)
Definition: navigation.h:213
uint16_t num_items
total number of items stored (excluding this one)
Definition: navigation.h:195
#define GEOFENCE_RANGE_WARNING_LIMIT
Definition: geofence.cpp:53
uint16_t update_counter
This counter is increased when (some) items change (this can wrap)
Definition: navigation.h:196
int map_projection_project(const struct map_projection_reference_s *ref, double lat, double lon, float *x, float *y)
Definition: geo.cpp:132
__EXPORT ssize_t dm_write(dm_item_t item, unsigned index, dm_persitence_t persistence, const void *buf, size_t count)
Write to the data manager file.
Definition: dataman.cpp:1072
int loadFromFile(const char *filename)
Load a single inclusion polygon, replacing any already existing polygons.
Definition: geofence.cpp:436
uint16_t dataman_index
Definition: geofence.h:149
orb_advert_t * get_mavlink_log_pub()
Definition: navigator.h:261
bool isHomeRequired()
Definition: geofence.cpp:569
uint16_t vertex_count
Definition: geofence.h:151
int map_projection_init(struct map_projection_reference_s *ref, double lat_0, double lon_0)
Initializes the map transformation given by the argument and sets the timestamp to now...
Definition: geo.cpp:105
uint16_t _update_counter
dataman update counter: if it does not match, we polygon data was updated
Definition: geofence.h:172
uint8_t frame
MAV_FRAME.
Definition: navigation.h:214
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
float _altitude_min
Definition: geofence.h:144
int getSource()
Definition: geofence.h:128
__EXPORT int dm_clear(dm_item_t item)
Clear a data Item.
Definition: dataman.cpp:1135
double lat
latitude in degrees
Definition: navigation.h:146