helios
helios copied to clipboard
Multi-Beam/Multi-Channel support in HELIOS++
Modern scanners in many fields have more than one channel Examples are the Velodyne Puck, Livox scanners, but also some RIEGL systems. See a list of examples here: scanner_implementation.pdf
While these scanners can currently be simulated by running the same survey multiple times with slighly different scanner definitions, this is unelegant and (e.g. for 64 channels) quite cumbersome.
Proposed solution The definition of multiple channels on Scanner-Level. Each channel has its own mounting (position and orientation) and own rotation axis.
Currently, we implement TLS and ALS/MLS very similarly, one with a rotating scanning plane (headRotateAxis
) and one with a scanning plane that is moved along a trajectory. Some new functionality is required here now:
Each channel can have its own:
- Beam origin and direction (via rotation)
- Scan plane normal (when not defined by the beam direction)
- Starting argument (e.g. phase shift for oscillating/risley prisms/...)
In the case of "typical" TLS, we can keep the concept of headRotateStart
, headRotateStop
and headRotatePerSeg
. For scanners like the velodyne puck or the risley prism scanners, the scene is typically sampled multiple times. Therefore, an "integration time" concept would be the better idea here.
Following are examples:
- Puck-like scanner with 3 channels that work parallel to each other. Here, I define the scanning plane to be horizontal:
<scanner id="demo_same_origin"
accuracy_m="0.02"
beamDivergence_rad="0.0027"
name="Demo"
optics="rotating"
pulseFreqs_Hz="50000"
pulseLength_ns="4"
rangeMin_m="2"
scanAngleMax_deg="180"
scanAngleEffectiveMax_deg="180"
wavelength_nm="905">
<channels>
<channel id="0">
<beamOrigin x="0" y="0" z="0">
<rot axis="y" angle_deg="-5"/> <!-- looking "down" 5 deg -->
</beamOrigin>
<scanPlaneNormal x="0" y="0" z="1"/>
</channel>
<channel id="1">
<beamOrigin x="0" y="0" z="0">
<!-- horizontal beam -->
</beamOrigin>
<scanPlaneNormal x="0" y="0" z="1"/>
</channel>
<channel id="2">
<beamOrigin x="0" y="0" z="0">
<rot axis="y" angle_deg="5"/> <!-- looking "up" 5 deg -->
</beamOrigin>
<scanPlaneNormal x="0" y="0" z="1"/>
</channel>
</channels>
<FWFSettings beamSampleQuality="3"/>
</scanner>
- Risely scanner with three different main directions (e.g. livox-mid-100)
<scanner id="livox-mid-100"
accuracy_m="0.02"
beamDivergence_rad="0.0027"
name="livox-mid-100"
optics="risely"
pulseFreqs_Hz="50000"
pulseLength_ns="4"
rangeMin_m= "2"
scanAngleMax_deg = "35"
scanAngleEffectiveMax_deg = "35"
rotorFreq1_Hz = "7294"
rotorFreq2_Hz = "-4664"
wavelength_nm="905">
<channels>
<channel id="0">
<beamOrigin x="0" y="0" z="0">
<rot axis="z" angle_deg="-30"/> <!-- cone center looking left 30 deg -->
</beamOrigin>
<!-- scan plane is defined by the central ray -->
</channel>
<channel id="1">
<beamOrigin x="0" y="0" z="0">
<!-- central cone -->
</beamOrigin>
</channel>
<channel id="2">
<beamOrigin x="0" y="0" z="0">
<rot axis="z" angle_deg="30"/> <!-- cone center looking right 30 deg -->
</beamOrigin>
</channel>
</channels>
<FWFSettings beamSampleQuality="3"/>
</scanner>
- RIEGL VQ-1560ii
<scanner id="VQ-1560ii"
accuracy_m="0.02"
beamDivergence_rad="0.0027"
name = "RIEGL VQ-1560ii"
optics = "rotating"
pulseFreqs_Hz = "150000,250000,350000,500000,700000,1000000,2000000"
pulseLength_ns = "4"
rangeMin_m = "100"
scanAngleMax_deg = "45"
scanAngleEffectiveMax_deg = "30"
scanFreqMin_Hz = "40"
scanFreqMax_Hz = "600"
wavelength_nm = "1064"
>
<channels>
<channel id="0">
<beamOrigin x="0" y="0.0" z="0.0">
<rot axis="y" angle_deg="-14" />
<rot axis="z" angle_deg="8" />
</beamOrigin>
<!-- scan plane defined via rotation of beam -->
</channel>
<channel id="1">
<beamOrigin x="0" y="0.0" z="0.0">
<rot axis="y" angle_deg="14" />
<rot axis="z" angle_deg="8" />
</beamOrigin>
<!-- scan plane defined via rotation of beam -->
</channel>
</scanner>
- Risely scanner with multiple beams (phase offset)
See e.g. https://www.livoxtech.com/de/avia
<scanner id = "livox_avis"
accuracy_m = "0.02"
beamDivergence_rad = "0.004887"
name = "Livox Avia"
optics = "risley"
pulseFreqs_Hz = "100000"
pulseLength_ns = "4"
rangeMin_m = "2"
scanAngleMax_deg = "35"
scanAngleEffectiveMax_deg = "35"
rotorFreq1_Hz = "7294"
rotorFreq2_Hz = "-4664"
wavelength_nm = "905"
maxNOR = "1"
>
<FWFSettings beamSampleQuality="3"/>
<channels>
<channel id="0">
<beamOrigin x="0" y="0" z="0">
<rot axis="x" angle_deg="90" />
<rot axis="z" angle_deg="90" />
</beamOrigin>
<timeArgument value="0" /> <!-- offset in seconds (?) -->
</channel>
<channel id="1">
<beamOrigin x="0" y="0" z="0">
<rot axis="x" angle_deg="90" />
<rot axis="z" angle_deg="90" />
</beamOrigin>
<timeArgument value="0.001" /> <!-- offset in seconds (?) -->
</channel>
<channel id="2">
<beamOrigin x="0" y="0" z="0">
<rot axis="x" angle_deg="90" />
<rot axis="z" angle_deg="90" />
</beamOrigin>
<timeArgument value="0.002" /> <!-- offset in seconds (?) -->
</channel>
<channel id="3">
<beamOrigin x="0" y="0" z="0">
<rot axis="x" angle_deg="90" />
<rot axis="z" angle_deg="90" />
</beamOrigin>
<timeArgument value="0.003" /> <!-- offset in seconds (?) -->
</channel>
<channel id="4">
<beamOrigin x="0" y="0" z="0">
<rot axis="x" angle_deg="90" />
<rot axis="z" angle_deg="90" />
</beamOrigin>
<timeArgument value="0.004" /> <!-- offset in seconds (?) -->
</channel>
<channel id="5">
<beamOrigin x="0" y="0" z="0">
<rot axis="x" angle_deg="90" />
<rot axis="z" angle_deg="90" />
</beamOrigin>
<timeArgument value="0.004" /> <!-- offset in seconds (?) -->
</channel>
</scanner>
Open Issues This concept still gives no options to combine two different scanning mechanisms into one scanner. A (maybe not well developed) idea would be a "composite" scanner type that allows the combination of existing scanners:
<scanner id="VQ-880G"
....
optics="composite">
<channels>
<channel source="#VQ-880G-IR" />
<channel source="#VQ-880G-G" />
</channels>
</scanner>
where VQ-880G-IR
and VQ-880G-G
are defined as separate scanners, one as rotating, one as palmer scanner. These channels cannot have an id, as they may each consist of multiple channels.
Output
Two different output options should be supported (probably by command line flag --splitByChannel
): One file per channel per leg, or one file per leg, but with an additional attribute / column set for the channel ID
Additional context For palmer scanners, the forward looking beams (azimuth 0-90° and 270-360°) are typically separated from the backward looking ones (90-270°). This behaviour should be implemented as part of this issue.