Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : 16 : #include "AP_RangeFinder_config.h" 17 : 18 : #if AP_RANGEFINDER_BACKEND_CAN_ENABLED 19 : 20 : #include <AP_HAL/AP_HAL.h> 21 : #include "AP_RangeFinder_Backend_CAN.h" 22 : 23 : const AP_Param::GroupInfo AP_RangeFinder_Backend_CAN::var_info[] = { 24 : 25 : // @Param: RECV_ID 26 : // @DisplayName: RangeFinder CAN receive ID 27 : // @Description: The receive ID of the CAN frames. A value of zero means all IDs are accepted. 28 : // @Range: 0 65535 29 : // @User: Advanced 30 : AP_GROUPINFO("RECV_ID", 10, AP_RangeFinder_Backend_CAN, receive_id, 0), 31 : 32 : // @Param: SNR_MIN 33 : // @DisplayName: RangeFinder Minimum signal strength 34 : // @Description: RangeFinder Minimum signal strength (SNR) to accept distance 35 : // @Range: 0 65535 36 : // @User: Advanced 37 : AP_GROUPINFO("SNR_MIN", 11, AP_RangeFinder_Backend_CAN, snr_min, 0), 38 : 39 : AP_GROUPEND 40 : }; 41 : 42 : // constructor 43 0 : AP_RangeFinder_Backend_CAN::AP_RangeFinder_Backend_CAN( 44 : RangeFinder::RangeFinder_State &_state, AP_RangeFinder_Params &_params, AP_CAN::Protocol can_type, 45 0 : const char *driver_name) : 46 0 : AP_RangeFinder_Backend(_state, _params) 47 : { 48 0 : AP_Param::setup_object_defaults(this, var_info); 49 0 : state.var_info = var_info; 50 0 : multican_rangefinder = NEW_NOTHROW MultiCAN{FUNCTOR_BIND_MEMBER(&AP_RangeFinder_Backend_CAN::handle_frame, bool, AP_HAL::CANFrame &), can_type, driver_name}; 51 0 : if (multican_rangefinder == nullptr) { 52 0 : AP_BoardConfig::allocation_error("Failed to create rangefinder multican"); 53 : } 54 0 : } 55 : 56 : // update the state of the sensor 57 0 : void AP_RangeFinder_Backend_CAN::update(void) 58 : { 59 0 : if (get_reading(state.distance_m)) { 60 : // update range_valid state based on distance measured 61 0 : state.last_reading_ms = AP_HAL::millis(); 62 0 : update_status(); 63 0 : } else if (AP_HAL::millis() - state.last_reading_ms >= read_timeout_ms()) { 64 0 : set_status(RangeFinder::Status::NoData); 65 : } 66 0 : } 67 : 68 : // get distance measurement 69 0 : bool AP_RangeFinder_Backend_CAN::get_reading(float &reading_m) 70 : { 71 0 : WITH_SEMAPHORE(_sem); 72 0 : if (_distance_count != 0) { 73 0 : reading_m = _distance_sum / _distance_count; 74 0 : _distance_sum = 0; 75 0 : _distance_count = 0; 76 0 : return true; 77 : } 78 : 79 0 : return false; 80 0 : } 81 : 82 : // return true if the CAN ID is correct 83 0 : bool AP_RangeFinder_Backend_CAN::is_correct_id(uint32_t id) const 84 : { 85 0 : if (receive_id != 0 && id != uint32_t(receive_id.get())) { 86 : // incorrect receive ID 87 0 : return false; 88 : } 89 0 : return true; 90 : } 91 : 92 : #endif // AP_RANGEFINDER_BACKEND_CAN_ENABLED