Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request - Ability to Save Geozones as an XML file #2323

Open
dchuryn opened this issue Jan 23, 2025 · 15 comments
Open

Feature Request - Ability to Save Geozones as an XML file #2323

dchuryn opened this issue Jan 23, 2025 · 15 comments
Labels
New Feature Entirely new feature or major feature change
Milestone

Comments

@dchuryn
Copy link

dchuryn commented Jan 23, 2025

Geozones is an incredible new feature that will help many pilots avoid flying in areas where they should not. and make RTH even more effective. I have multiple aircraft and in an ideal world, I would like to be able to define Geozones that I can create once and easily load onto multiple aircraft. I currently do that with Missions.

Current Experience:

  • Geozones interface is only available when an FC is connected to the configurator and Geozones are enabled in the Configuration tab
  • Geozones can only be saved to the Eprom
  • Geozones are lost from the configurator when you disconnect from the FC

Desired Experience:

Geozones can be created in Mission Planner without needing to be connected to a flight controller
Geozone can also be saved as an XML file locally on the computer that is running the configurator
Geozones can be loaded from the XML file into the configurator

Thank you for considering this and for all the work you do making INAV amazing.

@stronnag
Copy link
Collaborator

Good idea. Nicer than reading / writing CLI fles (which is what mwp does at the moment got offline editing / persistance).
Something like (for example):

<?xml version="1.0" encoding="utf-8"?>
<geozones>
  <geozone id="0" shape="circle" type="exclusive" minalt="123.0" maxalt="456.0" is_amsl="false" action="avoid">
    <vertices>
      <vertex id="0" latitude="54.3556810" longitude="-4.5287920" radius="160.0"/>
    </vertices>
  </geozone>
  <geozone id="1" shape="polygon" type="inclusive" minalt="0.0" maxalt="200.66" is_amsl="false" action="poshold">
    <vertices>
      <vertex id="0" latitude="54.3535614" longitude="-4.5303353"/>
      <vertex id="1" latitude="54.3518405" longitude="-4.5288563"/>
      <vertex id="2" latitude="54.3512220" longitude="-4.5223563"/>
      <vertex id="3" latitude="54.3530456" longitude="-4.5172406"/>
      <vertex id="4" latitude="54.3530815" longitude="-4.5157285"/>
      <vertex id="5" latitude="54.3539360" longitude="-4.5122910"/>
      <vertex id="6" latitude="54.3553608" longitude="-4.5105164"/>
      <vertex id="7" latitude="54.3569302" longitude="-4.5136845"/>
    </vertices>
  </geozone>
</geozones>

@stronnag
Copy link
Collaborator

stronnag commented Jan 23, 2025

@b14ckyy @Scavanger Do you see problems with this (like there are other non-geometric GeoZone parameters that make this impractical) ?

Otherwise I'll draft up a XSD for review as a path to standardisation across planners.

@b14ckyy
Copy link
Collaborator

b14ckyy commented Jan 23, 2025

Geozones could be simply transferred via cli by copying the relevant part of a diff. Editing is not recommended of course.

But I am open for any QoL feature as it makes a lot of sense to copy zones between crafts and even edit offline when the new Mission control is ready.

In this case I would even say that this exports also the safe homes in the same go. What do you think?

Edit: the settings for safehome are also split between 2 areas for a reason. The settings that will be plane specific based on flight performance are in advanced tuning.

For geozones we also have a few additional settings but these are also aircraft specific and not relevant for transferring between aircraft.

@b14ckyy b14ckyy added the New Feature Entirely new feature or major feature change label Jan 23, 2025
@b14ckyy b14ckyy added this to the 8.1 milestone Jan 23, 2025
@stronnag
Copy link
Collaborator

I think the whole issue / real issue is UX / Usability. Not being able to offline edit and persist to the file system artefacts such as Geozone (and Safehome) is a usability bug. The file format is somewhat irrelevant, as long as it is documented so we have an interoperable format between products.

OTOH, I find

