Skip to content

Invalid response checksum when attempting to adjust sample rate  #120

@tyler124

Description

@tyler124

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

Description:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions