2020-01-13 01:48:57 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "AP_RangeFinder.h"
|
|
|
|
#include "AP_RangeFinder_Backend_Serial.h"
|
|
|
|
|
|
|
|
#define LEDDARVU8_PAYLOAD_LENGTH (8*2)
|
|
|
|
|
|
|
|
class AP_RangeFinder_LeddarVu8 : public AP_RangeFinder_Backend_Serial
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
using AP_RangeFinder_Backend_Serial::AP_RangeFinder_Backend_Serial;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
// baudrate used during object construction:
|
|
|
|
uint32_t initial_baudrate(uint8_t serial_instance) const override {
|
|
|
|
return 115200;
|
|
|
|
}
|
|
|
|
|
|
|
|
// return sensor type as laser
|
|
|
|
MAV_DISTANCE_SENSOR _get_mav_distance_sensor_type() const override {
|
|
|
|
return MAV_DISTANCE_SENSOR_LASER;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get a reading, distance returned in reading_cm
|
2021-10-18 02:45:33 -03:00
|
|
|
bool get_reading(float &reading_m) override;
|
2020-01-13 01:48:57 -04:00
|
|
|
|
2020-01-20 04:14:04 -04:00
|
|
|
// maximum time between readings before we change state to NoData:
|
|
|
|
uint16_t read_timeout_ms() const override { return 500; }
|
|
|
|
|
2020-01-13 01:48:57 -04:00
|
|
|
private:
|
|
|
|
|
|
|
|
// function codes
|
|
|
|
enum class FunctionCode : uint8_t {
|
|
|
|
READ_HOLDING_REGISTER = 0x03,
|
|
|
|
READ_INPUT_REGISTER = 0x04,
|
|
|
|
WRITE_HOLDING_REGISTER = 0x06,
|
|
|
|
WRITE_MULTIPLE_REGISTER = 0x10,
|
|
|
|
READ_WRITE_MULTIPLE_REGISTER = 0x17
|
|
|
|
};
|
|
|
|
|
|
|
|
// register numbers for reading input registers
|
|
|
|
enum class RegisterNumber : uint8_t {
|
|
|
|
REGISTER_STATUS = 1, // 0 = detections not ready, 1 = ready
|
|
|
|
NUMBER_OF_SEGMENTS = 2,
|
|
|
|
NUMBER_OF_DETECTIONS = 11,
|
|
|
|
PERCENTAGE_OF_LIGHT_SOURCE_POWER = 12,
|
|
|
|
TIMESTAMP_LOW = 14,
|
|
|
|
TIMESTAMP_HIGH = 15,
|
|
|
|
FIRST_DISTANCE0 = 16, // distance of first detection for 1st segment, zero if no detection
|
|
|
|
FIRST_AMPLITUDE0 = 24, // amplitude of first detection * 64 for 1st segment
|
|
|
|
FIRST_FLAG0 = 32, // flags of first detection for 1st segment. Bit0:Valid, Bit1:Result of object demerging, Bit2:Reserved, Bit3:Saturated
|
|
|
|
// registers exist for distance, amplitude and flags for subsequent detections but are not used in this driver
|
|
|
|
};
|
|
|
|
|
|
|
|
// parsing state
|
|
|
|
enum class ParseState : uint8_t {
|
|
|
|
WAITING_FOR_ADDRESS,
|
|
|
|
WAITING_FOR_FUNCTION_CODE,
|
|
|
|
WAITING_FOR_PAYLOAD_LEN,
|
|
|
|
WAITING_FOR_PAYLOAD,
|
|
|
|
WAITING_FOR_CRC_LOW,
|
|
|
|
WAITING_FOR_CRC_HIGH,
|
|
|
|
};
|
|
|
|
|
|
|
|
// get sensor address from RNGFNDx_ADDR parameter
|
|
|
|
uint8_t get_sensor_address() const;
|
|
|
|
|
|
|
|
// send request to device to provide distances
|
|
|
|
void request_distances();
|
|
|
|
|
|
|
|
// process one byte received on serial port
|
|
|
|
// returns true if successfully parsed a message
|
|
|
|
// if distances are valid, valid_readings is set to true and distance is stored in reading_cm
|
|
|
|
bool parse_byte(uint8_t b, bool &valid_reading, uint16_t &reading_cm);
|
|
|
|
|
|
|
|
// structure holding latest message contents
|
|
|
|
// the order of fields matches the incoming message so it can be used to calculate the crc
|
|
|
|
struct PACKED {
|
|
|
|
uint8_t address; // device address (required for calculating crc)
|
|
|
|
uint8_t function_code; // function code (always 0x04 but required for calculating crc)
|
|
|
|
uint8_t payload_len; // message payload length
|
|
|
|
uint8_t payload[LEDDARVU8_PAYLOAD_LENGTH]; // payload
|
|
|
|
uint16_t crc; // latest message's crc
|
|
|
|
uint16_t payload_recv; // number of message's payload bytes received so far
|
|
|
|
ParseState state; // state of incoming message processing
|
|
|
|
} parsed_msg;
|
|
|
|
uint32_t last_distance_ms; // system time of last successful distance sensor read
|
|
|
|
uint32_t last_distance_request_ms; // system time of last request to sensor to send distances
|
|
|
|
};
|