2023-02-10 20:27:39 -04:00
|
|
|
/*
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Camera driver backend class. Each supported camera type
|
|
|
|
needs to have an object derived from this class.
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "AP_Camera_config.h"
|
|
|
|
|
|
|
|
#if AP_CAMERA_ENABLED
|
|
|
|
#include "AP_Camera.h"
|
2023-04-14 22:04:19 -03:00
|
|
|
#include <AP_Common/Location.h>
|
|
|
|
#include <AP_Logger/LogStructure.h>
|
2023-02-10 20:27:39 -04:00
|
|
|
|
|
|
|
class AP_Camera_Backend
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
// Constructor
|
|
|
|
AP_Camera_Backend(AP_Camera &frontend, AP_Camera_Params ¶ms, uint8_t instance);
|
|
|
|
|
|
|
|
/* Do not allow copies */
|
|
|
|
CLASS_NO_COPY(AP_Camera_Backend);
|
|
|
|
|
2024-02-13 22:13:12 -04:00
|
|
|
// camera options parameter values
|
2024-08-07 04:22:06 -03:00
|
|
|
enum class Option : uint8_t {
|
2024-02-13 22:13:12 -04:00
|
|
|
RecordWhileArmed = (1 << 0U)
|
2023-07-03 05:24:56 -03:00
|
|
|
};
|
2024-08-07 04:22:06 -03:00
|
|
|
bool option_is_enabled(Option option) const {
|
|
|
|
return ((uint8_t)_params.options.get() & (uint8_t)option) != 0;
|
|
|
|
}
|
2023-07-03 05:24:56 -03:00
|
|
|
|
2023-02-10 20:27:39 -04:00
|
|
|
// init - performs any required initialisation
|
2024-08-08 03:02:42 -03:00
|
|
|
virtual void init();
|
2023-02-10 20:27:39 -04:00
|
|
|
|
|
|
|
// update - should be called at 50hz
|
|
|
|
virtual void update();
|
|
|
|
|
|
|
|
// return true if healthy
|
|
|
|
virtual bool healthy() const { return true; }
|
|
|
|
|
|
|
|
// momentary switch to change camera between picture and video modes
|
|
|
|
virtual void cam_mode_toggle() {}
|
|
|
|
|
|
|
|
// take a picture. returns true on success
|
|
|
|
bool take_picture();
|
|
|
|
|
2023-08-04 03:08:32 -03:00
|
|
|
// take multiple pictures, time_interval between two consecutive pictures is in miliseconds
|
|
|
|
// total_num is number of pictures to be taken, -1 means capture forever
|
|
|
|
void take_multiple_pictures(uint32_t time_interval_ms, int16_t total_num);
|
|
|
|
|
2023-09-07 07:12:48 -03:00
|
|
|
// stop capturing multiple image sequence
|
|
|
|
void stop_capture();
|
|
|
|
|
2023-02-10 20:27:39 -04:00
|
|
|
// entry point to actually take a picture. returns true on success
|
|
|
|
virtual bool trigger_pic() = 0;
|
|
|
|
|
|
|
|
// start or stop video recording. returns true on success
|
|
|
|
// set start_recording = true to start record, false to stop recording
|
|
|
|
virtual bool record_video(bool start_recording) { return false; }
|
|
|
|
|
2023-04-06 21:49:46 -03:00
|
|
|
// set zoom specified as a rate or percentage
|
2023-04-18 22:06:16 -03:00
|
|
|
virtual bool set_zoom(ZoomType zoom_type, float zoom_value) { return false; }
|
2023-02-10 20:27:39 -04:00
|
|
|
|
2023-04-24 09:23:07 -03:00
|
|
|
// set focus specified as rate, percentage or auto
|
2023-02-10 20:27:39 -04:00
|
|
|
// focus in = -1, focus hold = 0, focus out = 1
|
2023-06-21 03:03:39 -03:00
|
|
|
virtual SetFocusResult set_focus(FocusType focus_type, float focus_value) { return SetFocusResult::UNSUPPORTED; }
|
2023-02-10 20:27:39 -04:00
|
|
|
|
2023-04-28 21:39:05 -03:00
|
|
|
// set tracking to none, point or rectangle (see TrackingType enum)
|
|
|
|
// if POINT only p1 is used, if RECTANGLE then p1 is top-left, p2 is bottom-right
|
|
|
|
// p1,p2 are in range 0 to 1. 0 is left or top, 1 is right or bottom
|
|
|
|
virtual bool set_tracking(TrackingType tracking_type, const Vector2f& p1, const Vector2f& p2) { return false; }
|
|
|
|
|
2023-07-14 08:21:02 -03:00
|
|
|
// set camera lens as a value from 0 to 5
|
|
|
|
virtual bool set_lens(uint8_t lens) { return false; }
|
|
|
|
|
2024-04-11 21:50:27 -03:00
|
|
|
#if AP_CAMERA_SET_CAMERA_SOURCE_ENABLED
|
2024-02-08 04:29:29 -04:00
|
|
|
// set_camera_source is functionally the same as set_lens except primary and secondary lenses are specified by type
|
|
|
|
virtual bool set_camera_source(AP_Camera::CameraSource primary_source, AP_Camera::CameraSource secondary_source) { return false; }
|
|
|
|
#endif
|
|
|
|
|
2023-11-02 00:34:31 -03:00
|
|
|
// get camera image horizontal or vertical field of view in degrees. returns 0 if unknown
|
|
|
|
float horizontal_fov() const { return MAX(0, _params.hfov); }
|
|
|
|
float vertical_fov() const { return MAX(0, _params.vfov); }
|
|
|
|
|
2023-04-28 20:54:00 -03:00
|
|
|
// handle MAVLink messages from the camera
|
2023-02-10 20:27:39 -04:00
|
|
|
virtual void handle_message(mavlink_channel_t chan, const mavlink_message_t &msg) {}
|
|
|
|
|
|
|
|
// configure camera
|
2023-10-30 23:29:17 -03:00
|
|
|
virtual void configure(float shooting_mode, float shutter_speed, float aperture, float ISO, int32_t exposure_type, int32_t cmd_id, float engine_cutoff_time) {}
|
2023-02-10 20:27:39 -04:00
|
|
|
|
|
|
|
// handle camera control
|
2023-10-30 23:29:17 -03:00
|
|
|
virtual void control(float session, float zoom_pos, float zoom_step, float focus_lock, int32_t shooting_cmd, int32_t cmd_id);
|
2023-02-10 20:27:39 -04:00
|
|
|
|
|
|
|
// set camera trigger distance in meters
|
|
|
|
void set_trigger_distance(float distance_m) { _params.trigg_dist.set(distance_m); }
|
|
|
|
|
|
|
|
// send camera feedback message to GCS
|
2023-04-11 21:11:26 -03:00
|
|
|
void send_camera_feedback(mavlink_channel_t chan);
|
2023-02-10 20:27:39 -04:00
|
|
|
|
2023-06-09 23:17:12 -03:00
|
|
|
// send camera information message to GCS
|
|
|
|
virtual void send_camera_information(mavlink_channel_t chan) const;
|
|
|
|
|
2024-08-08 03:02:42 -03:00
|
|
|
#if AP_CAMERA_INFO_FROM_SCRIPT_ENABLED
|
|
|
|
void set_camera_information(mavlink_camera_information_t camera_info);
|
|
|
|
#endif // AP_CAMERA_INFO_FROM_SCRIPT_ENABLED
|
|
|
|
|
2023-06-09 23:17:12 -03:00
|
|
|
// send camera settings message to GCS
|
|
|
|
virtual void send_camera_settings(mavlink_channel_t chan) const;
|
|
|
|
|
2023-09-20 23:37:23 -03:00
|
|
|
#if AP_CAMERA_SEND_FOV_STATUS_ENABLED
|
|
|
|
// send camera field of view status
|
|
|
|
void send_camera_fov_status(mavlink_channel_t chan) const;
|
|
|
|
#endif
|
|
|
|
|
2023-09-11 23:22:44 -03:00
|
|
|
// send camera capture status message to GCS
|
|
|
|
virtual void send_camera_capture_status(mavlink_channel_t chan) const;
|
|
|
|
|
2024-08-24 00:26:35 -03:00
|
|
|
#if AP_CAMERA_SEND_THERMAL_RANGE_ENABLED
|
|
|
|
// send camera thermal range message to GCS
|
|
|
|
virtual void send_camera_thermal_range(mavlink_channel_t chan) const {};
|
|
|
|
#endif
|
|
|
|
|
2023-04-07 23:35:51 -03:00
|
|
|
#if AP_CAMERA_SCRIPTING_ENABLED
|
|
|
|
// accessor to allow scripting backend to retrieve state
|
|
|
|
// returns true on success and cam_state is filled in
|
2023-04-14 21:39:16 -03:00
|
|
|
virtual bool get_state(AP_Camera::camera_state_t& cam_state) { return false; }
|
2024-08-23 02:54:59 -03:00
|
|
|
|
|
|
|
// change camera settings not normally used by autopilot
|
|
|
|
virtual bool change_setting(CameraSetting setting, float value) { return false; }
|
2023-04-07 23:35:51 -03:00
|
|
|
#endif
|
|
|
|
|
2023-02-10 20:27:39 -04:00
|
|
|
protected:
|
|
|
|
|
|
|
|
// references
|
|
|
|
AP_Camera &_frontend; // reference to the front end which holds parameters
|
|
|
|
AP_Camera_Params &_params; // parameters for this backend
|
|
|
|
|
|
|
|
// feedback pin related methods
|
|
|
|
void setup_feedback_callback();
|
|
|
|
void feedback_pin_isr(uint8_t pin, bool high, uint32_t timestamp_us);
|
|
|
|
void feedback_pin_timer();
|
|
|
|
void check_feedback();
|
|
|
|
|
|
|
|
// store vehicle location and attitude for use in camera_feedback message to GCS
|
|
|
|
void prep_mavlink_msg_camera_feedback(uint64_t timestamp_us);
|
|
|
|
struct {
|
|
|
|
uint64_t timestamp_us; // system time of most recent image
|
|
|
|
Location location; // location where most recent image was taken
|
|
|
|
int32_t roll_sensor; // vehicle roll in centi-degrees
|
|
|
|
int32_t pitch_sensor; // vehicle pitch in centi-degrees
|
|
|
|
int32_t yaw_sensor; // vehicle yaw in centi-degrees
|
|
|
|
uint32_t feedback_trigger_logged_count; // ID sequence number
|
|
|
|
} camera_feedback;
|
|
|
|
|
2023-08-04 03:08:32 -03:00
|
|
|
// Picture settings
|
|
|
|
struct {
|
|
|
|
uint32_t time_interval_ms; // time interval (in miliseconds) between two consecutive pictures
|
|
|
|
int16_t num_remaining; // number of pictures still to be taken, -1 means take unlimited pictures
|
|
|
|
} time_interval_settings;
|
|
|
|
|
2023-02-10 20:27:39 -04:00
|
|
|
// Logging Function
|
|
|
|
void log_picture();
|
|
|
|
void Write_Camera(uint64_t timestamp_us=0);
|
|
|
|
void Write_Trigger();
|
|
|
|
void Write_CameraInfo(enum LogMessages msg, uint64_t timestamp_us=0);
|
|
|
|
|
2023-08-01 15:45:51 -03:00
|
|
|
// get corresponding mount instance for the camera
|
|
|
|
uint8_t get_mount_instance() const;
|
|
|
|
|
2023-07-19 11:02:50 -03:00
|
|
|
// get mavlink gimbal device id which is normally mount_instance+1
|
|
|
|
uint8_t get_gimbal_device_id() const;
|
|
|
|
|
2024-08-08 03:02:42 -03:00
|
|
|
#if AP_CAMERA_INFO_FROM_SCRIPT_ENABLED
|
|
|
|
mavlink_camera_information_t _camera_info;
|
|
|
|
#endif // AP_CAMERA_INFO_FROM_SCRIPT_ENABLED
|
|
|
|
|
2023-02-10 20:27:39 -04:00
|
|
|
// internal members
|
|
|
|
uint8_t _instance; // this instance's number
|
|
|
|
bool timer_installed; // true if feedback pin change detected using timer
|
|
|
|
bool isr_installed; // true if feedback pin change is detected with an interrupt
|
|
|
|
uint8_t last_pin_state; // last pin state. used by timer based detection
|
|
|
|
uint32_t feedback_trigger_count; // number of times the interrupt detected the feedback pin changed
|
|
|
|
uint32_t feedback_trigger_timestamp_us; // system time (in microseconds) that timer detected the feedback pin changed
|
|
|
|
uint32_t feedback_trigger_logged_count; // number of times the feedback has been logged
|
|
|
|
bool trigger_pending; // true if a call to take_pic() was delayed due to the minimum time interval time
|
2023-08-04 03:08:32 -03:00
|
|
|
uint32_t last_picture_time_ms; // system time that photo was last taken
|
2023-02-10 20:27:39 -04:00
|
|
|
Location last_location; // Location that last picture was taken at (used for trigg_dist calculation)
|
|
|
|
uint16_t image_index; // number of pictures taken since boot
|
2023-07-03 05:24:56 -03:00
|
|
|
bool last_is_armed; // stores last arm/disarm state. true if it was armed lastly
|
2023-02-10 20:27:39 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // AP_CAMERA_ENABLED
|