<?xml version="1.0" standalone="yes"?>
<gezones>
  <geozone id="0" shape="circle" type="exclusive" minalt="23.0" maxalt="12300.0" is_amsl="true" action="avoid">
    <vertices id="0" latitude="54.355681" longitude="-4.528792" radius="160.0"/>
  </geozone>
  <geozone id="1" shape="polygon" type="inclusive" minalt="0.0" maxalt="10000.0" is_amsl="false" action="none">
    <vertices id="0" latitude="54.3535614" longitude="-4.5303353"/>
    <vertices id="1" latitude="54.3518405" longitude="-4.5288563"/>
    <vertices id="2" latitude="54.351222" longitude="-4.5223563"/>
    <vertices id="3" latitude="54.3530456" longitude="-4.5172406"/>
    <vertices id="4" latitude="54.3530815" longitude="-4.5157285"/>
    <vertices id="5" latitude="54.353936" longitude="-4.512291"/>
    <vertices id="6" latitude="54.3553608" longitude="-4.5105164"/>
    <vertices id="7" latitude="54.3569302" longitude="-4.5136845"/>
  </geozone>
  <geozone id="2" shape="polygon" type="exclusive" minalt="0.0" maxalt="10000.0" is_amsl="false" action="none">
    <vertices id="0" latitude="54.3554831" longitude="-4.5247084"/>
    <vertices id="1" latitude="54.3567914" longitude="-4.5185943"/>
    <vertices id="2" latitude="54.358035" longitude="-4.519585"/>
    <vertices id="3" latitude="54.3595101" longitude="-4.5246121"/>
    <vertices id="4" latitude="54.3579793" longitude="-4.5268677"/>
  </geozone>
  <geozone id="3" shape="circle" type="inclusive" minalt="0.0" maxalt="10000.0" is_amsl="false" action="rth">
    <vertices id="0" latitude="54.356769" longitude="-4.516625" radius="115.0"/>
  </geozone

to be a far more useful, human readable representation than:

# geozone
geozone 0 0 0 2300 12300 1 1 2
geozone vertex 0 0 543556810 -45287920
geozone vertex 0 1 16000 0

geozone 1 1 1 0 10000 0 0 8
geozone vertex 1 0 543535614 -45303353
geozone vertex 1 1 543518405 -45288563
geozone vertex 1 2 543512220 -45223563
geozone vertex 1 3 543530456 -45172406
geozone vertex 1 4 543530815 -45157285
geozone vertex 1 5 543539360 -45122910
geozone vertex 1 6 543553608 -45105164
geozone vertex 1 7 543569302 -45136845

geozone 2 1 0 0 10000 0 0 5
geozone vertex 2 0 543554831 -45247084
geozone vertex 2 1 543567914 -45185943
geozone vertex 2 2 543580350 -45195850
geozone vertex 2 3 543595101 -45246121
geozone vertex 2 4 543579793 -45268677

geozone 3 0 1 0 10000 0 3 2
geozone vertex 3 0 543567690 -45166250
geozone vertex 3 1 11500 0

Back to UX again ....

@stronnag
Copy link
Collaborator

As far as safehome, this is slightly more problematic for standalone usage with "fixed wing approach" as the geometry that is drawn (and executed) depends on two CLI variables that are not part of the safehome / fwapproach geospatial geometry (nav_fw_land_approach_length and nav_fw_loiter_radius). i.e the length of the "base leg" is computed as the maximum of nav_fw_land_approach_length / 2 or nav_fw_loiter_radius * 4. This is discussed in more detail (with pictures) in the mwp user guide.

One way of managing this would be to add some "options" (hints) to the XML file, which the application could choose to ignore when connected to a FC and having access to specific parameters for a particular aircraft.

So, for the CLI fragment:

# safehome
safehome 0 1 543540248 -45237071
safehome 1 1 543563486 -45129749
safehome 2 0 543526527 -45269011
safehome 3 1 543539528 -45132527
safehome 4 0 0 0
safehome 5 0 0 0
safehome 6 0 0 0
safehome 7 0 0 0

# fwapproach
fwapproach 0 6000 0 0 -330 69 0
fwapproach 1 12687 2687 1 -70 0 1
fwapproach 8 6000 500 0 34 0 0
fwapproach 10 0 0 0 43 103 0

