LCOV - code coverage report
Current view: top level - AP_Mount - AP_Mount_XFRobot.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 5 0.0 %
Date: 2026-09-09 11:02:08 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /*
       2             :   XFRobot camera gimbal using serial protocol backend class
       3             :  */
       4             : #pragma once
       5             : 
       6             : #include "AP_Mount_config.h"
       7             : 
       8             : #if HAL_MOUNT_XFROBOT_ENABLED
       9             : 
      10             : #include "AP_Mount_Backend_Serial.h"
      11             : #include <AP_Math/quaternion.h>
      12             : 
      13             : #define AP_MOUNT_XFROBOT_RECV_LENGTH_MAX    80  // maximum number of bytes that will be received from the gimbal
      14             : 
      15             : class AP_Mount_XFRobot : public AP_Mount_Backend_Serial
      16             : {
      17             : 
      18             : public:
      19             :     // Constructor
      20             :     using AP_Mount_Backend_Serial::AP_Mount_Backend_Serial;
      21             : 
      22             :     // update mount position - should be called periodically
      23             :     void update() override;
      24             : 
      25             :     // return true if healthy
      26             :     bool healthy() const override;
      27             : 
      28             :     // has_pan_control - returns true if this mount can control its pan (required for multicopters)
      29           0 :     bool has_pan_control() const override { return yaw_range_valid(); };
      30             : 
      31             :     // has_roll_control - returns true if this mount can control its roll
      32           0 :     bool has_roll_control() const override { return roll_range_valid(); };
      33             : 
      34             :     // has_pitch_control - returns true if this mount can control its tilt
      35           0 :     bool has_pitch_control() const override { return pitch_range_valid(); };
      36             : 
      37             :     //
      38             :     // camera controls for gimbals that include a camera
      39             :     //
      40             : 
      41             :     // take a picture.  returns true on success
      42             :     bool take_picture() override;
      43             : 
      44             :     // start or stop video recording.  returns true on success
      45             :     // set start_recording = true to start record, false to stop recording
      46             :     bool record_video(bool start_recording) override;
      47             : 
      48             :     // set zoom specified as a rate or percentage
      49             :     bool set_zoom(ZoomType zoom_type, float zoom_value) override;
      50             : 
      51             :     // set camera lens to cycle through pic-in-pic modes
      52             :     bool set_lens(uint8_t lens) override;
      53             : 
      54             :     // set focus specified as rate, percentage or auto
      55             :     // focus in = -1, focus hold = 0, focus out = 1
      56             :     SetFocusResult set_focus(FocusType focus_type, float focus_value) override;
      57             : 
      58             : protected:
      59             : 
      60             :     // get attitude as a quaternion.  returns true on success
      61             :     bool get_attitude_quaternion(Quaternion& att_quat) override;
      62             : 
      63             : private:
      64             : 
      65             :     // send text prefix string to reduce flash cost
      66             :     static const char* send_text_prefix;
      67             : 
      68             :     // camera and gimbal functions (aka order)
      69             :     enum class FunctionOrder : uint8_t {
      70             :         NONE = 0x00,                // null command
      71             :         CALIBRATION = 0x01,         // calibration
      72             :         ISOTHERM = 0x02,            // isotherm mode
      73             :         NEUTRAL = 0x03,             // neutral mode
      74             :         OSD_COORDINATE = 0x06,      // OSD coordinate control (vehicle or target)
      75             :         IMAGE_AUTO_REVERSE = 0x07,  // auto reverse on/off
      76             :         TIME_ZONE = 0x08,           // set timezone
      77             :         ANGLE_CONTROL = 0x10,       // angle control
      78             :         HEAD_LOCK = 0x11,           // head lock mode
      79             :         HEAD_FOLLOW = 0x12,         // head follow mode
      80             :         ORTHOVIEW = 0x13,           // orthoview mode
      81             :         EULER_ANGLE_CONTROL = 0x14, // euler angle control
      82             :         GAZE_GEO_COORDINATES = 0x15,// gaze mode with geo coordinates
      83             :         GAZE_GEO_TARGET_LOCK = 0x16,// gaze mode with geo target lock
      84             :         TRACK = 0x17,               // track mode
      85             :         CLICK_TO_AIM = 0x1A,        // click to aim
      86             :         FPV = 0x1C,                 // first person view
      87             :         SHUTTER = 0x20,             // take picture
      88             :         RECORD_VIDEO = 0x21,        // record video
      89             :         ZOOM_IN = 0x22,             // zoom in continuously
      90             :         ZOOM_OUT = 0x23,            // zoom ou continuously
      91             :         ZOOM_STOP = 0x24,           // stop zooming
      92             :         ZOOM_RATE = 0x25,           // zoom at specfiied rate
      93             :         FOCUS = 0x26,               // auto focus
      94             :         PALETTE = 0x2A,             // set palette
      95             :         NIGHT_VISION = 0x2B,        // set night vision on/off
      96             :         AREA_TEMP_MEASURE = 0x30,   // set area temperature measurement on/off
      97             :         AREA_TEMP_ALERT = 0x31,     // set area temperature alert on/off
      98             :         SPOT_TEMP_MEASURE = 0x33,   // set spot temperature measurement on/off
      99             :         OSD = 0x73,                 // show/hide osd
     100             :         PIC_IN_PIC = 0x74,          // show/hide picture in picture
     101             :         TARGET_DETECTION = 0x75,    // set target detection on/off
     102             :         DIGITAL_ZOOM = 0x76,        // set digital zoom on/off
     103             :         LIGHTING = 0x80,            // set lighting intensity (0~255)
     104             :         RANGING = 0x81,             // set ranging on/off
     105             :     };
     106             : 
     107             :     // parsing state
     108             :     enum class ParseState : uint8_t {
     109             :         WAITING_FOR_HEADER1,
     110             :         WAITING_FOR_HEADER2,
     111             :         WAITING_FOR_LENGTH_LOW,
     112             :         WAITING_FOR_LENGTH_HIGH,
     113             :         WAITING_FOR_DATA,
     114             :         WAITING_FOR_CRC_HIGH,
     115             :         WAITING_FOR_CRC_LOW
     116             :     };
     117             : 
     118             :     // camera image types
     119             :     enum class CameraType : uint8_t {
     120             :         MAIN_PIP_ZOOM_SUB_THERMAL = 1,
     121             :         MAIN_THERMAL_SUB_ZOOM = 2,
     122             :         MAIN_PIP_THERMAL_SUB_ZOOM = 3,
     123             :         MAIN_ZOOM_SUB_THERMAL = 4
     124             :        };
     125             : 
     126             :     // reading incoming packets from gimbal
     127             :     void read_incoming_packets();
     128             : 
     129             :     // process successfully decoded packets held in the _msg_buff structure
     130             :     void process_packet();
     131             : 
     132             :     // XFRobot can only send angles
     133           0 :     uint8_t natively_supported_mount_target_types() const override {
     134           0 :         return NATIVE_ANGLES_ONLY;
     135             :     };
     136             : 
     137             :     // send_target_angles
     138             :     void send_target_angles(const MountAngleTarget& angle_target_rad) override;
     139             : 
     140             :     // send simple (1byte) command to gimbal (e.g. take pic, start recording)
     141             :     // returns true on success, false on failure to send
     142             :     bool send_simple_command(FunctionOrder order, uint8_t param);
     143             : 
     144             :     // check for recording timeout
     145             :     void check_recording_timeout();
     146             : 
     147             :     // internal variables
     148             :     uint32_t last_send_ms;     // system time of last do_mount_control sent to gimbal
     149             : 
     150             :     //
     151             :     // packet structures
     152             :     //
     153             : 
     154             :     // SendPacket main and sub frames for sending to the camera gimbal
     155             :     struct PACKED SendPacketMainAndSubFrame {
     156             :         uint8_t header1;        // byte0, header1 (0x8A)
     157             :         uint8_t header2;        // byte1, header2 (0x5E)
     158             :         uint16_t length;        // byte2~3, length
     159             :         uint8_t version;        // byte 4: version (always 0x02)
     160             :         int16_t roll_control;   // byte 5~6: roll control value (int16, -18000 ~ +18000)
     161             :         int16_t pitch_control;  // byte 7~8: pitch control value (int16, -18000 ~ +18000)
     162             :         int16_t yaw_control;    // byte 9~10: yaw control value (int16, -18000 ~ +18000)
     163             :         uint8_t status;         // byte 11: status, Bit0:INS valid, Bit2:control values valid
     164             :         int16_t roll_abs;       // byte 12~13: absolute roll angle of vehicle (int16, -18000 ~ +18000)
     165             :         int16_t pitch_abs;      // byte 14~15: absolute pitch angle of vehicle (int16, -9000 ~ +9000)
     166             :         int16_t yaw_abs;        // byte 16~17: absolute yaw angle of vehicle (uint16, 0 ~ 36000)    
     167             :         int16_t accel_north;    // byte 18~19: North acceleration of vehicle (int16, cm/s/s)
     168             :         int16_t accel_east;     // byte 20~21: East acceleration of vehicle (int16, cm/s/s)
     169             :         int16_t accel_up;       // byte 22~23: Upward acceleration of vehicle (int16, cm/s/s)
     170             :         int16_t vel_north;      // byte 24~25: North speed of vehicle (int16, decimeter/s)
     171             :         int16_t vel_east;       // byte 26~27: East speed of vehicle (int16, decimeter/s)
     172             :         int16_t vel_up;         // byte 28~29: Upward speed of vehicle (int16, decimeter/s)
     173             :         uint8_t request_code;   // byte 30: request code of sub frame, header of requested sub data frame from GCU (aka camera)
     174             :         uint8_t reserved[6];    // byte 31~36: reserved/unused
     175             :         uint8_t sub_header;     // byte 37: header (always 0x01)
     176             :         int32_t longitude;      // byte 38~41: longitude of vehicle (int32, 1E7)
     177             :         int32_t latitude;       // byte 42~45: latitude of vehicle (int32, 1E7)
     178             :         int32_t alt_amsl;       // byte 46~49: altitude of vehicle (int32, mm)
     179             :         uint8_t gps_num_sats;   // byte 50: number of satellites
     180             :         uint32_t gps_week_ms;   // byte 51~54: GNSS milliseconds (uint32)
     181             :         uint16_t gps_week;      // byte 55~56: GNSS week number (uint16)
     182             :         int32_t alt_rel;        // byte 57~60: relative altitude (int32, mm, can be zero if unavailable)
     183             :         uint8_t reserved2[8];   // byte 61~68: reserved/unused
     184             :         FunctionOrder order;    // byte 69: order
     185             :     };
     186             : 
     187             :     // ReplyPacket main and sub frames for receiving data from camera gimbal
     188             :     struct PACKED ReplyPacketMainAndSubFrame {
     189             :         uint8_t header1;        // byte0, header1 (0x8A)
     190             :         uint8_t header2;        // byte1, header2 (0x5E)
     191             :         uint16_t length;        // byte2~3, length
     192             :         uint8_t version;        // byte 4: version
     193             :         uint8_t mode;           // byte 5: mode: 0x10:angle control, 0x11:head lock, 0x12: head follow, 0x13:orthoview, 0x14:euler angle control, 0x16:gaze, 0x17:track,0x1C:FPV
     194             :         uint16_t status;        // byte 6~7: status, Bit0:tracking success, Bit7:range and target coordinate valid, Bit8:ranging on, Bit9:night vision on, Bit10:lighting on, Bit12:Upward powered on
     195             :         int16_t horizontal_target; // byte 8~9: horizontal target (int16, -1000 ~ +1000, rightward is positive)
     196             :         int16_t vertical_target;   // byte 10~11: vertical target (int16, -1000 ~ +1000, downward is positive)
     197             :         int16_t angle_x;        // byte 12~13: x-axis angle (camera-frame pitch) of camera relative to vehicle (int16, -18000 ~ +18000)
     198             :         int16_t angle_y;        // byte 14~15: y-axis angle (camera-frame roll) of camera relative to vehicle (int16, -18000 ~ +18000)
     199             :         int16_t angle_z;        // byte 16~17: z-axis angle (camera-frame yaw) of camera relative to vehicle (int16, -18000 ~ +18000)
     200             :         int16_t roll_abs_cd;    // byte 18~19: roll angle of camera (absolute) (int16, -9000 ~ +9000)
     201             :         int16_t pitch_abs_cd;   // byte 20~21: pitch angle of camera (absolute) (int16, -18000 ~ +18000)
     202             :         uint16_t yaw_abs_cd;    // byte 22~23: yaw angle of camera (absolute) (uint16, 0 ~ +36000)
     203             :         int16_t angvel_x;       // byte 24~25: X-axis absolute angular velocity of camera (int16, centi-degrees/s)
     204             :         int16_t angvel_y;       // byte 26~27: Y-axis absolute angular velocity of camera (int16, centi-degrees/s)
     205             :         int16_t angvel_z;       // byte 28~29: Z-axis absolute angular velocity of camera (int16, centi-degrees/s)
     206             :         uint8_t reserved[7];    // byte 30~36: reserved/unused
     207             :         uint8_t sub_header;     // byte 37: header (0x01)
     208             :         uint8_t hardware_version; // byte 38: hardware version (uint8)
     209             :         uint8_t firmware_version; // byte 39: firmware version (uint8)
     210             :         uint8_t pod_code;       // byte 40: pod code
     211             :         uint16_t error_code;    // byte 41~42: error code, Bit7:hardware error, Bit13: mavlink communication freq anomaly, Bit14:BNSS unpositioned, Bit15:GCU hardware error
     212             :         int32_t target_dist_dm; // byte 43~46: distance from target (int32, decimeters, -1m or 0m is invalid measurement)
     213             :         int32_t target_lng;     // byte 47~50: longitude of target (int32, 1E7)
     214             :         int32_t target_lat;     // byte 51~54: latitude of target (int32, 1E7)
     215             :         int32_t target_alt;     // byte 55~58: altitude of target (int32, mm)
     216             :         uint16_t zoom_rate_rgb; // byte 59~60: zoom rate of RGB camera (uint16, resolution 0.1x)
     217             :         uint16_t zoom_rate_thermal; // byte 61~62: zoom rate of thermal camera (uint16, resolution 0.1x)
     218             :         uint8_t thermal_status; // byte 63: thermal camera status, Bit0:low temp alert, Bit1:high temp alert, Bit3:spot temp measurement on, Bit4:Isotherm on, Bit5:temp alert on, Bit6:area temp on, Bit7:temp available
     219             :         uint16_t camera_status; // byte 64~65: camera status, Bit0~Bit2:pic-in-pic mode, Bit4:recording, Bit11:image auto reverse off, Bit12:OSD displays target coordinate, Bit13:OSD on, Bit14:digital zoom on, Bit15:target detection on
     220             :         int8_t timezone;        // byte 66: timezone (int8, -12 ~ +12)
     221             :         uint8_t reserved2[2];   // byte 67~68: reserved/unused
     222             :         FunctionOrder order;   // byte 69: order
     223             :     };
     224             : 
     225             :     // 1byte Reply Packet.  Used for most replies from GCU
     226             :     struct PACKED PacketReply1Byte {
     227             :         uint8_t execution_state;    // byte 70, Success:0x00, Fail:0x01, Operating:0x02
     228             :     };
     229             : 
     230             :     // Packet CRC
     231             :     struct PACKED PacketCRC {
     232             :         uint8_t crc_high;    // byte 70: CRC high byte
     233             :         uint8_t crc_low;     // byte 71: CRC low byte
     234             :     };
     235             : 
     236             :     // structure to send set-atitude command to gimbal
     237             :     union SetAttitudePacket {
     238             :         struct PACKED {
     239             :             SendPacketMainAndSubFrame main;
     240             :             PacketCRC crc;
     241             :         } content;
     242             :         uint8_t bytes[sizeof(content)];
     243             :     };
     244             : 
     245             :     // structure to send a simple, 1byte command
     246             :     union SimpleCommand {
     247             :         struct PACKED {
     248             :             SendPacketMainAndSubFrame main;
     249             :             uint8_t param_1byte;
     250             :             PacketCRC crc;
     251             :         } content;
     252             :         uint8_t bytes[sizeof(content)];
     253             :     };
     254             : 
     255             :     // structure to decode incoming packets
     256             :     struct PACKED GCUSimpleReply {
     257             :         ReplyPacketMainAndSubFrame main;
     258             :         PacketReply1Byte param;
     259             :         PacketCRC crc;
     260             :     };
     261             : 
     262             :     // parser related variables
     263             :     union {
     264             :         GCUSimpleReply simple_reply;                        // simple reply
     265             :         uint8_t bytes[AP_MOUNT_XFROBOT_RECV_LENGTH_MAX];    // raw bytes
     266             :     } msg_buff;
     267             :     uint8_t msg_buff_len;                                   // number of bytes held in msg_buff.bytes
     268             : 
     269             :     struct {
     270             :         ParseState state;           // state of incoming message processing
     271             :         uint8_t len_expected;       // expected number of data bytes we expect to receive
     272             :         uint16_t crc;               // latest message's crc
     273             :         uint32_t last_received_ms;  // system time of last message received and successfully parsed
     274             :     } parser;
     275             : 
     276             :     // latest attitude
     277             :     struct {
     278             :         float roll_ef_deg;      // earth-frame roll angle in degrees
     279             :         float pitch_ef_deg;     // earth-frame pitch angle in degrees
     280             :         float yaw_bf_deg;       // body-frame yaw angle in degrees
     281             :         uint32_t update_ms;     // system time of last update
     282             :     } attitude_latest;
     283             : 
     284             :     // local variables
     285             :     bool got_firmware_version = false;  // true once hardware and firmware version has been received
     286             :     struct {
     287             :         bool recording;         // true if currently recording video
     288             :         bool request_start;     // true if requested start recording and request_ms > 0, false if requested stop recording
     289             :         uint32_t request_ms;    // system time of request to start recording, 0 if not requested
     290             :     } recording;
     291             : };
     292             : #endif // HAL_MOUNT_XFROBOT_ENABLED

Generated by: LCOV version 1.14