53 #define GEOFENCE_RANGE_WARNING_LIMIT 5000000 56 ModuleParams(navigator),
57 _navigator(navigator),
58 _sub_airdata(
ORB_ID(vehicle_air_data))
78 PX4_ERR(
"lock failed");
92 int num_fence_items = 0;
103 while (current_seq <= num_fence_items) {
105 bool is_circle_area =
false;
109 PX4_ERR(
"dm_read failed");
113 switch (mission_fence_point.
nav_cmd) {
121 is_circle_area =
true;
126 if (!is_circle_area && mission_fence_point.
vertex_count == 0) {
128 PX4_ERR(
"Polygon with 0 vertices. Skipping");
148 PX4_ERR(
"alloc failed");
156 if (is_circle_area) {
171 PX4_ERR(
"unhandled Fence command: %i", (
int)mission_fence_point.
nav_cmd);
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);
204 _sub_airdata.update();
205 const float baro_altitude_amsl = _sub_airdata.get().baro_alt_meter;
208 return checkAll(global_position, baro_altitude_amsl);
211 return checkAll((
double)gps_position.
lat * 1.0e-7, (
double)gps_position.
lon * 1.0e-7, baro_altitude_amsl);
223 bool inside_fence =
true;
227 const float max_horizontal_distance = _param_gf_max_hor_dist.get();
228 const float max_vertical_distance = _param_gf_max_ver_dist.get();
234 float dist_xy = -1.0f;
235 float dist_z = -1.0f;
239 if (max_vertical_distance >
FLT_EPSILON && (dist_z > max_vertical_distance)) {
242 (double)(dist_z - max_vertical_distance));
246 inside_fence =
false;
249 if (max_horizontal_distance >
FLT_EPSILON && (dist_xy > max_horizontal_distance)) {
252 (double)(dist_xy - max_horizontal_distance));
256 inside_fence =
false;
262 inside_fence = inside_fence &&
checkPolygons(lat, lon, altitude);
313 bool outside_exclusion =
true;
314 bool inside_inclusion =
false;
315 bool had_inclusion_areas =
false;
317 for (
int polygon_idx = 0; polygon_idx <
_num_polygons; ++polygon_idx) {
322 inside_inclusion =
true;
325 had_inclusion_areas =
true;
331 outside_exclusion =
false;
339 inside_inclusion =
true;
342 had_inclusion_areas =
true;
346 outside_exclusion =
false;
354 return (!had_inclusion_areas || inside_inclusion) && outside_exclusion;
385 PX4_ERR(
"Frame type %i not supported", (
int)temp_vertex_i.
frame);
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)) {
406 PX4_ERR(
"dm_read failed");
414 PX4_ERR(
"Frame type %i not supported", (
int)circle_point.
frame);
422 float x1, y1, x2, y2;
425 float dx = x1 - x2, dy = y1 - y2;
440 int pointCounter = 0;
441 bool gotVertical =
false;
442 const char commentChar =
'#';
458 if (fgets(line,
sizeof(line), fp) ==
nullptr) {
463 size_t textStart = 0;
465 while ((textStart <
sizeof(line) /
sizeof(
char)) && isspace(line[textStart])) { textStart++; }
468 if (line[textStart] == commentChar) {
473 if (line[0] ==
'\n') {
486 if (line[textStart] ==
'D' && line[textStart + 1] ==
'M' && line[textStart + 2] ==
'S') {
488 double lat_d, lat_m, lat_s, lon_d, lon_m, lon_s;
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.");
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;
502 if (sscanf(line,
"%lf %lf", &vertex.
lat, &vertex.
lon) != 2) {
503 PX4_ERR(
"Scanf to parse geofence vertex failed.");
509 sizeof(vertex)) !=
sizeof(vertex)) {
513 PX4_INFO(
"Geofence: point: %d, lat %.5lf: lon: %.5lf", pointCounter, vertex.
lat, vertex.
lon);
530 if (gotVertical && pointCounter > 2) {
535 for (
int seq = 1; seq <= pointCounter; ++seq) {
551 PX4_ERR(
"Geofence: import error");
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);
575 return max_horizontal_enabled || max_vertical_enabled || geofence_action_rtl;
580 int num_inclusion_polygons = 0, num_exclusion_polygons = 0, total_num_vertices = 0;
581 int num_inclusion_circles = 0, num_exclusion_circles = 0;
587 ++num_inclusion_polygons;
591 ++num_exclusion_polygons;
595 ++num_inclusion_circles;
599 ++num_exclusion_circles;
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,
#define mavlink_log_info(_pub, _text,...)
Send a mavlink info message (not printed to console).
void _updateFence()
implementation of updateFence(), but without locking
bool insideCircle(const PolygonInfo &polygon, double lat, double lon, float altitude)
Check if a single point is within a circle.
bool home_position_valid()
Global position setpoint in WGS84 coordinates.
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)
#define mavlink_log_critical(_pub, _text,...)
Send a mavlink critical message and print to console.
Helper class to access missions.
Definition of geo / math functions to perform geodesic calculations.
float altitude
altitude in meters (AMSL)
bool map_projection_initialized(const struct map_projection_reference_s *ref)
Checks if projection given as argument was initialized.
hrt_abstime _last_vertical_range_warning
__EXPORT int dm_lock(dm_item_t item)
Lock all items of a type.
bool checkAll(double lat, double lon, float altitude)
Check if a point passes the Geofence test.
struct home_position_s * get_home_position()
Getters.
bool insidePolygon(const PolygonInfo &polygon, double lat, double lon, float altitude)
Check if a single point is within a polygon.
hrt_abstime _last_horizontal_range_warning
uint16_t fence_type
one of MAV_CMD_NAV_FENCE_* (can also be a circular region)
uint16_t vertex_count
number of vertices in this polygon
void updateFence()
update the geofence from dataman.
#define GEOFENCE_FILENAME
void printStatus()
print Geofence status to the console
float circle_radius
geofence circle radius in meters (only used for NAV_CMD_NAV_FENCE_CIRCLE*)
High-resolution timer with callouts and timekeeping.
double lon
longitude in degrees
Provides functions for handling the geofence.
Geofence(Navigator *navigator)
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
__EXPORT ssize_t dm_read(dm_item_t item, unsigned index, void *buf, size_t count)
Retrieve from the data manager file.
map_projection_reference_s _projection_reference
reference to convert (lon, lat) to local [m]
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
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.
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
dataman housekeeping information for a specific item.
__EXPORT int dm_trylock(dm_item_t item)
Try to lock all items of a type (.
bool checkPolygons(double lat, double lon, float altitude)
Check if a point passes the Geofence test.
__EXPORT void dm_unlock(dm_item_t item)
Unlock a data Item.
uint16_t nav_cmd
navigation command (one of MAV_CMD_NAV_FENCE_*)
uint16_t num_items
total number of items stored (excluding this one)
#define GEOFENCE_RANGE_WARNING_LIMIT
uint16_t update_counter
This counter is increased when (some) items change (this can wrap)
int map_projection_project(const struct map_projection_reference_s *ref, double lat, double lon, float *x, float *y)
__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.
int loadFromFile(const char *filename)
Load a single inclusion polygon, replacing any already existing polygons.
orb_advert_t * get_mavlink_log_pub()
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...
uint16_t _update_counter
dataman update counter: if it does not match, we polygon data was updated
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
__EXPORT int dm_clear(dm_item_t item)
Clear a data Item.
double lat
latitude in degrees