LCOV - code coverage report
Current view: top level - AP_Terrain - TerrainMission.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 50 58 86.2 %
Date: 2026-09-09 11:02:08 Functions: 2 2 100.0 %

          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             :   handle checking mission points for terrain data
      17             :  */
      18             : 
      19             : #include "AP_Terrain.h"
      20             : 
      21             : #if AP_TERRAIN_AVAILABLE
      22             : 
      23             : #include <AP_HAL/AP_HAL.h>
      24             : #include <AP_Common/AP_Common.h>
      25             : #include <AP_Math/AP_Math.h>
      26             : #include <AP_Mission/AP_Mission.h>
      27             : #include <AP_Rally/AP_Rally.h>
      28             : #include <AP_GPS/AP_GPS.h>
      29             : 
      30             : extern const AP_HAL::HAL& hal;
      31             : 
      32             : /*
      33             :   check that we have fetched all mission terrain data
      34             :  */
      35     1293011 : void AP_Terrain::update_mission_data(void)
      36             : {
      37             : #if AP_MISSION_ENABLED
      38     1293011 :     const AP_Mission &mission = AP::mission();
      39             : 
      40     2582885 :     if (last_mission_change_ms != mission.last_change_time_ms() ||
      41     1289874 :         last_mission_spacing != grid_spacing) {
      42             :         // the mission has changed - start again
      43        3141 :         next_mission_index = 1;
      44        3141 :         next_mission_pos = 0;
      45        3141 :         last_mission_change_ms = mission.last_change_time_ms();
      46        3141 :         last_mission_spacing = grid_spacing;
      47             :     }
      48     1293011 :     if (next_mission_index == 0) {
      49             :         // nothing to do
      50     1292300 :         return;
      51             :     }
      52             : 
      53             :     uint16_t pending, loaded;
      54       76290 :     get_statistics(pending, loaded);
      55       76290 :     if (pending && AP::gps().status() >= AP_GPS_FixType::FIX_3D) {
      56             :         // wait till we have fully filled the current set of grids
      57       72525 :         return;
      58             :     }
      59             : 
      60             :     // don't do more than 20 waypoints at a time, to prevent too much
      61             :     // CPU usage
      62       22509 :     for (uint8_t i=0; i<20; i++) {
      63             :         // get next mission command
      64       21798 :         AP_Mission::Mission_Command cmd;
      65       21798 :         if (!mission.read_cmd_from_storage(next_mission_index, cmd)) {
      66             :             // nothing more to do
      67        2173 :             next_mission_index = 0;
      68        3054 :             return;
      69             :         }
      70             : 
      71             :         // we only want nav waypoint commands. That should be enough to
      72             :         // prefill the terrain data and makes many things much simpler
      73       19625 :         while ((cmd.id != MAV_CMD_NAV_WAYPOINT &&
      74       20879 :                 cmd.id != MAV_CMD_NAV_SPLINE_WAYPOINT) ||
      75       19251 :                (cmd.content.location.lat == 0 && cmd.content.location.lng == 0)) {
      76        1663 :             next_mission_index++;
      77        1663 :             if (!mission.read_cmd_from_storage(next_mission_index, cmd)) {
      78             :                 // nothing more to do
      79         409 :                 next_mission_index = 0;
      80         409 :                 next_mission_pos = 0;
      81         409 :                 return;
      82             :             }
      83             :         }
      84             : 
      85             :         // we will fetch 5 points around the waypoint. Four at 10 grid
      86             :         // spacings away at 45, 135, 225 and 315 degrees, and the
      87             :         // point itself
      88       19216 :         if (next_mission_pos != 4) {
      89       15465 :             cmd.content.location.offset_bearing(45+90*next_mission_pos, grid_spacing.get() * 10);
      90             :         }
      91             : 
      92             :         // we have a mission command to check
      93             :         float height;
      94       19216 :         if (!height_amsl(cmd.content.location, height)) {
      95             :             // if we can't get data for a mission item then return and
      96             :             // check again next time
      97         472 :             return;
      98             :         }
      99             : 
     100       18744 :         next_mission_pos++;
     101       18744 :         if (next_mission_pos == 5) {
     102             : #if TERRAIN_DEBUG
     103             :             hal.console->printf("checked waypoint %u\n", (unsigned)next_mission_index);
     104             : #endif
     105             : 
     106             :             // move to next waypoint
     107        3748 :             next_mission_index++;
     108        3748 :             next_mission_pos = 0;
     109             :         }
     110             :     }
     111             : #endif  // AP_MISSION_ENABLED
     112             : }
     113             : 
     114             : #if HAL_RALLY_ENABLED
     115             : /*
     116             :   check that we have fetched all rally terrain data
     117             :  */
     118     1293011 : void AP_Terrain::update_rally_data(void)
     119             : {
     120     1293011 :     const AP_Rally *rally = AP::rally();
     121     1293011 :     if (rally == nullptr) {
     122           0 :         return;
     123             :     }
     124             : 
     125     2584331 :     if (last_rally_change_ms != rally->last_change_time_ms() ||
     126     1291320 :         last_rally_spacing != grid_spacing) {
     127             :         // a rally point has changed - start again
     128        1695 :         next_rally_index = 1;
     129        1695 :         last_rally_change_ms = rally->last_change_time_ms();
     130        1695 :         last_rally_spacing = grid_spacing;
     131             :     }
     132     1293011 :     if (next_rally_index == 0) {
     133             :         // nothing to do
     134     1291082 :         return;
     135             :     }
     136             : 
     137             :     uint16_t pending, loaded;
     138        1929 :     get_statistics(pending, loaded);
     139        1929 :     if (pending && AP::gps().status() >= AP_GPS_FixType::FIX_3D) {
     140             :         // wait till we have fully filled the current set of grids
     141         236 :         return;
     142             :     }
     143             : 
     144             :     while (true) {
     145             :         // get next rally point
     146             :         struct RallyLocation rp;
     147        1693 :         if (!rally->get_rally_point_with_index(next_rally_index, rp)) {
     148             :             // nothing more to do
     149        1693 :             next_rally_index = 0;
     150        1693 :             return;
     151             :         }
     152             : 
     153           0 :         Location loc;
     154           0 :         loc.lat = rp.lat;
     155           0 :         loc.lng = rp.lng;
     156             :         float height;
     157           0 :         if (!height_amsl(loc, height)) {
     158             :             // if we can't get data for a rally item then return and
     159             :             // check again next time
     160           0 :             return;
     161             :         }
     162             : 
     163             : #if TERRAIN_DEBUG
     164             :         hal.console->printf("checked rally point %u\n", (unsigned)next_rally_index);
     165             : #endif
     166             : 
     167             :         // move to next rally point
     168           0 :         next_rally_index++;
     169           0 :     }
     170             : }
     171             : #endif
     172             : 
     173             : #endif // AP_TERRAIN_AVAILABLE

Generated by: LCOV version 1.14