LCOV - code coverage report
Current view: top level - AP_AIS - AP_AIS_Vessel.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 62 82 75.6 %
Date: 2026-09-09 11:02:08 Functions: 9 9 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             : // Automatic Identification System, https://gpsd.gitlab.io/gpsd/AIVDM.html
      17             : 
      18             : #include "AP_AIS.h"
      19             : 
      20             : #if AP_AIS_ENABLED
      21             : 
      22             : #include <AP_Math/AP_Math.h>
      23             : 
      24             : // Reset vessel to default unknown state
      25          13 : void AP_AIS::ais_vehicle_t::reset()
      26             : {
      27             :     // Set to values for invalid in MAVLink spec
      28          13 :     memset(this, 0, sizeof(*this));
      29          13 :     info.lat                 = INT32_MAX;
      30          13 :     info.lon                 = INT32_MAX;
      31          13 :     info.COG                 = UINT16_MAX;
      32          13 :     info.heading             = UINT16_MAX;
      33          13 :     info.velocity            = UINT16_MAX;
      34          13 :     info.dimension_bow       = UINT16_MAX;
      35          13 :     info.dimension_stern     = UINT16_MAX;
      36          13 :     info.turn_rate           = INT8_MAX;
      37          13 :     info.navigational_status = AIS_NAV_STATUS::AIS_NAV_STATUS_UNKNOWN;
      38          13 :     info.type                = AIS_TYPE::AIS_TYPE_UNKNOWN;
      39          13 :     info.dimension_port      = UINT8_MAX;
      40          13 :     info.dimension_starboard = UINT8_MAX;
      41          13 : }
      42             : 
      43             : // Apply dimensions to a vessel
      44             : // All dimensions are in meters from the provided location
      45          13 : void AP_AIS::ais_vehicle_t::set_dimensions(uint16_t bow, uint16_t stern, uint8_t port, uint8_t star)
      46             : {
      47          13 :     if (bow == 0 || stern == 0 || port == 0 || star == 0) {
      48             :         // Incoming dimensions are not valid
      49             :         // Never clear existing dimensions
      50           1 :         return;
      51             :     }
      52             : 
      53             :     // Set valid dimensions flag
      54          12 :     info.flags |= AIS_FLAGS_VALID_DIMENSIONS;
      55             : 
      56             :     // clear large dimension flags
      57          12 :     const uint16_t mask = ~(AIS_FLAGS_LARGE_BOW_DIMENSION | AIS_FLAGS_LARGE_STERN_DIMENSION | AIS_FLAGS_LARGE_PORT_DIMENSION | AIS_FLAGS_LARGE_STARBOARD_DIMENSION);
      58          12 :     info.flags &= mask; 
      59             : 
      60             :     // Set large dimension flags
      61          12 :     if (bow == 511) {
      62           1 :         info.flags |= AIS_FLAGS_LARGE_BOW_DIMENSION;
      63             :     }
      64          12 :     if (stern == 511) {
      65           2 :         info.flags |= AIS_FLAGS_LARGE_STERN_DIMENSION;
      66             :     }
      67          12 :     if (port == 63) {
      68           0 :         info.flags |= AIS_FLAGS_LARGE_PORT_DIMENSION;
      69             :     }
      70          12 :     if (star == 63) {
      71           2 :         info.flags |= AIS_FLAGS_LARGE_STARBOARD_DIMENSION;
      72             :     }
      73             : 
      74             :     // Set values
      75          12 :     info.dimension_bow = bow;
      76          12 :     info.dimension_stern = stern;
      77          12 :     info.dimension_port = port;
      78          12 :     info.dimension_starboard = star;
      79             : }
      80             : 
      81             : // Apply course over ground to a vessel
      82             : // cog in cdeg
      83          45 : void AP_AIS::ais_vehicle_t::set_cog(uint16_t cog)
      84             : {
      85          45 :     if (cog < 36000) {
      86             :         // Valid
      87           0 :         info.flags |= AIS_FLAGS_VALID_COG;
      88           0 :         info.COG = cog;
      89           0 :         return;
      90             :     }
      91             : 
      92             :     // Invalid
      93          45 :     info.flags &= ~AIS_FLAGS_VALID_COG;
      94          45 :     info.COG = UINT16_MAX;
      95             : }
      96             : 
      97             : // Apply speed over ground to a vessel
      98             : // sog in 0.1 Knots
      99          45 : void AP_AIS::ais_vehicle_t::set_sog(uint16_t sog)
     100             : {
     101          45 :     if (sog >= 1023) {
     102             :         // Invalid
     103           0 :         info.flags &= ~(AIS_FLAGS_VALID_VELOCITY | AIS_FLAGS_HIGH_VELOCITY);
     104           0 :         info.velocity = UINT16_MAX;
     105           0 :         return;
     106             :     }
     107             : 
     108             :     // Valid
     109          45 :     info.flags |= AIS_FLAGS_VALID_VELOCITY;
     110             : 
     111             :     // More than 102.2 knots, don't know by how much
     112          45 :     if (sog == 1022) {
     113           0 :         info.flags |= AIS_FLAGS_HIGH_VELOCITY;
     114             :     } else {
     115          45 :         info.flags &= ~AIS_FLAGS_HIGH_VELOCITY;
     116             :     }
     117             : 
     118             :     // Convert 0.1 knots to cm/s
     119          45 :     info.velocity = sog * 0.1 * KNOTS_TO_M_PER_SEC * 100.0;
     120             : 
     121             : }
     122             : 
     123             : // Apply position accuracy flag to a vessel
     124          45 : void AP_AIS::ais_vehicle_t::set_pos_acc(bool pos_acc)
     125             : {
     126          45 :     if (pos_acc) {
     127           0 :         info.flags |= AIS_FLAGS_POSITION_ACCURACY;
     128           0 :         return;
     129             :     }
     130             : 
     131          45 :     info.flags &= ~AIS_FLAGS_POSITION_ACCURACY;
     132             : }
     133             : 
     134             : // Apply rate of turn to a vessel
     135             : // rot in none standard units!
     136          45 : void AP_AIS::ais_vehicle_t::set_rot(int8_t rot)
     137             : {
     138          45 :     if (rot <= -128) {
     139             :         // Invalid
     140           0 :         info.flags &= ~(AIS_FLAGS_VALID_TURN_RATE | AIS_FLAGS_TURN_RATE_SIGN_ONLY);
     141           0 :         info.turn_rate = INT8_MAX;
     142           0 :         return;
     143             :     }
     144             : 
     145             :     // Valid value
     146          45 :     info.flags |= AIS_FLAGS_VALID_TURN_RATE;
     147          45 :     const int8_t sign = rot > 0 ? 1 : -1;
     148          45 :     if (rot == 127 || rot == -127) {
     149           0 :         info.flags |= AIS_FLAGS_TURN_RATE_SIGN_ONLY;
     150           0 :         info.turn_rate = sign;
     151           0 :         return;
     152             :     }
     153             : 
     154             :     // Apply expo formula and convert from deg per min to cdeg per second
     155             :     // constrain to avoid overflow, probably need to change the units or increase to int16
     156          45 :     info.turn_rate = sign * MIN(sq(rot / 4.733) * (100.0 / 60.0), INT8_MAX - 1);
     157             : }
     158             : 
     159             : // Set true heading of vessel
     160             : // heading in centi-degrees
     161          45 : void AP_AIS::ais_vehicle_t::set_heading(uint16_t heading)
     162             : {
     163          45 :     if (heading < 360 * 100) {
     164             :         // Valid
     165          45 :         info.heading = heading;
     166          45 :         return;
     167             :     }
     168             : 
     169             :     // Invalid
     170           0 :     info.heading = UINT16_MAX;
     171             : }
     172             : 
     173             : // Set call sign of vessel
     174          13 : void AP_AIS::ais_vehicle_t::set_callsign(const char* callsign)
     175             : {
     176          13 :     if (strlen(callsign) == 0) {
     177             :         // Never clear call sign
     178           0 :         return;
     179             :     }
     180             : 
     181          13 :     info.flags |= AIS_FLAGS_VALID_CALLSIGN;
     182          13 :     memcpy(info.callsign, callsign, sizeof(info.callsign));
     183             : }
     184             : 
     185             : // Set name of vessel
     186          13 : void AP_AIS::ais_vehicle_t::set_name(const char* name)
     187             : {
     188          13 :     if (strlen(name) == 0) {
     189             :         // Never clear name
     190          13 :         return;
     191             :     }
     192             : 
     193           0 :     info.flags |= AIS_FLAGS_VALID_NAME;
     194           0 :     memcpy(info.name, name, sizeof(info.name));
     195             : }
     196             : 
     197             : #endif  // AP_AIS_ENABLED

Generated by: LCOV version 1.14