Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_DAL/AP_DAL_RangeFinder.cpp
Views: 1798
#include "AP_DAL_RangeFinder.h"12#include <AP_Logger/AP_Logger.h>34#include <AP_RangeFinder/AP_RangeFinder_Backend.h>56#if AP_RANGEFINDER_ENABLED78#include "AP_DAL.h"9#include <AP_BoardConfig/AP_BoardConfig.h>10#include <AP_Vehicle/AP_Vehicle_Type.h>11#include <AP_InternalError/AP_InternalError.h>1213AP_DAL_RangeFinder::AP_DAL_RangeFinder()14{15#if !APM_BUILD_TYPE(APM_BUILD_AP_DAL_Standalone) && !APM_BUILD_TYPE(APM_BUILD_Replay)16_RRNH.num_sensors = AP::rangefinder()->num_sensors();17_RRNI = NEW_NOTHROW log_RRNI[_RRNH.num_sensors];18_backend = NEW_NOTHROW AP_DAL_RangeFinder_Backend *[_RRNH.num_sensors];19if (!_RRNI || !_backend) {20goto failed;21}22for (uint8_t i=0; i<_RRNH.num_sensors; i++) {23_RRNI[i].instance = i;24}25for (uint8_t i=0; i<_RRNH.num_sensors; i++) {26// this avoids having to discard a const....27_backend[i] = NEW_NOTHROW AP_DAL_RangeFinder_Backend(_RRNI[i]);28if (!_backend[i]) {29goto failed;30}31}32return;33failed:34AP_BoardConfig::allocation_error("DAL backends");35#endif36}3738int16_t AP_DAL_RangeFinder::ground_clearance_cm_orient(enum Rotation orientation) const39{40#if !APM_BUILD_TYPE(APM_BUILD_AP_DAL_Standalone)41const auto *rangefinder = AP::rangefinder();4243if (orientation != ROTATION_PITCH_270) {44// the EKF only asks for this from a specific orientation. Thankfully.45INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);46return rangefinder->ground_clearance_cm_orient(orientation);47}48#endif4950return _RRNH.ground_clearance_cm;51}5253int16_t AP_DAL_RangeFinder::max_distance_cm_orient(enum Rotation orientation) const54{55#if !APM_BUILD_TYPE(APM_BUILD_AP_DAL_Standalone)56if (orientation != ROTATION_PITCH_270) {57const auto *rangefinder = AP::rangefinder();58// the EKF only asks for this from a specific orientation. Thankfully.59INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);60return rangefinder->max_distance_cm_orient(orientation);61}62#endif6364return _RRNH.max_distance_cm;65}6667void AP_DAL_RangeFinder::start_frame()68{69const auto *rangefinder = AP::rangefinder();70if (rangefinder == nullptr) {71return;72}7374const log_RRNH old = _RRNH;7576// EKF only asks for this *down*.77_RRNH.ground_clearance_cm = rangefinder->ground_clearance_cm_orient(ROTATION_PITCH_270);78_RRNH.max_distance_cm = rangefinder->max_distance_cm_orient(ROTATION_PITCH_270);7980WRITE_REPLAY_BLOCK_IFCHANGED(RRNH, _RRNH, old);8182for (uint8_t i=0; i<_RRNH.num_sensors; i++) {83auto *backend = rangefinder->get_backend(i);84if (backend == nullptr) {85continue;86}87_backend[i]->start_frame(backend);88}89}9091929394AP_DAL_RangeFinder_Backend::AP_DAL_RangeFinder_Backend(struct log_RRNI &RRNI) :95_RRNI(RRNI)96{97}9899void AP_DAL_RangeFinder_Backend::start_frame(AP_RangeFinder_Backend *backend) {100const log_RRNI old = _RRNI;101_RRNI.orientation = backend->orientation();102_RRNI.status = (uint8_t)backend->status();103_RRNI.pos_offset = backend->get_pos_offset();104_RRNI.distance_cm = backend->distance_cm();105WRITE_REPLAY_BLOCK_IFCHANGED(RRNI, _RRNI, old);106}107108// return true if we have a range finder with the specified orientation109bool AP_DAL_RangeFinder::has_orientation(enum Rotation orientation) const110{111for (uint8_t i=0; i<_RRNH.num_sensors; i++) {112if (_RRNI[i].orientation == orientation) {113return true;114}115}116return false;117}118119120AP_DAL_RangeFinder_Backend *AP_DAL_RangeFinder::get_backend(uint8_t id) const121{122if (id >= RANGEFINDER_MAX_INSTANCES) {123INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);124return nullptr;125}126if (id >= _RRNH.num_sensors) {127return nullptr;128}129130return _backend[id];131}132133void AP_DAL_RangeFinder::handle_message(const log_RRNH &msg)134{135_RRNH = msg;136if (_RRNH.num_sensors > 0 && _RRNI == nullptr) {137_RRNI = NEW_NOTHROW log_RRNI[_RRNH.num_sensors];138_backend = NEW_NOTHROW AP_DAL_RangeFinder_Backend *[_RRNH.num_sensors];139}140}141142void AP_DAL_RangeFinder::handle_message(const log_RRNI &msg)143{144if (_RRNI != nullptr && msg.instance < _RRNH.num_sensors) {145_RRNI[msg.instance] = msg;146if (_backend != nullptr && _backend[msg.instance] == nullptr) {147_backend[msg.instance] = NEW_NOTHROW AP_DAL_RangeFinder_Backend(_RRNI[msg.instance]);148}149}150}151152#endif // AP_RANGEFINDER_ENABLED153154155