set nav_fw_land_approach_length = 150
set nav_fw_loiter_radius = 40

One might end up with a more readable application (INAV Configurator, mwp) XML file:

<?xml version="1.0" standalone="yes"?>
<safehomes>
  <description version="1.0" generator="clish2xml.rb">
    <options name="nav_fw_land_approach_length" value="150"/>
    <options name="nav_fw_loiter_radius" value="40"/>
  </description>
  <safehome id="0" enabled="true" latitude="54.3540248" longitude="-4.5237071"/>
  <safehome id="1" enabled="true" latitude="54.3563486" longitude="-4.5129749"/>
  <safehome id="2" enabled="false" latitude="54.3526527" longitude="-4.5269011"/>
  <safehome id="3" enabled="true" latitude="54.3539528" longitude="-4.5132527"/>
  <safehome id="4" enabled="false" latitude="0.0" longitude="0.0"/>
  <safehome id="5" enabled="false" latitude="0.0" longitude="0.0"/>
  <safehome id="6" enabled="false" latitude="0.0" longitude="0.0"/>
  <safehome id="7" enabled="false" latitude="0.0" longitude="0.0"/>
  <fwapproach approachalt="60.0" index="0" landalt="0.0" landheading1="0" landheading2="-330" approachdirection="right" sealevelref="false"/>
  <fwapproach approachalt="126.87" index="1" landalt="26.87" landheading1="1" landheading2="-70" approachdirection="left" sealevelref="false"/>
</safehomes>

@b14ckyy
Copy link
Collaborator

b14ckyy commented Jan 24, 2025

Since Autoland representations on the Map are depending on the individual plane config and make not much sense to be edited offline anyway, they could just be ignored in offline mode and only loaded when a FC is connected or if a FC was connected, taking the last known settings into account. If the User switches the FC to import the Zones or Safe Homes, MWP or Configurator could update the map drawings.

@stronnag
Copy link
Collaborator

Attached are proposed safehome and geozone schemas (with sample files and backing CLI data).
Should anyone be interested in pursuing this in the Configurator:

  • Once there is consensus on schemas, these should be added to the main INAV repository docs/development/ (the home of the mission XSD).
  • The same would then be added to mwp (in addition to extant CLI file I/O).

schema-proposal.zip

@mmosca
Copy link
Collaborator

mmosca commented Jan 28, 2025

How about GeoJSON? https://geojson.org/

A zone could be represented as a feature, with a polygon as geometry and the options can be defined as properties.

{
  "type": "FeatureCollection",
    "features": [
    {
      "type": "Feature",
      "properties": {
        "type":"inclusive",
        "minalt":"0.0",
        "maxalt":"10000.0",
        "is_amsl":"false", 
        "action":"none"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          ["54.3535614", "-4.5303353"],
          ["54.3518405", "-4.5288563"],
          ["54.3512220", "-4.5223563"],
          ["54.3530456", "-4.5172406"],
          ["54.3530815", "-4.5157285"],
          ["54.3539360", "-4.5122910"],
          ["54.3553608", "-4.5105164"],
          ["54.3569302", "-4.5136845"],
          ["54.3535614", "-4.5303353"]
        ]
      }
    }
  ]
}

@mmosca
Copy link
Collaborator

mmosca commented Jan 28, 2025

GeoJSON is also use often with GIS tools, so it is likely has the potential to integrate well with other tools.

@stronnag
Copy link
Collaborator

That could work.

GeoJSON has no means to represent a circle. You could just use points (centre and a property) or multi-point , however only bespoke tools would be able to decode them as circles. So the "GIS tools" integration potential is not that great. Or you have the properties INAV needs as properties, and the circle as a polygon for "other tool" visualisation and the file becomes rather large and not human readable (this is what mwp does for its KML conversion).

I have no preference either way, however I feel we will get better interoperability between tools with a formal schema.

@mmosca
Copy link
Collaborator

mmosca commented Jan 29, 2025

The lack of circle is indeed a valid concern.

A common workaround seems to define circles as a point with a radius property. That may not be ideal, but would keep it short and simple.

