#include #include #include "AP_RangeFinder_Benewake_CAN.h" #include #if AP_RANGEFINDER_BENEWAKE_CAN_ENABLED RangeFinder_MultiCAN *AP_RangeFinder_Benewake_CAN::multican; /* constructor */ AP_RangeFinder_Benewake_CAN::AP_RangeFinder_Benewake_CAN(RangeFinder::RangeFinder_State &_state, AP_RangeFinder_Params &_params) : AP_RangeFinder_Backend_CAN(_state, _params) { if (multican == nullptr) { multican = new RangeFinder_MultiCAN(AP_CAN::Protocol::Benewake, "Benewake MultiCAN"); if (multican == nullptr) { AP_BoardConfig::allocation_error("Benewake_CAN"); } } { // add to linked list of drivers WITH_SEMAPHORE(multican->sem); auto *prev = multican->drivers; next = prev; multican->drivers = this; } } // handler for incoming frames for H30 radar bool AP_RangeFinder_Benewake_CAN::handle_frame_H30(AP_HAL::CANFrame &frame) { /* The H30 produces 3 targets, each as 16 bit unsigned integers in cm. Only look at target1 for now */ const uint16_t target1_cm = be16toh_ptr(&frame.data[0]); if (target1_cm == 0) { // no target gives 0 return false; } //uint16_t target2 = be16toh_ptr(&frame.data[2]); //uint16_t target3 = be16toh_ptr(&frame.data[4]); accumulate_distance_m(target1_cm * 0.01); return true; } // handler for incoming frames. These come in at 100Hz bool AP_RangeFinder_Benewake_CAN::handle_frame(AP_HAL::CANFrame &frame) { WITH_SEMAPHORE(_sem); if (frame.isExtended()) { // H30 radar uses extended frames const int32_t id = int32_t(frame.id & AP_HAL::CANFrame::MaskExtID); if (!is_correct_id(id)) { return false; } return handle_frame_H30(frame); } const uint16_t id = frame.id & AP_HAL::CANFrame::MaskStdID; if (!is_correct_id(id)) { return false; } const uint16_t dist_cm = le16toh_ptr(&frame.data[0]); const uint16_t snr = le16toh_ptr(&frame.data[2]); if (snr_min != 0 && snr < uint16_t(snr_min.get())) { // too low signal strength return true; } accumulate_distance_m(dist_cm * 0.01); return true; } #endif // AP_RANGEFINDER_BENEWAKE_CAN_ENABLED