qgroundcontrol icon indicating copy to clipboard operation
qgroundcontrol copied to clipboard

Terrain Following Fix and Improvements

Open tilaktilak opened this issue 5 years ago • 40 comments

This issue is a follow-up to the discussion from #7765

Terrain Altitude of Planned Home is not determined properly

At first it's not determined, but works if we move it. Here the error shown :

TerrainQueryLog: Error in fetching elevation tile. Empty response.

image

TODO :

  • Currently QGC does not support ArduPilot vehicle terrain requests where terrain maps are uploaded to the vehicle such that things like an RTL and follow terrain

  • Changing to a new terrain server and supporting vehicle terrain requests. (Probably a big item)

tilaktilak avatar Sep 05 '19 21:09 tilaktilak

So the first phase for this is to switch to a new terrain server. I want to do that like ArduPilot does which is using height files (.hgt, https://dds.cr.usgs.gov/srtm/version2_1/Documentation/SRTM_Topo.pdf). Auterion has agreed to host the server. ArduPilot folks are ok with QGC hitting there servers until Auterion can stand up the data.

I had already done some false starts at coding this. The trickiest part is going to be the fact that normally height files are zipped. Which means QGC needs cross-platform unzip capability. That likely means including the zlib source in QGC and building it ourselves. Would could create a different format for zipping which would work with Qt quncompress but having unzip as a general capability in QGC is useful for more than just terrain. If we had unzip we could read .kmz files instead of just .kml files.

Once we get the file downloaded (using QGCDownload), and unzipped. It's just a matter of translating into the binary format for our offilne database. TerrainQuery.* and TerrainTile.* are a good place to start looking at that.

DonLakeFlyer avatar Sep 06 '19 16:09 DonLakeFlyer

That's great for #7790 ! I can have a look at zlib and how to compile it then.

tilaktilak avatar Sep 08 '19 23:09 tilaktilak

I notice that zlib looks present already in our repo, at least for windows : https://github.com/mavlink/qgroundcontrol/tree/master/libs/zlib/windows

tilaktilak avatar Sep 09 '19 00:09 tilaktilak

The implementation should to be able to support DEM tiles from a GIS tile server in GeoTIFF format (for example). What is the reason for using the SRTM height format in the first place?

edwinhayes avatar Sep 09 '19 03:09 edwinhayes

What is the reason for using the SRTM height format in the first place?

Because it's a compact format which compresses well. Which in turn means download times are fast.

DonLakeFlyer avatar Sep 09 '19 15:09 DonLakeFlyer

I notice that zlib looks present already in our repo, at least for windows :

Ah, interesting. Didn't know that. @dogmaphobic What's going on with this zlib? Can we get support for all OS?

DonLakeFlyer avatar Sep 09 '19 15:09 DonLakeFlyer

What is the reason for using the SRTM height format in the first place?

Because it's a compact format which compresses well. Which in turn means download times are fast.

I think the question was why not using a tile server software like OpenMaptiles or GeoServer. Then we can query tiles as it's done by QGC Map engine (with x,y and zoom). The transfer speed optimization is handled by the tile service itself. This could also allow to overlay terrain in a map for instance.

tilaktilak avatar Sep 09 '19 19:09 tilaktilak

I think the question was why not using a tile server software like OpenMaptiles or GeoServer. Then we can query tiles as it's done by QGC Map engine (with x,y and zoom). The transfer speed optimization is handled by the tile service itself. This could also allow to overlay terrain in a map for instance.

Correct. Also, it means the existing functionality for precaching tiles should be able to be reused for precaching the terrain data, which is important since Ardupilot can ask for tiles in flight which weren't part of the original mission:

http://ardupilot.org/copter/docs/terrain-following.html http://ardupilot.org/plane/docs/common-terrain-following.html#common-terrain-following

edwinhayes avatar Sep 09 '19 20:09 edwinhayes

QGC already has terrain height caching support. The format of the data doesn't really make that any easier/harder.

The problem with existing terrain height servers is that they tend to come with all sorts of varying license agreements. The one killer that always seems to show up is not being able to cache the data locally. Other one is support for hitting it from all around the world. Hence not fighing with license agreements tends to be easier.

This could also allow to overlay terrain in a map for instance.

That would require a lot of additional work on map display. Seems unrelated to terrain height discussion.

DonLakeFlyer avatar Sep 09 '19 22:09 DonLakeFlyer

QGC already has terrain height caching support. The format of the data doesn't really make that any easier/harder.

That's not necessarily true; the SRTM data only provides for elevation data at a fixed resolution, whereas other formats support regionation. Does QGC's caching model support regionation of data to cope with caching extremely large areas?

That would require a lot of additional work on map display

It's work which [we're] going to have to do, regardless of whether it gets added to the mainline. Mission Planner supports it today and our customers want it.

edwinhayes avatar Sep 09 '19 22:09 edwinhayes

I think QGC cached data is fixed at something like 30m spacing.

Does QGC's caching model support regionation of data to cope with caching extremely large areas?

Not quite sure what that means. But if it means, zoom levels on the terrain height data so you can store large areas at low zoom level then I get it. And yes that would be much better than whats there now. Wasn't thinking along those lines.

DonLakeFlyer avatar Sep 09 '19 22:09 DonLakeFlyer

Sorry, yeah that's right: replacing the high resolution data (in each 'region' I guess) with a single lower resolution value.

edwinhayes avatar Sep 09 '19 23:09 edwinhayes

Having a look at the software I realized that Elevation tiles seems to be downloadable through Offline Maps menu. Does someone knows how it works and where this elevation data is used ?

Capture d’écran_2019-09-10_13-27-17

tilaktilak avatar Sep 10 '19 01:09 tilaktilak

for reference : https://github.com/mavlink/qgroundcontrol/pull/5842

tilaktilak avatar Sep 10 '19 02:09 tilaktilak

  • You can set the Altitude on items to be "Above Terrain". This will set the actual altitude of the item to be an AMSL value being terrain height at that point + altitude.
  • Survey/Corridor support a Terrain mode which you can turn on. This will generate a survey which which is a certain amount of height above terrain. It will create interstitial items within the transect to keep it at that height based on a tolerance and max/climb descent rates. Create a survey, turn it on, load to vehicle. Pull it back from vehicle if you want to see what it actually generated.
  • Click the "T" next to +/- and it will show the mission status which will show terrain heights for each waypoint in relationship to waypoint height. It will turn the bar red if the item is below terrain.

DonLakeFlyer avatar Sep 10 '19 02:09 DonLakeFlyer

Example terrain waypoints: Screen Shot 2019-09-09 at 7 27 01 PM

Terrain follow survey: Screen Shot 2019-09-09 at 7 28 06 PM

DonLakeFlyer avatar Sep 10 '19 02:09 DonLakeFlyer

Thanks for all this info, So can the elevation tiles be cached offline (same as maps) ?

tilaktilak avatar Sep 10 '19 02:09 tilaktilak

So can the elevation tiles be cached offline (same as maps) ?

yup. When you download a map area, it by default downloads elevation as well.

DonLakeFlyer avatar Sep 10 '19 04:09 DonLakeFlyer

Following discussion here : #7864

