-
Notifications
You must be signed in to change notification settings - Fork 86
Description
Hello,
I'm creating a C++ class that uses the libsweep low level API and also includes some additional error checking and functionality like automatically disabling scanning before attempting to set a new sample rate. I have a unit test that does things like set sample rates, sets sample rates while scanning, and stops scanning. Sometimes my unit tests run as expected and pass, other times it hangs or I get a "Invalid response checksum" error.
Here's the code i'm working with:
SweepLidar.hpp
#ifndef SWEEP_LIDAR_H
#define SWEEP_LIDAR_H
#include <stdint.h>
#include <iostream>
#include "sweep/sweep.hpp"
class SweepLidar
{
public:
SweepLidar(const char* inputPort) : device(new sweep::sweep(inputPort)), currentlyScanning(false)
{ }
int32_t setSampleRate(int32_t rate);
void startScanning();
void stopScanning();
private:
std::unique_ptr<sweep::sweep> device;
bool currentlyScanning;
};
#endif
SweepLidar.cpp
#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include "SweepLidar.hpp"
#include "errorCodes.hpp"
int32_t SweepLidar::setSampleRate(int32_t rate)
{
int32_t status = ERROR;
//Save the current state of the device, so that we can return the device to that state once we're finished
bool deviceOriginallyScanning = currentlyScanning;
if (rate == 500 || rate == 750 || rate == 1000)
{
if (currentlyScanning)
{
std::cout << "Disengaging scanning while sample rate is adjusted." << std::endl;
stopScanning();
}
device->set_sample_rate(rate);
//Verify that the sample rate we now retrieve is the new sample rate
int32_t currentSampleRate = device->get_sample_rate();
if (currentSampleRate == rate)
{
status = SUCCESS;
std::cout << "Successfully set LIDAR sample rate to: " << currentSampleRate << "hz" << std::endl;
}
//Return the device to its original state
if (deviceOriginallyScanning)
{
std::cout << "Reengaging scanning." << std::endl;
startScanning();
}
}
else
{
status = INVALID_SAMPLE_RATE;
std::cerr << "Error: sample rate of " << rate << "Hz not available. Options: 500Hz, 750Hz, 1000Hz." << std::endl;
}
return status;
}
void SweepLidar::startScanning()
{
std::cout << "Starting data capture..." << std::endl;
device->start_scanning();
currentlyScanning = true;
}
void SweepLidar::stopScanning()
{
std::cout << "Stopping data capture..." << std::endl;
device->stop_scanning();
currentlyScanning = false;
}
main.cpp
#include <iostream>
#include "SweepLidar.hpp"
#include "errorCodes.hpp"
using namespace std;
static void lidarSetSampleRateUnitTest() {
int cases = 0;
int failures = 0;
int32_t status = ERROR;
SweepLidar lidar("/dev/ttyUSB0");
cases++;
status = lidar.setSampleRate(500);
if (status != SUCCESS)
{
failures++;
}
cases++;
status = lidar.setSampleRate(1000);
if (status != SUCCESS)
{
failures++;
}
cases++;
status = lidar.setSampleRate(550);
if (status != INVALID_SAMPLE_RATE)
{
failures++;
}
cases++;
lidar.startScanning();
status = lidar.setSampleRate(750);
lidar.stopScanning();
if (status != SUCCESS)
{
failures++;
}
cases++;
lidar.startScanning();
status = lidar.setSampleRate(1000);
lidar.stopScanning();
if (status != SUCCESS)
{
failures++;
}
cout << "Test cases:" << cases << endl;
cout << "Failed:" << failures << endl;
}
int main()
{
lidarSetSampleRateUnitTest();
return 0;
}
Around 80% of the time, the tests successfully runs with the following output:
Creating sweep lidar...
Successfully set LIDAR sample rate to: 500hz
Successfully set LIDAR sample rate to: 1000hz
Error: sample rate of 550Hz not available. Options: 500Hz, 750Hz, 1000Hz.
Starting data capture...
Disengaging scanning while sample rate is adjusted.
Stopping data capture...
Successfully set LIDAR sample rate to: 750hz
Reengaging scanning.
Starting data capture...
Stopping data capture...
Starting data capture...
Disengaging scanning while sample rate is adjusted.
Stopping data capture...
Successfully set LIDAR sample rate to: 1000hz
Reengaging scanning.
Starting data capture...
Stopping data capture...
Test cases:5
Failed:0
Around 20% of the time, the unit test will fail by either hanging when attempting to stop the in-progress scan to adjust the sample rate, or fail by throwing an "Invalid response checksum" error also when attempting to stop an in-progress scan to adjust the sample rate:
> Creating sweep lidar...
> Successfully set LIDAR sample rate to: 500hz
> Successfully set LIDAR sample rate to: 1000hz
> Error: sample rate of 550Hz not available. Options: 500Hz, 750Hz, 1000Hz.
> Starting data capture...
> Disengaging scanning while sample rate is adjusted.
> Stopping data capture...
> (hangs here)
Creating sweep lidar...
Successfully set LIDAR sample rate to: 500hz
Successfully set LIDAR sample rate to: 1000hz
Error: sample rate of 550Hz not available. Options: 500Hz, 750Hz, 1000Hz.
Starting data capture...
Disengaging scanning while sample rate is adjusted.
Stopping data capture...
Successfully set LIDAR sample rate to: 750hz
Reengaging scanning.
Starting data capture...
Stopping data capture...
Starting data capture...
Disengaging scanning while sample rate is adjusted.
Stopping data capture...
terminate called after throwing an instance of 'sweep::device_error'
what(): invalid response header checksum
Aborted
Process returned 134 (0x86) execution time : 0.258 s
Press ENTER to continue.
sweep firmware version
v1.4
libsweep version + affected bindings
v1.2.3
operating system
Raspbian
Platform/Hardware Setup
USB connection to Raspberry Pi 3B