text: // WARNING: THIS FILE IS AUTOGENERATED! As such, it should not be edited.
  // Edits need to be made to the proto files
  // (see https://github.com/mavlink/MAVSDK-Proto/blob/main/protos/telemetry/telemetry.proto)
  
  #pragma once
  
  #include <array>
  #include <cmath>
  #include <functional>
  #include <limits>
  #include <memory>
  #include <string>
  #include <utility>
  #include <vector>
  
  #include "mavsdk/plugin_base.h"
  
  namespace mavsdk {
  
  class System;
  class TelemetryImpl;
  
  /**
   * @brief Allow users to get vehicle telemetry and state information
   * (e.g. battery, GPS, RC connection, flight mode etc.) and set telemetry update rates.
   */
  class Telemetry : public PluginBase {
  public:
      /**
       * @brief Constructor. Creates the plugin for a specific System.
       *
       * The plugin is typically created as shown below:
       *
       *     ```cpp
       *     auto telemetry = Telemetry(system);
       *     ```
       *
       * @param system The specific system associated with this plugin.
       */
      explicit Telemetry(System& system); // deprecated
  
      /**
       * @brief Constructor. Creates the plugin for a specific System.
       *
       * The plugin is typically created as shown below:
       *
       *     ```cpp
       *     auto telemetry = Telemetry(system);
       *     ```
       *
       * @param system The specific system associated with this plugin.
       */
      explicit Telemetry(std::shared_ptr<System> system); // new
  
      /**
       * @brief Destructor (internal use only).
       */
      ~Telemetry();
  
      /**
       * @brief GPS fix type.
       */
      enum class FixType {
          NoGps, /**< @brief No GPS connected. */
          NoFix, /**< @brief No position information, GPS is connected. */
          Fix2D, /**< @brief 2D position. */
          Fix3D, /**< @brief 3D position. */
          FixDgps, /**< @brief DGPS/SBAS aided 3D position. */
          RtkFloat, /**< @brief RTK float, 3D position. */
          RtkFixed, /**< @brief RTK Fixed, 3D position. */
      };
  
      /**
       * @brief Stream operator to print information about a `Telemetry::FixType`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::FixType const& fix_type);
  
      /**
       * @brief Flight modes.
       *
       * For more information about flight modes, check out
       * https://docs.px4.io/master/en/config/flight_mode.html.
       */
      enum class FlightMode {
          Unknown, /**< @brief Mode not known. */
          Ready, /**< @brief Armed and ready to take off. */
          Takeoff, /**< @brief Taking off. */
          Hold, /**< @brief Holding (hovering in place (or circling for fixed-wing vehicles). */
          Mission, /**< @brief In mission. */
          ReturnToLaunch, /**< @brief Returning to launch position (then landing). */
          Land, /**< @brief Landing. */
          Offboard, /**< @brief In 'offboard' mode. */
          FollowMe, /**< @brief In 'follow-me' mode. */
          Manual, /**< @brief In 'Manual' mode. */
          Altctl, /**< @brief In 'Altitude Control' mode. */
          Posctl, /**< @brief In 'Position Control' mode. */
          Acro, /**< @brief In 'Acro' mode. */
          Stabilized, /**< @brief In 'Stabilize' mode. */
          Rattitude, /**< @brief In 'Rattitude' mode. */
      };
  
      /**
       * @brief Stream operator to print information about a `Telemetry::FlightMode`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::FlightMode const& flight_mode);
  
      /**
       * @brief Status types.
       */
      enum class StatusTextType {
          Debug, /**< @brief Debug. */
          Info, /**< @brief Information. */
          Notice, /**< @brief Notice. */
          Warning, /**< @brief Warning. */
          Error, /**< @brief Error. */
          Critical, /**< @brief Critical. */
          Alert, /**< @brief Alert. */
          Emergency, /**< @brief Emergency. */
      };
  
      /**
       * @brief Stream operator to print information about a `Telemetry::StatusTextType`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::StatusTextType const& status_text_type);
  
      /**
       * @brief Landed State enumeration.
       */
      enum class LandedState {
          Unknown, /**< @brief Landed state is unknown. */
          OnGround, /**< @brief The vehicle is on the ground. */
          InAir, /**< @brief The vehicle is in the air. */
          TakingOff, /**< @brief The vehicle is taking off. */
          Landing, /**< @brief The vehicle is landing. */
      };
  
      /**
       * @brief Stream operator to print information about a `Telemetry::LandedState`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::LandedState const& landed_state);
  
      /**
       * @brief VTOL State enumeration
       */
      enum class VtolState {
          Undefined, /**< @brief MAV is not configured as VTOL. */
          TransitionToFw, /**< @brief VTOL is in transition from multicopter to fixed-wing. */
          TransitionToMc, /**< @brief VTOL is in transition from fixed-wing to multicopter. */
          Mc, /**< @brief VTOL is in multicopter state. */
          Fw, /**< @brief VTOL is in fixed-wing state. */
      };
  
      /**
       * @brief Stream operator to print information about a `Telemetry::VtolState`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::VtolState const& vtol_state);
  
      /**
       * @brief Position type in global coordinates.
       */
      struct Position {
          double latitude_deg{double(NAN)}; /**< @brief Latitude in degrees (range: -90 to +90) */
          double longitude_deg{double(NAN)}; /**< @brief Longitude in degrees (range: -180 to +180) */
          float absolute_altitude_m{
              float(NAN)}; /**< @brief Altitude AMSL (above mean sea level) in metres */
          float relative_altitude_m{
              float(NAN)}; /**< @brief Altitude relative to takeoff altitude in metres */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::Position` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::Position& lhs, const Telemetry::Position& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Position`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Position const& position);
  
      /**
       * @brief Heading type used for global position
       */
      struct Heading {
          double heading_deg{double(NAN)}; /**< @brief Heading in degrees (range: 0 to +360) */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::Heading` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::Heading& lhs, const Telemetry::Heading& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Heading`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Heading const& heading);
  
      /**
       * @brief Quaternion type.
       *
       * All rotations and axis systems follow the right-hand rule.
       * The Hamilton quaternion product definition is used.
       * A zero-rotation quaternion is represented by (1,0,0,0).
       * The quaternion could also be written as w + xi + yj + zk.
       *
       * For more info see: https://en.wikipedia.org/wiki/Quaternion
       */
      struct Quaternion {
          float w{float(NAN)}; /**< @brief Quaternion entry 0, also denoted as a */
          float x{float(NAN)}; /**< @brief Quaternion entry 1, also denoted as b */
          float y{float(NAN)}; /**< @brief Quaternion entry 2, also denoted as c */
          float z{float(NAN)}; /**< @brief Quaternion entry 3, also denoted as d */
          uint64_t timestamp_us{}; /**< @brief Timestamp in microseconds */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::Quaternion` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::Quaternion& lhs, const Telemetry::Quaternion& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Quaternion`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Quaternion const& quaternion);
  
      /**
       * @brief Euler angle type.
       *
       * All rotations and axis systems follow the right-hand rule.
       * The Euler angles follow the convention of a 3-2-1 intrinsic Tait-Bryan rotation sequence.
       *
       * For more info see https://en.wikipedia.org/wiki/Euler_angles
       */
      struct EulerAngle {
          float roll_deg{
              float(NAN)}; /**< @brief Roll angle in degrees, positive is banking to the right */
          float pitch_deg{
              float(NAN)}; /**< @brief Pitch angle in degrees, positive is pitching nose up */
          float yaw_deg{
              float(NAN)}; /**< @brief Yaw angle in degrees, positive is clock-wise seen from above */
          uint64_t timestamp_us{}; /**< @brief Timestamp in microseconds */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::EulerAngle` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::EulerAngle& lhs, const Telemetry::EulerAngle& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::EulerAngle`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::EulerAngle const& euler_angle);
  
      /**
       * @brief Angular velocity type.
       */
      struct AngularVelocityBody {
          float roll_rad_s{float(NAN)}; /**< @brief Roll angular velocity */
          float pitch_rad_s{float(NAN)}; /**< @brief Pitch angular velocity */
          float yaw_rad_s{float(NAN)}; /**< @brief Yaw angular velocity */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::AngularVelocityBody` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(
          const Telemetry::AngularVelocityBody& lhs, const Telemetry::AngularVelocityBody& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::AngularVelocityBody`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::AngularVelocityBody const& angular_velocity_body);
  
      /**
       * @brief GPS information type.
       */
      struct GpsInfo {
          int32_t num_satellites{0}; /**< @brief Number of visible satellites in use */
          FixType fix_type{}; /**< @brief Fix type */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::GpsInfo` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::GpsInfo& lhs, const Telemetry::GpsInfo& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::GpsInfo`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::GpsInfo const& gps_info);
  
      /**
       * @brief Raw GPS information type.
       *
       * Warning: this is an advanced type! If you want the location of the drone, use
       * the position instead. This message exposes the raw values of the GNSS sensor.
       */
      struct RawGps {
          uint64_t timestamp_us{}; /**< @brief Timestamp in microseconds (UNIX Epoch time or time
                                      since system boot, to be inferred) */
          double latitude_deg{}; /**< @brief Latitude in degrees (WGS84, EGM96 ellipsoid) */
          double longitude_deg{}; /**< @brief Longitude in degrees (WGS84, EGM96 ellipsoid) */
          float absolute_altitude_m{}; /**< @brief Altitude AMSL (above mean sea level) in metres */
          float hdop{}; /**< @brief GPS HDOP horizontal dilution of position (unitless). If unknown,
                           set to NaN */
          float vdop{}; /**< @brief GPS VDOP vertical dilution of position (unitless). If unknown, set
                           to NaN */
          float velocity_m_s{}; /**< @brief Ground velocity in metres per second */
          float cog_deg{}; /**< @brief Course over ground (NOT heading, but direction of movement) in
                              degrees. If unknown, set to NaN */
          float
              altitude_ellipsoid_m{}; /**< @brief Altitude in metres (above WGS84, EGM96 ellipsoid) */
          float horizontal_uncertainty_m{}; /**< @brief Position uncertainty in metres */
          float vertical_uncertainty_m{}; /**< @brief Altitude uncertainty in metres */
          float velocity_uncertainty_m_s{}; /**< @brief Velocity uncertainty in metres per second */
          float heading_uncertainty_deg{}; /**< @brief Heading uncertainty in degrees */
          float yaw_deg{}; /**< @brief Yaw in earth frame from north. */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::RawGps` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::RawGps& lhs, const Telemetry::RawGps& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::RawGps`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::RawGps const& raw_gps);
  
      /**
       * @brief Battery type.
       */
      struct Battery {
          uint32_t id{0}; /**< @brief Battery ID, for systems with multiple batteries */
          float voltage_v{float(NAN)}; /**< @brief Voltage in volts */
          float remaining_percent{
              float(NAN)}; /**< @brief Estimated battery remaining (range: 0.0 to 1.0) */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::Battery` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::Battery& lhs, const Telemetry::Battery& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Battery`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Battery const& battery);
  
      /**
       * @brief Health type.
       */
      struct Health {
          bool is_gyrometer_calibration_ok{false}; /**< @brief True if the gyrometer is calibrated */
          bool is_accelerometer_calibration_ok{
              false}; /**< @brief True if the accelerometer is calibrated */
          bool is_magnetometer_calibration_ok{
              false}; /**< @brief True if the magnetometer is calibrated */
          bool is_local_position_ok{false}; /**< @brief True if the local position estimate is good
                                               enough to fly in 'position control' mode */
          bool is_global_position_ok{false}; /**< @brief True if the global position estimate is good
                                                enough to fly in 'position control' mode */
          bool is_home_position_ok{
              false}; /**< @brief True if the home position has been initialized properly */
          bool is_armable{false}; /**< @brief True if system can be armed */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::Health` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::Health& lhs, const Telemetry::Health& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Health`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Health const& health);
  
      /**
       * @brief Remote control status type.
       */
      struct RcStatus {
          bool was_available_once{false}; /**< @brief True if an RC signal has been available once */
          bool is_available{false}; /**< @brief True if the RC signal is available now */
          float signal_strength_percent{
              float(NAN)}; /**< @brief Signal strength (range: 0 to 100, NaN if unknown) */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::RcStatus` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::RcStatus& lhs, const Telemetry::RcStatus& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::RcStatus`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::RcStatus const& rc_status);
  
      /**
       * @brief StatusText information type.
       */
      struct StatusText {
          StatusTextType type{}; /**< @brief Message type */
          std::string text{}; /**< @brief MAVLink status message */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::StatusText` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::StatusText& lhs, const Telemetry::StatusText& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::StatusText`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::StatusText const& status_text);
  
      /**
       * @brief Actuator control target type.
       */
      struct ActuatorControlTarget {
          int32_t group{0}; /**< @brief An actuator control group is e.g. 'attitude' for the core
                               flight controls, or 'gimbal' for a payload. */
          std::vector<float>
              controls{}; /**< @brief Controls normed from -1 to 1, where 0 is neutral position. */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::ActuatorControlTarget` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(
          const Telemetry::ActuatorControlTarget& lhs, const Telemetry::ActuatorControlTarget& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::ActuatorControlTarget`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::ActuatorControlTarget const& actuator_control_target);
  
      /**
       * @brief Actuator output status type.
       */
      struct ActuatorOutputStatus {
          uint32_t active{0}; /**< @brief Active outputs */
          std::vector<float> actuator{}; /**< @brief Servo/motor output values */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::ActuatorOutputStatus` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(
          const Telemetry::ActuatorOutputStatus& lhs, const Telemetry::ActuatorOutputStatus& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::ActuatorOutputStatus`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::ActuatorOutputStatus const& actuator_output_status);
  
      /**
       * @brief Covariance type.
       *
       * Row-major representation of a 6x6 cross-covariance matrix
       * upper right triangle.
       * Set first to NaN if unknown.
       */
      struct Covariance {
          std::vector<float>
              covariance_matrix{}; /**< @brief Representation of a covariance matrix. */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::Covariance` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::Covariance& lhs, const Telemetry::Covariance& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Covariance`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Covariance const& covariance);
  
      /**
       * @brief Velocity type, represented in the Body (X Y Z) frame and in metres/second.
       */
      struct VelocityBody {
          float x_m_s{}; /**< @brief Velocity in X in metres/second */
          float y_m_s{}; /**< @brief Velocity in Y in metres/second */
          float z_m_s{}; /**< @brief Velocity in Z in metres/second */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::VelocityBody` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::VelocityBody& lhs, const Telemetry::VelocityBody& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::VelocityBody`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::VelocityBody const& velocity_body);
  
      /**
       * @brief Position type, represented in the Body (X Y Z) frame
       */
      struct PositionBody {
          float x_m{}; /**< @brief X Position in metres. */
          float y_m{}; /**< @brief Y Position in metres. */
          float z_m{}; /**< @brief Z Position in metres. */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::PositionBody` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::PositionBody& lhs, const Telemetry::PositionBody& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::PositionBody`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::PositionBody const& position_body);
  
      /**
       * @brief Odometry message type.
       */
      struct Odometry {
          /**
           * @brief Mavlink frame id
           */
          enum class MavFrame {
              Undef, /**< @brief Frame is undefined.. */
              BodyNed, /**< @brief Setpoint in body NED frame. This makes sense if all position
                          control is externalized - e.g. useful to command 2 m/s^2 acceleration to the
                          right.. */
              VisionNed, /**< @brief Odometry local coordinate frame of data given by a vision
                            estimation system, Z-down (x: north, y: east, z: down).. */
              EstimNed, /**< @brief Odometry local coordinate frame of data given by an estimator
                           running onboard the vehicle, Z-down (x: north, y: east, z: down).. */
          };
  
          /**
           * @brief Stream operator to print information about a `Telemetry::MavFrame`.
           *
           * @return A reference to the stream.
           */
          friend std::ostream&
          operator<<(std::ostream& str, Telemetry::Odometry::MavFrame const& mav_frame);
  
          uint64_t time_usec{}; /**< @brief Timestamp (0 to use Backend timestamp). */
          MavFrame frame_id{}; /**< @brief Coordinate frame of reference for the pose data. */
          MavFrame child_frame_id{}; /**< @brief Coordinate frame of reference for the velocity in
                                        free space (twist) data. */
          PositionBody position_body{}; /**< @brief Position. */
          Quaternion
              q{}; /**< @brief Quaternion components, w, x, y, z (1 0 0 0 is the null-rotation). */
          VelocityBody velocity_body{}; /**< @brief Linear velocity (m/s). */
          AngularVelocityBody angular_velocity_body{}; /**< @brief Angular velocity (rad/s). */
          Covariance pose_covariance{}; /**< @brief Pose cross-covariance matrix. */
          Covariance velocity_covariance{}; /**< @brief Velocity cross-covariance matrix. */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::Odometry` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::Odometry& lhs, const Telemetry::Odometry& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Odometry`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Odometry const& odometry);
  
      /**
       * @brief DistanceSensor message type.
       */
      struct DistanceSensor {
          float minimum_distance_m{
              float(NAN)}; /**< @brief Minimum distance the sensor can measure, NaN if unknown. */
          float maximum_distance_m{
              float(NAN)}; /**< @brief Maximum distance the sensor can measure, NaN if unknown. */
          float current_distance_m{
              float(NAN)}; /**< @brief Current distance reading, NaN if unknown. */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::DistanceSensor` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool
      operator==(const Telemetry::DistanceSensor& lhs, const Telemetry::DistanceSensor& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::DistanceSensor`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::DistanceSensor const& distance_sensor);
  
      /**
       * @brief Scaled Pressure message type.
       */
      struct ScaledPressure {
          uint64_t timestamp_us{}; /**< @brief Timestamp (time since system boot) */
          float absolute_pressure_hpa{}; /**< @brief Absolute pressure in hPa */
          float differential_pressure_hpa{}; /**< @brief Differential pressure 1 in hPa */
          float temperature_deg{}; /**< @brief Absolute pressure temperature (in celsius) */
          float differential_pressure_temperature_deg{}; /**< @brief Differential pressure temperature
                                                            (in celsius, 0 if not available) */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::ScaledPressure` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool
      operator==(const Telemetry::ScaledPressure& lhs, const Telemetry::ScaledPressure& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::ScaledPressure`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::ScaledPressure const& scaled_pressure);
  
      /**
       * @brief PositionNed message type.
       */
      struct PositionNed {
          float north_m{float(NAN)}; /**< @brief Position along north direction in metres */
          float east_m{float(NAN)}; /**< @brief Position along east direction in metres */
          float down_m{float(NAN)}; /**< @brief Position along down direction in metres */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::PositionNed` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::PositionNed& lhs, const Telemetry::PositionNed& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::PositionNed`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::PositionNed const& position_ned);
  
      /**
       * @brief VelocityNed message type.
       */
      struct VelocityNed {
          float north_m_s{}; /**< @brief Velocity along north direction in metres per second */
          float east_m_s{}; /**< @brief Velocity along east direction in metres per second */
          float down_m_s{}; /**< @brief Velocity along down direction in metres per second */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::VelocityNed` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::VelocityNed& lhs, const Telemetry::VelocityNed& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::VelocityNed`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::VelocityNed const& velocity_ned);
  
      /**
       * @brief PositionVelocityNed message type.
       */
      struct PositionVelocityNed {
          PositionNed position{}; /**< @brief Position (NED) */
          VelocityNed velocity{}; /**< @brief Velocity (NED) */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::PositionVelocityNed` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(
          const Telemetry::PositionVelocityNed& lhs, const Telemetry::PositionVelocityNed& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::PositionVelocityNed`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::PositionVelocityNed const& position_velocity_ned);
  
      /**
       * @brief GroundTruth message type.
       */
      struct GroundTruth {
          double latitude_deg{double(NAN)}; /**< @brief Latitude in degrees (range: -90 to +90) */
          double longitude_deg{double(NAN)}; /**< @brief Longitude in degrees (range: -180 to 180) */
          float absolute_altitude_m{
              float(NAN)}; /**< @brief Altitude AMSL (above mean sea level) in metres */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::GroundTruth` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::GroundTruth& lhs, const Telemetry::GroundTruth& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::GroundTruth`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::GroundTruth const& ground_truth);
  
      /**
       * @brief FixedwingMetrics message type.
       */
      struct FixedwingMetrics {
          float airspeed_m_s{
              float(NAN)}; /**< @brief Current indicated airspeed (IAS) in metres per second */
          float throttle_percentage{float(NAN)}; /**< @brief Current throttle setting (0 to 100) */
          float climb_rate_m_s{float(NAN)}; /**< @brief Current climb rate in metres per second */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::FixedwingMetrics` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool
      operator==(const Telemetry::FixedwingMetrics& lhs, const Telemetry::FixedwingMetrics& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::FixedwingMetrics`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::FixedwingMetrics const& fixedwing_metrics);
  
      /**
       * @brief AccelerationFrd message type.
       */
      struct AccelerationFrd {
          float forward_m_s2{
              float(NAN)}; /**< @brief Acceleration in forward direction in metres per second^2 */
          float right_m_s2{
              float(NAN)}; /**< @brief Acceleration in right direction in metres per second^2 */
          float down_m_s2{
              float(NAN)}; /**< @brief Acceleration in down direction in metres per second^2 */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::AccelerationFrd` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool
      operator==(const Telemetry::AccelerationFrd& lhs, const Telemetry::AccelerationFrd& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::AccelerationFrd`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::AccelerationFrd const& acceleration_frd);
  
      /**
       * @brief AngularVelocityFrd message type.
       */
      struct AngularVelocityFrd {
          float forward_rad_s{
              float(NAN)}; /**< @brief Angular velocity in forward direction in radians per second */
          float right_rad_s{
              float(NAN)}; /**< @brief Angular velocity in right direction in radians per second */
          float down_rad_s{
              float(NAN)}; /**< @brief Angular velocity in Down direction in radians per second */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::AngularVelocityFrd` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool
      operator==(const Telemetry::AngularVelocityFrd& lhs, const Telemetry::AngularVelocityFrd& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::AngularVelocityFrd`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::AngularVelocityFrd const& angular_velocity_frd);
  
      /**
       * @brief MagneticFieldFrd message type.
       */
      struct MagneticFieldFrd {
          float forward_gauss{
              float(NAN)}; /**< @brief Magnetic field in forward direction measured in Gauss */
          float right_gauss{
              float(NAN)}; /**< @brief Magnetic field in East direction measured in Gauss */
          float down_gauss{
              float(NAN)}; /**< @brief Magnetic field in Down direction measured in Gauss */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::MagneticFieldFrd` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool
      operator==(const Telemetry::MagneticFieldFrd& lhs, const Telemetry::MagneticFieldFrd& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::MagneticFieldFrd`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::MagneticFieldFrd const& magnetic_field_frd);
  
      /**
       * @brief Imu message type.
       */
      struct Imu {
          AccelerationFrd acceleration_frd{}; /**< @brief Acceleration */
          AngularVelocityFrd angular_velocity_frd{}; /**< @brief Angular velocity */
          MagneticFieldFrd magnetic_field_frd{}; /**< @brief Magnetic field */
          float temperature_degc{float(NAN)}; /**< @brief Temperature */
          uint64_t timestamp_us{}; /**< @brief Timestamp in microseconds */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::Imu` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool operator==(const Telemetry::Imu& lhs, const Telemetry::Imu& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Imu`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Imu const& imu);
  
      /**
       * @brief Gps global origin type.
       */
      struct GpsGlobalOrigin {
          double latitude_deg{double(NAN)}; /**< @brief Latitude of the origin */
          double longitude_deg{double(NAN)}; /**< @brief Longitude of the origin */
          float altitude_m{float(NAN)}; /**< @brief Altitude AMSL (above mean sea level) in metres */
      };
  
      /**
       * @brief Equal operator to compare two `Telemetry::GpsGlobalOrigin` objects.
       *
       * @return `true` if items are equal.
       */
      friend bool
      operator==(const Telemetry::GpsGlobalOrigin& lhs, const Telemetry::GpsGlobalOrigin& rhs);
  
      /**
       * @brief Stream operator to print information about a `Telemetry::GpsGlobalOrigin`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream&
      operator<<(std::ostream& str, Telemetry::GpsGlobalOrigin const& gps_global_origin);
  
      /**
       * @brief Possible results returned for telemetry requests.
       */
      enum class Result {
          Unknown, /**< @brief Unknown result. */
          Success, /**< @brief Success: the telemetry command was accepted by the vehicle. */
          NoSystem, /**< @brief No system connected. */
          ConnectionError, /**< @brief Connection error. */
          Busy, /**< @brief Vehicle is busy. */
          CommandDenied, /**< @brief Command refused by vehicle. */
          Timeout, /**< @brief Request timed out. */
          Unsupported, /**< @brief Request not supported. */
      };
  
      /**
       * @brief Stream operator to print information about a `Telemetry::Result`.
       *
       * @return A reference to the stream.
       */
      friend std::ostream& operator<<(std::ostream& str, Telemetry::Result const& result);
  
      /**
       * @brief Callback type for asynchronous Telemetry calls.
       */
      using ResultCallback = std::function<void(Result)>;
  
      /**
       * @brief Callback type for subscribe_position.
       */
  
      using PositionCallback = std::function<void(Position)>;
  
      /**
       * @brief Subscribe to 'position' updates.
       */
      void subscribe_position(PositionCallback callback);
  
      /**
       * @brief Poll for 'Position' (blocking).
       *
       * @return One Position update.
       */
      Position position() const;
  
      /**
       * @brief Callback type for subscribe_home.
       */
  
      using HomeCallback = std::function<void(Position)>;
  
      /**
       * @brief Subscribe to 'home position' updates.
       */
      void subscribe_home(HomeCallback callback);
  
      /**
       * @brief Poll for 'Position' (blocking).
       *
       * @return One Position update.
       */
      Position home() const;
  
      /**
       * @brief Callback type for subscribe_in_air.
       */
  
      using InAirCallback = std::function<void(bool)>;
  
      /**
       * @brief Subscribe to in-air updates.
       */
      void subscribe_in_air(InAirCallback callback);
  
      /**
       * @brief Poll for 'bool' (blocking).
       *
       * @return One bool update.
       */
      bool in_air() const;
  
      /**
       * @brief Callback type for subscribe_landed_state.
       */
  
      using LandedStateCallback = std::function<void(LandedState)>;
  
      /**
       * @brief Subscribe to landed state updates
       */
      void subscribe_landed_state(LandedStateCallback callback);
  
      /**
       * @brief Poll for 'LandedState' (blocking).
       *
       * @return One LandedState update.
       */
      LandedState landed_state() const;
  
      /**
       * @brief Callback type for subscribe_armed.
       */
  
      using ArmedCallback = std::function<void(bool)>;
  
      /**
       * @brief Subscribe to armed updates.
       */
      void subscribe_armed(ArmedCallback callback);
  
      /**
       * @brief Poll for 'bool' (blocking).
       *
       * @return One bool update.
       */
      bool armed() const;
  
      /**
       * @brief Callback type for subscribe_vtol_state.
       */
  
      using VtolStateCallback = std::function<void(VtolState)>;
  
      /**
       * @brief subscribe to vtol state Updates
       */
      void subscribe_vtol_state(VtolStateCallback callback);
  
      /**
       * @brief Poll for 'VtolState' (blocking).
       *
       * @return One VtolState update.
       */
      VtolState vtol_state() const;
  
      /**
       * @brief Callback type for subscribe_attitude_quaternion.
       */
  
      using AttitudeQuaternionCallback = std::function<void(Quaternion)>;
  
      /**
       * @brief Subscribe to 'attitude' updates (quaternion).
       */
      void subscribe_attitude_quaternion(AttitudeQuaternionCallback callback);
  
      /**
       * @brief Poll for 'Quaternion' (blocking).
       *
       * @return One Quaternion update.
       */
      Quaternion attitude_quaternion() const;
  
      /**
       * @brief Callback type for subscribe_attitude_euler.
       */
  
      using AttitudeEulerCallback = std::function<void(EulerAngle)>;
  
      /**
       * @brief Subscribe to 'attitude' updates (Euler).
       */
      void subscribe_attitude_euler(AttitudeEulerCallback callback);
  
      /**
       * @brief Poll for 'EulerAngle' (blocking).
       *
       * @return One EulerAngle update.
       */
      EulerAngle attitude_euler() const;
  
      /**
       * @brief Callback type for subscribe_attitude_angular_velocity_body.
       */
  
      using AttitudeAngularVelocityBodyCallback = std::function<void(AngularVelocityBody)>;
  
      /**
       * @brief Subscribe to 'attitude' updates (angular velocity)
       */
      void subscribe_attitude_angular_velocity_body(AttitudeAngularVelocityBodyCallback callback);
  
      /**
       * @brief Poll for 'AngularVelocityBody' (blocking).
       *
       * @return One AngularVelocityBody update.
       */
      AngularVelocityBody attitude_angular_velocity_body() const;
  
      /**
       * @brief Callback type for subscribe_camera_attitude_quaternion.
       */
  
      using CameraAttitudeQuaternionCallback = std::function<void(Quaternion)>;
  
      /**
       * @brief Subscribe to 'camera attitude' updates (quaternion).
       */
      void subscribe_camera_attitude_quaternion(CameraAttitudeQuaternionCallback callback);
  
      /**
       * @brief Poll for 'Quaternion' (blocking).
       *
       * @return One Quaternion update.
       */
      Quaternion camera_attitude_quaternion() const;
  
      /**
       * @brief Callback type for subscribe_camera_attitude_euler.
       */
  
      using CameraAttitudeEulerCallback = std::function<void(EulerAngle)>;
  
      /**
       * @brief Subscribe to 'camera attitude' updates (Euler).
       */
      void subscribe_camera_attitude_euler(CameraAttitudeEulerCallback callback);
  
      /**
       * @brief Poll for 'EulerAngle' (blocking).
       *
       * @return One EulerAngle update.
       */
      EulerAngle camera_attitude_euler() const;
  
      /**
       * @brief Callback type for subscribe_velocity_ned.
       */
  
      using VelocityNedCallback = std::function<void(VelocityNed)>;
  
      /**
       * @brief Subscribe to 'ground speed' updates (NED).
       */
      void subscribe_velocity_ned(VelocityNedCallback callback);
  
      /**
       * @brief Poll for 'VelocityNed' (blocking).
       *
       * @return One VelocityNed update.
       */
      VelocityNed velocity_ned() const;
  
      /**
       * @brief Callback type for subscribe_gps_info.
       */
  
      using GpsInfoCallback = std::function<void(GpsInfo)>;
  
      /**
       * @brief Subscribe to 'GPS info' updates.
       */
      void subscribe_gps_info(GpsInfoCallback callback);
  
      /**
       * @brief Poll for 'GpsInfo' (blocking).
       *
       * @return One GpsInfo update.
       */
      GpsInfo gps_info() const;
  
      /**
       * @brief Callback type for subscribe_raw_gps.
       */
  
      using RawGpsCallback = std::function<void(RawGps)>;
  
      /**
       * @brief Subscribe to 'Raw GPS' updates.
       */
      void subscribe_raw_gps(RawGpsCallback callback);
  
      /**
       * @brief Poll for 'RawGps' (blocking).
       *
       * @return One RawGps update.
       */
      RawGps raw_gps() const;
  
      /**
       * @brief Callback type for subscribe_battery.
       */
  
      using BatteryCallback = std::function<void(Battery)>;
  
      /**
       * @brief Subscribe to 'battery' updates.
       */
      void subscribe_battery(BatteryCallback callback);
  
      /**
       * @brief Poll for 'Battery' (blocking).
       *
       * @return One Battery update.
       */
      Battery battery() const;
  
      /**
       * @brief Callback type for subscribe_flight_mode.
       */
  
      using FlightModeCallback = std::function<void(FlightMode)>;
  
      /**
       * @brief Subscribe to 'flight mode' updates.
       */
      void subscribe_flight_mode(FlightModeCallback callback);
  
      /**
       * @brief Poll for 'FlightMode' (blocking).
       *
       * @return One FlightMode update.
       */
      FlightMode flight_mode() const;
  
      /**
       * @brief Callback type for subscribe_health.
       */
  
      using HealthCallback = std::function<void(Health)>;
  
      /**
       * @brief Subscribe to 'health' updates.
       */
      void subscribe_health(HealthCallback callback);
  
      /**
       * @brief Poll for 'Health' (blocking).
       *
       * @return One Health update.
       */
      Health health() const;
  
      /**
       * @brief Callback type for subscribe_rc_status.
       */
  
      using RcStatusCallback = std::function<void(RcStatus)>;
  
      /**
       * @brief Subscribe to 'RC status' updates.
       */
      void subscribe_rc_status(RcStatusCallback callback);
  
      /**
       * @brief Poll for 'RcStatus' (blocking).
       *
       * @return One RcStatus update.
       */
      RcStatus rc_status() const;
  
      /**
       * @brief Callback type for subscribe_status_text.
       */
  
      using StatusTextCallback = std::function<void(StatusText)>;
  
      /**
       * @brief Subscribe to 'status text' updates.
       */
      void subscribe_status_text(StatusTextCallback callback);
  
      /**
       * @brief Poll for 'StatusText' (blocking).
       *
       * @return One StatusText update.
       */
      StatusText status_text() const;
  
      /**
       * @brief Callback type for subscribe_actuator_control_target.
       */
  
      using ActuatorControlTargetCallback = std::function<void(ActuatorControlTarget)>;
  
      /**
       * @brief Subscribe to 'actuator control target' updates.
       */
      void subscribe_actuator_control_target(ActuatorControlTargetCallback callback);
  
      /**
       * @brief Poll for 'ActuatorControlTarget' (blocking).
       *
       * @return One ActuatorControlTarget update.
       */
      ActuatorControlTarget actuator_control_target() const;
  
      /**
       * @brief Callback type for subscribe_actuator_output_status.
       */
  
      using ActuatorOutputStatusCallback = std::function<void(ActuatorOutputStatus)>;
  
      /**
       * @brief Subscribe to 'actuator output status' updates.
       */
      void subscribe_actuator_output_status(ActuatorOutputStatusCallback callback);
  
      /**
       * @brief Poll for 'ActuatorOutputStatus' (blocking).
       *
       * @return One ActuatorOutputStatus update.
       */
      ActuatorOutputStatus actuator_output_status() const;
  
      /**
       * @brief Callback type for subscribe_odometry.
       */
  
      using OdometryCallback = std::function<void(Odometry)>;
  
      /**
       * @brief Subscribe to 'odometry' updates.
       */
      void subscribe_odometry(OdometryCallback callback);
  
      /**
       * @brief Poll for 'Odometry' (blocking).
       *
       * @return One Odometry update.
       */
      Odometry odometry() const;
  
      /**
       * @brief Callback type for subscribe_position_velocity_ned.
       */
  
      using PositionVelocityNedCallback = std::function<void(PositionVelocityNed)>;
  
      /**
       * @brief Subscribe to 'position velocity' updates.
       */
      void subscribe_position_velocity_ned(PositionVelocityNedCallback callback);
  
      /**
       * @brief Poll for 'PositionVelocityNed' (blocking).
       *
       * @return One PositionVelocityNed update.
       */
      PositionVelocityNed position_velocity_ned() const;
  
      /**
       * @brief Callback type for subscribe_ground_truth.
       */
  
      using GroundTruthCallback = std::function<void(GroundTruth)>;
  
      /**
       * @brief Subscribe to 'ground truth' updates.
       */
      void subscribe_ground_truth(GroundTruthCallback callback);
  
      /**
       * @brief Poll for 'GroundTruth' (blocking).
       *
       * @return One GroundTruth update.
       */
      GroundTruth ground_truth() const;
  
      /**
       * @brief Callback type for subscribe_fixedwing_metrics.
       */
  
      using FixedwingMetricsCallback = std::function<void(FixedwingMetrics)>;
  
      /**
       * @brief Subscribe to 'fixedwing metrics' updates.
       */
      void subscribe_fixedwing_metrics(FixedwingMetricsCallback callback);
  
      /**
       * @brief Poll for 'FixedwingMetrics' (blocking).
       *
       * @return One FixedwingMetrics update.
       */
      FixedwingMetrics fixedwing_metrics() const;
  
      /**
       * @brief Callback type for subscribe_imu.
       */
  
      using ImuCallback = std::function<void(Imu)>;
  
      /**
       * @brief Subscribe to 'IMU' updates (in SI units in NED body frame).
       */
      void subscribe_imu(ImuCallback callback);
  
      /**
       * @brief Poll for 'Imu' (blocking).
       *
       * @return One Imu update.
       */
      Imu imu() const;
  
      /**
       * @brief Callback type for subscribe_scaled_imu.
       */
  
      using ScaledImuCallback = std::function<void(Imu)>;
  
      /**
       * @brief Subscribe to 'Scaled IMU' updates.
       */
      void subscribe_scaled_imu(ScaledImuCallback callback);
  
      /**
       * @brief Poll for 'Imu' (blocking).
       *
       * @return One Imu update.
       */
      Imu scaled_imu() const;
  
      /**
       * @brief Callback type for subscribe_raw_imu.
       */
  
      using RawImuCallback = std::function<void(Imu)>;
  
      /**
       * @brief Subscribe to 'Raw IMU' updates.
       */
      void subscribe_raw_imu(RawImuCallback callback);
  
      /**
       * @brief Poll for 'Imu' (blocking).
       *
       * @return One Imu update.
       */
      Imu raw_imu() const;
  
      /**
       * @brief Callback type for subscribe_health_all_ok.
       */
  
      using HealthAllOkCallback = std::function<void(bool)>;
  
      /**
       * @brief Subscribe to 'HealthAllOk' updates.
       */
      void subscribe_health_all_ok(HealthAllOkCallback callback);
  
      /**
       * @brief Poll for 'bool' (blocking).
       *
       * @return One bool update.
       */
      bool health_all_ok() const;
  
      /**
       * @brief Callback type for subscribe_unix_epoch_time.
       */
  
      using UnixEpochTimeCallback = std::function<void(uint64_t)>;
  
      /**
       * @brief Subscribe to 'unix epoch time' updates.
       */
      void subscribe_unix_epoch_time(UnixEpochTimeCallback callback);
  
      /**
       * @brief Poll for 'uint64_t' (blocking).
       *
       * @return One uint64_t update.
       */
      uint64_t unix_epoch_time() const;
  
      /**
       * @brief Callback type for subscribe_distance_sensor.
       */
  
      using DistanceSensorCallback = std::function<void(DistanceSensor)>;
  
      /**
       * @brief Subscribe to 'Distance Sensor' updates.
       */
      void subscribe_distance_sensor(DistanceSensorCallback callback);
  
      /**
       * @brief Poll for 'DistanceSensor' (blocking).
       *
       * @return One DistanceSensor update.
       */
      DistanceSensor distance_sensor() const;
  
      /**
       * @brief Callback type for subscribe_scaled_pressure.
       */
  
      using ScaledPressureCallback = std::function<void(ScaledPressure)>;
  
      /**
       * @brief Subscribe to 'Scaled Pressure' updates.
       */
      void subscribe_scaled_pressure(ScaledPressureCallback callback);
  
      /**
       * @brief Poll for 'ScaledPressure' (blocking).
       *
       * @return One ScaledPressure update.
       */
      ScaledPressure scaled_pressure() const;
  
      /**
       * @brief Callback type for subscribe_heading.
       */
  
      using HeadingCallback = std::function<void(Heading)>;
  
      /**
       * @brief Subscribe to 'Heading' updates.
       */
      void subscribe_heading(HeadingCallback callback);
  
      /**
       * @brief Poll for 'Heading' (blocking).
       *
       * @return One Heading update.
       */
      Heading heading() const;
  
      /**
       * @brief Set rate to 'position' updates.
       *
       * This function is non-blocking. See 'set_rate_position' for the blocking counterpart.
       */
      void set_rate_position_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'position' updates.
       *
       * This function is blocking. See 'set_rate_position_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_position(double rate_hz) const;
  
      /**
       * @brief Set rate to 'home position' updates.
       *
       * This function is non-blocking. See 'set_rate_home' for the blocking counterpart.
       */
      void set_rate_home_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'home position' updates.
       *
       * This function is blocking. See 'set_rate_home_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_home(double rate_hz) const;
  
      /**
       * @brief Set rate to in-air updates.
       *
       * This function is non-blocking. See 'set_rate_in_air' for the blocking counterpart.
       */
      void set_rate_in_air_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to in-air updates.
       *
       * This function is blocking. See 'set_rate_in_air_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_in_air(double rate_hz) const;
  
      /**
       * @brief Set rate to landed state updates
       *
       * This function is non-blocking. See 'set_rate_landed_state' for the blocking counterpart.
       */
      void set_rate_landed_state_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to landed state updates
       *
       * This function is blocking. See 'set_rate_landed_state_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_landed_state(double rate_hz) const;
  
      /**
       * @brief Set rate to VTOL state updates
       *
       * This function is non-blocking. See 'set_rate_vtol_state' for the blocking counterpart.
       */
      void set_rate_vtol_state_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to VTOL state updates
       *
       * This function is blocking. See 'set_rate_vtol_state_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_vtol_state(double rate_hz) const;
  
      /**
       * @brief Set rate to 'attitude' updates.
       *
       * This function is non-blocking. See 'set_rate_attitude' for the blocking counterpart.
       */
      void set_rate_attitude_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'attitude' updates.
       *
       * This function is blocking. See 'set_rate_attitude_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_attitude(double rate_hz) const;
  
      /**
       * @brief Set rate of camera attitude updates.
       *
       * This function is non-blocking. See 'set_rate_camera_attitude' for the blocking counterpart.
       */
      void set_rate_camera_attitude_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate of camera attitude updates.
       *
       * This function is blocking. See 'set_rate_camera_attitude_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_camera_attitude(double rate_hz) const;
  
      /**
       * @brief Set rate to 'ground speed' updates (NED).
       *
       * This function is non-blocking. See 'set_rate_velocity_ned' for the blocking counterpart.
       */
      void set_rate_velocity_ned_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'ground speed' updates (NED).
       *
       * This function is blocking. See 'set_rate_velocity_ned_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_velocity_ned(double rate_hz) const;
  
      /**
       * @brief Set rate to 'GPS info' updates.
       *
       * This function is non-blocking. See 'set_rate_gps_info' for the blocking counterpart.
       */
      void set_rate_gps_info_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'GPS info' updates.
       *
       * This function is blocking. See 'set_rate_gps_info_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_gps_info(double rate_hz) const;
  
      /**
       * @brief Set rate to 'battery' updates.
       *
       * This function is non-blocking. See 'set_rate_battery' for the blocking counterpart.
       */
      void set_rate_battery_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'battery' updates.
       *
       * This function is blocking. See 'set_rate_battery_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_battery(double rate_hz) const;
  
      /**
       * @brief Set rate to 'RC status' updates.
       *
       * This function is non-blocking. See 'set_rate_rc_status' for the blocking counterpart.
       */
      void set_rate_rc_status_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'RC status' updates.
       *
       * This function is blocking. See 'set_rate_rc_status_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_rc_status(double rate_hz) const;
  
      /**
       * @brief Set rate to 'actuator control target' updates.
       *
       * This function is non-blocking. See 'set_rate_actuator_control_target' for the blocking
       * counterpart.
       */
      void set_rate_actuator_control_target_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'actuator control target' updates.
       *
       * This function is blocking. See 'set_rate_actuator_control_target_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_actuator_control_target(double rate_hz) const;
  
      /**
       * @brief Set rate to 'actuator output status' updates.
       *
       * This function is non-blocking. See 'set_rate_actuator_output_status' for the blocking
       * counterpart.
       */
      void set_rate_actuator_output_status_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'actuator output status' updates.
       *
       * This function is blocking. See 'set_rate_actuator_output_status_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_actuator_output_status(double rate_hz) const;
  
      /**
       * @brief Set rate to 'odometry' updates.
       *
       * This function is non-blocking. See 'set_rate_odometry' for the blocking counterpart.
       */
      void set_rate_odometry_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'odometry' updates.
       *
       * This function is blocking. See 'set_rate_odometry_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_odometry(double rate_hz) const;
  
      /**
       * @brief Set rate to 'position velocity' updates.
       *
       * This function is non-blocking. See 'set_rate_position_velocity_ned' for the blocking
       * counterpart.
       */
      void set_rate_position_velocity_ned_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'position velocity' updates.
       *
       * This function is blocking. See 'set_rate_position_velocity_ned_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_position_velocity_ned(double rate_hz) const;
  
      /**
       * @brief Set rate to 'ground truth' updates.
       *
       * This function is non-blocking. See 'set_rate_ground_truth' for the blocking counterpart.
       */
      void set_rate_ground_truth_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'ground truth' updates.
       *
       * This function is blocking. See 'set_rate_ground_truth_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_ground_truth(double rate_hz) const;
  
      /**
       * @brief Set rate to 'fixedwing metrics' updates.
       *
       * This function is non-blocking. See 'set_rate_fixedwing_metrics' for the blocking counterpart.
       */
      void set_rate_fixedwing_metrics_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'fixedwing metrics' updates.
       *
       * This function is blocking. See 'set_rate_fixedwing_metrics_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_fixedwing_metrics(double rate_hz) const;
  
      /**
       * @brief Set rate to 'IMU' updates.
       *
       * This function is non-blocking. See 'set_rate_imu' for the blocking counterpart.
       */
      void set_rate_imu_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'IMU' updates.
       *
       * This function is blocking. See 'set_rate_imu_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_imu(double rate_hz) const;
  
      /**
       * @brief Set rate to 'Scaled IMU' updates.
       *
       * This function is non-blocking. See 'set_rate_scaled_imu' for the blocking counterpart.
       */
      void set_rate_scaled_imu_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'Scaled IMU' updates.
       *
       * This function is blocking. See 'set_rate_scaled_imu_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_scaled_imu(double rate_hz) const;
  
      /**
       * @brief Set rate to 'Raw IMU' updates.
       *
       * This function is non-blocking. See 'set_rate_raw_imu' for the blocking counterpart.
       */
      void set_rate_raw_imu_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'Raw IMU' updates.
       *
       * This function is blocking. See 'set_rate_raw_imu_async' for the non-blocking counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_raw_imu(double rate_hz) const;
  
      /**
       * @brief Set rate to 'unix epoch time' updates.
       *
       * This function is non-blocking. See 'set_rate_unix_epoch_time' for the blocking counterpart.
       */
      void set_rate_unix_epoch_time_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'unix epoch time' updates.
       *
       * This function is blocking. See 'set_rate_unix_epoch_time_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_unix_epoch_time(double rate_hz) const;
  
      /**
       * @brief Set rate to 'Distance Sensor' updates.
       *
       * This function is non-blocking. See 'set_rate_distance_sensor' for the blocking counterpart.
       */
      void set_rate_distance_sensor_async(double rate_hz, const ResultCallback callback);
  
      /**
       * @brief Set rate to 'Distance Sensor' updates.
       *
       * This function is blocking. See 'set_rate_distance_sensor_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      Result set_rate_distance_sensor(double rate_hz) const;
  
      /**
       * @brief Callback type for get_gps_global_origin_async.
       */
      using GetGpsGlobalOriginCallback = std::function<void(Result, GpsGlobalOrigin)>;
  
      /**
       * @brief Get the GPS location of where the estimator has been initialized.
       *
       * This function is non-blocking. See 'get_gps_global_origin' for the blocking counterpart.
       */
      void get_gps_global_origin_async(const GetGpsGlobalOriginCallback callback);
  
      /**
       * @brief Get the GPS location of where the estimator has been initialized.
       *
       * This function is blocking. See 'get_gps_global_origin_async' for the non-blocking
       * counterpart.
       *
       * @return Result of request.
       */
      std::pair<Result, Telemetry::GpsGlobalOrigin> get_gps_global_origin() const;
  
      /**
       * @brief Copy constructor.
       */
      Telemetry(const Telemetry& other);
  
      /**
       * @brief Equality operator (object is not copyable).
       */
      const Telemetry& operator=(const Telemetry&) = delete;
  
  private:
      /** @private Underlying implementation, set at instantiation */
      std::unique_ptr<TelemetryImpl> _impl;
  };
  
  } // namespace mavsdk