Line data Source code
1 : /*
2 : This program is free software: you can redistribute it and/or modify
3 : it under the terms of the GNU General Public License as published by
4 : the Free Software Foundation, either version 3 of the License, or
5 : (at your option) any later version.
6 :
7 : This program is distributed in the hope that it will be useful,
8 : but WITHOUT ANY WARRANTY; without even the implied warranty of
9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 : GNU General Public License for more details.
11 :
12 : You should have received a copy of the GNU General Public License
13 : along with this program. If not, see <http://www.gnu.org/licenses/>.
14 : */
15 :
16 : /*
17 : Mount driver backend class. Each supported mount type
18 : needs to have an object derived from this class.
19 : */
20 : #pragma once
21 :
22 : #include "AP_Mount_config.h"
23 :
24 : #if HAL_MOUNT_ENABLED
25 :
26 : #include <GCS_MAVLink/GCS_MAVLink.h>
27 : #include <AP_Common/AP_Common.h>
28 : #include <AP_Common/Location.h>
29 : #include <RC_Channel/RC_Channel.h>
30 : #include <AP_Camera/AP_Camera_shareddefs.h>
31 : #include <SRV_Channel/SRV_Channel.h>
32 : #include "AP_Mount.h"
33 :
34 : class AP_Mount_Backend
35 : {
36 : public:
37 : // Constructor
38 112 : AP_Mount_Backend(class AP_Mount &frontend, class AP_Mount_Params ¶ms, uint8_t instance) :
39 112 : _frontend(frontend),
40 112 : _params(params),
41 112 : _instance(instance),
42 112 : _open_idx(_instance == 0? SRV_Channel::k_mount_open : SRV_Channel::k_mount2_open)
43 112 : {}
44 :
45 : // init - performs any required initialisation for this instance
46 : virtual void init();
47 :
48 : // set device id of this instance, for MNTx_DEVID parameter
49 : void set_dev_id(uint32_t id);
50 :
51 : // update mount position - should be called periodically
52 : virtual void update();
53 :
54 : // used for gimbals that need to read INS data at full rate
55 3099790 : virtual void update_fast() {}
56 :
57 : // return true if healthy
58 563 : virtual bool healthy() const { return true; }
59 :
60 : // return true if this mount accepts roll or pitch targets
61 : virtual bool has_roll_control() const;
62 : virtual bool has_pitch_control() const;
63 :
64 : // returns true if this mount can control its pan (required for multicopters)
65 : virtual bool has_pan_control() const = 0;
66 :
67 : // get attitude as a quaternion. returns true on success.
68 : // att_quat will be an earth-frame quaternion rotated such that
69 : // yaw is in body-frame.
70 : virtual bool get_attitude_quaternion(Quaternion& att_quat) = 0;
71 :
72 : // get angular velocity of mount. Only available on some backends
73 65269 : virtual bool get_angular_velocity(Vector3f& rates) { return false; }
74 :
75 : // returns true if mode is a valid mode, false otherwise:
76 : bool valid_mode(MAV_MOUNT_MODE mode) const;
77 :
78 : // get mount's mode
79 1312545 : enum MAV_MOUNT_MODE get_mode() const { return _mode; }
80 :
81 : // set mount's mode
82 : bool set_mode(enum MAV_MOUNT_MODE mode);
83 :
84 : // set yaw_lock used in RC_TARGETING mode. If true, the gimbal's yaw target is maintained in earth-frame meaning it will lock onto an earth-frame heading (e.g. North)
85 : // If false (aka "follow") the gimbal's yaw is maintained in body-frame meaning it will rotate with the vehicle
86 : void set_yaw_lock(bool yaw_lock);
87 :
88 : // set pitch_lock used in RC_TARGETING mode. If true, the gimbal's tilt target is maintained in earth-frame meaning it will lock onto an earth-frame
89 : // If false (aka "follow") the gimbal's tilt is maintained in body-frame meaning it will tilt with the vehicle
90 0 : void set_pitch_lock(bool pitch_lock) { _pitch_lock = pitch_lock; }
91 :
92 : // set roll_lock used in RC_TARGETING mode. If true, the gimbal's roll target is maintained in earth-frame meaning it will lock onto an earth-frame
93 : // If false (aka "follow") the gimbal's tilt is maintained in body-frame meaning it will roll with the vehicle
94 0 : void set_roll_lock(bool roll_lock) { _roll_lock = roll_lock; }
95 :
96 : #if AP_MOUNT_POI_LOCK_ENABLED
97 : // set poi_lock to switch to GPS Targeting mode using current GPS point in gimbal's view or current saved poi and save entry mode for suspend function
98 : void set_poi_lock();
99 : // clears poi_lock and reverts to default targeting mode
100 : void clear_poi_lock();
101 : // reverts to saved poi entry mode but maintains poi location if set_poi_lock is called again without clearing it
102 : void suspend_poi_lock();
103 : // check that poi_target has been set
104 10 : bool roi_is_set() { return !_roi_target.is_zero(); }
105 : #endif // AP_MOUNT_POI_LOCK_ENABLED
106 :
107 : // set angle target in degrees
108 : // roll and pitch are in earth-frame
109 : // yaw_is_earth_frame (aka yaw_lock) should be true if yaw angle is earth-frame, false if body-frame
110 : void set_angle_target(float roll_deg, float pitch_deg, float yaw_deg, bool yaw_is_earth_frame);
111 :
112 : // sets rate target in deg/s
113 : // yaw_lock should be true if the yaw rate is earth-frame, false if body-frame (e.g. rotates with body of vehicle)
114 : void set_rate_target(float roll_degs, float pitch_degs, float yaw_degs, bool yaw_is_earth_frame);
115 :
116 : // set_roi_target - sets target location that mount should attempt to point towards
117 : void set_roi_target(const Location &target_loc);
118 : // clear_roi_target - clears target location that mount should attempt to point towards
119 : void clear_roi_target();
120 :
121 : // set_sys_target - sets system that mount should attempt to point towards
122 : void set_target_sysid(uint8_t sysid);
123 :
124 : #if AP_MOUNT_ROI_WPNEXT_OFFSET_ENABLED
125 : // set_roi_target_wpnext_offset - point to next waypoint, with offsets
126 : void set_roi_target_wpnext_offset(const Vector3f &rpy);
127 : #endif // AP_MOUNT_ROI_WPNEXT_OFFSET_ENABLED
128 :
129 : // handle do_mount_control command. Returns MAV_RESULT_ACCEPTED on success
130 : MAV_RESULT handle_command_do_mount_control(const mavlink_command_int_t &packet);
131 :
132 : // handle do_gimbal_manager_configure. Returns MAV_RESULT_ACCEPTED on success
133 : // requires original message in order to extract caller's sysid and compid
134 : MAV_RESULT handle_command_do_gimbal_manager_configure(const mavlink_command_int_t &packet, const mavlink_message_t &msg);
135 :
136 : // send a GIMBAL_DEVICE_ATTITUDE_STATUS message to GCS
137 : void send_gimbal_device_attitude_status(mavlink_channel_t chan);
138 :
139 : // return gimbal capabilities sent to GCS in the GIMBAL_MANAGER_INFORMATION
140 : virtual uint32_t get_gimbal_manager_capability_flags() const;
141 :
142 : // send a GIMBAL_MANAGER_INFORMATION message to GCS
143 : void send_gimbal_manager_information(mavlink_channel_t chan);
144 :
145 : // send a GIMBAL_MANAGER_STATUS message to GCS
146 : void send_gimbal_manager_status(mavlink_channel_t chan);
147 :
148 : // handle a GIMBAL_REPORT message
149 0 : virtual void handle_gimbal_report(mavlink_channel_t chan, const mavlink_message_t &msg) {}
150 :
151 : // handle a PARAM_VALUE message
152 0 : virtual void handle_param_value(const mavlink_message_t &msg) {}
153 :
154 : // handle a GLOBAL_POSITION_INT message
155 : bool handle_global_position_int(uint8_t msg_sysid, const mavlink_global_position_int_t &packet);
156 :
157 : // handle GIMBAL_DEVICE_INFORMATION message
158 0 : virtual void handle_gimbal_device_information(const mavlink_message_t &msg) {}
159 :
160 : // handle GIMBAL_DEVICE_ATTITUDE_STATUS message
161 0 : virtual void handle_gimbal_device_attitude_status(const mavlink_message_t &msg) {}
162 :
163 : #if AP_SCRIPTING_ENABLED
164 : // get target rate in deg/sec. returns true on success
165 : virtual bool get_rate_target(float& roll_degs, float& pitch_degs, float& yaw_degs, bool& yaw_is_earth_frame);
166 :
167 : // get target angle in deg. returns true on success
168 : virtual bool get_angle_target(float& roll_deg, float& pitch_deg, float& yaw_deg, bool& yaw_is_earth_frame);
169 :
170 : // get mount target location. returns true on success
171 : bool get_location_target(Location &target_loc);
172 : #endif
173 :
174 : // accessors for scripting backends
175 0 : virtual void set_attitude_euler(float roll_deg, float pitch_deg, float yaw_bf_deg) {};
176 :
177 : #if AP_SCRIPTING_ENABLED
178 : // used by a script sending messages to a physical device to
179 : // indicate what targets can be either natively sent to the device
180 : // or internally handled by the script
181 0 : virtual void set_natively_supported_mount_target_types(uint8_t types_mask) { }
182 : #endif // AP_SCRIPTING_ENABLED
183 :
184 : // write mount log packet
185 : void write_log(uint64_t timestamp_us);
186 :
187 : //
188 : // camera controls for gimbals that include a camera
189 : //
190 :
191 : // take a picture. returns true on success
192 0 : virtual bool take_picture() { return false; }
193 :
194 : // start or stop video recording. returns true on success
195 : // set start_recording = true to start record, false to stop recording
196 0 : virtual bool record_video(bool start_recording) { return false; }
197 :
198 : // set zoom specified as a rate or percentage
199 0 : virtual bool set_zoom(ZoomType zoom_type, float zoom_value) { return false; }
200 :
201 : // set focus specified as rate, percentage or auto
202 : // focus in = -1, focus hold = 0, focus out = 1
203 0 : virtual SetFocusResult set_focus(FocusType focus_type, float focus_value) { return SetFocusResult::UNSUPPORTED; }
204 :
205 : // set tracking to none, point or rectangle (see TrackingType enum)
206 : // if POINT only p1 is used, if RECTANGLE then p1 is top-left, p2 is bottom-right
207 : // p1,p2 are in range 0 to 1. 0 is left or top, 1 is right or bottom
208 0 : virtual bool set_tracking(TrackingType tracking_type, const Vector2f& p1, const Vector2f& p2) { return false; }
209 :
210 : // set camera lens as a value from 0 to 5
211 0 : virtual bool set_lens(uint8_t lens) { return false; }
212 :
213 : #if HAL_MOUNT_SET_CAMERA_SOURCE_ENABLED
214 : // set_camera_source is functionally the same as set_lens except primary and secondary lenses are specified by type
215 : // primary and secondary sources use the AP_Camera::CameraSource enum cast to uint8_t
216 0 : virtual bool set_camera_source(uint8_t primary_source, uint8_t secondary_source) { return false; }
217 : #endif
218 :
219 : // send camera information message to GCS
220 : void send_camera_information(mavlink_channel_t chan) const;
221 :
222 : // virtual methods supplying data for send_camera_information
223 : // backends that have no associated camera (e.g. pass-through gimbals like STorM32)
224 : // should leave has_camera_information() returning false to suppress sending
225 0 : virtual bool has_camera_information() const { return false; }
226 0 : virtual void get_camera_vendor_name(char *buf, uint8_t buflen) const { }
227 0 : virtual void get_camera_model_name(char *buf, uint8_t buflen) const { }
228 0 : virtual uint32_t get_camera_firmware_version() const { return 0; }
229 3 : virtual float get_camera_focal_length_mm() const { return NaNf; }
230 4 : virtual uint8_t get_camera_lens_id() const { return 0; }
231 0 : virtual uint32_t get_camera_cap_flags() const { return 0; }
232 :
233 : // send camera settings message to GCS
234 0 : virtual void send_camera_settings(mavlink_channel_t chan) const {}
235 :
236 : // send camera capture status message to GCS
237 0 : virtual void send_camera_capture_status(mavlink_channel_t chan) const {}
238 :
239 : #if AP_MOUNT_SEND_THERMAL_RANGE_ENABLED
240 : // send camera thermal status message to GCS
241 0 : virtual void send_camera_thermal_range(mavlink_channel_t chan) const {}
242 : #endif
243 :
244 : // change camera settings not normally used by autopilot
245 0 : virtual bool change_setting(CameraSetting setting, float value) { return false; }
246 :
247 : #if AP_MOUNT_POI_TO_LATLONALT_ENABLED
248 : // get poi information. Returns true on success and fills in gimbal attitude, location and poi location
249 : bool get_poi(uint8_t instance, Quaternion &quat, Location &loc, Location &poi_loc);
250 : #endif
251 :
252 : //
253 : // rangefinder
254 : //
255 :
256 : // get rangefinder distance. Returns true on success
257 73640 : virtual bool get_rangefinder_distance(float& distance_m) const { return false; }
258 :
259 : // enable/disable rangefinder. Returns true on success
260 0 : virtual bool set_rangefinder_enable(bool enable) { return false; }
261 :
262 : protected:
263 :
264 : enum class MountTargetType {
265 : ANGLE = 0,
266 : RATE = 1,
267 : RETRACTED = 2,
268 : NEUTRAL = 3,
269 : LOCATION = 4,
270 : };
271 :
272 : // class for a single angle or rate target
273 : class MountAngleTarget {
274 : public:
275 : float roll;
276 : float pitch;
277 : float yaw;
278 : bool pitch_is_ef = true; //can be changed on select gimbals
279 : bool roll_is_ef = true; //can be changed on select gimbals
280 : bool yaw_is_ef;
281 :
282 : // return body-frame yaw angle from a mount target (in radians)
283 : float get_bf_yaw() const;
284 :
285 : // return earth-frame yaw angle from a mount target (in radians)
286 : float get_ef_yaw() const;
287 :
288 : // set roll, pitch, yaw and yaw_is_ef from Vector3f
289 : void set(const Vector3f& rpy, bool yaw_is_ef_in);
290 : };
291 : class MountRateTarget {
292 : public:
293 : float roll; // roll rate in radians/second
294 : float pitch; // roll rate in radians/second
295 : float yaw; // roll rate in radians/second
296 : bool pitch_is_ef = true;
297 : bool roll_is_ef = true;
298 : bool yaw_is_ef; // if set then `yaw` is a rate in earth frame
299 : };
300 :
301 : // returns a bitmask of MountTargetTypes which this backend supports
302 : // FIXME: make this pure-virtual
303 0 : virtual uint8_t natively_supported_mount_target_types() const { return 0; };
304 :
305 : // some static const masks to try to make the backends easier to read:
306 : static constexpr uint8_t NATIVE_ANGLES_ONLY = (1U << uint8_t(MountTargetType::ANGLE));
307 : static constexpr uint8_t NATIVE_RATES_ONLY = (1U << uint8_t(MountTargetType::RATE));
308 : static constexpr uint8_t NATIVE_ANGLES_AND_RATES_ONLY = (
309 : 1U << uint8_t(MountTargetType::ANGLE) |
310 : 1U << uint8_t(MountTargetType::RATE)
311 : );
312 :
313 : // returns true if the backend natively supports type. e.g. if
314 : // "type" here is "MountTargetType::ANGLE" and the backend has
315 : // indicated support of angles in the
316 : // natively_supported_mount_target_types() bitmask then we can can
317 : // send_angle_targets on the backend and have that work (meaning
318 : // the backend has overrriden that method).
319 673715 : bool natively_supports(MountTargetType type) const {
320 673715 : uint8_t supported = natively_supported_mount_target_types();
321 673715 : return (supported & (1U<<(uint8_t(type)))) != 0;
322 : }
323 :
324 : // look at what MountTargetTypes this mount supports; convert to
325 : // supported mount target type from unsupported mount target type
326 : // if required and then send commands to gimbal via virtual
327 : // methods:
328 : void send_target_to_gimbal();
329 :
330 : // FIXME: make it an internal error for these to ever be called:
331 0 : virtual void send_target_angles(const MountAngleTarget &angle_rad) { }
332 0 : virtual void send_target_rates(const MountRateTarget &rate_rads) { }
333 0 : virtual void send_target_retracted() { }
334 0 : virtual void send_target_neutral() { }
335 0 : virtual void send_target_location(const Location &roi_loc) { }
336 :
337 : // options parameter bitmask handling
338 : enum class Options : uint8_t {
339 : RCTARGETING_LOCK_FROM_PREVMODE = (1U << 0), // RC_TARGETING mode's lock/follow state maintained from previous mode
340 : NEUTRAL_ON_RC_FS = (1U << 1), // move mount to netral position on RC failsafe
341 : FPV_LOCK = (1U << 2), // if mount supports, force body frame FPV lock on yaw/roll/pitch unconditionally in RC Targeting mode
342 : };
343 336428 : bool option_set(Options opt) const { return (_params.options.get() & (uint8_t)opt) != 0; }
344 :
345 : // called when mount mode is RC-targetting, updates the mnt_target object from RC inputs:
346 : void update_mnt_target_from_rc_target();
347 :
348 : //called to remove lean angle in roll/pitch mount angle to convert to bodyframe
349 : void adjust_mnt_target_if_RP_locked();
350 :
351 : // if this function returns true, then when roll and pitch have
352 : // been locked to body frame (e.g. the user is using a switch or mount option to
353 : // lock them to body frame) we add in the vehicle's roll and
354 : // pitch to the target angles to position the gimbal in body
355 : // frame. This is used on mounts which do not have the option to
356 : // move in body frame themselves (e.g. SToRM32 in its normal
357 : // configuration) and can be overriden in their heading files
358 371526 : virtual bool apply_bf_roll_pitch_adjustments_in_rc_targeting() const {
359 371526 : return false;
360 : }
361 :
362 : // method for the mount backends to call to update mnt_target based on
363 : // the mount mode. Methods in here may be overridden by the derived
364 : // class to customise behaviour
365 : void update_mnt_target();
366 : void _update_mnt_target();
367 :
368 : // returns true if user has configured a valid roll angle range
369 : // allows user to disable roll even on 3-axis gimbal
370 21277 : bool roll_range_valid() const { return (_params.roll_angle_min < _params.roll_angle_max); }
371 :
372 : // returns true if user has configured a valid pitch angle range
373 : // allows user to disable pitch even on 3-axis gimbal
374 126120 : bool pitch_range_valid() const { return (_params.pitch_angle_min < _params.pitch_angle_max); }
375 :
376 : // returns true if user has configured a valid yaw angle range
377 : // allows user to disable yaw even on 3-axis gimbal
378 66774 : bool yaw_range_valid() const { return (_params.yaw_angle_min < _params.yaw_angle_max); }
379 :
380 : // returns true if mavlink heartbeat should be suppressed for this gimbal (only used by Solo gimbal)
381 64373 : virtual bool suppress_heartbeat() const { return false; }
382 :
383 : // change to RC_TARGETTING mode if rc inputs have changed by more than the dead zone
384 : // should be called on every update
385 : void set_rctargeting_on_rcinput_change();
386 :
387 : // get angle targets (in radians) to ROI location
388 : // returns true on success, false on failure
389 : bool get_angle_target_to_roi(MountAngleTarget& angle_rad) const WARN_IF_UNUSED;
390 :
391 : // get angle targets (in radians) to home location
392 : // returns true on success, false on failure
393 : bool get_angle_target_to_home(MountAngleTarget& angle_rad) const WARN_IF_UNUSED;
394 :
395 : #if AP_MOUNT_ROI_WPNEXT_OFFSET_ENABLED
396 : // get angle targets (in radians) to next waypoint, with offsets previously supplied
397 : // returns true on success, false on failure
398 : bool get_angle_target_to_wpnext_offset(MountAngleTarget& angle_rad) const WARN_IF_UNUSED;
399 : #endif // AP_MOUNT_ROI_WPNEXT_OFFSET_ENABLED
400 :
401 : // get angle targets (in radians) to a vehicle with sysid of _target_sysid
402 : // returns true on success, false on failure
403 : bool get_angle_target_to_sysid(MountAngleTarget& angle_rad) const WARN_IF_UNUSED;
404 :
405 : // update angle targets using a given rate target
406 : // the resulting angle_rad yaw frame will match the rate_rad yaw frame
407 : // assumes a 50hz update rate
408 : void update_angle_target_from_rate(const MountRateTarget& rate_rad, MountAngleTarget& angle_rad) const;
409 :
410 : // helper function to provide GIMBAL_DEVICE_FLAGS for use in GIMBAL_DEVICE_ATTITUDE_STATUS message
411 : uint16_t get_gimbal_device_flags() const;
412 :
413 : // sent warning to GCS
414 : void send_warning_to_GCS(const char* warning_str);
415 :
416 : AP_Mount &_frontend; // reference to the front end which holds parameters
417 : AP_Mount_Params &_params; // parameters for this backend
418 : uint8_t _instance; // this instance's number
419 :
420 : MAV_MOUNT_MODE _mode; // current mode (see MAV_MOUNT_MODE enum)
421 :
422 : // structure for MAVLink Targeting angle and rate targets
423 : struct {
424 : MountTargetType target_type;// MAVLink targeting mode's current target type (e.g. angle or rate)
425 : MountAngleTarget angle_rad; // angle target in radians
426 : MountRateTarget rate_rads; // rate target in rad/s
427 : uint32_t last_rate_request_ms;
428 : uint32_t poi_start_ms; // time we started trying to find the gimbal POI for an AuxFunc::MOUNT_POI_LOCK
429 : bool pointing_at_poi_at_home_alt;
430 : } mnt_target;
431 :
432 : // RP earth frame locks accessible by backend
433 : bool _pitch_lock = true; // pitch_lock used in RC_TARGETING mode. True if the gimbal's tilt target is maintained in earth-frame, if false (aka "follow") it is maintained in body-frame
434 : bool _roll_lock = true; // roll_lock used in RC_TARGETING mode. True if the gimbal's roll target is maintained in earth-frame, if false (aka "follow") it is maintained in body-frame
435 :
436 : bool clear_roi_pending; // True if there is a pending clear ROI request
437 :
438 : private:
439 :
440 : // get pilot input (in the range -1 to +1) received through RC
441 : void get_rc_input(float& roll_in, float& pitch_in, float& yaw_in) const;
442 :
443 : // get angle targets (in radians) to a Location
444 : // returns true on success, false on failure
445 : bool get_angle_target_to_location(const Location &loc, MountAngleTarget& angle_rad) const WARN_IF_UNUSED;
446 :
447 : #if AP_MOUNT_POI_TO_LATLONALT_ENABLED
448 : // calculate the Location that the gimbal is pointing at
449 : void calculate_poi();
450 : #endif
451 :
452 : #if AP_MOUNT_POI_LOCK_ENABLED
453 : // calculate the Location that the gimbal is pointing at, assuming the target is at home altitude
454 : bool calculate_poi_at_home_alt(Location &target_location);
455 : #endif
456 :
457 : bool _yaw_lock; // yaw_lock used in RC_TARGETING mode. True if the gimbal's yaw target is maintained in earth-frame, if false (aka "follow") it is maintained in body-frame
458 :
459 : float _yaw_lock_heading_rad; // mount earth frame direction captured upon calling set_yaw_lock
460 :
461 : #if AP_MOUNT_POI_TO_LATLONALT_ENABLED
462 : struct {
463 : HAL_Semaphore sem; // semaphore protecting this structure
464 : uint32_t poi_request_ms; // system time POI was last requested
465 : uint32_t poi_update_ms; // system time POI was calculated
466 : Location loc; // gimbal location used for poi calculation
467 : Location poi_loc; // location of the POI
468 : Quaternion att_quat; // attitude quaternion of the gimbal
469 : } poi_calculation;
470 : #endif
471 :
472 : Location _roi_target; // roi target location
473 :
474 : #if AP_MOUNT_POI_LOCK_ENABLED
475 : void update_poi_lock_target();
476 :
477 : // mount mode saved here entering poi lock for
478 : // switching poi lock back to previous mode with aux function middle position
479 : MAV_MOUNT_MODE saved_mount_mode = MAV_MOUNT_MODE_ENUM_END;
480 : #endif // AP_MOUNT_POI_LOCK_ENABLED
481 :
482 : #if AP_MOUNT_ROI_WPNEXT_OFFSET_ENABLED
483 : Vector3f _roi_wpnext_rpy; // angular offsets for pointing-at-waypoint
484 : #endif // AP_MOUNT_ROI_WPNEXT_OFFSET_ENABLED
485 :
486 : uint8_t _target_sysid; // sysid to track
487 : Location _target_sysid_location;// sysid target location
488 : uint32_t _target_sysid_update_ms;// system time (ms) _target_sysid_location was last updated
489 :
490 : uint32_t _last_warning_ms; // system time of last warning sent to GCS
491 :
492 : // structure holding the last RC inputs
493 : struct {
494 : bool initialised;
495 : int16_t roll_in;
496 : int16_t pitch_in;
497 : int16_t yaw_in;
498 : } last_rc_input;
499 :
500 : // structure holding mavlink sysid and compid of controller of this gimbal
501 : // see MAV_CMD_DO_GIMBAL_MANAGER_CONFIGURE and GIMBAL_MANAGER_STATUS
502 : struct mavlink_control_id_t {
503 : uint8_t sysid;
504 : uint8_t compid;
505 :
506 : // equality operators
507 8 : bool operator==(const mavlink_control_id_t &rhs) const { return (sysid == rhs.sysid && compid == rhs.compid); }
508 8 : bool operator!=(const mavlink_control_id_t &rhs) const { return !(*this == rhs); }
509 : } mavlink_control_id;
510 :
511 : // SRV_Channel mount open function index
512 : SRV_Channel::Function _open_idx;
513 : };
514 :
515 : #endif // HAL_MOUNT_ENABLED
|