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_config.h" 17 : 18 : #if AP_PROXIMITY_AIRSIMSITL_ENABLED 19 : 20 : #include "AP_Proximity_AirSimSITL.h" 21 : 22 : #define PROXIMITY_MAX_RANGE 100.0f 23 : #define PROXIMITY_ACCURACY 0.1f // minimum distance (in meters) between objects sent to object database 24 : 25 : // update the state of the sensor 26 0 : void AP_Proximity_AirSimSITL::update(void) 27 : { 28 0 : SITL::vector3f_array &points = sitl->state.scanner.points; 29 0 : if (points.length == 0) { 30 0 : set_status(AP_Proximity::Status::NoData); 31 0 : return; 32 : } 33 : 34 0 : set_status(AP_Proximity::Status::Good); 35 : 36 : // reset all faces to default so that it can be filled with the fresh lidar data 37 0 : frontend.boundary.reset(); 38 : 39 : // precalculate sq of min distance 40 0 : const float distance_min_sq = sq(distance_min_m()); 41 : 42 : // variables used to reduce data sent to object database 43 0 : const float accuracy_sq = sq(PROXIMITY_ACCURACY); 44 0 : bool prev_pos_valid = false; 45 0 : Vector2f prev_pos; 46 : // clear temp boundary since we have a new message 47 0 : temp_boundary.reset(); 48 : 49 0 : for (uint16_t i=0; i<points.length; i++) { 50 0 : Vector3f &point = points.data[i]; 51 0 : if (point.is_zero()) { 52 0 : continue; 53 : } 54 : 55 : // calculate distance to point and check larger than min distance 56 0 : const Vector2f new_pos = Vector2f{point.x, point.y}; 57 0 : const float distance_sq = new_pos.length_squared(); 58 0 : if (distance_sq > distance_min_sq) { 59 : 60 : // add distance to the 3D boundary 61 0 : const float yaw_angle_deg = wrap_360(degrees(atan2f(point.y, point.x))); 62 0 : const AP_Proximity_Boundary_3D::Face face = frontend.boundary.get_face(yaw_angle_deg); 63 : // store the min distance in each face in a temp boundary 64 0 : temp_boundary.add_distance(face, yaw_angle_deg, safe_sqrt(distance_sq)); 65 : 66 : // check distance from previous point to reduce amount of data sent to object database 67 0 : if (!prev_pos_valid || ((new_pos - prev_pos).length_squared() >= accuracy_sq)) { 68 : // update OA database 69 0 : database_push(yaw_angle_deg, safe_sqrt(distance_sq)); 70 : // store point 71 0 : prev_pos_valid = true; 72 0 : prev_pos = new_pos; 73 : } 74 : } 75 : } 76 : // copy temp boundary to real boundary 77 0 : temp_boundary.update_3D_boundary(state.instance, frontend.boundary); 78 : } 79 : 80 : // get maximum and minimum distances (in meters) of primary sensor 81 0 : float AP_Proximity_AirSimSITL::distance_max_m() const 82 : { 83 0 : return PROXIMITY_MAX_RANGE; 84 : } 85 : 86 0 : float AP_Proximity_AirSimSITL::distance_min_m() const 87 : { 88 0 : return 0.0f; 89 : } 90 : 91 : // get distance upwards in meters. returns true on success 92 0 : bool AP_Proximity_AirSimSITL::get_upward_distance(float &distance) const 93 : { 94 : // we don't have an upward facing laser 95 0 : return false; 96 : } 97 : 98 : #endif // AP_PROXIMITY_AIRSIMSITL_ENABLED