LCOV - code coverage report
Current view: top level - GCS_MAVLink - MissionItemProtocol_Rally.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 58 85 68.2 %
Date: 2026-09-09 11:02:08 Functions: 9 11 81.8 %

          Line data    Source code
       1             : /*
       2             :   Implementation details for transfering rally point information using
       3             :   the MISSION_ITEM protocol to and from a GCS.
       4             : 
       5             :   This program is free software: you can redistribute it and/or modify
       6             :   it under the terms of the GNU General Public License as published by
       7             :   the Free Software Foundation, either version 3 of the License, or
       8             :   (at your option) any later version.
       9             : 
      10             :   This program is distributed in the hope that it will be useful,
      11             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :   GNU General Public License for more details.
      14             : 
      15             :   You should have received a copy of the GNU General Public License
      16             :   along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17             : */
      18             : 
      19             : #include "GCS_config.h"
      20             : #include <AP_Rally/AP_Rally_config.h>
      21             : 
      22             : #if HAL_GCS_ENABLED && HAL_RALLY_ENABLED
      23             : 
      24             : #include "MissionItemProtocol_Rally.h"
      25             : 
      26             : #include <AP_Logger/AP_Logger.h>
      27             : #include <AP_Rally/AP_Rally.h>
      28             : #include <GCS_MAVLink/GCS.h>
      29             : #include <AP_Terrain/AP_Terrain.h>
      30             : 
      31           6 : MAV_MISSION_RESULT MissionItemProtocol_Rally::append_item(const mavlink_mission_item_int_t &cmd)
      32             : {
      33             :     RallyLocation rallyloc;
      34           6 :     const MAV_MISSION_RESULT ret = convert_MISSION_ITEM_INT_to_RallyLocation(cmd, rallyloc);
      35           6 :     if (ret != MAV_MISSION_ACCEPTED) {
      36           0 :         return ret;
      37             :     }
      38           6 :     if (!rally.append(rallyloc)) {
      39           0 :         return MAV_MISSION_ERROR;
      40             :     }
      41           6 :     return MAV_MISSION_ACCEPTED;
      42             : }
      43             : 
      44         886 : MAV_MISSION_RESULT MissionItemProtocol_Rally::complete(const GCS_MAVLINK &_link)
      45             : {
      46             : #if HAL_LOGGING_ENABLED
      47         886 :     AP::logger().Write_Rally();
      48             : #endif
      49         886 :     return MAV_MISSION_ACCEPTED;
      50             : }
      51             : 
      52           0 : bool MissionItemProtocol_Rally::clear_all_items()
      53             : {
      54           0 :     rally.truncate(0);
      55           0 :     return true;
      56             : }
      57             : 
      58           8 : MAV_MISSION_RESULT MissionItemProtocol_Rally::convert_MISSION_ITEM_INT_to_RallyLocation(const mavlink_mission_item_int_t &cmd, RallyLocation &ret)
      59             : {
      60           8 :     if (cmd.command != MAV_CMD_NAV_RALLY_POINT) {
      61           0 :         return MAV_MISSION_UNSUPPORTED;
      62             :     }
      63           8 :     if (!check_lat(cmd.x)) {
      64           0 :         return MAV_MISSION_INVALID_PARAM5_X;
      65             :     }
      66           8 :     if (!check_lng(cmd.y)) {
      67           0 :         return MAV_MISSION_INVALID_PARAM6_Y;
      68             :     }
      69           8 :     if (cmd.z < INT16_MIN || cmd.z > INT16_MAX) {
      70           0 :         return MAV_MISSION_INVALID_PARAM7;
      71             :     }
      72           8 :     ret = {};
      73             : 
      74           8 :     switch (cmd.frame) {
      75           2 :         case MAV_FRAME_GLOBAL:
      76             :         case MAV_FRAME_GLOBAL_INT:
      77           2 :             ret.alt_frame = uint8_t(Location::AltFrame::ABSOLUTE);
      78           2 :             break;
      79             : 
      80           6 :         case MAV_FRAME_GLOBAL_RELATIVE_ALT:
      81             :         case MAV_FRAME_GLOBAL_RELATIVE_ALT_INT:
      82           6 :             ret.alt_frame = uint8_t(Location::AltFrame::ABOVE_HOME);
      83           6 :             break;
      84             : 
      85             : #if AP_TERRAIN_AVAILABLE
      86           0 :         case MAV_FRAME_GLOBAL_TERRAIN_ALT:
      87             :         case MAV_FRAME_GLOBAL_TERRAIN_ALT_INT:
      88           0 :             ret.alt_frame = uint8_t(Location::AltFrame::ABOVE_TERRAIN);
      89           0 :             break;
      90             : #endif
      91             : 
      92           0 :         default:
      93           0 :             return MAV_MISSION_UNSUPPORTED_FRAME;
      94             :     }
      95             : 
      96             :     // Fresh points always use new alt frame format
      97           8 :     ret.alt_frame_valid = true;
      98             : 
      99           8 :     ret.lat = cmd.x;
     100           8 :     ret.lng = cmd.y;
     101           8 :     ret.alt = cmd.z;
     102           8 :     return MAV_MISSION_ACCEPTED;
     103             : }
     104             : 
     105             : /*
     106             :   static function to get rally item as mavlink_mission_item_int_t
     107             :  */
     108           5 : bool MissionItemProtocol_Rally::get_item_as_mission_item(uint16_t seq,
     109             :                                                          mavlink_mission_item_int_t &ret_packet)
     110             : {
     111           5 :     auto *rallyp = AP::rally();
     112             : 
     113             :     RallyLocation rallypoint;
     114             : 
     115           5 :     if (rallyp == nullptr || !rallyp->get_rally_point_with_index(seq, rallypoint)) {
     116           0 :         return false;
     117             :     }
     118             : 
     119             :     // Default to relative to home
     120           5 :     ret_packet = {
     121           5 :         x: rallypoint.lat,
     122           5 :         y: rallypoint.lng,
     123           5 :         z: float(rallypoint.alt),
     124             :         seq: seq,
     125             :         command: MAV_CMD_NAV_RALLY_POINT,
     126             :         frame: MAV_FRAME_GLOBAL_RELATIVE_ALT,
     127             :         mission_type: MAV_MISSION_TYPE_RALLY,
     128             :     };
     129             : 
     130           5 :     if (rallypoint.alt_frame_valid == 1) {
     131           5 :         switch (Location::AltFrame(rallypoint.alt_frame)) {
     132           2 :             case Location::AltFrame::ABSOLUTE:
     133           2 :                 ret_packet.frame = MAV_FRAME_GLOBAL;
     134           2 :                 break;
     135             : 
     136           3 :             case Location::AltFrame::ABOVE_HOME:
     137           3 :                 ret_packet.frame = MAV_FRAME_GLOBAL_RELATIVE_ALT;
     138           3 :                 break;
     139             : 
     140           0 :             case Location::AltFrame::ABOVE_ORIGIN:
     141             :                 // Above origin alt frame is not supported
     142           0 :                 return false;
     143             : 
     144           0 :             case Location::AltFrame::ABOVE_TERRAIN:
     145           0 :                 ret_packet.frame = MAV_FRAME_GLOBAL_TERRAIN_ALT;
     146           0 :                 break;
     147             :         }
     148             :     }
     149             : 
     150           5 :     return true;
     151             : }
     152             : 
     153           5 : MAV_MISSION_RESULT MissionItemProtocol_Rally::get_item(uint16_t seq, mavlink_mission_item_int_t &ret_packet)
     154             : {
     155           5 :     if (seq >= item_count()) {
     156           0 :         return MAV_MISSION_INVALID_SEQUENCE;
     157             :     }
     158             : 
     159           5 :     if (!get_item_as_mission_item(seq, ret_packet)) {
     160           0 :         return MAV_MISSION_INVALID_SEQUENCE;
     161             :     }
     162           5 :     return MAV_MISSION_ACCEPTED;
     163             : }
     164             : 
     165          17 : uint16_t MissionItemProtocol_Rally::item_count() const {
     166          17 :     return rally.get_rally_total();
     167             : }
     168             : 
     169         886 : uint16_t MissionItemProtocol_Rally::max_items() const {
     170         886 :     return rally.get_rally_max();
     171             : }
     172             : 
     173           2 : MAV_MISSION_RESULT MissionItemProtocol_Rally::replace_item(const mavlink_mission_item_int_t &cmd)
     174             : {
     175             :     RallyLocation rallyloc;
     176           2 :     const MAV_MISSION_RESULT ret = convert_MISSION_ITEM_INT_to_RallyLocation(cmd, rallyloc);
     177           2 :     if (ret != MAV_MISSION_ACCEPTED) {
     178           0 :         return ret;
     179             :     }
     180           2 :     if (!rally.set_rally_point_with_index(cmd.seq, rallyloc)) {
     181           0 :         return MAV_MISSION_ERROR;
     182             :     }
     183           2 :     return MAV_MISSION_ACCEPTED;
     184             : }
     185             : 
     186           0 : void MissionItemProtocol_Rally::timeout()
     187             : {
     188           0 :     link->send_text(MAV_SEVERITY_WARNING, "Rally upload timeout");
     189           0 : }
     190             : 
     191         886 : void MissionItemProtocol_Rally::truncate(const mavlink_mission_count_t &packet)
     192             : {
     193         886 :     rally.truncate(packet.count);
     194         886 : }
     195             : 
     196             : #endif  // HAL_GCS_ENABLED && HAL_RALLY_ENABLED

Generated by: LCOV version 1.14