Slamtec devices count their angle clockwise viewed from the top
(Interface Protocol spec; the official rplidar_ros node mirrors the
angles for the same reason), but the decode used the raw ascending
angles as CCW for a right-side-up unit and mirrored them for an
upside-down one — exactly backwards. Field-verified 2026-07-23: a
right-side-up C1 produced a left-right mirrored sweep against a
verified right-handed reference lidar.
Now: right-side-up mirrors (angle' = 2π − raw, nodes walked backwards);
upside-down uses the raw ascending angles, because the physical flip
already reverses the apparent rotation. The mountedUpsideDown flag
finally carries its true physical meaning.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The repo is now self-contained: driver_rplidar compiles the SDK from
third_party/rplidar_sdk (Linux sources only, teardown delete[] bug fixed
in place), so a plain cmake configure needs no SDK path and no probing —
the XLIDAR_RPLIDAR_SDK_DIR option and external references are gone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DeviceConfig now carries an optional transport (serial/udp/tcp) instead of
the ESPE-only use_udp bool. Plugins validate it in create_driver_instance:
a fixed-transport driver configured with the wrong transport fails open()
with InvalidConfig (via InvalidConfigDriver — the plugin ABI forbids
returning nullptr) rather than silently ignoring the setting. Selectable
drivers (ESPE) switch TCP/UDP through the same field. config.json
load/save round-trips "transport" for every transport, including serial,
and migrates legacy use_udp:true entries.
Diagnostics drops the per-vendor accessors (espe_fault, rplidar_fault,
monitor_fault, sick_error, pollution_*, contamination_*, manipulation) for
one common shape: a list of DiagnosticIssue{severity, code, detail} with
cross-vendor codes, plus a raw map of vendor passthrough values and
to_json() for hosts that prefer a string. Vendor bit decoding now lives in
one place (decode_diagnostics); has_fault/has_warning/healthy keep their
meaning, so is_ready()/wait_ready() are unchanged.
Also: README regains the model/protocol and ExtraInfo tables lost in the
lidarlib->xlidar refactor (verified against current code), and the empty
xlocd/ tree left by a stray sync run is gone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>