AP_Camera: RunCam camera backend

RunCam parameter conversion
add RunCam camera settings and control
This commit is contained in:
Andy Piper
2024-12-13 11:07:09 +00:00
parent 90fc426fd5
commit 399f9f6f98
6 changed files with 232 additions and 29 deletions
+68 -1
View File
@@ -6,6 +6,7 @@
#include <AP_Math/AP_Math.h>
#include <AP_HAL/AP_HAL.h>
#include <SRV_Channel/SRV_Channel.h>
#include <AP_Vehicle/AP_Vehicle.h>
#include "AP_Camera_Backend.h"
#include "AP_Camera_Servo.h"
#include "AP_Camera_Relay.h"
@@ -14,6 +15,7 @@
#include "AP_Camera_MAVLink.h"
#include "AP_Camera_MAVLinkCamV2.h"
#include "AP_Camera_Scripting.h"
#include "AP_RunCam.h"
const AP_Param::GroupInfo AP_Camera::var_info[] = {
@@ -41,10 +43,24 @@ const AP_Param::GroupInfo AP_Camera::var_info[] = {
// @Path: AP_Camera_Params.cpp
AP_SUBGROUPINFO(_params[1], "2", 13, AP_Camera, AP_Camera_Params),
#endif
#if AP_CAMERA_RUNCAM_ENABLED
// @Group: 1_RC_
// @Path: AP_RunCam.cpp
AP_SUBGROUPVARPTR(_backends[0], "1_RC_", 14, AP_Camera, _backend_var_info[0]),
#if AP_CAMERA_MAX_INSTANCES > 1
// @Group: 2_RC_
// @Path: AP_RunCam.cpp
AP_SUBGROUPVARPTR(_backends[1], "2_RC_", 15, AP_Camera, _backend_var_info[1]),
#endif
#endif
AP_GROUPEND
};
#if AP_CAMERA_RUNCAM_ENABLED
const AP_Param::GroupInfo *AP_Camera::_backend_var_info[AP_CAMERA_MAX_INSTANCES];
#endif
extern const AP_HAL::HAL& hal;
AP_Camera::AP_Camera(uint32_t _log_camera_bit) :
@@ -238,6 +254,17 @@ void AP_Camera::init()
case CameraType::SCRIPTING:
_backends[instance] = NEW_NOTHROW AP_Camera_Scripting(*this, _params[instance], instance);
break;
#endif
#if AP_CAMERA_RUNCAM_ENABLED
// check for RunCam driver
case CameraType::RUNCAM:
if (_backends[instance] == nullptr) { // may have already been created by the conversion code
_backends[instance] = NEW_NOTHROW AP_RunCam(*this, _params[instance], instance, _runcam_instances);
_backend_var_info[instance] = AP_RunCam::var_info;
AP_Param::load_object_from_eeprom(_backends[instance], _backend_var_info[instance]);
_runcam_instances++;
}
break;
#endif
case CameraType::NONE:
break;
@@ -899,7 +926,11 @@ AP_Camera_Backend *AP_Camera::get_instance(uint8_t instance) const
void AP_Camera::convert_params()
{
// exit immediately if CAM1_TYPE has already been configured
if (_params[0].type.configured()) {
if (_params[0].type.configured()
#if AP_CAMERA_RUNCAM_ENABLED
&& _params[1].type.configured()
#endif
) {
return;
}
@@ -919,6 +950,42 @@ void AP_Camera::convert_params()
}
_params[0].type.set_and_save(cam1_type);
#if AP_CAMERA_RUNCAM_ENABLED
// RunCam PARAMETER_CONVERSION - Added: Nov-2024 ahead of 4.7 release
// Since slot 1 is essentially used by the trigger type, we will use slot 2 for runcam
int8_t rc_type = 0;
// find vehicle's top level key
uint16_t k_param_vehicle_key;
if (!AP_Param::find_top_level_key_by_pointer(AP::vehicle(), k_param_vehicle_key)) {
return;
}
// RunCam protocol configured so set cam type to RunCam
bool rc_protocol_configured = false;
AP_SerialManager *serial_manager = AP_SerialManager::get_singleton();
if (serial_manager && serial_manager->find_serial(AP_SerialManager::SerialProtocol_RunCam, 0)) {
rc_protocol_configured = true;
}
const AP_Param::ConversionInfo rc_type_info = {
k_param_vehicle_key, AP_GROUP_ELEM_IDX(1, 1), AP_PARAM_INT8, "CAM_RC_TYPE"
};
AP_Int8 rc_type_old;
const bool found_rc_type = AP_Param::find_old_parameter(&rc_type_info, &rc_type_old);
if (rc_protocol_configured || (found_rc_type && rc_type_old.get() > 0)) {
rc_type = int8_t(CameraType::RUNCAM);
_backends[1] = NEW_NOTHROW AP_RunCam(*this, _params[1], 1, _runcam_instances);
_backend_var_info[1] = AP_RunCam::var_info;
AP_Param::convert_class(k_param_vehicle_key, &_backends[1], _backend_var_info[1], 1, false);
AP_Param::invalidate_count();
_runcam_instances++;
}
_params[1].type.set_and_save(rc_type);
#endif // AP_CAMERA_RUNCAM_ENABLED
// convert CAM_DURATION (in deci-seconds) to CAM1_DURATION (in seconds)
int8_t cam_duration = 0;
if (AP_Param::get_param_by_index(this, 1, AP_PARAM_INT8, &cam_duration) && (cam_duration > 0)) {
+10
View File
@@ -23,6 +23,7 @@ class AP_Camera_Mount;
class AP_Camera_MAVLink;
class AP_Camera_MAVLinkCamV2;
class AP_Camera_Scripting;
class AP_RunCam;
/// @class Camera
/// @brief Object managing a Photo or video camera
@@ -37,6 +38,7 @@ class AP_Camera {
friend class AP_Camera_MAVLink;
friend class AP_Camera_MAVLinkCamV2;
friend class AP_Camera_Scripting;
friend class AP_RunCam;
public:
@@ -72,6 +74,9 @@ public:
#endif
#if AP_CAMERA_SCRIPTING_ENABLED
SCRIPTING = 7, // Scripting backend
#endif
#if AP_CAMERA_RUNCAM_ENABLED
RUNCAM = 8, // RunCam backend
#endif
};
@@ -216,6 +221,11 @@ protected:
// parameters for backends
AP_Camera_Params _params[AP_CAMERA_MAX_INSTANCES];
#if AP_CAMERA_RUNCAM_ENABLED
// var info pointer for RunCam
static const struct AP_Param::GroupInfo *_backend_var_info[AP_CAMERA_MAX_INSTANCES];
uint8_t _runcam_instances;
#endif
private:
+1 -1
View File
@@ -8,7 +8,7 @@ const AP_Param::GroupInfo AP_Camera_Params::var_info[] = {
// @Param: _TYPE
// @DisplayName: Camera shutter (trigger) type
// @Description: how to trigger the camera to take a picture
// @Values: 0:None, 1:Servo, 2:Relay, 3:GoPro in Solo Gimbal, 4:Mount (Siyi/Topotek/Viewpro/Xacti), 5:MAVLink, 6:MAVLinkCamV2, 7:Scripting
// @Values: 0:None, 1:Servo, 2:Relay, 3:GoPro in Solo Gimbal, 4:Mount (Siyi/Topotek/Viewpro/Xacti), 5:MAVLink, 6:MAVLinkCamV2, 7:Scripting, 8:RunCam
// @User: Standard
AP_GROUPINFO_FLAGS("_TYPE", 1, AP_Camera_Params, type, 0, AP_PARAM_FLAG_ENABLE),
+4
View File
@@ -62,3 +62,7 @@
#ifndef AP_CAMERA_INFO_FROM_SCRIPT_ENABLED
#define AP_CAMERA_INFO_FROM_SCRIPT_ENABLED AP_CAMERA_SCRIPTING_ENABLED
#endif
#ifndef AP_CAMERA_RUNCAM_ENABLED
#define AP_CAMERA_RUNCAM_ENABLED AP_CAMERA_BACKEND_DEFAULT_ENABLED && HAL_RUNCAM_ENABLED
#endif
File diff suppressed because it is too large Load Diff
+41 -8
View File
@@ -23,7 +23,9 @@
#include "AP_Camera_config.h"
#if HAL_RUNCAM_ENABLED
#include "AP_Camera_Backend.h"
#if AP_CAMERA_RUNCAM_ENABLED
#include <AP_Param/AP_Param.h>
#include <RC_Channel/RC_Channel.h>
@@ -38,10 +40,10 @@
/// @class AP_RunCam
/// @brief Object managing a RunCam device
class AP_RunCam
class AP_RunCam : public AP_Camera_Backend
{
public:
AP_RunCam();
AP_RunCam(AP_Camera &frontend, AP_Camera_Params &params, uint8_t instance, uint8_t runcam_instance);
// do not allow copies
CLASS_NO_COPY(AP_RunCam);
@@ -51,7 +53,7 @@ public:
return _singleton;
}
enum class DeviceType {
enum class DeviceModel {
Disabled = 0,
SplitMicro = 1, // video support only
Split = 2, // camera and video support
@@ -79,22 +81,49 @@ public:
VIDEO_RECORDING_AT_BOOT = (1 << 4)
};
// return true if healthy
bool healthy() const override;
// momentary switch to change camera between picture and video modes
void cam_mode_toggle() override;
// entry point to actually take a picture. returns true on success
bool trigger_pic() override;
// send camera information message to GCS
void send_camera_information(mavlink_channel_t chan) const override;
// send camera settings message to GCS
void send_camera_settings(mavlink_channel_t chan) const override;
// initialize the RunCam driver
void init();
void init() override;
// camera button simulation
bool simulate_camera_button(const ControlOperation operation, const uint32_t transition_timeout = RUNCAM_DEFAULT_BUTTON_PRESS_DELAY);
// start the video
void start_recording();
// stop the video
void stop_recording();
// start or stop video recording. returns true on success
// set start_recording = true to start record, false to stop recording
bool record_video(bool _start_recording) override {
if (_start_recording) {
start_recording();
} else {
stop_recording();
}
return true;
}
// enter the OSD menu
void enter_osd();
// exit the OSD menu
void exit_osd();
// OSD control determined by camera options
void osd_option();
// update loop
void update();
// update - should be called at 50hz
void update() override;
// Check whether arming is allowed
bool pre_arm_check(char *failure_msg, const uint8_t failure_msg_len) const;
@@ -265,6 +294,10 @@ private:
static uint8_t _sub_menu_lengths[RUNCAM_NUM_SUB_MENUS];
// shared inbound scratch space
uint8_t _recv_buf[RUNCAM_MAX_PACKET_SIZE]; // all the response contexts use same recv buffer
// the runcam instance
uint8_t _runcam_instance;
static const char* _models[RUNCAM_MAX_DEVICE_TYPES];
class Request;
@@ -435,4 +468,4 @@ namespace AP
AP_RunCam *runcam();
};
#endif // HAL_RUNCAM_ENABLED
#endif // AP_CAMERA_RUNCAM_ENABLED