A plus that may be overlooked is that js mapping libraries, like leaflet tend to support geojson and may do most of the work for us when reading/exporting. (At least on the configurator side). We still would need to translate it into msp, but that is true for any format we pick.

{
  "type": "FeatureCollection",
    "features": [
    {
      "type": "Feature",
      "properties": {
        "radius": 500,
        "type":"inclusive",
        "minalt":"0.0",
        "maxalt":"10000.0",
        "is_amsl":"false", 
        "action":"none"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          ["54.3535614", "-4.5303353"]
        ]
      }
    }
  ]
}

(I am ok with a custom xml schema as well)

@stronnag
Copy link
Collaborator

Just a note:

  • None of the GeoJSON examples are valid GeoJSON
  • GeoJSON requires coordinates as easting, northing (in common with most GIS representations)

I am also OK with either. If we do go the GeoJSON route, we need to:

  • Provide some documentation defining the mandatory properties and enumerations
  • Generate valid GeoJSON that is acceptable to 3rd party tools.

@stronnag
Copy link
Collaborator

stronnag commented Jan 29, 2025

I took the KML from the original example, converted it to GeoJSON, added INAV / Geozone properties, remove the polyline interpretation of the circles. Imported into QGIS:

Image

Circles are just points of course.

Valid GeoJSON:

{
   "crs" : {
      "properties" : {
         "name" : "urn:ogc:def:crs:OGC:1.3:CRS84"
      },
      "type" : "name"
   },
   "features" : [
       {
         "geometry" : {
             "coordinates" : [
		 -4.5287920,
		 54.3556810
            ],
            "type" : "Point"
         },
         "properties" : {
            "Description" : "INAV Geozone",
             "Name" : "Circle 1",
	     "Type" : "Exclusive",
	     "Action" : "Avoid",
	     "MinAlt" : 23.0,
	     "MaxAlt" : 120.0,
	     "IsAMSL" : true,
	     "Radius" : 160.0
         },
         "type" : "Feature"
       },
       {
         "geometry" : {
            "coordinates" : [
               [
                  [
                     -4.5303353,
                     54.3535614
                  ],
                  [
                     -4.5288563,
                     54.3518405
                  ],
                  [
                     -4.5223563,
                     54.351222
                  ],
                  [
                     -4.5172406,
                     54.3530456
                  ],
                  [
                     -4.5157285,
                     54.3530815
                  ],
                  [
                     -4.512291,
                     54.353936
                  ],
                  [
                     -4.5105164,
                     54.3553608
                  ],
                  [
                     -4.5136845,
                     54.3569302
                  ],
                  [
                     -4.5303353,
                     54.3535614
                  ]
               ]
            ],
            "type" : "Polygon"
         },
         "properties" : {
             "Description" : "INAV Geozone",
             "Name" : "Polygon  1",
	     "Type" : "Inclusive",
	     "Action" : "None",
	     "MinAlt" : 0.0,
	     "MaxAlt" : 100.0,
	     "IsAMSL" : false
         },
         "type" : "Feature"
      },
      {
         "geometry" : {
            "coordinates" : [
               [
                  [
                     -4.5247084,
                     54.3554831
                  ],
                  [
                     -4.5185943,
                     54.3567914
                  ],
                  [
                     -4.519585,
                     54.358035
                  ],
                  [
                     -4.5246121,
                     54.3595101
                  ],
                  [
                     -4.5268677,
                     54.3579793
                  ],
                  [
                     -4.5247084,
                     54.3554831
                  ]
               ]
            ],
            "type" : "Polygon"
         },
         "properties" : {
            "Description" : "INAV Geozone",
             "Name" : "Polygon  2",
	     "Type" : "Exclusive",
	     "Action" : "None",
	     "MinAlt" : 0.0,
	     "MaxAlt" : 100.0,
	     "IsAMSL" : false
         },
         "type" : "Feature"
      },
       {
         "geometry" : {
             "coordinates" : [
		 -4.5166250,
		 54.3567690
	     ],
            "type" : "Point"
         },
         "properties" : {
            "Description" : "INAV Geozone",
             "Name" : "Circle 2",
	     "Type" : "Inclusive",
	     "Action" : "RTH",
	     "MinAlt" : 0.0,
	     "MaxAlt" : 1000,
	     "IsAMSL" : false,
	     "Radius" : 115.0
         },
         "type" : "Feature"
      }
   ],
   "name" : "geozones",
   "type" : "FeatureCollection"
}

