C# / .NET Reactive Extensions (Rx) for LIDAR scanners
This project is maintained by StaudtEngineering
A lightweight but powerful Lidar scanner driver and data processing library for .NET providing support for multiple Lidar scanners and an intuitive way to process samples received by the scanner.
PointsInAzimuthRange
PointsInDistanceRange
RadiusRangeMinDistance
RadiusRangeMaxDistance
PointsInBox
BufferByScan
These device are officially supported by LidaRx:
Here’s a simple example using a Scanse.io Sweep sensor.
Basically the program connects to the Sweep on Com1
, set the motor speed to 10Hz and the sample rate to 1kHz
using (var sweep = new SweepScanner("COM1"))
{
await sweep.ConnectAsync();
await sweep.SetMotorSpeedAsync(SweepMotorSpeed.Speed10Hz);
await sweep.SetSampleRateAsync(SweepSampleRate.SampleRate1000);
await sweep.StartScanAsync();
…then the program registers for LidarStatusEvent
with the LidarStatusLevel.Error
and logs the
messages to the console.
// log errors to the console
sweep.OnlyStatusEvents(LidarStatusLevel.Error).Subscribe(ev =>
{
Console.WriteLine($"Error: {ev.Message}");
});
Next, the program takes the LIDAR point stream and filters away all the points that are outside of the distance
range 40cm to 100cm (imagine two concentric circles around the scanner; only points between them propagate in the
resulting Observable<LidarPoint>
stream)
// using the data stream for multiple subscriptions
var pointsBetween400and1000mm = sweep
.OnlyLidarPoints() // filter away all those status messages
.Where(pt => pt.Distance > 400) // unit is mm
.Where(pt => pt.Distance <= 1000); // unit is mm
Finally we use the restrained stream as source for a Rx Buffer()
which collects all the points into consecutive
“1 second long” buffers. In the second part the program uses the pointsBetween400and1000mm
stream and restricts
it further to points in the azimuth range of -45 to +45 degree.
// buffer in 1second long samples
pointsBetween400and1000mm
.Buffer(TimeSpan.FromSeconds(1000))
.Subscribe(buffer =>
{
Console.WriteLine($"{buffer.Count} points in [400;1000]mm range per second");
});
// this narrows down the point stream to points in the -45 to +45 degree range
pointsBetween400and1000mm
.PointsInAzimuthRange(-45, 45)
.Subscribe(pt =>
{
// write the points to disk?!
});
This part uses the full stream of LidarPoint
from the scanner but instead of buffering on a time basis as in
the code above it buffers by scan (basically per scanner head revolution).
// buffer the lidar points in scans
sweep.OnlyLidarPoints()
.BufferByScan()
.Subscribe(scan =>
{
Console.WriteLine($"Got {scan.Count} points for scan {scan.Scan}");
Console.WriteLine($"Most distant point: {scan.Points.Max(pt => pt.Distance)}mm");
Console.WriteLine($"Closest point: {scan.Points.Min(pt => pt.Distance)}mm");
});
Console.ReadLine(); // wait here 'till user hits the enter key
sweep.StopScan();
}
PointsIn3DModel(string pathToStlFile)
)lidaRx is dual licensed. Unless you’ve made a separate licence agreement with Staudt Engineering (for example because you can’t stand the LGPL / use contact form on http://www.staudt-engineering.com) you can use lidaRx under the GNU Lesser General Public License v3.0. The full licence text is available in this repository: LICENSE
Commercial support and device driver development service is available, support for open source usage is limited on a “free time available” basis, but please feel free to open issues or pull requests if you can think of something that would make this library more awesome :)