mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-26 12:53:35 +08:00
camera_trigger : optimize GCS test command handling
This commit is contained in:
committed by
Lorenz Meier
parent
0a80ee6c20
commit
3ebfb0cd27
@@ -47,6 +47,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <mathlib/mathlib.h>
|
#include <mathlib/mathlib.h>
|
||||||
#include <px4_workqueue.h>
|
#include <px4_workqueue.h>
|
||||||
#include <systemlib/systemlib.h>
|
#include <systemlib/systemlib.h>
|
||||||
@@ -60,10 +61,8 @@
|
|||||||
#include <uORB/topics/vehicle_command.h>
|
#include <uORB/topics/vehicle_command.h>
|
||||||
#include <uORB/topics/vehicle_command_ack.h>
|
#include <uORB/topics/vehicle_command_ack.h>
|
||||||
#include <uORB/topics/vehicle_local_position.h>
|
#include <uORB/topics/vehicle_local_position.h>
|
||||||
#include <poll.h>
|
|
||||||
#include <drivers/drv_gpio.h>
|
|
||||||
#include <drivers/drv_hrt.h>
|
#include <drivers/drv_hrt.h>
|
||||||
#include <board_config.h>
|
|
||||||
|
|
||||||
#include "interfaces/src/camera_interface.h"
|
#include "interfaces/src/camera_interface.h"
|
||||||
#include "interfaces/src/gpio.h"
|
#include "interfaces/src/gpio.h"
|
||||||
@@ -355,6 +354,7 @@ CameraTrigger::enable_keep_alive(bool on)
|
|||||||
void
|
void
|
||||||
CameraTrigger::toggle_power()
|
CameraTrigger::toggle_power()
|
||||||
{
|
{
|
||||||
|
|
||||||
// schedule power toggle calls
|
// schedule power toggle calls
|
||||||
hrt_call_after(&_engage_turn_on_off_call, 0,
|
hrt_call_after(&_engage_turn_on_off_call, 0,
|
||||||
(hrt_callout)&CameraTrigger::engange_turn_on_off, this);
|
(hrt_callout)&CameraTrigger::engange_turn_on_off, this);
|
||||||
@@ -383,7 +383,7 @@ CameraTrigger::start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prevent camera from sleeping, if triggering is enabled and the interface supports it
|
// Prevent camera from sleeping, if triggering is enabled and the interface supports it
|
||||||
if (_mode > 0 && _mode < 4 && _camera_interface->has_power_control()) {
|
if ((_mode > 0 && _mode < 4) && _camera_interface->has_power_control()) {
|
||||||
toggle_power();
|
toggle_power();
|
||||||
enable_keep_alive(true);
|
enable_keep_alive(true);
|
||||||
|
|
||||||
@@ -434,24 +434,66 @@ CameraTrigger::cycle_trampoline(void *arg)
|
|||||||
trig->_vcommand_sub = orb_subscribe(ORB_ID(vehicle_command));
|
trig->_vcommand_sub = orb_subscribe(ORB_ID(vehicle_command));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updated;
|
bool updated = false;
|
||||||
orb_check(trig->_vcommand_sub, &updated);
|
orb_check(trig->_vcommand_sub, &updated);
|
||||||
|
|
||||||
struct vehicle_command_s cmd = {};
|
struct vehicle_command_s cmd = {};
|
||||||
unsigned cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED;
|
unsigned cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED;
|
||||||
bool need_ack = false;
|
bool need_ack = false;
|
||||||
|
|
||||||
// while the trigger is inactive it has to be ready
|
// this flag is set when the polling loop is slowed down to allow the camera to power on
|
||||||
// to become active instantaneously
|
bool turning_on = false;
|
||||||
|
|
||||||
|
// while the trigger is inactive it has to be ready to become active instantaneously
|
||||||
int poll_interval_usec = 5000;
|
int poll_interval_usec = 5000;
|
||||||
|
|
||||||
if (trig->_mode < 3) {
|
// check for command update
|
||||||
|
if (updated) {
|
||||||
|
|
||||||
// Check update from command
|
orb_copy(ORB_ID(vehicle_command), trig->_vcommand_sub, &cmd);
|
||||||
|
|
||||||
|
// We always check for this command as it is used by the GCS to fire test shots
|
||||||
|
if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_DIGICAM_CONTROL) {
|
||||||
|
|
||||||
|
need_ack = true;
|
||||||
|
|
||||||
|
if (cmd.param5 > 0) {
|
||||||
|
|
||||||
|
// If camera isn't powered on, we enable power
|
||||||
|
// to it on getting the test command.
|
||||||
|
|
||||||
|
if (trig->_camera_interface->has_power_control() &&
|
||||||
|
!trig->_camera_interface->is_powered_on()) {
|
||||||
|
|
||||||
|
trig->toggle_power();
|
||||||
|
trig->enable_keep_alive(true);
|
||||||
|
|
||||||
|
// Give the camera time to turn on before starting to send trigger signals
|
||||||
|
poll_interval_usec = 3000000;
|
||||||
|
turning_on = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// One-shot trigger
|
||||||
|
trig->_trigger_enabled = true;
|
||||||
|
cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trig->_trigger_enabled && !turning_on) {
|
||||||
|
|
||||||
|
// One-shot trigger
|
||||||
|
trig->shoot_once();
|
||||||
|
trig->_trigger_enabled = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trig->_mode == 1) { // 1 - Command controlled mode
|
||||||
|
|
||||||
|
// Check for command update
|
||||||
if (updated) {
|
if (updated) {
|
||||||
|
|
||||||
orb_copy(ORB_ID(vehicle_command), trig->_vcommand_sub, &cmd);
|
|
||||||
|
|
||||||
if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_TRIGGER_CONTROL) {
|
if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_TRIGGER_CONTROL) {
|
||||||
|
|
||||||
need_ack = true;
|
need_ack = true;
|
||||||
@@ -480,98 +522,83 @@ CameraTrigger::cycle_trampoline(void *arg)
|
|||||||
|
|
||||||
cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
|
cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
|
||||||
|
|
||||||
} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_DIGICAM_CONTROL) {
|
|
||||||
|
|
||||||
need_ack = true;
|
|
||||||
|
|
||||||
if (cmd.param5 > 0) {
|
|
||||||
// One-shot trigger
|
|
||||||
trig->shoot_once();
|
|
||||||
cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} else if (trig->_mode == 3 || trig->_mode == 4) { // 3,4 - Distance controlled modes
|
||||||
|
|
||||||
} else if (trig->_mode == 4) {
|
// Set trigger based on covered distance
|
||||||
|
if (trig->_vlposition_sub < 0) {
|
||||||
|
trig->_vlposition_sub = orb_subscribe(ORB_ID(vehicle_local_position));
|
||||||
|
}
|
||||||
|
|
||||||
// Set trigger based on covered distance
|
struct vehicle_local_position_s pos = {};
|
||||||
if (trig->_vlposition_sub < 0) {
|
|
||||||
trig->_vlposition_sub = orb_subscribe(ORB_ID(vehicle_local_position));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vehicle_local_position_s pos;
|
orb_copy(ORB_ID(vehicle_local_position), trig->_vlposition_sub, &pos);
|
||||||
|
|
||||||
orb_copy(ORB_ID(vehicle_local_position), trig->_vlposition_sub, &pos);
|
if (pos.xy_valid) {
|
||||||
|
|
||||||
if (pos.xy_valid) {
|
// Check update from command
|
||||||
|
if (updated) {
|
||||||
|
|
||||||
bool turning_on = false;
|
if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_CAM_TRIGG_DIST) {
|
||||||
|
|
||||||
// Check update from command
|
need_ack = true;
|
||||||
if (updated) {
|
|
||||||
|
|
||||||
orb_copy(ORB_ID(vehicle_command), trig->_vcommand_sub, &cmd);
|
// Set trigger to disabled if the set distance is not positive
|
||||||
|
if (cmd.param1 > 0.0f && !trig->_trigger_enabled) {
|
||||||
|
|
||||||
if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_CAM_TRIGG_DIST) {
|
if (trig->_camera_interface->has_power_control()) {
|
||||||
|
trig->toggle_power();
|
||||||
|
trig->enable_keep_alive(true);
|
||||||
|
|
||||||
need_ack = true;
|
// Give the camera time to turn on, before starting to send trigger signals
|
||||||
|
poll_interval_usec = 3000000;
|
||||||
|
turning_on = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Set trigger to disabled if the set distance is not positive
|
} else if (cmd.param1 <= 0.0f && trig->_trigger_enabled) {
|
||||||
if (cmd.param1 > 0.0f && !trig->_trigger_enabled) {
|
|
||||||
|
|
||||||
if (trig->_camera_interface->has_power_control()) {
|
hrt_cancel(&(trig->_engagecall));
|
||||||
trig->toggle_power();
|
hrt_cancel(&(trig->_disengagecall));
|
||||||
trig->enable_keep_alive(true);
|
|
||||||
|
if (trig->_camera_interface->has_power_control()) {
|
||||||
|
trig->enable_keep_alive(false);
|
||||||
|
trig->toggle_power();
|
||||||
|
}
|
||||||
|
|
||||||
// Give the camera time to turn on, before starting to send trigger signals
|
|
||||||
poll_interval_usec = 5000000;
|
|
||||||
turning_on = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (cmd.param1 <= 0.0f && trig->_trigger_enabled) {
|
trig->_trigger_enabled = cmd.param1 > 0.0f;
|
||||||
|
trig->_distance = cmd.param1;
|
||||||
|
|
||||||
hrt_cancel(&(trig->_engagecall));
|
cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
|
||||||
hrt_cancel(&(trig->_disengagecall));
|
|
||||||
|
|
||||||
if (trig->_camera_interface->has_power_control()) {
|
|
||||||
trig->enable_keep_alive(false);
|
|
||||||
trig->toggle_power();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trig->_trigger_enabled = cmd.param1 > 0.0f;
|
if (trig->_trigger_enabled && !turning_on) {
|
||||||
trig->_distance = cmd.param1;
|
|
||||||
|
|
||||||
cmd_result = vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED;
|
// Initialize position if not done yet
|
||||||
|
math::Vector<2> current_position(pos.x, pos.y);
|
||||||
|
|
||||||
|
if (!trig->_valid_position) {
|
||||||
|
// First time valid position, take first shot
|
||||||
|
trig->_last_shoot_position = current_position;
|
||||||
|
trig->_valid_position = pos.xy_valid;
|
||||||
|
trig->shoot_once();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that distance threshold is exceeded
|
||||||
|
if ((trig->_last_shoot_position - current_position).length() >= trig->_distance) {
|
||||||
|
trig->shoot_once();
|
||||||
|
trig->_last_shoot_position = current_position;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
poll_interval_usec = 100000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trig->_trigger_enabled && !turning_on) {
|
|
||||||
|
|
||||||
// Initialize position if not done yet
|
|
||||||
math::Vector<2> current_position(pos.x, pos.y);
|
|
||||||
|
|
||||||
if (!trig->_valid_position) {
|
|
||||||
// First time valid position, take first shot
|
|
||||||
trig->_last_shoot_position = current_position;
|
|
||||||
trig->_valid_position = pos.xy_valid;
|
|
||||||
trig->shoot_once();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that distance threshold is exceeded
|
|
||||||
if ((trig->_last_shoot_position - current_position).length() >= trig->_distance) {
|
|
||||||
trig->shoot_once();
|
|
||||||
trig->_last_shoot_position = current_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
poll_interval_usec = 100000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
* @file camera_trigger_params.c
|
* @file camera_trigger_params.c
|
||||||
* Camera trigger parameters
|
* Camera trigger parameters
|
||||||
*
|
*
|
||||||
* @author Mohammed Kabir <mhkabir98@gmail.com>
|
* @author Mohammed Kabir <kabir@uasys.io>
|
||||||
* @author Andreas Bircher <andreas@wingtra.com>
|
* @author Andreas Bircher <andreas@wingtra.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool has_power_control() { return false; }
|
virtual bool has_power_control() { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the camera connected to the interface
|
||||||
|
* is turned on.
|
||||||
|
* @return true if camera is on
|
||||||
|
*/
|
||||||
|
virtual bool is_powered_on() { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public:
|
|||||||
|
|
||||||
bool has_power_control() { return true; }
|
bool has_power_control() { return true; }
|
||||||
|
|
||||||
|
bool is_powered_on() { return _camera_is_on; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup();
|
void setup();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user