@cosmarc So I rework a little bit the TerrainQuery code + create a generic class for MapProvider ( Then a big hash table contains all providers ). This is beneficial for both map/elevation. We can create a child of MapProvider that will fetch data from a WMS server, or even a SRTM mirror, same for I ended up adding gdal to QGC to open geotiff and apply transformation, so with gdal onboard theorically we can open every format compatible ( See here : https://gdal.org/api/raster_c_api.html#_CPPv48GDALOpenPKc10GDALAccess and here : https://gdal.org/drivers/raster/index.html) ! On my current version QGC search in a folder for .tiff files to try to retrieve elevation data from it, if it's not available fallback to Airmap elevation. My current working branch is really messy (include some UI changes on OfflineMap that are just random experiments to connect things together) but it's here : https://github.com/Aeronavics/qgroundcontrol/tree/MapProviders_step2 I Also had in mind adding the ability to manage several elevation provider ( and class them by priority ) and same thing with the map provider (Adding the ability to overlay maps and put an orthophoto on the top of a basemap as it appear useful for our customers, that is basically the purpose of my messy UI changes in MapProviders_step2 branch).

There is a first PR related to the creation of a generic class for MapProviders here : https://github.com/mavlink/qgroundcontrol/pull/7818

My work/challenges at the moment :

  • Link gdal statically to optimize QGC binary size.
  • I manage to compile my code on Windows, Linux and Android with dynamic libs but have no access to an OSX platform.
  • I need a nice UI menu to connect this backend ( How to add elevation providers map layers from a given list, add custom element in this list (with a WMS url or a local folder of tile), handle layers ordering, opacity for basemap. Integrate the ability to overlay maps in FlightMap item ( I though about a repeater of FlightMap items somewhere between the current map and the items on the map ).

tilaktilak avatar Oct 07 '19 22:10 tilaktilak

@tilaktilak Nice work! I've managed to statically compile libproj (6.2.0) and gdal (3.0.1) on linux but the size of the binary is huge (93MB with most of the drivers disabled). Let's have a call on skype(ID: cosmin_marc) and discuss more. I think we can work together, especially on the backend part. I have a few questions:

  • Why did you choose gdal 2.4.2 over 3.0.1?
  • Is your dynamically linked gdal library working if there's no libproj available on android? Didn't saw any libproj related stuff on the diff.
  • Did you tested on android and it worked only with libgdal.so? If it worked it means that somehow libgdal.so is statically linked against libproj.a or something like this.

cosmarc avatar Oct 08 '19 09:10 cosmarc

@tilaktilak Nice work! I've managed to statically compile libproj (6.2.0) and gdal (3.0.1) on linux but the size of the binary is huge (93MB with most of the drivers disabled).

Same for me, here my options to compile gdal. I think I removed proj from the list as well. gdal_compile.txt

Let's have a call on skype(ID: cosmin_marc) and discuss more. I think we can work together, especially on the backend part.

I have a few questions:

* Why did you choose gdal 2.4.2 over 3.0.1?

For dependencies issues with gdal from ubuntu repos ( I think it was to keep the same OpenSSL version as the one in QGC), And also API and doc are not aligned with versions. We can probably pick another version though, but I've tried several ones and it tend to get bigger with years ^^.

* Is your dynamically linked gdal library working if there's no [libproj](https://github.com/OSGeo/PROJ/) available on android? Didn't saw any libproj related stuff on the [diff](https://github.com/mavlink/qgroundcontrol/compare/master...Aeronavics:MapProviders_step2).

Not sure actually, the app launch but did'nt have console to check if things works, but I am not sure I do need libproj for what i'm doing though.

* Did you tested on android and it worked only with libgdal.so? If it worked it means that somehow libgdal.so is statically linked against libproj.a or something like this.

Here my example code : geotiff2.txt I compile it with : g++ geotiff2.cpp -std=c++11 /pathtomylib/libgdal.a -ljson-c -lgeos_c -lpthread -ldl

tilaktilak avatar Oct 08 '19 20:10 tilaktilak

Got some good news :

~~I confirm that I don't need libproj to extract elevation data from a geotiff.~~ [EDIT] : Got the feeling that GetGeoTransform will need proj, to be confirmed.

I recompiled gdal (.so) with the minimal set of components (gdal_compile.txt in my previous post).

I got an app that successfully open a geotiff and extract some data (the min and the max elevation.) : OK I got a segfault after that ...

So compiling a minimal gdal + linking dynamically seems great option to minimize apk size. (this test apk is 37Mb, but it might be too tight, got a segfault somewhere that I need to find.)

[ Another thing that might be not related : I can't open a QGCFileDialog from my Android phone. ]

tilaktilak avatar Oct 09 '19 03:10 tilaktilak

The segfault was due to libproj not beeing present. Calls to Coordinate transformation functions ended up with segfault : https://gdal.org/tutorials/osr_api_tut.html?highlight=ogrcreatecoordinatetransformation#coordinate-transformation

tilaktilak avatar Oct 10 '19 00:10 tilaktilak

Just have a quick question as to the status of this effort. We are looking into flying a Velodyne lidar on our FF AltaX, which uses or can use QGroundControl, and I was taking a look again to see if the ability to load custom DEMs had been enabled yet in the master of this software. It looks like a lot of progress was made a while back but it hasn't been closed yet, nor is there an obvious option in the manual.

Is this still in development and if so, do you maybe have a working branch (beta) of this?

In the short term I think the built-in elevation will be sufficient, but longer-term custom site-specific DEMs would be helpful. I do realize that adding that feature means a lot of new overhead and library management, as is clear in this thread! But I figured I would ask

serbinsh avatar Dec 15 '22 16:12 serbinsh

Hi serbinsh, Thanks for your message. This PR contained a rework of the terrain provider (following the first PR I did on map providers) + the integration of GDAL and LibProj used to load the DEMs, so pretty much all the backend to load a DEM and use it while mission planning. Since then, I started a development services company to do this kind of work, I will have more capacity by the beginning of the year, I'll be happy to get in touch if you think you could be interested. Otherwise, happy to assist you if you're willing to carry on and get this PR ready by yourself.

tilaktilak avatar Dec 15 '22 16:12 tilaktilak

@tilaktilak Thanks for the quick reply! Understandable and thanks for letting me know the state of this PR. I would be happy to help in the new year if I can so consider me interested in the chance that we can talk next year about what it would take to complete this. email: [email protected]

serbinsh avatar Dec 15 '22 17:12 serbinsh

Hello,

Is anyone still working on this effort? Just some notes:

  • GDAL has support for using terrain data over the network with vsicurl driver
  • GDAL continues to actively be developed, and supports tons of file formats
  • GDAL can unzip tile data with vsizip
  • ArduPilot terrain server now has a VRT file hosted for the SRTM1 data at ap_srtm1.zip
  • For more efficient access, you can even use a seek-optimized zip
  • I have experience using GDAL in grid_map_geo

I spent a little time trying to get GDAL part of the build system. The approach taken in QGCExternalLibs.pri by adding the library as a submodule and then listing out all the individual includes and source files doesn't seem feasible for a library like GDAL. Is there a way to have the QT build system just use CMake for GDAL all the time?

I have it included in the CMake build in this branch: https://github.com/Ryanf55/qgroundcontrol/pull/new/add-gdal-map-provider

Ryanf55 avatar Apr 06 '24 15:04 Ryanf55

@Ryanf55 I would also be interested in having GDAL in QGC, I think it could be very handy. I don't have a lot of time in the near future to spend on this, but If you decide to go forward I will be available to help out a bit. Thanks!

Davidsastresas avatar Apr 10 '24 12:04 Davidsastresas

Sounds good. What would you consider a minimal PR suitable for merge? I propose the following starting with the build system:

  • GDAL included as a submodule, or through find_package
  • Headers get resolved
  • Library can be linked to
  • Compiles on major platforms using CMake
  • Includes a CMake Optoin to disable GDAL support

Ryanf55 avatar Apr 12 '24 17:04 Ryanf55

It seems like I remember from way back when that GDAL wasn't supported on all QGC platforms.

DonLakeFlyer avatar Apr 12 '24 20:04 DonLakeFlyer