-
Notifications
You must be signed in to change notification settings - Fork 44
pyhelios ๐ The util subpackage
The util
subpackage of pyhelios contains a number of utility scripts.
The xmlchecker
is a tool to validate XML files against XML style definitions (XSDs) before executing a survey. It is only a Python wrapper around the standard command line call and does not use the Python bindings.
If no errors are found in the XML configurations, the specified survey is executed as usual. Other wise, the XML errors are reported to the user and HELIOS++ is not run.
The script takes the same arguments as the HELIOS++
command line call (Optional arguments).
The example below shows how to execute the same survey with the standard command line call, and with the python script and XML validation.
Command line:
run\helios data\surveys\toyblocks\als_toyblocks.xml --lasOutput
Python:
python pyhelios\util\xmlchecker.py data\surveys\toyblocks\als_toyblocks.xml --lasOutput
You may want to share or publish your simulation, so that others can reproduce it. For this purpose, you can use the tool archive.py
, which will write
- the data folder with all sceneparts, scanner-XMLs, platform XMLs, scene-XMLs and survey-XMLs for the specified survey(s)
- the assets folder
- the run folder (from your HELIOS repository or downloaded from GitHub)
- a file
version.txt
containing the version number [To do: image of folder structure]
Usage example:
python pyhelios\util\archive.py run\helios.exe data\surveys\toyblocks\als_toyblocks.xml my_archive.zip
Multiple surveys can be specified by creating an ASCII file with one survey path per line and providing this instead of the survey XML.
Such an ASCII file my_surveys.txt
may look like this:
data\surveys\survey1.xml
data\surveys\survey2.xml
data\surveys\survey3.xml
To create the zip-archive, run:
python pyhelios\util\archive.py run\helios.exe my_surveys.txt archive.zip
The scene writer contains a number of functions which facilitate writing scene XMLs, which can then be executed either with pyhelios
or by running HELIOS++ from the command line.
These functions include:
- adding transformation filters
- adding sceneparts
- creating the scene
Import the script
from pyhelios.util import scene_writer
Create transformation filters
filters = scene_writer.add_transformation_filters(translation=[478335.125, 5473887.89, 0.0], rotation=[0, 0, 90], on_ground=-1)
Create scene parts Here, we load a digital elevation model (DEM) from a GeoTIFF file and a 3D model of a tree from an OBJ file. To our seconds scene part, the tree, we apply the transformation that was created in the previous step.
sp = scene_writer.create_scenepart_tiff(r"data/sceneparts/tiff/dem_hd.tif",
matfile=r"data/sceneparts/basic/groundplane/groundplane.mtl",
matname="None")
sp2 = scene_writer.create_scenepart_obj("data/sceneparts/arbaro/black_tupelo_low.obj", trafofilter=filters)
Create the scene XML
Finally, we create a scene XML file with these scene parts.
scene = scene_writer.build_scene(scene_id="test", name="test_scene", sceneparts=[sp, sp2])
print(scene)
Output:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<scene id="test" name="test_scene">
<part>
<filter type="geotiffloader">
<param type="string" key="filepath" value="data/sceneparts/tiff/dem_hd.tif" />
<param type="string" key="matfile" value="data/sceneparts/basic/groundplane/groundplane.mtl" />
<param type="string" key="matname" value="None" />
</filter>
</part>
<part>
<filter type="objloader">
<param type="string" key="filepath" value="data/sceneparts/arbaro/black_tupelo_low.obj up="z" />
</filter>
<filter type="translate">
<param type="integer" key="onGround" value="-1" />
<param type="vec3" key="offset" value="478335.125;5473887.89;0.0" />
</filter>
<filter type="rotate">
<param key="rotation" type="rotation">
<rot angle_deg="0" axis="x"/>
<rot angle_deg="0" axis="y"/>
<rot angle_deg="90" axis="z"/>
</param>
</filter>
</part>
</scene>
</document>
Check out this Jupyter Notebook to see how these functions may be used in a typical workflow.
The flight planner facilitates the creation of survey files, specifically of the legs
(or waypoints) of a survey.
The flight planner functionality encompasses:
- create the flight plan (i.e., the waypoints) for given parameters (flight pattern, strip spacing, bounding box of the scan area)
- create waypoints from a shapefile
- plot a flight plan
- write the legs for the survey XML file
Import the script
from pyhelios.util import flight_planner
Define the parameters
bbox = [-200, -50, 200, 50]
strip_spacing = 45
alt = 1000
scannerSettings = "template1"
platform_speed = 5
Generate waypoints
# possible flight-patterns: parallel, criss-cross (default: parallel)
waypoints, center_point, distance = flight_planner.compute_flight_lines(bbox, spacing=strip_spacing, flight_pattern="parallel")
# or to create a rotated flight plan, e.g. by 15 degrees:
waypoints, center_point, distance = flight_planner.compute_flight_lines(bbox, spacing=strip_spacing, rotate_deg=15)
print(f"Flight duration: {distance / platform_speed / 60:.2f} min")
Output:
Flight duration: 4.30 min
Plot the flight plan (optional)
plot = flight_planner.plot_flight_plan(waypoints)
plot.show()
Output:
Write the legs for the survey XML file
print(str(flight_planner.write_legs(waypoints, altitude=alt, template_id=scannerSettings, speed=platform_speed)))
Output:
<leg>
<platformSettings x="181.5383082282002" y="-95.23047120351222" z="1000" movePerSec_m="5" />
<scannerSettings template="template1" trajectoryTimeInterval_s="0.05" />
</leg>
<leg>
<platformSettings x="-204.8320222874271" y="8.297146837496072" z="1000" movePerSec_m="5" />
<scannerSettings template="template1" active="false" trajectoryTimeInterval_s="0.05" />
</leg>
<leg>
<platformSettings x="-193.18516525781365" y="51.76380902050415" z="1000" movePerSec_m="5" />
<scannerSettings template="template1" trajectoryTimeInterval_s="0.05" />
</leg>
<leg>
<platformSettings x="193.18516525781365" y="-51.76380902050415" z="1000" movePerSec_m="5" />
<scannerSettings template="template1" active="false" trajectoryTimeInterval_s="0.05" />
</leg>
<leg>
<platformSettings x="204.8320222874271" y="-8.297146837496072" z="1000" movePerSec_m="5" />
<scannerSettings template="template1" trajectoryTimeInterval_s="0.05" />
</leg>
<leg>
<platformSettings x="-181.5383082282002" y="95.23047120351222" z="1000" movePerSec_m="5" />
<scannerSettings template="template1" active="false" trajectoryTimeInterval_s="0.05" />
</leg>
Check out this Jupyter Notebook to see how the flight_planner
may be used in a typical workflow.