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_Proximity.h" 17 : #include <AP_Common/AP_Common.h> 18 : #include <AP_AHRS/AP_AHRS.h> 19 : #include <AP_HAL/AP_HAL.h> 20 : 21 : #if HAL_PROXIMITY_ENABLED 22 : 23 : #define PROXIMITY_ALT_DETECT_TIMEOUT_MS 500 // alt readings should arrive within this much time 24 : 25 : extern const AP_HAL::HAL& hal; 26 : 27 : // set alt as read from downward facing rangefinder. Tilt is already adjusted for. 28 1518828 : void AP_Proximity::set_rangefinder_alt(bool use, bool healthy, float alt_cm) 29 : { 30 1518828 : _rangefinder_state.use = use; 31 1518828 : _rangefinder_state.healthy = healthy; 32 1518828 : _rangefinder_state.alt_cm = alt_cm; 33 1518828 : _rangefinder_state.last_downward_update_ms = AP_HAL::millis(); 34 1518828 : } 35 : 36 : // get alt from rangefinder in meters 37 0 : bool AP_Proximity::get_rangefinder_alt(float &alt_m) const 38 : { 39 0 : if (!_rangefinder_state.use || !_rangefinder_state.healthy) { 40 : // range finder is not healthy 41 0 : return false; 42 : } 43 : 44 0 : const uint32_t dt = AP_HAL::millis() - _rangefinder_state.last_downward_update_ms; 45 0 : if (dt > PROXIMITY_ALT_DETECT_TIMEOUT_MS) { 46 0 : return false; 47 : } 48 : 49 : // readings are healthy 50 0 : alt_m = _rangefinder_state.alt_cm * 0.01f; 51 0 : return true; 52 : } 53 : 54 : // Check if Obstacle defined by body-frame yaw and pitch is near ground 55 429304 : bool AP_Proximity::check_obstacle_near_ground(float pitch, float yaw, float distance) const 56 : { 57 : #if !APM_BUILD_TYPE(APM_BUILD_AP_Periph) 58 429304 : if (!_ign_gnd_enable) { 59 429304 : return false; 60 : } 61 0 : if (!hal.util->get_soft_armed()) { 62 : // don't run this feature while vehicle is disarmed, otherwise proximity data will not show up on GCS 63 0 : return false; 64 : } 65 0 : if ((pitch > 90.0f) || (pitch < -90.0f)) { 66 : // sanity check on pitch 67 0 : return false; 68 : } 69 : // Assume object is yaw and pitch bearing and distance meters away from the vehicle 70 0 : Vector3f object_3D; 71 0 : object_3D.offset_bearing(wrap_180(yaw), (pitch * -1.0f), distance); 72 0 : const Matrix3f body_to_ned = AP::ahrs().get_rotation_body_to_ned(); 73 0 : const Vector3f rotated_object_3D = body_to_ned * object_3D; 74 : 75 0 : float alt = FLT_MAX; 76 0 : if (!get_rangefinder_alt(alt)) { 77 0 : return false; 78 : } 79 : 80 0 : if (rotated_object_3D.z > -0.5f) { 81 : // obstacle is at the most 0.5 meters above vehicle 82 0 : if ((alt - _alt_min_m) < rotated_object_3D.z) { 83 : // obstacle is near or below ground 84 0 : return true; 85 : } 86 : } 87 : #endif 88 0 : return false; 89 : } 90 : 91 : 92 : #endif // HAL_PROXIMITY_ENABLED