24 #if AP_TERRAIN_AVAILABLE 33 #include <sys/types.h> 53 AP_GROUPINFO(
"SPACING", 1, AP_Terrain, grid_spacing, 100),
63 disk_io_state(DiskIoIdle),
69 directory_created(false),
71 have_current_loc_height(false),
72 last_current_loc_height(0)
75 memset(&home_loc, 0,
sizeof(home_loc));
76 memset(&disk_block, 0,
sizeof(disk_block));
77 memset(last_request_time_ms, 0,
sizeof(last_request_time_ms));
89 bool AP_Terrain::height_amsl(
const Location &loc,
float &height,
bool corrected)
91 if (!enable || !allocate()) {
96 if (loc.
lat == home_loc.lat &&
97 loc.
lng == home_loc.lng) {
106 struct grid_info info;
108 calculate_grid_info(loc, info);
111 const struct grid_block &grid = find_grid_cache(info).grid;
117 ASSERT_RANGE(info.idx_x, 0, TERRAIN_GRID_BLOCK_SIZE_X-2);
118 ASSERT_RANGE(info.idx_y, 0, TERRAIN_GRID_BLOCK_SIZE_Y-2);
122 if (!check_bitmap(grid, info.idx_x, info.idx_y) ||
123 !check_bitmap(grid, info.idx_x, info.idx_y+1) ||
124 !check_bitmap(grid, info.idx_x+1, info.idx_y) ||
125 !check_bitmap(grid, info.idx_x+1, info.idx_y+1)) {
130 int16_t h00, h01, h10, h11;
132 h00 = grid.height[info.idx_x+0][info.idx_y+0];
133 h01 = grid.height[info.idx_x+0][info.idx_y+1];
134 h10 = grid.height[info.idx_x+1][info.idx_y+0];
135 h11 = grid.height[info.idx_x+1][info.idx_y+1];
140 float avg1 = (1.0f-info.frac_x) * h00 + info.frac_x * h10;
141 float avg2 = (1.0f-info.frac_x) * h01 + info.frac_x * h11;
142 float avg = (1.0f-info.frac_y) * avg1 + info.frac_y * avg2;
149 home_height = height;
173 bool AP_Terrain::height_terrain_difference_home(
float &terrain_difference,
bool extrapolate)
175 float height_home, height_loc;
176 if (!height_amsl(
ahrs.
get_home(), height_home,
false)) {
187 if (!height_amsl(loc, height_loc,
false)) {
188 if (!extrapolate || !have_current_loc_height) {
196 height_loc = last_current_loc_height;
199 terrain_difference = height_loc - height_home;
214 bool AP_Terrain::height_above_terrain(
float &terrain_altitude,
bool extrapolate)
216 float terrain_difference;
217 if (!height_terrain_difference_home(terrain_difference, extrapolate)) {
221 float relative_home_altitude;
223 relative_home_altitude = -relative_home_altitude;
225 terrain_altitude = relative_home_altitude - terrain_difference;
244 bool AP_Terrain::height_relative_home_equivalent(
float terrain_altitude,
245 float &relative_home_altitude,
248 float terrain_difference;
249 if (!height_terrain_difference_home(terrain_difference, extrapolate)) {
252 relative_home_altitude = terrain_altitude + terrain_difference;
261 float AP_Terrain::lookahead(
float bearing,
float distance,
float climb_ratio)
263 if (!enable || !allocate() || grid_spacing <= 0) {
273 if (!height_amsl(loc, base_height,
false)) {
279 float lookahead_estimate = 0;
282 while (distance > 0) {
284 climb += climb_ratio * grid_spacing;
285 distance -= grid_spacing;
287 if (height_amsl(loc, height,
false)) {
288 float rise = (height - base_height) - climb;
289 if (rise > lookahead_estimate) {
290 lookahead_estimate = rise;
295 return lookahead_estimate;
304 void AP_Terrain::update(
void)
316 bool terrain_valid = pos_valid && height_amsl(loc, height,
false);
317 if (pos_valid && terrain_valid) {
318 last_current_loc_height = height;
319 have_current_loc_height =
true;
323 update_mission_data();
333 system_status = TerrainStatusUnhealthy;
334 }
else if (!terrain_valid) {
336 system_status = TerrainStatusUnhealthy;
338 system_status = TerrainStatusOK;
342 system_status = TerrainStatusDisabled;
360 float terrain_height = 0;
361 float current_height = 0;
362 uint16_t pending, loaded;
364 height_amsl(loc, terrain_height,
false);
365 height_above_terrain(current_height,
true);
366 get_statistics(pending, loaded);
374 spacing : (uint16_t)grid_spacing,
375 terrain_height : terrain_height,
376 current_height : current_height,
387 bool AP_Terrain::allocate(
void)
392 if (cache !=
nullptr) {
395 cache = (
struct grid_cache *)
calloc(TERRAIN_GRID_BLOCK_CACHE_SIZE,
sizeof(cache[0]));
396 if (cache ==
nullptr) {
398 gcs().
send_text(MAV_SEVERITY_CRITICAL,
"Terrain: Allocation failed");
401 cache_size = TERRAIN_GRID_BLOCK_CACHE_SIZE;
405 #endif // AP_TERRAIN_AVAILABLE void get_relative_position_D_home(float &posD) const override
void location_update(struct Location &loc, float bearing, float distance)
Object managing Rally Points.
#define AP_PARAM_FLAG_ENABLE
Interface definition for the various Ground Control System.
const struct Location & get_home(void) const
void clear_capabilities(uint64_t cap)
#define AP_GROUPINFO(name, idx, clazz, element, def)
void set_capabilities(uint64_t cap)
void WriteBlock(const void *pBuffer, uint16_t size)
void * calloc(size_t nmemb, size_t size)
int32_t lat
param 3 - Latitude * 10**7
#define AP_GROUPINFO_FLAGS(name, idx, clazz, element, def, flags)
int32_t alt
param 2 - Altitude in centimeters (meters * 100) see LOCATION_ALT_MAX_M
bool get_position(struct Location &loc) const override
void send_text(MAV_SEVERITY severity, const char *fmt,...)
Common definitions and utility routines for the ArduPilot libraries.
int32_t lng
param 4 - Longitude * 10**7
#define LOG_PACKET_HEADER_INIT(id)
static void setup_object_defaults(const void *object_pointer, const struct GroupInfo *group_info)