pyhelios
¶This page will give an introduction on using HELIOS++ python bindings with pyhelios
.
pyhelios
allows you to:
pyhelios
¶The package pyhelios
is contained in the distribution root folder. It consists of different python scripts and the python-helios bindings. These bindings are actually present in the run
-folder as _pyhelios.pyd/[.so]
, but are imported when you import pyhelios
. The python scripts contain functions to create and work with simulations (e.g., SimulationBuilder
) and a util
subpackage, where tools for scene generation and flight planning are found.
Before importing, make sure that the HELIOS++ root directory is either the current working folder or added to the PATH environment variable.
As this notebook is not located in the HELIOS++ root directory, we add the path to the HELIOS++ root directory to the PATH environment variable with sys.path.append
.
import sys
import os
from pathlib import Path
current_folder = globals()["_dh"][0]
helios_path = str(Path(current_folder).parent)
sys.path.append(helios_path) # add helios-plusplus directory to PATH
import pyhelios
os.chdir(helios_path)
print(pyhelios.getVersion())
1.1.1
# pyhelios.loggingQuiet()
# pyhelios.loggingSilent()
pyhelios.loggingDefault()
# pyhelios.loggingVerbose()
# pyhelios.loggingVerbose2()
# Set seed for default random number generator.
pyhelios.setDefaultRandomnessGeneratorSeed("123")
simBuilder = pyhelios.SimulationBuilder(
"data/surveys/toyblocks/als_toyblocks.xml", "assets/", "output/"
)
# simBuilder.setNumThreads(1) # use only one thread (to ensure reproducibility)
simBuilder.setLasOutput(True)
simBuilder.setZipOutput(True)
simBuilder.setCallbackFrequency(10) # Run with callback
simBuilder.setFinalOutput(True) # Return output at join
# simBuilder.setExportToFile(False) # Disable export point cloud to file
simBuilder.setRebuildScene(True)
sim = simBuilder.build()
SimulationBuilder is building simulation ... SimulationBuilder built simulation in 0.3059422999999999 seconds
Simulations can also be paused, resumed and stopped:
sim.start()
sim.pause()
sim.resume()
sim.stop()
With various functions, we can find out the simulation status.
sim.isStarted()
sim.isRunning()
sim.isPaused()
sim.isStopped()
sim.isFinished()
import time
sim.start()
if sim.isStarted():
print("Simulation is started!")
time.sleep(1.0)
sim.pause()
if sim.isPaused():
print("Simulation is paused!")
if not sim.isRunning():
print("Simulation is not running.")
time.sleep(5)
start_time = time.time()
sim.resume()
if sim.isRunning():
print("Simulation is resumed!")
while sim.isRunning():
duration = time.time() - start_time
mins = duration // 60
secs = duration % 60
print(
"\r"
+ "Simulation is running since {} min and {} sec. Please wait.".format(
int(mins), int(secs)
),
end="",
)
time.sleep(1)
if sim.isFinished():
print("\nSimulation has finished.")
Simulation is started! Simulation is paused! Simulation is not running. Simulation is resumed! Simulation is running since 0 min and 18 sec. Please wait. Simulation has finished.
If final output was enabled (simBuilder.setFinalOutput(True)
)., the simulation output, i.e. measurement and trajectory points, can be accessed using sim.join()
.
# Create instance of PyHeliosOutputWrapper class using sim.join().
# Contains attributes 'measurements' and 'trajectories' which are Python wrappers
# of classes that contain the output vectors.
output = sim.join()
# Create instances of vector classes by accessing 'measurements' and 'trajectories' attributes of output wrapper.
measurements = output.measurements
trajectories = output.trajectories
# Each element of vectors contains a measurement point or point in trajectory respectively.
# Access through getPosition().
starting_point = trajectories[0].getPosition()
end_point = trajectories[len(trajectories) - 1].getPosition()
# Access individual x, y and z vals.
print(
f"Trajectory starting point : ({starting_point.x}, {starting_point.y}, {starting_point.z})"
)
print(
f"Trajectory end point : ({end_point.x:.1f}, {end_point.y:.1f}, {end_point.z:.1f})"
)
Trajectory starting point : (-30.0, -50.0, 100.0) Trajectory end point : (69.9, 50.0, 100.0)
pyhelios
contains additional tools for output handling (pyhelios/output_handling.py). These allow to convert the trajectory and point outputs to lists or numpy arrays.
meas_array, traj_array = pyhelios.outputToNumpy(output)
import numpy as np
np.set_printoptions(formatter={"float": "{0:0.3f}".format})
print(
f"""
First three rows of measurement array:
{meas_array[:3, :]}
First three rows of trajectory array:
{traj_array[:3, :]}
"""
)
First three rows of measurement array: [[-29.846 -13.246 0.012 20.000 20.085 100.994 0.001 0.342 -0.940 62543.211 0.000 1.000 1.000 1.000 0.000 0.000 -2147483648.000] [-24.944 -13.595 0.012 20.003 20.085 100.994 0.047 0.339 -0.940 68765.772 0.000 1.000 1.000 33.000 0.000 0.000 -2147483648.000] [-29.693 -13.259 0.046 20.000 20.085 100.994 0.003 0.342 -0.940 74992.121 0.000 1.000 1.000 2.000 0.000 0.000 -2147483648.000]] First three rows of trajectory array: [[-30.000 -50.000 100.000 -2147483648.000 0.000 0.000 4.712] [-29.700 -50.000 100.000 -2147483648.000 0.000 0.000 4.712] [-29.400 -50.000 100.000 -2147483648.000 0.000 0.000 4.712]]
Columns of the measurements array:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
pos.x | pos.y | pos.z | ori.x | ori.y | ori.z | dir.x | dir.y | dir.z | intensity | echoWidth | NumberOfReturns | ReturnNumber | FullwaveIndex | classification | gpsTime |
Columns of the trajectories array:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
pos.x | pos.y | pos.z | gpsTime | roll | pitch | yaw |