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

          Line data    Source code
       1             : /*
       2             :   DroneCAN gimbal driver
       3             : 
       4             :   Implements gimbal control and attitude feedback using the DroneCAN / DSDL / com / xacti messages
       5             :   see https://github.com/dronecan/DSDL/tree/master/com/xacti
       6             : 
       7             :  */
       8             : 
       9             : #pragma once
      10             : 
      11             : #include "AP_Mount_config.h"
      12             : 
      13             : #if HAL_MOUNT_XACTI_ENABLED
      14             : 
      15             : #include "AP_Mount_Backend.h"
      16             : 
      17             : #include <AP_HAL/AP_HAL.h>
      18             : #include <AP_Math/AP_Math.h>
      19             : #include <AP_Common/AP_Common.h>
      20             : #include <AP_DroneCAN/AP_DroneCAN.h>
      21             : #include <AP_HAL/utility/RingBuffer.h>
      22             : #include "AP_Mount.h"
      23             : 
      24             : class AP_Mount_Xacti : public AP_Mount_Backend
      25             : {
      26             : 
      27             : public:
      28             :     // Constructor
      29             :     AP_Mount_Xacti(class AP_Mount &frontend, class AP_Mount_Params &params, uint8_t instance);
      30             : 
      31             :     /* Do not allow copies */
      32             :     CLASS_NO_COPY(AP_Mount_Xacti);
      33             : 
      34             :     // init - performs any required initialisation for this instance
      35             :     void init() override;
      36             : 
      37             :     // update mount position - should be called periodically
      38             :     void update() override;
      39             : 
      40             :     // return true if healthy
      41             :     bool healthy() const override;
      42             : 
      43             :     // has_pan_control - returns true if this mount can control its pan (required for multicopters)
      44           0 :     bool has_pan_control() const override { return yaw_range_valid(); };
      45             : 
      46             :     //
      47             :     // camera controls
      48             :     //
      49             : 
      50             :     // take a picture.  returns true on success
      51             :     bool take_picture() override;
      52             : 
      53             :     // start or stop video recording
      54             :     // set start_recording = true to start record, false to stop recording
      55             :     bool record_video(bool start_recording) override;
      56             : 
      57             :     // set zoom specified as a rate or percentage
      58             :     bool set_zoom(ZoomType zoom_type, float zoom_value) override;
      59             : 
      60             :     // set focus specified as rate, percentage or auto
      61             :     // focus in = -1, focus hold = 0, focus out = 1
      62             :     SetFocusResult set_focus(FocusType focus_type, float focus_value) override;
      63             : 
      64             :     // set camera lens as a value from 0 to 5
      65             :     bool set_lens(uint8_t lens) override;
      66             : 
      67             :     // set_camera_source is functionally the same as set_lens except primary and secondary lenses are specified by type
      68             :     // primary and secondary sources use the AP_Camera::CameraSource enum cast to uint8_t
      69             :     bool set_camera_source(uint8_t primary_source, uint8_t secondary_source) override;
      70             : 
      71           0 :     bool has_camera_information() const override { return true; }
      72             :     // return camera vendor name
      73           0 :     void get_camera_vendor_name(char *buf, uint8_t buflen) const override { strncpy(buf, "Xacti", buflen); }
      74             :     // return camera model name
      75           0 :     void get_camera_model_name(char *buf, uint8_t buflen) const override { strncpy(buf, "CX-GB100", buflen); }
      76             :     // return camera firmware version
      77           0 :     uint32_t get_camera_firmware_version() const override { return _firmware_version.received ? _firmware_version.mav_ver : 0; }
      78             :     // return camera capability flags
      79           0 :     uint32_t get_camera_cap_flags() const override {
      80             :         return (CAMERA_CAP_FLAGS_CAPTURE_VIDEO |
      81             :                 CAMERA_CAP_FLAGS_CAPTURE_IMAGE |
      82           0 :                 CAMERA_CAP_FLAGS_HAS_BASIC_FOCUS);
      83             :     }
      84             : 
      85             :     // send camera settings message to GCS
      86             :     void send_camera_settings(mavlink_channel_t chan) const override;
      87             : 
      88             :     // subscribe to Xacti DroneCAN messages
      89             :     static bool subscribe_msgs(AP_DroneCAN* ap_dronecan);
      90             : 
      91             :     // xacti specific message handlers
      92             :     static void handle_gimbal_attitude_status(AP_DroneCAN* ap_dronecan, const CanardRxTransfer& transfer, const com_xacti_GimbalAttitudeStatus &msg);
      93             :     static void handle_gnss_status_req(AP_DroneCAN* ap_dronecan, const CanardRxTransfer& transfer, const com_xacti_GnssStatusReq &msg);
      94             : 
      95             : protected:
      96             : 
      97             :     // get attitude as a quaternion.  returns true on success
      98             :     bool get_attitude_quaternion(Quaternion& att_quat) override;
      99             : 
     100             :     // Xacti can send either rates or angles
     101           0 :     uint8_t natively_supported_mount_target_types() const override {
     102           0 :         return NATIVE_ANGLES_AND_RATES_ONLY;
     103             :     };
     104             : 
     105             : private:
     106             : 
     107             :     // send text prefix string to reduce flash cost
     108             :     static const char* send_text_prefix;
     109             : 
     110             :     // Sensor mode enumeration (aka lens)
     111             :     enum class SensorsMode : uint8_t {
     112             :         RGB = 0,    // RGB (aka "visible)")
     113             :         IR = 1,     // Infrared, aka thermal
     114             :         PIP = 2,    // RGB with IR PIP
     115             :         NDVI = 3,   // NDVI (vegetation greenness)
     116             :     };
     117             :     // array of sensor mode enumeration strings for display to user
     118             :     // if enum above is updated, also update sensor_mode_str definition in cpp
     119             :     static const char* sensor_mode_str[];
     120             : 
     121             :     // send target pitch and yaw rates to gimbal
     122             :     void send_target_rates(const MountRateTarget &rate_rads) override;
     123             : 
     124             :     // send target pitch and yaw angles to gimbal
     125             :     void send_target_angles(const MountAngleTarget &angle_rad) override;
     126             : 
     127             :     // register backend in detected modules array used to map DroneCAN port and node id to backend
     128             :     void register_backend();
     129             : 
     130             :     // find backend associated with the given dronecan port and node_id.  also associates backends with zero node ids
     131             :     // returns pointer to backend on success, nullptr on failure
     132             :     static AP_Mount_Xacti* get_dronecan_backend(AP_DroneCAN* ap_dronecan, uint8_t node_id);
     133             : 
     134             :     // DroneCAN parameter handling methods
     135             :     FUNCTOR_DECLARE(param_int_cb, bool, AP_DroneCAN*, const uint8_t, const char*, int32_t &);
     136             :     FUNCTOR_DECLARE(param_string_cb, bool, AP_DroneCAN*, const uint8_t, const char*, AP_DroneCAN::string &);
     137             :     FUNCTOR_DECLARE(param_save_cb, void, AP_DroneCAN*, const uint8_t, bool);
     138             :     bool handle_param_get_set_response_int(AP_DroneCAN* ap_dronecan, const uint8_t node_id, const char* name, int32_t &value);
     139             :     bool handle_param_get_set_response_string(AP_DroneCAN* ap_dronecan, const uint8_t node_id, const char* name, AP_DroneCAN::string &value);
     140             :     void handle_param_save_response(AP_DroneCAN* ap_dronecan, const uint8_t node_id, bool success);
     141             : 
     142             :     // param enum.  If enum is updated also update _param_names definition in cpp
     143             :     enum class Param : uint8_t {
     144             :         SingleShot = 0,
     145             :         Recording,
     146             :         FocusMode,
     147             :         SensorMode,
     148             :         DigitalZoomMagnification,
     149             :         FirmwareVersion,
     150             :         Status,
     151             :         DateTime,
     152             :         OpticalZoomMagnification,
     153             :         LAST = OpticalZoomMagnification,            // this should be equal to the final parameter enum
     154             :     };
     155             :     static const char* _param_names[];              // array of Xacti parameter strings
     156             : 
     157             :     // get parameter name for a particular param enum value
     158             :     // returns an empty string if not found (which should never happen)
     159             :     const char* get_param_name_str(Param param) const;
     160             : 
     161             :     // helper function to get and set parameters
     162             :     bool set_param_int32(Param param, int32_t param_value);
     163             :     bool set_param_string(Param param, const AP_DroneCAN::string& param_value);
     164             :     bool get_param_string(Param param);
     165             : 
     166             :     // process queue of set parameter items. returns true if set-parameter message was sent
     167             :     bool process_set_param_int32_queue();
     168             : 
     169             :     // send gimbal control message via DroneCAN
     170             :     // mode is 2:angle control or 3:rate control
     171             :     // pitch_cd is pitch angle in centi-degrees or pitch rate in cds
     172             :     // yaw_cd is angle in centi-degrees or yaw rate in cds
     173             :     void send_gimbal_control(uint8_t mode, int16_t pitch_cd, int16_t yaw_cd);
     174             : 
     175             :     // send vehicle attitude to gimbal via DroneCAN.  now_ms is current system time
     176             :     // returns true if sent so that we avoid immediately trying to also send other messages
     177             :     bool send_copter_att_status(uint32_t now_ms);
     178             : 
     179             :     // update zoom rate controller.  now_ms is current system time
     180             :     // returns true if sent so that we avoid immediately trying to also send other messages
     181             :     bool update_zoom_rate_control(uint32_t now_ms);
     182             : 
     183             :     // request firmware version.  now_ms is current system time
     184             :     // returns true if sent so that we avoid immediately trying to also send other messages
     185             :     bool request_firmware_version(uint32_t now_ms);
     186             : 
     187             :     // request parameters used to determine camera capabilities.  now_ms is current system time
     188             :     // returns true if a param get/set was sent so that we avoid sending other messages
     189             :     bool request_capabilities(uint32_t now_ms);
     190             : 
     191             :     // set date and time.  now_ms is current system time
     192             :     bool set_datetime(uint32_t now_ms);
     193             : 
     194             :     // request status.  now_ms is current system time
     195             :     // returns true if sent so that we avoid immediately trying to also send other messages
     196             :     bool request_status(uint32_t now_ms);
     197             : 
     198             :     // check if safe to send message (if messages sent too often camera will not respond)
     199             :     // now_ms is current system time
     200             :     bool is_safe_to_send(uint32_t now_ms) const;
     201             : 
     202             :     // internal variables
     203             :     bool _initialised;                              // true once the driver has been initialised
     204             : 
     205             :     // attitude received from gimbal
     206             :     Quaternion _current_attitude_quat;              // current attitude as a quaternion
     207             :     uint32_t _last_current_attitude_quat_ms;        // system time _current_angle_rad was updated
     208             :     bool _recording_video;                          // true if recording video
     209             :     uint16_t _last_digital_zoom_param_value = 100;  // last digital zoom parameter value sent to camera.  100 ~ 1000 (interval 100)
     210             :     uint16_t _last_optical_zoom_param_value = 100;  // last optical zoom parameter value sent to camera.  100 ~ 250 (interval 10)
     211             :     struct {
     212             :         bool enabled;                               // true if zoom rate control is enabled
     213             :         int8_t dir;                                 // zoom direction (-1 to zoom out, +1 to zoom in)
     214             :         uint32_t last_update_ms;                    // system time that zoom rate control last updated zoom
     215             :     } _zoom_rate_control;
     216             : 
     217             :     // firmware version received from gimbal
     218             :     struct {
     219             :         uint32_t last_request_ms;                   // system time of last request for firmware version
     220             :         bool received;                              // true once firmware version has been received
     221             :         char str[12] {};                            // firmware version string (11 bytes + 1 null byte)
     222             :         uint32_t mav_ver;                           // version formatted for reporting to GCS via CAMERA_INFORMATION message
     223             :     } _firmware_version;
     224             : 
     225             :     // date and time handling
     226             :     struct {
     227             :         uint32_t last_request_ms;                   // system time that date/time was last requested
     228             :         bool set;                                   // true once date/time has been set
     229             :     } _datetime;
     230             : 
     231             :     // capability handling
     232             :     enum class Capability : uint8_t {
     233             :         False = 0,
     234             :         True = 1,
     235             :         Unknown = 2,
     236             :     };
     237             :     struct {
     238             :         bool received;                              // true if we have determined cameras capabilities
     239             :         uint32_t first_request_ms;                  // system time of first request for capabilities (used to timeout)
     240             :         uint32_t last_request_ms;                   // system time of last capability related parameter check
     241             :         Capability optical_zoom;                    // Yes if camera has optical zoom
     242             :     } capabilities = {false, 0, 0, Capability::Unknown};
     243             : 
     244             :     // gimbal status handling
     245             :     enum class ErrorStatus : uint32_t {
     246             :         TAKING_PICTURE = 0x04,                      // currently taking a picture
     247             :         RECORDING_VIDEO = 0x08,                     // currently recording video
     248             :         CANNOT_TAKE_PIC = 0x20,
     249             :         TIME_NOT_SET = 0x10000,
     250             :         MEDIA_ERROR = 0x20000,
     251             :         LENS_ERROR = 0x40000,
     252             :         MOTOR_INIT_ERROR = 0x100000,
     253             :         MOTOR_OPERATION_ERROR = 0x200000,
     254             :         GIMBAL_CONTROL_ERROR = 0x400000,
     255             :         TEMP_WARNING = 0x1000000
     256             :     };
     257             :     struct {
     258             :         uint32_t error_status;                      // see ErrorStatus enum
     259             :         uint32_t video_remain_time;                 // max seconds of video that may be recorded before SD card is full
     260             :         uint32_t photo_remain_count;                // max number of pics before SD card is full
     261             :         uint32_t sd_card_size_mb;                   // SD card size in MB
     262             :         uint32_t sd_card_free_mb;                   // SD card remaining size in MB
     263             :         uint16_t body;                              // body type
     264             :         uint16_t cmos;                              // cmos type
     265             :         uint16_t gimbal_pitch;                      // gimbal pitch angle
     266             :         uint16_t gimbal_roll;                       // gimbal roll angle
     267             :         uint16_t gimbal_yaw;                        // gimbal yaw angle
     268             :         uint16_t reserved1;
     269             :         uint8_t date_time[7];                       // camera's date and time
     270             :         uint8_t reserved2;
     271             :         uint32_t exposure_time_us;                  // camera's exposure time in us
     272             :         uint16_t apeture;                           // cameras' aperture * 100
     273             :         uint16_t iso_sensitivity;                   // camera's iso sensitivity
     274             :     } _status;                                      // latest status received
     275             :     static_assert(sizeof(_status) == 48, "status must be 48 bytes");           // status should be 48 bytes
     276             :     struct {
     277             :         uint32_t last_request_ms;                   // system time that status was last requested
     278             :         uint32_t last_error_status;                 // last error status reported to user
     279             :     } _status_report;
     280             :     bool _motor_error;                              // true if status reports motor or control error (used for health reporting)
     281             :     bool _camera_error;                             // true if status reports camera error
     282             : 
     283             :     // DroneCAN related variables
     284             :     static struct DetectedModules {
     285             :         AP_Mount_Xacti *driver;                     // pointer to Xacti backends
     286             :         AP_DroneCAN* ap_dronecan;                   // DroneCAN interface used by this backend
     287             :         uint8_t node_id;                            // DroneCAN node id associated by this backend
     288             :     } _detected_modules[AP_MOUNT_MAX_INSTANCES];
     289             :     static HAL_Semaphore _sem_registry;             // semaphore protecting access to _detected_modules table
     290             :     uint32_t last_send_gimbal_control_ms;           // system time that send_gimbal_control was last called (used to slow down sends to 5hz)
     291             :     uint32_t last_send_copter_att_status_ms;        // system time that send_copter_att_status was last called (used to slow down sends to 10hz)
     292             :     uint32_t last_send_getset_param_ms;             // system time that a get or set parameter message was sent
     293             : 
     294             :     // queue of set parameter int32 items.  set-parameter requests to camera are throttled to improve reliability
     295             :     struct SetParamQueueItem {
     296             :         Param param;                                // parameter (name)
     297             :         int32_t value;                              // parameter value
     298             :     };
     299             :     ObjectArray<SetParamQueueItem> *_set_param_int32_queue; // queue of set-parameter items
     300             : };
     301             : 
     302             : #endif // HAL_MOUNT_XACTI_ENABLED

Generated by: LCOV version 1.14