{ "cells": [ { "cell_type": "markdown", "id": "d34a9654", "metadata": {}, "source": [ "# Multi-Scanner simulation with the Velodyne® VLP-16 (\"Puck\")\n", "\n", "Notebook: Lukas Winiwarter, 2022\n", "\n", "In this demo, we demonstrate how a scanner with multiple scanlines, such as the Velodyne® VLP-16, can be configured in HELIOS++. The demo contains two surveys, one for a static simulation (scanner at a single location) and one for a dynamic simulation (scanner moving between waypoints)." ] }, { "cell_type": "code", "execution_count": 1, "id": "796cf736", "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "from IPython.display import Code\n", "from pyhelios.util.xmldisplayer import display_xml, find_playback_dir" ] }, { "cell_type": "code", "execution_count": 2, "id": "02f990df", "metadata": {}, "outputs": [], "source": [ "import os\n", "\n", "os.chdir(\"..\")" ] }, { "cell_type": "markdown", "id": "14eb3773", "metadata": {}, "source": [ "## Scanner\n", "\n", "As the scanner is the main component in this demo, we investigate the **scanner** XML file `tls_scanners.xml`. Here, we find a predefined *Velodyne VLP-16*. Other scanners, such as the *Velodyne Puck LITE*, or the *Ouster OS2* can be implemented in similar ways." ] }, { "cell_type": "code", "execution_count": 3, "id": "0115b1c5", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
<scanner id="vlp16" accuracy_m="0.03" beamDivergence_rad="0.0007" name="Velodyne VLP-16" optics="rotating" pulseFreqs_Hz="18750" pulseLength_ns="4" rangeMin_m="0.0100" rangeMax_m="100" scanAngleMax_deg="1" scanAngleEffectiveMax_deg="1" scanFreqMin_Hz="0" scanFreqMax_Hz="0" wavelength_nm="903" maxNOR="2" headRotatePerSecMax_deg="7200">\n",
"\t\t\t\t\n",
"\t\t<FWFSettings beamSampleQuality="1" />\t<!-- set to one for fast simulations -->\n",
"\t\t<channels>\n",
"\t\t\t<channel id="0">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="-15" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="1">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="1" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="2">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="-13" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="3">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="3" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="4">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="-11" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="5">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="5" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="6">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="-9" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="7">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="7" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="8">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="-7" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="9">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="9" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="10">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="-5" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="11">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="11" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="12">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="-3" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="13">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="13" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="14">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="-1" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t\t<channel id="15">\n",
"\t\t\t\t<beamOrigin x="0" y="0" z="0">\n",
"\t\t\t\t\t<rot axis="x" angle_deg="15" />\t\t\t\t\t\n",
"\t\t\t\t</beamOrigin>\n",
"\t\t\t</channel>\n",
"\t\t</channels>\n",
"\n",
"\t</scanner>\n",
"\t\n",
"<document>\n",
" <scannerSettings id="scaset" active="true" pulseFreq_hz="18750" scanFreq_hz="0" />\n",
" <survey name="box_puck_static" scene="data/scenes/demo/box_scene.xml#box_scene" platform="data/platforms.xml#tripod" scanner="data/scanners_tls.xml#vlp16">\n",
"\t\t<leg>\n",
" <platformSettings x="0" y="0" z="0" />\n",
"\t\t\t<scannerSettings template="scaset" headRotatePerSec_deg="3600" headRotateStart_deg="0" headRotateStop_deg="3600" /> <!-- 1 second integration time -->\n",
" </leg>\n",
" </survey>\n",
"</document>\n",
"<document>\n",
" <scannerSettings id="scaset" active="true" pulseFreq_hz="18750" scanFreq_hz="0" />\n",
" <survey name="box_puck_moving" scene="data/scenes/demo/box_scene.xml#box_scene" platform="data/platforms.xml#simple_linearpath" scanner="data/scanners_tls.xml#vlp16">\n",
"\t\t<leg>\n",
" <platformSettings x="-40" y="0" z="0" movePerSec_m="8" /> <!-- with 8 m/s, we make it to +40 in 10 seconds -->\n",
"\t\t\t<scannerSettings template="scaset" trajectoryTimeInterval_s="0.01" headRotatePerSec_deg="3600" headRotateStart_deg="0" headRotateStop_deg="36000" /> <!-- the rotation will also take 10 seconds -->\n",
" </leg>\n",
"\t\t\t<leg>\n",
" <platformSettings x="40" y="0" z="0" />\n",
"\t\t\t<scannerSettings active="false" />\n",
" </leg>\n",
" </survey>\n",
"</document>\n",
"