@stronnag
Copy link
Collaborator

$ ogrinfo -al /tmp/example.geojson 
INFO: Open of `/tmp/example.geojson'
      using driver `GeoJSON' successful.

Layer name: geozones
Geometry: Unknown (any)
Feature Count: 4
Extent: (-4.530335, 54.351222) - (-4.510516, 54.359510)
Layer SRS WKT:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["geodetic latitude (Lat)",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["geodetic longitude (Lon)",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    ID["EPSG",4326]]
Data axis to CRS axis mapping: 2,1
Description: String (0.0)
Name: String (0.0)
Type: String (0.0)
Action: String (0.0)
MinAlt: Real (0.0)
MaxAlt: Real (0.0)
IsAMSL: String(JSON) (0.0)
Radius: Real (0.0)
OGRFeature(geozones):0
  Description (String) = INAV Geozone
  Name (String) = Circle 1
  Type (String) = Exclusive
  Action (String) = Avoid
  MinAlt (Real) = 23
  MaxAlt (Real) = 120
  IsAMSL (String(JSON)) = true
  Radius (Real) = 160
  POINT (-4.528792 54.355681)

OGRFeature(geozones):1
  Description (String) = INAV Geozone
  Name (String) = Polygon  1
  Type (String) = Inclusive
  Action (String) = None
  MinAlt (Real) = 0
  MaxAlt (Real) = 100
  IsAMSL (String(JSON)) = IsAMSL
  POLYGON ((-4.5303353 54.3535614,-4.5288563 54.3518405,-4.5223563 54.351222,-4.5172406 54.3530456,-4.5157285 54.3530815,-4.512291 54.353936,-4.5105164 54.3553608,-4.5136845 54.3569302,-4.5303353 54.3535614))

OGRFeature(geozones):2
  Description (String) = INAV Geozone
  Name (String) = Polygon  2
  Type (String) = Exclusive
  Action (String) = None
  MinAlt (Real) = 0
  MaxAlt (Real) = 100
  IsAMSL (String(JSON)) = false
  POLYGON ((-4.5247084 54.3554831,-4.5185943 54.3567914,-4.519585 54.358035,-4.5246121 54.3595101,-4.5268677 54.3579793,-4.5247084 54.3554831))

OGRFeature(geozones):3
  Description (String) = INAV Geozone
  Name (String) = Circle 2
  Type (String) = Inclusive
  Action (String) = RTH
  MinAlt (Real) = 0
  MaxAlt (Real) = 1000
  IsAMSL (String(JSON)) = false
  Radius (Real) = 115
  POINT (-4.516625 54.356769)

@mmosca
Copy link
Collaborator

mmosca commented Jan 29, 2025

Just a note:

* None of the GeoJSON examples are valid GeoJSON

* GeoJSON requires coordinates as easting, northing (in common with most GIS representations)

That was my attempt at writing an example by hand. I did not try to pass it through link. Been a while since I actually used GeoJSON. Nice to see you managed to convert from KML to GeoJSON and make it work with my suggestion.

Quick summary:

geoJSON:
Pros:

  • Standard used by other GIS tools, like possible to export valid INAV GeoJSON from standard tools.
  • Flexible enough to accept our properties
  • Basic tools exist to validate
  • Human readable enough

Cons:

  • No circle
  • Properties are too flexible, so it is quite easy to write valid GeoJSON that wouldn't necessarily work in INAV. :)

XML:
Pros:

  • We can have a strict schema for INAV
  • Tooling to validate xml schemas exist
  • We can do whatever we want

Cons:

  • Custom format will have less integration options as code will need to be written (if we can use KML, it will likely match or exceed geoJSON in compatibility)
    In my view: GeoJSON is a format with a standard that is used in GIS applications.
  • While XML is human readable, JSON seems a bit less noisy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
New Feature Entirely new feature or major feature change
Projects
None yet
Development

No branches or pull requests

4 participants