Skip to content

C# / .NET Reactive Extensions (Rx) for LIDAR scanners

License

Notifications You must be signed in to change notification settings

yunuseysr/LidaRx

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LidaRx

Build status NuGet NuGet

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.

Features

  • Unified data processing with all the power of Rx.NET at your fingertip
  • 3D coordinates
    • Configurable sensor position and orientation
    • Sensor position and orientation updatable at runtime
  • Vendor agnostic sensor fusion (join data streams from multiple scanners)
  • Comprehensive API an helpers: LidaRx readme
    • Unified base API for scanners: connect/disconnect, start/stop scanning and simple status information
    • Polar coordinates filters
      • PointsInAzimuthRange
      • PointsInDistanceRange
      • RadiusRangeMinDistance
      • RadiusRangeMaxDistance
    • Cartesian coordinates filters
      • PointsInBox
    • Grouping/Transforming operators
      • BufferByScan
  • Fully async
  • Cross platform support:
    • .NET Standard 1.5 / .NET Core 1.0
    • .NET Standard 2.0 / .NET Core 2.0
    • .NET 4.6+

Supported devices

These device are officially supported by LidaRx:

  • Scanse.io SWEEP Readme
  • Pepperl+Fuchs OMDxxx-R2000 device family (HD and UHD) Readme

Show me some code!

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();
}

Roadmap

  • Usable implementation of 3D collision test (think of PointsIn3DModel(string pathToStlFile) )
  • Points to object matching
  • Point and motion tracking

License

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

Support & Contribution

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 :)

About

C# / .NET Reactive Extensions (Rx) for LIDAR scanners

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 100.0%