Closed Soeren3003 closed 7 years ago
Hello Soeren,
so, basically the issue is that you just took the console app code and dropped it into a Winforms context, where a few things behave differently. Notably Console.ReadLine()
which does return immediately; this means that you start, then stop scanning in just a few instructions.
So either you'll have to switch to a console application or split things in a way that they work in the Win-forms context (which would be put one half of the code [setup + subscriptions] in - for ex. - the load handler of the form, and then put the stop scan call and disposal stuff into the form closed handler)
Regarding the SweepProtocolErrorException
I can only guess that it happens when you stop your application the hard way (SIGKILL) before the driver could issue a stop scan signal to Sweep. The Scanner doesn't stop sending data then and when the driver tries to send setup commands it doesn't get the expected answer.
Oh well, thats make sense, but now i copied my method into a console-app and it doesent run, too. The programm runs only to await sweep.ConnectAsync();
and after that it breaks up without a error message or something else. The COM4 is the port with is showing me in the sweep-demo.
`class Program { static void Main(string[] args) { Test(); } static async void Test() { using (var sweep = new SweepScanner("COM4")) { await sweep.ConnectAsync(); await sweep.SetMotorSpeedAsync(SweepMotorSpeed.Speed10Hz); await sweep.SetSamplingRateAsync(SweepSampleRate.SampleRate1000);
await sweep.StartScanAsync();
// 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
// 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?!
});
// 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");
});
sweep.StopScan();
}
}
}`
Hi again,
you're running into the same issue as previously - I guess you're not really familiar with the async/await stuff(?)
When you call an async method the compiler basically starts a new thread (in which the callee is executed) then immediately returns, so basically you call to Test()
does return immediately, then main()
ends and the program finishes.
One possibility would be to have the signature of Test()
be static async Task Test()
(note the return type) and then call Test().Wait();
which - even if it's not really clean code - does what you want. Btw. when you see async void
in a method signature which is not an event handler you're probably doing something wrong! It's actually pretty dangerous and can lead to hard to debug errors as exceptions can't be properly caught from the calling side etc...
the async await stuff is really cool, but there are a few potentially confusing things happening under the covers, so you might want to get familiar with TPL and await/async.
Here's some good reading:
https://docs.microsoft.com/en-us/dotnet/csharp/async https://codeblog.jonskeet.uk/category/eduasync/
Good luck!
I have copied your code, but it doesnt work really ... The only thing which is working is the speed setup.
"0 points in [400;1000]mm range per second"
Sometimes the programm throws the following exception by running the connect method:
Ausnahme ausgelöst: Staudt.Engineering.LidaRx.Drivers.Sweep.Exceptions.SweepProtocolErrorException in mscorlib.dll
My code looks like these: