Line data Source code
1 : /// @file AP_Camera.h
2 : /// @brief Photo or video camera manager, with EEPROM-backed storage of constants.
3 : #pragma once
4 :
5 : #include "AP_Camera_config.h"
6 :
7 : #if AP_CAMERA_ENABLED
8 :
9 : #include <AP_Param/AP_Param.h>
10 : #include <GCS_MAVLink/GCS_MAVLink.h>
11 : #include <GCS_MAVLink/ap_message.h>
12 : #include "AP_Camera_Params.h"
13 : #include "AP_Camera_shareddefs.h"
14 :
15 : #define AP_CAMERA_MAX_INSTANCES 2 // maximum number of camera backends
16 :
17 : // declare backend classes
18 : class AP_Camera_Backend;
19 : class AP_Camera_Servo;
20 : class AP_Camera_Relay;
21 : class AP_Camera_SoloGimbal;
22 : class AP_Camera_Mount;
23 : class AP_Camera_MAVLink;
24 : class AP_Camera_MAVLinkCamV2;
25 : class AP_Camera_Scripting;
26 : class AP_RunCam;
27 :
28 : /// @class Camera
29 : /// @brief Object managing a Photo or video camera
30 : class AP_Camera {
31 :
32 : // declare backends as friends
33 : friend class AP_Camera_Backend;
34 : friend class AP_Camera_Servo;
35 : friend class AP_Camera_Relay;
36 : friend class AP_Camera_SoloGimbal;
37 : friend class AP_Camera_Mount;
38 : friend class AP_Camera_MAVLink;
39 : friend class AP_Camera_MAVLinkCamV2;
40 : friend class AP_Camera_Scripting;
41 : friend class AP_RunCam;
42 :
43 : public:
44 :
45 : // constructor
46 : AP_Camera(uint32_t _log_camera_bit);
47 :
48 : /* Do not allow copies */
49 : CLASS_NO_COPY(AP_Camera);
50 :
51 : // get singleton instance
52 4996 : static AP_Camera *get_singleton() { return _singleton; }
53 :
54 : // enums
55 : enum class CameraType {
56 : NONE = 0, // None
57 : #if AP_CAMERA_SERVO_ENABLED
58 : SERVO = 1, // Servo/PWM controlled camera
59 : #endif
60 : #if AP_CAMERA_RELAY_ENABLED
61 : RELAY = 2, // Relay controlled camera
62 : #endif
63 : #if AP_CAMERA_SOLOGIMBAL_ENABLED
64 : SOLOGIMBAL = 3, // GoPro in Solo gimbal
65 : #endif
66 : #if AP_CAMERA_MOUNT_ENABLED
67 : MOUNT = 4, // Mount library implements camera
68 : #endif
69 : #if AP_CAMERA_MAVLINK_ENABLED
70 : MAVLINK = 5, // MAVLink enabled camera
71 : #endif
72 : #if AP_CAMERA_MAVLINKCAMV2_ENABLED
73 : MAVLINK_CAMV2 = 6, // MAVLink camera v2
74 : #endif
75 : #if AP_CAMERA_SCRIPTING_ENABLED
76 : SCRIPTING = 7, // Scripting backend
77 : #endif
78 : #if AP_CAMERA_RUNCAM_ENABLED
79 : RUNCAM = 8, // RunCam backend
80 : #endif
81 : };
82 :
83 : // detect and initialise backends
84 : void init();
85 :
86 : // update - to be called periodically at 50Hz
87 : void update();
88 :
89 : #if HAL_GCS_ENABLED
90 : // handle MAVLink messages from the camera
91 : void handle_message(mavlink_channel_t chan, const mavlink_message_t &msg);
92 :
93 : // handle MAVLink command from GCS to control the camera
94 : MAV_RESULT handle_command(const mavlink_command_int_t &packet);
95 :
96 : // send a mavlink message; returns false if there was not space to
97 : // send the message, true otherwise
98 : bool send_mavlink_message(class GCS_MAVLINK &link, const enum ap_message id);
99 :
100 : // send camera information for a specific instance (0-based) to GCS
101 : void send_camera_information(uint8_t instance, mavlink_channel_t chan);
102 : #endif // HAL_GCS_ENABLED
103 :
104 : #if HAL_MAVLINK_BINDINGS_ENABLED
105 : // methods to handle mavlink-style instance-id (0 meaning all cameras)
106 : MAV_RESULT handle_mav_DO_SET_CAM_TRIGG_DISTANCE(uint8_t instance_id, bool trigger, float dist_m);
107 : MAV_RESULT handle_mav_SET_CAMERA_ZOOM(uint8_t instance_id, CAMERA_ZOOM_TYPE mav_zoom_type, float zoom_value);
108 : MAV_RESULT handle_mav_SET_CAMERA_FOCUS(uint8_t instance_id, SET_FOCUS_TYPE mav_focus_type, float focus_value);
109 : #endif // HAL_MAVLINK_BINDINGS_ENABLED
110 :
111 : // select which instance to send on the next deferred MSG_CAMERA_INFORMATION send
112 8 : void set_camera_information_send_instance(int16_t instance) { _camera_information_send_instance = instance; }
113 :
114 : // configure camera
115 : void configure(float shooting_mode, float shutter_speed, float aperture, float ISO, int32_t exposure_type, int32_t cmd_id, float engine_cutoff_time);
116 : void configure(uint8_t instance, float shooting_mode, float shutter_speed, float aperture, float ISO, int32_t exposure_type, int32_t cmd_id, float engine_cutoff_time);
117 :
118 : // handle camera control
119 : void control(float session, float zoom_pos, float zoom_step, float focus_lock, int32_t shooting_cmd, int32_t cmd_id);
120 : void control(uint8_t instance, float session, float zoom_pos, float zoom_step, float focus_lock, int32_t shooting_cmd, int32_t cmd_id);
121 :
122 : // set camera trigger distance in a mission
123 : void set_trigger_distance(uint8_t instance, float distance_m);
124 :
125 : // momentary switch to change camera between picture and video modes
126 : void cam_mode_toggle();
127 : void cam_mode_toggle(uint8_t instance);
128 :
129 : // take a picture. If instance is not provided, all available cameras affected
130 : // returns true if at least one camera took a picture
131 : bool take_picture();
132 : bool take_picture(uint8_t instance);
133 :
134 : // take multiple pictures, time_interval between two consecutive pictures is in miliseconds
135 : // if instance is not provided, all available cameras affected
136 : // time_interval_ms must be positive
137 : // total_num is number of pictures to be taken, -1 means capture forever
138 : // returns true if at least one camera is successful
139 : bool take_multiple_pictures(uint32_t time_interval_ms, int16_t total_num);
140 : bool take_multiple_pictures(uint8_t instance, uint32_t time_interval_ms, int16_t total_num);
141 :
142 : // stop capturing multiple image sequence
143 : void stop_capture();
144 : bool stop_capture(uint8_t instance);
145 :
146 : // start/stop recording video
147 : // start_recording should be true to start recording, false to stop recording
148 : bool record_video(bool start_recording);
149 : bool record_video(uint8_t instance, bool start_recording);
150 :
151 : // set zoom specified as a rate or percentage
152 : bool set_zoom(ZoomType zoom_type, float zoom_value);
153 : bool set_zoom(uint8_t instance, ZoomType zoom_type, float zoom_value);
154 :
155 : // set focus specified as rate, percentage or auto
156 : // focus in = -1, focus hold = 0, focus out = 1
157 : SetFocusResult set_focus(FocusType focus_type, float focus_value);
158 : SetFocusResult set_focus(uint8_t instance, FocusType focus_type, float focus_value);
159 :
160 : // set tracking to none, point or rectangle (see TrackingType enum)
161 : // if POINT only p1 is used, if RECTANGLE then p1 is top-left, p2 is bottom-right
162 : // p1,p2 are in range 0 to 1. 0 is left or top, 1 is right or bottom
163 : bool set_tracking(TrackingType tracking_type, const Vector2f& p1, const Vector2f& p2);
164 : bool set_tracking(uint8_t instance, TrackingType tracking_type, const Vector2f& p1, const Vector2f& p2);
165 :
166 : #if AP_CAMERA_SET_CAMERA_SOURCE_ENABLED
167 : // set camera lens as a value from 0 to 5, instance starts from 0
168 : bool set_lens(uint8_t lens);
169 : bool set_lens(uint8_t instance, uint8_t lens);
170 :
171 : // camera source handling enum. This is a one-to-one mapping with the CAMERA_SOURCE mavlink enum
172 : // set_camera_source is functionally the same as set_lens except primary and secondary lenses are specified by type
173 : enum class CameraSource {
174 : DEFAULT = 0,
175 : RGB = 1,
176 : IR = 2,
177 : NDVI = 3,
178 : RGB_WIDEANGLE = 4,
179 : };
180 : bool set_camera_source(uint8_t instance, CameraSource primary_source, CameraSource secondary_source);
181 : #endif
182 :
183 : // set if vehicle is in AUTO mode
184 3718 : void set_is_auto_mode(bool enable) { _is_in_auto_mode = enable; }
185 :
186 : #if AP_CAMERA_SCRIPTING_ENABLED
187 : // structure and accessors for use by scripting backends
188 : typedef struct {
189 : uint16_t take_pic_incr; // incremented each time camera is requested to take a picture
190 : bool recording_video; // true when recording video
191 : uint8_t zoom_type; // see ZoomType enum (1:Rate or 2:Pct)
192 : float zoom_value; // percentage or zoom out = -1, hold = 0, zoom in = 1
193 : uint8_t focus_type; // see FocusType enum (1:Rate, 2:Pct, 4:Auto)
194 : float focus_value; // If Rate, focus in = -1, focus hold = 0, focus out = 1. If PCT 0 to 100
195 : uint8_t tracking_type; // see TrackingType enum (0:NONE, 1:POINT, 2:RECTANGLE)
196 : Vector2f tracking_p1; // center or top-left tracking point. x left-right, y is top-bottom. range is 0 to 1
197 : Vector2f tracking_p2; // bottom-right tracking point. x left-right, y is top-bottom. range is 0 to 1
198 : } camera_state_t;
199 :
200 : // accessor to allow scripting backend to retrieve state
201 : // returns true on success and cam_state is filled in
202 : bool get_state(uint8_t instance, camera_state_t& cam_state);
203 :
204 : // change camera settings not normally used by autopilot
205 : bool change_setting(uint8_t instance, CameraSetting setting, float value);
206 : #endif
207 :
208 : #if AP_CAMERA_INFO_FROM_SCRIPT_ENABLED
209 : void set_camera_information(mavlink_camera_information_t camera_info);
210 : void set_camera_information(uint8_t instance, mavlink_camera_information_t camera_info);
211 :
212 : void set_stream_information(mavlink_video_stream_information_t camera_info);
213 : void set_stream_information(uint8_t instance, mavlink_video_stream_information_t camera_info);
214 : #endif // AP_CAMERA_INFO_FROM_SCRIPT_ENABLED
215 :
216 : // Return true and the relay index if relay camera backend is selected, used for conversion to relay functions
217 : bool get_legacy_relay_index(int8_t &index) const;
218 :
219 : // allow threads to lock against AHRS update
220 0 : HAL_Semaphore &get_semaphore() { return _rsem; }
221 :
222 : // parameter var table
223 : static const struct AP_Param::GroupInfo var_info[];
224 :
225 : protected:
226 :
227 : // return true if vehicle mode allows trigg dist
228 2060 : bool vehicle_mode_ok_for_trigg_dist() const { return (_auto_mode_only == 0) || _is_in_auto_mode; }
229 :
230 : // return maximum acceptable vehicle roll angle (in degrees)
231 2060 : int16_t get_roll_max() const { return _max_roll; }
232 :
233 : // return log bit
234 66 : uint32_t get_log_camera_bit() const { return log_camera_bit; }
235 :
236 : // parameters for backends
237 : AP_Camera_Params _params[AP_CAMERA_MAX_INSTANCES];
238 : #if AP_CAMERA_RUNCAM_ENABLED
239 : // var info pointer for RunCam
240 : static const struct AP_Param::GroupInfo *_backend_var_info[AP_CAMERA_MAX_INSTANCES];
241 : uint8_t _runcam_instances;
242 : #endif
243 :
244 : private:
245 :
246 : static AP_Camera *_singleton;
247 :
248 : // parameters
249 : AP_Int8 _auto_mode_only; // if 1: trigger by distance only if in AUTO mode.
250 : AP_Int16 _max_roll; // Maximum acceptable roll angle when trigging camera
251 :
252 : // check instance number is valid
253 : AP_Camera_Backend *get_instance(uint8_t instance) const;
254 :
255 : // perform any required parameter conversion
256 : void convert_params();
257 : #if AP_CAMERA_RUNCAM_ENABLED && (AP_CAMERA_MAX_INSTANCES > 1)
258 : void convert_runcam_params();
259 : #endif // AP_CAMERA_RUNCAM_ENABLED && (AP_CAMERA_MAX_INSTANCES > 1)
260 :
261 : // send camera feedback message to GCS
262 : void send_feedback(mavlink_channel_t chan);
263 :
264 : // send camera information message to GCS
265 : void send_camera_information(mavlink_channel_t chan);
266 :
267 : #if AP_MAVLINK_MSG_VIDEO_STREAM_INFORMATION_ENABLED
268 : void send_video_stream_information(mavlink_channel_t chan);
269 : #endif // AP_MAVLINK_MSG_VIDEO_STREAM_INFORMATION_ENABLED
270 :
271 : // send camera settings message to GCS
272 : void send_camera_settings(mavlink_channel_t chan);
273 :
274 : #if AP_CAMERA_SEND_FOV_STATUS_ENABLED
275 : // send camera field of view status
276 : void send_camera_fov_status(mavlink_channel_t chan);
277 : #endif
278 :
279 : // send camera capture status message to GCS
280 : void send_camera_capture_status(mavlink_channel_t chan);
281 :
282 : #if AP_CAMERA_SEND_THERMAL_RANGE_ENABLED
283 : // send camera thermal range message to GCS
284 : void send_camera_thermal_range(mavlink_channel_t chan);
285 : #endif
286 :
287 : HAL_Semaphore _rsem; // semaphore for multi-thread access
288 : AP_Camera_Backend *primary; // primary camera backed
289 : bool _is_in_auto_mode; // true if in AUTO mode
290 : uint32_t log_camera_bit; // logging bit (from LOG_BITMASK) to enable camera logging
291 : AP_Camera_Backend *_backends[AP_CAMERA_MAX_INSTANCES]; // pointers to instantiated backends
292 : // Stashes the 0-based instance requested by MAV_CMD_REQUEST_MESSAGE(CAMERA_INFORMATION, param2).
293 : // Used to pass the target instance through the deferred-message path so that COMMAND_ACK is
294 : // transmitted before the CAMERA_INFORMATION response. -1 means send for all instances.
295 : int16_t _camera_information_send_instance = -1;
296 : };
297 :
298 : namespace AP {
299 : AP_Camera *camera();
300 : };
301 :
302 : #endif
|