Skip to content

Commit 196e983

Browse files
committed
documentation, don't load from SD card if data are not needed
1 parent 8670090 commit 196e983

4 files changed

Lines changed: 90 additions & 8 deletions

File tree

docs/Terrain.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Terrain
2+
3+
```mermaid
4+
flowchart TD
5+
SD[Terrain data on SD card]
6+
GPS[GPS position]
7+
BARO[Baro altitude]
8+
AGL[Computed AGL]
9+
10+
SD --> AGL
11+
GPS --> AGL
12+
BARO --> AGL
13+
```
14+
15+
This feature is available **only on H7-based flight controllers with an SD card** (preferably SDIO). Due to the high CPU load
16+
and SD card read speed requirements of terrain data processing, it is not supported on weaker hardware.
17+
18+
This feature in iNav determines the model’s altitude above ground level using preloaded elevation maps
19+
(terrain / SRTM data) stored on an SD card, without requiring a physical rangefinder. Based on the current GPS position, the
20+
flight controller identifies the corresponding point in the terrain map, calculates the ground elevation, and derives the
21+
altitude above terrain.
22+
23+
In this first implementation, the calculated value is used **only for informational display in the OSD**. It is indicative
24+
only, does not yet behave as a true virtual rangefinder, and is not used for navigation or automatic altitude control. If the
25+
terrain data are unavailable or a read error occurs, the feature is automatically disabled.
26+
27+
# SD Card Preparation
28+
29+
For proper operation, the SD card must be prepared in advance. It is recommended to create a **partition with a maximum size
30+
of 4 GB** and format it. Formatting should be done using the official
31+
[**SD Memory Card Formatter**](https://www.sdcard.org/downloads/formatter/sd-memory-card-formatter-for-windows-download/) tool from the SD Association,
32+
which ensures correct alignment and a compatible file system structure. Using this tool minimizes the risk of terrain data
33+
read issues during flight and is considered the recommended method for preparing an SD card for iNav.
34+
35+
# Data Generation and Copying
36+
37+
To generate elevation maps, use the terrain generator web tool available at https://terrain.ardupilot.org/
38+
39+
In iNav, **only 30 m resolution (SRTM1)** is currently supported, so this option must be selected during data generation.
40+
The generated files are then copied to the SD card into the appropriate directory structure.
41+
42+
Copying can be done via **iNav MSC (Mass Storage Class)**, but this method is very slow, so using an **external SD card reader**
43+
is strongly recommended. Before copying the data, the file **`FREESPAC.E`** must be deleted from the root directory of the SD
44+
card. iNav uses this file to track available disk space, and without deleting it, the card may appear to be full. After the
45+
copying process is complete, iNav will automatically recreate this file on the next startup.
46+
47+
# Enabling and Displaying Terrain Data
48+
49+
To display altitude above terrain in iNav, the OSD element **“Rangefinder distance”** must be enabled. If terrain data are
50+
available on the SD card and no valid data are available from a dedicated rangefinder, the value calculated by the terrain
51+
system will be displayed. If a rangefinder is present and providing valid data, its measurements always take priority and the
52+
actual distance to the ground will be shown.
53+
54+
Loading terrain data from the SD card is enabled via the CLI using the following command:
55+
56+
```text
57+
set terrain_enabled = ON
58+
save
59+
```
60+
61+
After restarting the flight controller, iNav will automatically start loading terrain data and, when conditions are met, use
62+
them to display altitude above terrain.
63+
64+
Finally, it is **strongly recommended to use only high-quality, branded SD cards** from reputable manufacturers. The terrain
65+
system is sensitive to SD card read speed and reliability, and low-quality or counterfeit cards may cause read errors,
66+
display dropouts, or automatic disabling of the feature during flight. Using a quality SD card significantly improves the
67+
stability and reliability of the terrain feature.

src/main/io/osd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2456,7 +2456,7 @@ static bool osdDrawSingleElement(uint8_t item)
24562456
buff[1] = '-';
24572457
buff[2] = '-';
24582458
} else {
2459-
osdFormatDistanceSymbol(buff, range, 1, 3);
2459+
osdFormatDistanceSymbol(buff, range, 0, 3);
24602460
}
24612461
}
24622462
break;

src/main/terrain/terrain.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@ PG_RESET_TEMPLATE(terrainConfig_t, terrainConfig,
4848
.terrainEnabled = false,
4949
);
5050

51-
static bool terrainSubsystemSdCardOk = false;
51+
52+
static struct {
53+
bool isStarted;
54+
bool terrainSubsystemSdCardOk;
55+
} terrainSystemStatus = {
56+
.isStarted = false,
57+
.terrainSubsystemSdCardOk = false,
58+
};
5259

5360
static struct {
5461
timeMs_t lastUpdate;
@@ -122,23 +129,25 @@ void terrainUpdateTask(timeUs_t currentTimeUs)
122129
{
123130
UNUSED(currentTimeUs);
124131

125-
//terrain must be enabled
132+
if(terrainSystemStatus.isStarted == false)
133+
{
134+
return;
135+
}
136+
126137
if(terrainConfig()->terrainEnabled == false){
127138
return;
128139
}
129140

130-
//must be GPS fix
131141
if(STATE(GPS_FIX) == false){
132142
return;
133143
}
134144

135145
/////////////////////////////////////////////////////////////////////////////////////////////////////
136-
137-
if(terrainSubsystemSdCardOk == false){
138-
terrainSubsystemSdCardOk = sdcard_isInserted() && sdcard_isFunctional() && afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_READY;
146+
if(terrainSystemStatus.terrainSubsystemSdCardOk == false){
147+
terrainSystemStatus.terrainSubsystemSdCardOk = sdcard_isInserted() && sdcard_isFunctional() && afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_READY;
139148
}
140149

141-
if(terrainSubsystemSdCardOk == true) {
150+
if(terrainSystemStatus.terrainSubsystemSdCardOk == true) {
142151
//this call IO to load data from SD card
143152
loadGridToCacheTask();
144153
}
@@ -181,6 +190,11 @@ void terrainUpdateTask(timeUs_t currentTimeUs)
181190

182191
int32_t terrainGetLastDistanceCm(void)
183192
{
193+
//start terrain system after first query to terrain height
194+
if(terrainConfig()->terrainEnabled && !terrainSystemStatus.isStarted){
195+
terrainSystemStatus.isStarted = true;
196+
}
197+
184198
return terrainHeight.lastUpdate + 500 < millis() ? TERRAIN_STATUS_NO_DATA : terrainHeight.terrainAGL;
185199
}
186200

src/main/terrain/terrain_io.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ void loadGridToCacheTask(void)
253253

254254
//////////////////////////////////////////////////////////////////////
255255
/////// OPEN FILE PENDING WATCHDOG ///////////////////////////////////
256+
// asynfatfs can be in infinite state "opening" if card failures during opening. So after a while reset state machine
256257
if(terrainIoState.status == TERRAIN_IO_OPEN_FILE_PENDING){
257258
if(millis() - terrainIoState.openFileStartTimeMs > 3000){
258259
LOG_DEBUG(SYSTEM, "TERRAIN OPEN FILE TIMEOUT");

0 commit comments

Comments
 (0)