|
| 1 | +# See what your LiDAR sees: a live browser plot for `lds2d` |
| 2 | + |
| 3 | +*Draft — announcement / blog post* |
| 4 | + |
| 5 | +A spinning LiDAR is one of those parts that feels like magic right up until you |
| 6 | +plug it in and get… a wall of numbers. `angle 182.40 dist_mm 1043 quality 71`, |
| 7 | +forty thousand times a second. You believe it's working. You can't *see* that |
| 8 | +it's working. |
| 9 | + |
| 10 | +So the latest `lds2d` release adds a way to see it. One command, any browser: |
| 11 | + |
| 12 | +``` |
| 13 | +pip install 'lds2d[viz]' |
| 14 | +lds2d viz |
| 15 | +``` |
| 16 | + |
| 17 | +Open `http://<your-pi>:8080` from your laptop and the room draws itself — a |
| 18 | +live polar plot of every return, the walls and furniture sweeping into place at |
| 19 | +5–6 Hz. No desktop on the Pi, no X11, no ROS, no rviz. Just a web page. |
| 20 | + |
| 21 | + <!-- TODO: drop in a screenshot of the polar view --> |
| 22 | + |
| 23 | +## What `lds2d` is |
| 24 | + |
| 25 | +If you're new here: [`lds2d`](https://github.com/kaiaai/lds2d) is a small, |
| 26 | +pure-Python driver for 2D LiDARs on Linux and the Raspberry Pi — a Pythonic port |
| 27 | +of the [kaiaai/LDS](https://github.com/kaiaai/LDS) C++ library. Where the C++ |
| 28 | +side targets Arduino with registered callbacks, `lds2d` gives you plain |
| 29 | +iterators: |
| 30 | + |
| 31 | +```python |
| 32 | +from lds2d import Lidar |
| 33 | + |
| 34 | +with Lidar.open("LD14P", "/dev/serial0") as lidar: |
| 35 | + for scan in lidar.scans(): # one full rotation at a time |
| 36 | + pts = scan.valid_points |
| 37 | + print(f"{scan.scan_freq_hz:.1f} Hz {len(pts)} points") |
| 38 | +``` |
| 39 | + |
| 40 | +It speaks **23 LiDAR models** today — across LDROBOT (LD14P/LD19/LD06/STL19P), |
| 41 | +YDLIDAR (X2/X3/X4/SCL/T-mini), RPLIDAR (A1/C1), 3irobotix (Delta-2A/2B/2D/2G, |
| 42 | +LDS08RR), Neato/Xiaomi (XV11, LDS01RR, LDS02RR), Camsense X1 and the Hitachi-LG |
| 43 | +HLS-LFCD2 (TurtleBot3 LDS-01) — including running the PID + PWM motor loop for |
| 44 | +the ones that have no onboard speed control and need the Pi to spin them. Each is |
| 45 | +a faithful port of the kaiaai/LDS C++ driver, unit-tested against recorded byte |
| 46 | +streams; the models we haven't yet re-checked on physical hardware are flagged as |
| 47 | +such. |
| 48 | + |
| 49 | +## The visualizer, end to end |
| 50 | + |
| 51 | +The browser view is deliberately boring on the inside, which is the point. Three |
| 52 | +small pieces: |
| 53 | + |
| 54 | +- **A background reader thread** pulls full rotations off whatever driver you |
| 55 | + opened — `lidar.scans()` — and hands each one to a buffer. |
| 56 | +- **A thread-safe latest-scan buffer** holds exactly one rotation, converted to a |
| 57 | + compact JSON-ready dict of valid points. The web request thread reads it; the |
| 58 | + reader thread writes it; a lock keeps them from tearing. |
| 59 | +- **A tiny Flask app** serves two routes: `/scan.json` (the latest scan) and `/` |
| 60 | + (a single, dependency-free HTML page). The page polls every ~120 ms and redraws |
| 61 | + a `<canvas>` in polar coordinates — points coloured by signal strength, a range |
| 62 | + ring that auto-scales to the room, and a HUD with the live scan rate and point |
| 63 | + count. |
| 64 | + |
| 65 | +Because the visualizer reads through the same `scans()` iterator every driver |
| 66 | +already exposes, it works with *all 23* sensors for free — including the |
| 67 | +host-driven-motor ones, where simply iterating keeps the motor spinning: |
| 68 | + |
| 69 | +``` |
| 70 | +lds2d --model LDS02RR --pwm software viz |
| 71 | +``` |
| 72 | + |
| 73 | +Prefer to wire it into your own app? The Python entry point is one call: |
| 74 | + |
| 75 | +```python |
| 76 | +from lds2d import Lidar |
| 77 | +from lds2d.viz import serve |
| 78 | + |
| 79 | +with Lidar.open("LD14P", "/dev/serial0") as lidar: |
| 80 | + serve(lidar, port=8080) |
| 81 | +``` |
| 82 | + |
| 83 | +## Tested without touching hardware |
| 84 | + |
| 85 | +`lds2d` has a rule: every driver is unit-tested against recorded byte streams, so |
| 86 | +the whole suite runs on a laptop with no sensor attached. The visualizer keeps |
| 87 | +that rule. |
| 88 | + |
| 89 | +The serial port and the spinning motor are pushed to the edges; the logic in the |
| 90 | +middle is plain, testable code. The scan→JSON conversion is a pure function. The |
| 91 | +buffer is exercised by four threads hammering it at once to prove it never tears. |
| 92 | +The reader is driven by a *fake* LiDAR that yields a fixed list of scans, and a |
| 93 | +deliberately exploding one to prove a yanked cable ends the thread quietly instead |
| 94 | +of crashing the server. The Flask routes are checked with Flask's test client — |
| 95 | +no browser, no port. And an end-to-end test feeds real LD14P packet bytes through |
| 96 | +the actual parser, through the buffer, out of the HTTP endpoint, and asserts the |
| 97 | +points that come back. |
| 98 | + |
| 99 | +The hardware-dependent surface is small enough to eyeball; everything else has a |
| 100 | +test. That's the whole bet. |
| 101 | + |
| 102 | +## Get it |
| 103 | + |
| 104 | +``` |
| 105 | +pip install 'lds2d[viz]' |
| 106 | +lds2d viz |
| 107 | +``` |
| 108 | + |
| 109 | +It pairs with the step-by-step Raspberry Pi tutorials this library grew out of: |
| 110 | + |
| 111 | +- [Connect & read the LD14P on a Raspberry Pi](https://makerspet.com/blog/tutorial-connect-ldrobot-ld14p-lidar-to-raspberry-pi-python/) |
| 112 | +- [Control the LD14P motor](https://makerspet.com/blog/tutorial-control-ldrobot-ld14p-lidar-motor-raspberry-pi-python/) |
| 113 | + |
| 114 | +The driver architecture is built to grow — and it has: from three models to 23 in |
| 115 | +one pass, each ported from the kaiaai/LDS C++ and verified. If you've got a 2D |
| 116 | +LiDAR and a Pi, there's a good chance it's already supported — give it a spin and |
| 117 | +watch the room appear. |
| 118 | + |
| 119 | +*`lds2d` is Apache-2.0. The LiDAR that inspired it lives at |
| 120 | +[makerspet.com](https://makerspet.com/product/ldrobot-ld14p-lidar/).* |
0 commit comments