feat(camera_feedback): gate CAMERA_IMAGE_CAPTURED by param (#27920)

* feat(camera_feedback): gate CAMERA_IMAGE_CAPTURED by param

Some cameras implementing the MAVLink Camera Protocol (e.g. reached via
TRIG_INTERFACE=MAVLink) report CAMERA_IMAGE_CAPTURED themselves. The
autopilot's camera_feedback also emitted this message, so the ground
station saw duplicate capture messages for every shot.

Add a bool 'report' field to the camera_capture message, set from the new
CAM_CAP_REPORT parameter, and gate the CAMERA_IMAGE_CAPTURED stream on it.
When reporting is disabled the capture is still published and logged for
geotagging; only the MAVLink message to the ground station is suppressed.

CAM_CAP_REPORT applies live (no reboot); it only gates a MAVLink message,
unlike CAM_CAP_FBACK which reconfigures the capture pin.

* fix(camera_feedback): update docs
This commit is contained in:
Julian Oes
2026-07-22 20:03:50 +12:00
committed by GitHub
parent 2829c928c4
commit afa97475f0
8 changed files with 69 additions and 2 deletions

View File

@@ -179,6 +179,10 @@ PX4 emits the MAVLink [CAMERA_TRIGGER](https://mavlink.io/en/messages/common.htm
If camera capture is configured, the timestamp from the camera capture driver is used, otherwise the triggering timestamp.
:::
PX4 also reports each capture to the ground station as a [CAMERA_IMAGE_CAPTURED](https://mavlink.io/en/messages/common.html#CAMERA_IMAGE_CAPTURED) message.
This is controlled by [CAM_CAP_REPORT](../advanced_config/parameter_reference.md#CAM_CAP_REPORT), which is enabled by default and only needs to be disabled for cameras that report captures themselves (see [Capture Reporting](../camera/mavlink_v1_camera.md#capture-reporting)).
Captures are logged for geotagging either way.
## Testing Trigger Functionality
:::warning

View File

@@ -113,3 +113,11 @@ You can also [set the parameters directly](../advanced_config/parameters.md):
- [TRIG_INTERFACE](../advanced_config/parameter_reference.md#TRIG_INTERFACE) — `3`: MAVLink
:::
### Capture Reporting
Some MAVLink cameras emit [CAMERA_IMAGE_CAPTURED](https://mavlink.io/en/messages/common.html#CAMERA_IMAGE_CAPTURED) themselves each time an image is captured.
By default PX4 emits this message for every capture as well, so a ground station would see each capture reported twice.
Set [CAM_CAP_REPORT](../advanced_config/parameter_reference.md#CAM_CAP_REPORT) to `0` to stop PX4 reporting captures, leaving the camera as the only source of the message.
Captures are still logged for geotagging when reporting is disabled.

View File

@@ -7,3 +7,4 @@ float32 alt # Altitude (AMSL)
float32 ground_distance # Altitude above ground (meters)
float32[4] q # Attitude of the camera relative to NED earth-fixed frame when using a gimbal, otherwise vehicle attitude
int8 result # 1 for success, 0 for failure, -1 if camera does not provide feedback
bool report # Report this capture to the ground station (CAMERA_IMAGE_CAPTURED); it is always logged regardless

View File

@@ -38,4 +38,6 @@ px4_add_module(
CameraFeedback.hpp
DEPENDS
px4_work_queue
MODULE_CONFIG
camera_feedback_params.yaml
)

View File

@@ -46,6 +46,12 @@ CameraFeedback::CameraFeedback() :
if (_p_cam_cap_fback != PARAM_INVALID) {
param_get(_p_cam_cap_fback, (int32_t *)&_cam_cap_fback);
}
_p_cam_cap_report = param_find("CAM_CAP_REPORT");
if (_p_cam_cap_report != PARAM_INVALID) {
param_get(_p_cam_cap_report, &_cam_cap_report);
}
}
bool
@@ -70,6 +76,17 @@ CameraFeedback::Run()
return;
}
// Apply CAM_CAP_REPORT changes live (it only gates a MAVLink message, so no
// reboot needed). Checked here because it is only used when publishing below.
if (_parameter_update_sub.updated()) {
parameter_update_s pupdate;
_parameter_update_sub.copy(&pupdate);
if (_p_cam_cap_report != PARAM_INVALID) {
param_get(_p_cam_cap_report, &_cam_cap_report);
}
}
camera_trigger_s trig{};
while (_trigger_sub.update(&trig)) {
@@ -151,6 +168,12 @@ CameraFeedback::Run()
capture.result = 1;
// Cameras that report captures themselves (e.g. implementing the MAVLink
// Camera Protocol) set CAM_CAP_REPORT to 0 so we don't emit a duplicate
// CAMERA_IMAGE_CAPTURED.
// The capture is still published and logged for geotagging regardless.
capture.report = (_cam_cap_report != 0);
_capture_pub.publish(capture);
}
}
@@ -202,8 +225,10 @@ If camera capture is enabled, then trigger information from the camera capture p
otherwise trigger information at the point the camera was commanded to trigger is published
(from the `camera_trigger` module).
The `CAMERA_IMAGE_CAPTURED` message is then emitted (by streaming code) following `CameraCapture` updates.
`CameraCapture` topics are also logged and can be used for geotagging.
The `CAMERA_IMAGE_CAPTURED` message is then emitted (by streaming code) following `CameraCapture` updates,
unless `CAM_CAP_REPORT` is disabled (for cameras that report captures themselves, e.g. cameras
implementing the MAVLink Camera Protocol). `CameraCapture` topics are always logged and can be used
for geotagging regardless.
### Implementation

View File

@@ -53,6 +53,7 @@
#include <uORB/SubscriptionCallback.hpp>
#include <uORB/topics/camera_capture.h>
#include <uORB/topics/camera_trigger.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/gimbal_device_attitude_status.h>
@@ -85,9 +86,13 @@ private:
uORB::Subscription _gpos_sub{ORB_ID(vehicle_global_position)};
uORB::Subscription _att_sub{ORB_ID(vehicle_attitude)};
uORB::Subscription _gimbal_sub{ORB_ID(gimbal_device_attitude_status)};
uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)};
uORB::Publication<camera_capture_s> _capture_pub{ORB_ID(camera_capture)};
param_t _p_cam_cap_fback;
int32_t _cam_cap_fback{0};
param_t _p_cam_cap_report;
int32_t _cam_cap_report{1};
};

View File

@@ -0,0 +1,17 @@
module_name: camera_feedback
parameters:
- group: Camera Control
definitions:
CAM_CAP_REPORT:
description:
short: Report captures to the ground station
long: |
Whether the autopilot reports captures to the ground station by emitting
CAMERA_IMAGE_CAPTURED.
Disable for cameras that report captures themselves (e.g. cameras
implementing the MAVLink Camera Protocol) to avoid duplicate
CAMERA_IMAGE_CAPTURED messages. Capture events are still published on the
camera_capture topic and logged for geotagging regardless of this setting.
type: boolean
default: 1

View File

@@ -64,6 +64,11 @@ private:
camera_capture_s capture;
if ((_mavlink->get_free_tx_buf() >= get_size()) && _capture_sub.update(&capture)) {
if (!capture.report) {
// Camera reports captures itself (CAM_CAP_REPORT=0); don't duplicate.
return false;
}
mavlink_camera_image_captured_t msg{};
msg.time_boot_ms = capture.timestamp / 1000;