PX4 Firmware
PX4 Autopilot Software http://px4.io
camera_trigger.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2015-2017 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file camera_trigger.cpp
36  *
37  * External camera-IMU synchronisation and triggering, and support for
38  * camera manipulation using PWM signals over FMU auxillary pins.
39  *
40  * @author Mohammed Kabir <kabir@uasys.io>
41  * @author Kelly Steich <kelly.steich@wingtra.com>
42  * @author Andreas Bircher <andreas@wingtra.com>
43  */
44 
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <fcntl.h>
49 #include <stdbool.h>
50 #include <poll.h>
51 #include <mathlib/mathlib.h>
52 #include <matrix/math.hpp>
53 #include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
54 #include <systemlib/err.h>
55 #include <parameters/param.h>
56 #include <systemlib/mavlink_log.h>
57 
59 #include <uORB/Subscription.hpp>
67 
68 #include <drivers/drv_hrt.h>
69 
71 #include "interfaces/src/gpio.h"
72 #include "interfaces/src/pwm.h"
74 
75 extern "C" __EXPORT int camera_trigger_main(int argc, char *argv[]);
76 
77 typedef enum : int32_t {
84 
85 typedef enum : int32_t {
92 
93 #define commandParamToInt(n) static_cast<int>(n >= 0 ? n + 0.5f : n - 0.5f)
94 
95 class CameraTrigger : public px4::ScheduledWorkItem
96 {
97 public:
98  /**
99  * Constructor
100  */
101  CameraTrigger();
102 
103  /**
104  * Destructor, also kills task.
105  */
106  ~CameraTrigger() override;
107 
108  /**
109  * Run intervalometer update
110  */
111  void update_intervalometer();
112 
113  /**
114  * Run distance-based trigger update
115  */
116  void update_distance();
117 
118  /**
119  * Trigger the camera just once
120  */
121  void shoot_once();
122 
123  /**
124  * Toggle keep camera alive functionality
125  */
126  void enable_keep_alive(bool on);
127 
128  /**
129  * Toggle camera power (on/off)
130  */
131  void toggle_power();
132 
133  /**
134  * Start the task.
135  */
136  bool start();
137 
138  /**
139  * Stop the task.
140  */
141  void stop();
142 
143  /**
144  * Display status.
145  */
146  void status();
147 
148  /**
149  * Trigger one image
150  */
151  void test();
152 
153 private:
154 
161 
163  float _interval;
164  float _distance;
165  uint32_t _trigger_seq;
168  bool _one_shot;
173 
175  uORB::Subscription _lpos_sub{ORB_ID(vehicle_local_position)};
176 
178 
180 
187 
189  int32_t _cam_cap_fback;
190 
192  CameraInterface *_camera_interface; ///< instance of camera interface
193 
194  /**
195  * Vehicle command handler
196  */
197  void Run() override;
198 
199  /**
200  * Fires trigger
201  */
202  static void engage(void *arg);
203 
204  /**
205  * Resets trigger
206  */
207  static void disengage(void *arg);
208 
209  /**
210  * Fires on/off
211  */
212  static void engange_turn_on_off(void *arg);
213 
214  /**
215  * Resets on/off
216  */
217  static void disengage_turn_on_off(void *arg);
218 
219  /**
220  * Enables keep alive signal
221  */
222  static void keep_alive_up(void *arg);
223  /**
224  * Disables keep alive signal
225  */
226  static void keep_alive_down(void *arg);
227 
228 };
229 
230 namespace camera_trigger
231 {
233 }
234 
236  ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::lp_default),
237  _engagecall {},
238  _disengagecall {},
243  _activation_time(0.5f /* ms */),
244  _interval(100.0f /* ms */),
245  _distance(25.0f /* m */),
246  _trigger_seq(0),
247  _trigger_enabled(false),
248  _trigger_paused(false),
249  _one_shot(false),
250  _test_shot(false),
251  _turning_on(false),
252  _last_shoot_position(0.0f, 0.0f),
253  _valid_position(false),
254  _trigger_pub(nullptr),
256  _cam_cap_fback(0),
258  _camera_interface(nullptr)
259 {
260  // Initiate camera interface based on camera_interface_mode
261  if (_camera_interface != nullptr) {
262  delete (_camera_interface);
263  // set to zero to ensure parser is not used while not instantiated
264  _camera_interface = nullptr;
265  }
266 
267  // Parameters
268  _p_interval = param_find("TRIG_INTERVAL");
269  _p_distance = param_find("TRIG_DISTANCE");
270  _p_activation_time = param_find("TRIG_ACT_TIME");
271  _p_mode = param_find("TRIG_MODE");
272  _p_interface = param_find("TRIG_INTERFACE");
273  _p_cam_cap_fback = param_find("CAM_CAP_FBACK");
274 
278  param_get(_p_mode, (int32_t *)&_trigger_mode);
281 
282  switch (_camera_interface_mode) {
283 #ifdef __PX4_NUTTX
284 
286  _camera_interface = new CameraInterfaceGPIO();
287  break;
288 
290  _camera_interface = new CameraInterfacePWM();
291  break;
292 
294  _camera_interface = new CameraInterfaceSeagull();
295  break;
296 
297 #endif
298 
300  // start an interface that does nothing. Instead mavlink will listen to the camera_trigger uORB message
302  break;
303 
304  default:
305  PX4_ERR("unknown camera interface mode: %i", (int)_camera_interface_mode);
306  break;
307  }
308 
309  // Enforce a lower bound on the activation interval in PWM modes to not miss
310  // engage calls in-between 50Hz PWM pulses. (see PX4 PR #6973)
311  if ((_activation_time < 40.0f) &&
312  (_camera_interface_mode == CAMERA_INTERFACE_MODE_GENERIC_PWM ||
313  _camera_interface_mode == CAMERA_INTERFACE_MODE_SEAGULL_MAP2_PWM)) {
314  _activation_time = 40.0f;
315  PX4_WARN("Trigger interval too low for PWM interface, setting to 40 ms");
317  }
318 
319  // Advertise critical publishers here, because we cannot advertise in interrupt context
320  struct camera_trigger_s trigger = {};
321 
322  if (!_cam_cap_fback) {
324 
325  } else {
326  _trigger_pub = orb_advertise(ORB_ID(camera_trigger_secondary), &trigger);
327  }
328 }
329 
331 {
332  if (_camera_interface != nullptr) {
333  delete (_camera_interface);
334  }
335 
337 }
338 
339 void
341 {
342  // the actual intervalometer runs in interrupt context, so we only need to call
343  // control_intervalometer once on enabling/disabling trigger to schedule the calls.
344 
346  // schedule trigger on and off calls
347  hrt_call_every(&_engagecall, 0, (_interval * 1000),
349 
350  // schedule trigger on and off calls
351  hrt_call_every(&_disengagecall, 0 + (_activation_time * 1000), (_interval * 1000),
353 
354  }
355 }
356 
357 void
359 {
360  if (_turning_on) {
361  return;
362  }
363 
364  if (_trigger_enabled) {
365  vehicle_local_position_s local{};
366  _lpos_sub.copy(&local);
367 
368  if (local.xy_valid) {
369 
370  // Initialize position if not done yet
371  matrix::Vector2f current_position(local.x, local.y);
372 
373  if (!_valid_position) {
374  // First time valid position, take first shot
375  _last_shoot_position = current_position;
376  _valid_position = local.xy_valid;
377  shoot_once();
378  }
379 
380  // Check that distance threshold is exceeded
381  if (matrix::Vector2f(_last_shoot_position - current_position).length() >= _distance) {
382  shoot_once();
383  _last_shoot_position = current_position;
384 
385  }
386  }
387  }
388 }
389 
390 void
392 {
393  if (on) {
394  // schedule keep-alive up and down calls
395  hrt_call_every(&_keepalivecall_up, 0, (60000 * 1000),
397 
398  hrt_call_every(&_keepalivecall_down, 0 + (30000 * 1000), (60000 * 1000),
400 
401  } else {
402  // cancel all calls
405  }
406 }
407 
408 void
410 {
411  // schedule power toggle calls
414 
415  hrt_call_after(&_disengage_turn_on_off_call, 0 + (200 * 1000),
417 }
418 
419 void
421 {
422  if (!_trigger_paused) {
423  // schedule trigger on and off calls
426 
429  }
430 }
431 
432 bool
434 {
435  if (_camera_interface == nullptr) {
436  if (camera_trigger::g_camera_trigger != nullptr) {
439 
440  }
441 
442  return false;
443  }
444 
449 
450  // If in always-on mode and the interface supports it, enable power to the camera
451  toggle_power();
452  enable_keep_alive(true);
453 
454  } else {
455  enable_keep_alive(false);
456  }
457 
458  // enable immediately if configured that way
460  // enable and start triggering
461  _trigger_enabled = true;
463 
465  // just enable, but do not fire. actual trigger is based on distance covered
466  _trigger_enabled = true;
467  }
468 
469  // start to monitor at high rate for trigger enable command
470  ScheduleNow();
471 
472  return true;
473 }
474 
475 void
477 {
478  ScheduleClear();
479 
486 
487  if (camera_trigger::g_camera_trigger != nullptr) {
490  }
491 }
492 
493 void
495 {
496  vehicle_command_s vcmd{};
497  vcmd.timestamp = hrt_absolute_time();
498  vcmd.param5 = 1.0;
499  vcmd.command = vehicle_command_s::VEHICLE_CMD_DO_DIGICAM_CONTROL;
500 
501  uORB::PublicationQueued<vehicle_command_s> vcmd_pub{ORB_ID(vehicle_command)};
502  vcmd_pub.publish(vcmd);
503 }
504 
505 void
507 {
508  // default loop polling interval
509  int poll_interval_usec = 5000;
510 
511  vehicle_command_s cmd{};
512  unsigned cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED;
513  bool need_ack = false;
514 
515  // this flag is set when the polling loop is slowed down to allow the camera to power on
516  _turning_on = false;
517 
518  // these flags are used to detect state changes in the command loop
519  bool main_state = _trigger_enabled;
520  bool pause_state = _trigger_paused;
521 
522  bool updated = _command_sub.update(&cmd);
523 
524  // Command handling
525  if (updated) {
526  if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_DIGICAM_CONTROL) {
527 
528  need_ack = true;
529 
530  if (commandParamToInt(cmd.param7) == 1) {
531  // test shots are not logged or forwarded to GCS for geotagging
532  _test_shot = true;
533  }
534 
535  if (commandParamToInt((float)cmd.param5) == 1) {
536  // Schedule shot
537  _one_shot = true;
538  }
539 
540  cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
541 
542  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_TRIGGER_CONTROL) {
543 
544  need_ack = true;
545 
546  if (commandParamToInt(cmd.param3) == 1) {
547  // pause triggger
548  _trigger_paused = true;
549 
550  } else if (commandParamToInt(cmd.param3) == 0) {
551  _trigger_paused = false;
552  }
553 
554  if (commandParamToInt(cmd.param2) == 1) {
555  // reset trigger sequence
556  _trigger_seq = 0;
557  }
558 
559  if (commandParamToInt(cmd.param1) == 1) {
560  _trigger_enabled = true;
561 
562  } else if (commandParamToInt(cmd.param1) == 0) {
563  _trigger_enabled = false;
564  }
565 
566  cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
567 
568  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_CAM_TRIGG_DIST) {
569 
570  need_ack = true;
571 
572  /*
573  * TRANSITIONAL SUPPORT ADDED AS OF 11th MAY 2017 (v1.6 RELEASE)
574  */
575 
576  if (cmd.param1 > 0.0f) {
577  _distance = cmd.param1;
579 
580  _trigger_enabled = true;
581  _trigger_paused = false;
582 
583  } else if (commandParamToInt(cmd.param1) == 0) {
584  _trigger_paused = true;
585 
586  } else if (commandParamToInt(cmd.param1) == -1) {
587  _trigger_enabled = false;
588  }
589 
590  // We can only control the shutter integration time of the camera in GPIO mode (for now)
591  if (cmd.param2 > 0.0f) {
593  _activation_time = cmd.param2;
595  }
596  }
597 
598  // Trigger once immediately if param is set
599  if (cmd.param3 > 0.0f) {
600  // Schedule shot
601  _one_shot = true;
602  }
603 
604  cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
605 
606  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_CAM_TRIGG_INTERVAL) {
607 
608  need_ack = true;
609 
610  if (cmd.param1 > 0.0f) {
611  _interval = cmd.param1;
613  }
614 
615  // We can only control the shutter integration time of the camera in GPIO mode
616  if (cmd.param2 > 0.0f) {
618  _activation_time = cmd.param2;
620  }
621  }
622 
623  cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
624  }
625  }
626 
627  // State change handling
628  if ((main_state != _trigger_enabled) ||
629  (pause_state != _trigger_paused) ||
630  _one_shot) {
631 
632  if (_trigger_enabled || _one_shot) { // Just got enabled via a command
633 
634  // If camera isn't already powered on, we enable power to it
637 
638  toggle_power();
639  enable_keep_alive(true);
640 
641  // Give the camera time to turn on before starting to send trigger signals
642  poll_interval_usec = 3000000;
643  _turning_on = true;
644  }
645 
646  } else if (!_trigger_enabled || _trigger_paused) { // Just got disabled/paused via a command
647 
648  // Power off the camera if we are disabled
651  !_trigger_enabled) {
652 
653  enable_keep_alive(false);
654  toggle_power();
655  }
656 
657  // cancel all calls for both disabled and paused
660 
661  // ensure that the pin is off
663 
664  // reset distance counter if needed
667 
668  // this will force distance counter reinit on getting enabled/unpaused
669  _valid_position = false;
670  }
671  }
672 
673  // only run on state changes, not every loop iteration
675  // update intervalometer state and reset calls
677  }
678  }
679 
680  // run every loop iteration and trigger if needed
683 
684  // update distance counter and trigger
685  update_distance();
686  }
687 
688  // One shot command-based capture handling
689  if (_one_shot && !_turning_on) {
690 
691  // One-shot trigger
692  shoot_once();
693  _one_shot = false;
694 
695  if (_test_shot) {
696  _test_shot = false;
697  }
698  }
699 
700  // Command ACK handling
701  if (updated && need_ack) {
702  vehicle_command_ack_s command_ack{};
703 
704  command_ack.timestamp = hrt_absolute_time();
705  command_ack.command = cmd.command;
706  command_ack.result = (uint8_t)cmd_result;
707  command_ack.target_system = cmd.source_system;
708  command_ack.target_component = cmd.source_component;
709 
710  _cmd_ack_pub.publish(command_ack);
711  }
712 
713  ScheduleDelayed(poll_interval_usec);
714 }
715 
716 void
718 {
719  CameraTrigger *trig = static_cast<CameraTrigger *>(arg);
720 
721  // Trigger the camera
722  trig->_camera_interface->trigger(true);
723 
724  if (trig->_test_shot) {
725  // do not send messages or increment frame count for test shots
726  return;
727  }
728 
729  // Send camera trigger message. This messages indicates that we sent
730  // the camera trigger request. Does not guarantee capture.
731 
732  struct camera_trigger_s trigger = {};
733 
734  // Set timestamp the instant after the trigger goes off
735  trigger.timestamp = hrt_absolute_time();
736 
737  timespec tv = {};
738  px4_clock_gettime(CLOCK_REALTIME, &tv);
739  trigger.timestamp_utc = (uint64_t) tv.tv_sec * 1000000 + tv.tv_nsec / 1000;
740 
741  trigger.seq = trig->_trigger_seq;
742  trigger.feedback = false;
743 
744  if (!trig->_cam_cap_fback) {
745  orb_publish(ORB_ID(camera_trigger), trig->_trigger_pub, &trigger);
746 
747  } else {
748  orb_publish(ORB_ID(camera_trigger_secondary), trig->_trigger_pub, &trigger);
749  }
750 
751  // increment frame count
752  trig->_trigger_seq++;
753 }
754 
755 void
757 {
758  CameraTrigger *trig = static_cast<CameraTrigger *>(arg);
759 
760  trig->_camera_interface->trigger(false);
761 }
762 
763 void
765 {
766  CameraTrigger *trig = static_cast<CameraTrigger *>(arg);
767 
769 }
770 
771 void
773 {
774  CameraTrigger *trig = static_cast<CameraTrigger *>(arg);
775 
776  trig->_camera_interface->send_toggle_power(false);
777 }
778 
779 void
781 {
782  CameraTrigger *trig = static_cast<CameraTrigger *>(arg);
783 
784  trig->_camera_interface->send_keep_alive(true);
785 }
786 
787 void
789 {
790  CameraTrigger *trig = static_cast<CameraTrigger *>(arg);
791 
792  trig->_camera_interface->send_keep_alive(false);
793 }
794 
795 void
797 {
798  PX4_INFO("main state : %s", _trigger_enabled ? "enabled" : "disabled");
799  PX4_INFO("pause state : %s", _trigger_paused ? "paused" : "active");
800  PX4_INFO("mode : %i", _trigger_mode);
801 
804  PX4_INFO("interval : %.2f [ms]", (double)_interval);
805 
808  PX4_INFO("distance : %.2f [m]", (double)_distance);
809  }
810 
812  PX4_INFO("camera power : %s", _camera_interface->is_powered_on() ? "ON" : "OFF");
813  }
814 
815  PX4_INFO("activation time : %.2f [ms]", (double)_activation_time);
817 }
818 
819 static int usage()
820 {
821  PX4_INFO("usage: camera_trigger {start|stop|status|test|test_power}\n");
822  return 1;
823 }
824 
825 int camera_trigger_main(int argc, char *argv[])
826 {
827  if (argc < 2) {
828  return usage();
829  }
830 
831  if (!strcmp(argv[1], "start")) {
832 
833  if (camera_trigger::g_camera_trigger != nullptr) {
834  PX4_WARN("already running");
835  return 0;
836  }
837 
839 
840  if (camera_trigger::g_camera_trigger == nullptr) {
841  PX4_WARN("alloc failed");
842  return 1;
843  }
844 
846  PX4_WARN("failed to start camera trigger");
847  return 1;
848  }
849 
850  return 0;
851  }
852 
853  if (camera_trigger::g_camera_trigger == nullptr) {
854  PX4_WARN("not running");
855  return 1;
856 
857  } else if (!strcmp(argv[1], "stop")) {
859 
860  } else if (!strcmp(argv[1], "status")) {
862 
863  } else if (!strcmp(argv[1], "test")) {
865 
866  } else if (!strcmp(argv[1], "test_power")) {
868 
869  } else {
870  return usage();
871  }
872 
873  return 0;
874 }
param_t _p_cam_cap_fback
void status()
Display status.
Interface with cameras via pwm.
static void keep_alive_up(void *arg)
Enables keep alive signal.
CameraTrigger()
Constructor.
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
Definition: parameters.cpp:589
static void disengage_turn_on_off(void *arg)
Resets on/off.
struct hrt_call _keepalivecall_up
struct hrt_call _disengage_turn_on_off_call
static int usage()
__EXPORT int param_set_no_notification(param_t param, const void *val)
Set the value of a parameter, but do not notify the system about the change.
Definition: parameters.cpp:820
void(* hrt_callout)(void *arg)
Callout function type.
Definition: drv_hrt.h:67
virtual void send_toggle_power(bool enable)
send command to turn the camera on/off
~CameraTrigger() override
Destructor, also kills task.
Definition: I2C.hpp:51
bool publish(const T &data)
Publish the struct.
orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data)
Definition: uORB.cpp:43
virtual bool is_powered_on()
Checks if the camera connected to the interface is turned on.
bool start()
Start the task.
High-resolution timer with callouts and timekeeping.
CameraInterface * _camera_interface
instance of camera interface
uint64_t timestamp_utc
uORB::Subscription _lpos_sub
void stop()
Stop the task.
Global flash based parameter store.
__EXPORT int camera_trigger_main(int argc, char *argv[])
static void engage(void *arg)
Fires trigger.
void toggle_power()
Toggle camera power (on/off)
param_t _p_activation_time
orb_advert_t _trigger_pub
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
__EXPORT void hrt_call_after(struct hrt_call *entry, hrt_abstime delay, hrt_callout callout, void *arg)
Call callout(arg) after delay has elapsed.
static void keep_alive_down(void *arg)
Disables keep alive signal.
static void engange_turn_on_off(void *arg)
Fires on/off.
virtual void send_keep_alive(bool enable)
send command to prevent the camera from sleeping
void * arg
Definition: drv_hrt.h:78
trigger_mode_t _trigger_mode
void shoot_once()
Trigger the camera just once.
void update_distance()
Run distance-based trigger update.
virtual void info()
Display info.
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
void enable_keep_alive(bool on)
Toggle keep camera alive functionality.
virtual void trigger(bool trigger_on_true)
trigger the camera
struct hrt_call _engage_turn_on_off_call
struct hrt_call _disengagecall
__EXPORT void hrt_call_every(struct hrt_call *entry, hrt_abstime delay, hrt_abstime interval, hrt_callout callout, void *arg)
Call callout(arg) after delay, and then after every interval.
CameraTrigger * g_camera_trigger
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
Definition: uORB.cpp:70
struct hrt_call _keepalivecall_down
void update_intervalometer()
Run intervalometer update.
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
Definition: parameters.cpp:370
Interface supported cameras using a Seagull MAP2 interface.
void Run() override
Vehicle command handler.
uint32_t _trigger_seq
struct hrt_call _engagecall
uORB::Subscription _command_sub
matrix::Vector2f _last_shoot_position
trigger_mode_t
camera_interface_mode_t _camera_interface_mode
Definition: bst.cpp:62
Callout record.
Definition: drv_hrt.h:72
int32_t _cam_cap_fback
uORB::PublicationQueued< vehicle_command_ack_s > _cmd_ack_pub
bool update(void *dst)
Update the struct.
virtual bool has_power_control()
Checks if the interface has support for camera power control.
#define commandParamToInt(n)
void test()
Trigger one image.
static void disengage(void *arg)
Resets trigger.
bool copy(void *dst)
Copy the struct.
camera_interface_mode_t
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
uint32_t param_t
Parameter handle.
Definition: param.h:98
__EXPORT void hrt_cancel(struct hrt_call *entry)
Remove the entry from the callout list.