7#include <QtCore/QDateTime>
8#include <QtCore/QLoggingCategory>
9#include <QtCore/QtMath>
20 bool canCaptureImageInVideoMode,
21 bool canCaptureVideoInImageMode,
23 bool hasTrackingPoint,
24 bool hasTrackingRectangle)
28 uint32_t configuredFlags = 0;
29 if (captureVideo) configuredFlags |= CAMERA_CAP_FLAGS_CAPTURE_VIDEO;
30 if (captureImage) configuredFlags |= CAMERA_CAP_FLAGS_CAPTURE_IMAGE;
31 if (hasModes) configuredFlags |= CAMERA_CAP_FLAGS_HAS_MODES;
32 if (hasVideoStream) configuredFlags |= CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM;
33 if (canCaptureImageInVideoMode) configuredFlags |= CAMERA_CAP_FLAGS_CAN_CAPTURE_IMAGE_IN_VIDEO_MODE;
34 if (canCaptureVideoInImageMode) configuredFlags |= CAMERA_CAP_FLAGS_CAN_CAPTURE_VIDEO_IN_IMAGE_MODE;
35 if (hasBasicZoom) configuredFlags |= CAMERA_CAP_FLAGS_HAS_BASIC_ZOOM;
36 if (hasTrackingPoint) configuredFlags |= CAMERA_CAP_FLAGS_HAS_TRACKING_POINT;
37 if (hasTrackingRectangle) configuredFlags |= CAMERA_CAP_FLAGS_HAS_TRACKING_RECTANGLE;
40 _cameras[0].compId = MAV_COMP_ID_CAMERA;
41 _cameras[0].capFlags = configuredFlags;
42 _cameras[0].cameraMode = CAMERA_MODE_IMAGE;
43 if ((configuredFlags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM) && (configuredFlags & CAMERA_CAP_FLAGS_HAS_MODES)) {
44 _cameras[0].cameraMode = CAMERA_MODE_VIDEO;
48 _cameras[1].compId = MAV_COMP_ID_CAMERA2;
49 _cameras[1].capFlags = CAMERA_CAP_FLAGS_CAPTURE_IMAGE;
50 _cameras[1].cameraMode = CAMERA_MODE_IMAGE;
55 for (uint8_t i = 0; i < kNumCameras; i++) {
56 if (_cameras[i].compId == compId) {
63const char *MockLinkCamera::_imageCaptureStatusToString(uint8_t status)
70 default:
return "Unknown";
76 for (uint8_t i = 0; i < kNumCameras; i++) {
78 (void) mavlink_msg_heartbeat_pack_chan(
84 MAV_AUTOPILOT_INVALID,
96 QMutexLocker locker(&_camerasMutex);
97 const qint64 now = QDateTime::currentMSecsSinceEpoch();
99 for (uint8_t i = 0; i < kNumCameras; i++) {
108 qCDebug(MockLinkCameraLog) <<
"Camera" << cam->
compId <<
"single-shot complete, total:" << cam->
imagesCaptured;
109 _sendCameraImageCaptured(cam->
compId);
110 _sendCameraCaptureStatus(cam->
compId);
118 const double elapsed =
static_cast<double>(now - cam->
trackingStartMs) / 1000.0;
119 const float driftX = 0.05f *
static_cast<float>(qSin(elapsed * 0.7));
120 const float driftY = 0.05f *
static_cast<float>(qSin(elapsed * 1.1));
128 const float cx = std::clamp(cam->
trackAnchorX + driftX, halfW, 1.0f - halfW);
129 const float cy = std::clamp(cam->
trackAnchorY + driftY, halfH, 1.0f - halfH);
136 _sendCameraTrackingImageStatus(cam->
compId);
145 if (msg.msgid != MAVLINK_MSG_ID_COMMAND_LONG) {
150 mavlink_msg_command_long_decode(&msg, &request);
153 if (request.target_component < MAV_COMP_ID_CAMERA || request.target_component > MAV_COMP_ID_CAMERA6) {
157 const uint8_t targetCompId = request.target_component;
159 if (request.command == MAV_CMD_REQUEST_MESSAGE) {
160 return _handleRequestMessage(request, targetCompId);
163 return _handleCameraCommand(request, targetCompId);
171 QMutexLocker locker(&_camerasMutex);
172 CameraState *cam = _findCamera(targetCompId);
177 switch (request.command) {
178 case MAV_CMD_REQUEST_CAMERA_INFORMATION:
179 _sendCameraInformation(targetCompId);
180 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
183 case MAV_CMD_REQUEST_CAMERA_SETTINGS:
184 _sendCameraSettings(targetCompId);
185 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
188 case MAV_CMD_REQUEST_STORAGE_INFORMATION:
189 _sendStorageInformation(targetCompId);
190 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
193 case MAV_CMD_REQUEST_CAMERA_CAPTURE_STATUS:
194 _sendCameraCaptureStatus(targetCompId);
195 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
198 case MAV_CMD_REQUEST_VIDEO_STREAM_INFORMATION:
199 if (cam->capFlags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM) {
200 const uint8_t streamId =
static_cast<uint8_t
>(request.param1);
203 for (uint8_t s = 1; s <= kNumStreams; s++) {
204 _sendVideoStreamInformation(targetCompId, s);
207 _sendVideoStreamInformation(targetCompId, streamId);
209 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
211 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
215 case MAV_CMD_REQUEST_VIDEO_STREAM_STATUS:
216 if (cam->capFlags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM) {
217 const uint8_t streamId =
static_cast<uint8_t
>(request.param1);
219 for (uint8_t s = 1; s <= kNumStreams; s++) {
220 _sendVideoStreamStatus(targetCompId, s);
223 _sendVideoStreamStatus(targetCompId, streamId);
225 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
227 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
231 case MAV_CMD_SET_CAMERA_MODE:
232 if (cam->capFlags & CAMERA_CAP_FLAGS_HAS_MODES) {
233 const uint8_t requestedMode =
static_cast<uint8_t
>(request.param2);
235 if ((requestedMode != CAMERA_MODE_IMAGE) && (requestedMode != CAMERA_MODE_VIDEO)) {
236 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
240 const bool supportsImageMode =
241 (cam->capFlags & CAMERA_CAP_FLAGS_CAPTURE_IMAGE) ||
242 (cam->capFlags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM);
243 const bool supportsVideoMode =
244 (cam->capFlags & CAMERA_CAP_FLAGS_CAPTURE_VIDEO) ||
245 (cam->capFlags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM);
247 if ((requestedMode == CAMERA_MODE_IMAGE && !supportsImageMode) ||
248 (requestedMode == CAMERA_MODE_VIDEO && !supportsVideoMode)) {
249 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
253 cam->cameraMode = requestedMode;
254 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"mode set to" << cam->cameraMode;
255 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
257 _sendCameraSettings(targetCompId);
259 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
263 case MAV_CMD_IMAGE_START_CAPTURE:
264 if (cam->capFlags & CAMERA_CAP_FLAGS_CAPTURE_IMAGE) {
265 if ((cam->capFlags & CAMERA_CAP_FLAGS_HAS_MODES) &&
266 (cam->cameraMode == CAMERA_MODE_VIDEO) &&
267 !(cam->capFlags & CAMERA_CAP_FLAGS_CAN_CAPTURE_IMAGE_IN_VIDEO_MODE)) {
268 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
272 const float interval = request.param2;
273 const int count =
static_cast<int>(request.param3);
279 cam->image_interval = interval;
280 cam->imagesCaptured += (count > 0) ? count : 1;
281 cam->singleShotStartMs = 0;
285 cam->image_interval = 0.0f;
286 cam->singleShotStartMs = QDateTime::currentMSecsSinceEpoch();
289 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"image capture started"
290 <<
"interval:" << interval <<
"count:" << count;
291 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
293 _sendCameraCaptureStatus(targetCompId);
295 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
299 case MAV_CMD_IMAGE_STOP_CAPTURE:
300 if (cam->capFlags & CAMERA_CAP_FLAGS_CAPTURE_IMAGE) {
302 cam->image_interval = 0.0f;
303 cam->singleShotStartMs = 0;
304 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"image capture stopped";
305 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
306 _sendCameraCaptureStatus(targetCompId);
308 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
312 case MAV_CMD_VIDEO_START_CAPTURE:
313 if (cam->capFlags & CAMERA_CAP_FLAGS_CAPTURE_VIDEO) {
314 if ((cam->capFlags & CAMERA_CAP_FLAGS_HAS_MODES) &&
315 (cam->cameraMode == CAMERA_MODE_IMAGE) &&
316 !(cam->capFlags & CAMERA_CAP_FLAGS_CAN_CAPTURE_VIDEO_IN_IMAGE_MODE)) {
317 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
321 cam->recording =
true;
322 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"video recording started";
323 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
324 _sendCameraCaptureStatus(targetCompId);
326 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
330 case MAV_CMD_VIDEO_STOP_CAPTURE:
331 if (cam->capFlags & CAMERA_CAP_FLAGS_CAPTURE_VIDEO) {
332 cam->recording =
false;
333 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"video recording stopped";
334 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
335 _sendCameraCaptureStatus(targetCompId);
337 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
341 case MAV_CMD_STORAGE_FORMAT:
342 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"storage formatted";
343 cam->imagesCaptured = 0;
345 cam->image_interval = 0.0f;
346 cam->singleShotStartMs = 0;
347 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
348 _sendStorageInformation(targetCompId);
351 case MAV_CMD_SET_CAMERA_ZOOM:
352 if (cam->capFlags & CAMERA_CAP_FLAGS_HAS_BASIC_ZOOM) {
353 cam->zoomLevel = request.param2;
354 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"zoom set to" << cam->zoomLevel;
355 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
356 _sendCameraSettings(targetCompId);
358 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
362 case MAV_CMD_SET_CAMERA_FOCUS:
363 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
366 case MAV_CMD_RESET_CAMERA_SETTINGS:
367 cam->cameraMode = CAMERA_MODE_IMAGE;
368 cam->zoomLevel = 1.0f;
369 cam->focusLevel = 0.0f;
371 cam->image_interval = 0.0f;
372 cam->singleShotStartMs = 0;
373 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"settings reset";
374 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
375 _sendCameraSettings(targetCompId);
378 case MAV_CMD_CAMERA_TRACK_POINT:
379 if (cam->capFlags & CAMERA_CAP_FLAGS_HAS_TRACKING_POINT) {
380 cam->trackingMode = CAMERA_TRACKING_MODE_POINT;
381 cam->trackPointX = request.param1;
382 cam->trackPointY = request.param2;
383 cam->trackRadius = request.param3;
384 cam->trackAnchorX = request.param1;
385 cam->trackAnchorY = request.param2;
386 cam->trackingStartMs = QDateTime::currentMSecsSinceEpoch();
387 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"tracking point"
388 << cam->trackPointX << cam->trackPointY <<
"radius" << cam->trackRadius;
389 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
391 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
395 case MAV_CMD_CAMERA_TRACK_RECTANGLE:
396 if (cam->capFlags & CAMERA_CAP_FLAGS_HAS_TRACKING_RECTANGLE) {
397 cam->trackingMode = CAMERA_TRACKING_MODE_RECTANGLE;
398 cam->trackRecTopX = request.param1;
399 cam->trackRecTopY = request.param2;
400 cam->trackRecBottomX = request.param3;
401 cam->trackRecBottomY = request.param4;
402 cam->trackAnchorX = (request.param1 + request.param3) / 2.0f;
403 cam->trackAnchorY = (request.param2 + request.param4) / 2.0f;
404 cam->trackingStartMs = QDateTime::currentMSecsSinceEpoch();
405 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"tracking rectangle"
406 << cam->trackRecTopX << cam->trackRecTopY
407 <<
"->" << cam->trackRecBottomX << cam->trackRecBottomY;
408 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
410 _sendCommandAck(targetCompId, request.command, MAV_RESULT_DENIED);
414 case MAV_CMD_CAMERA_STOP_TRACKING:
415 cam->trackingMode = CAMERA_TRACKING_MODE_NONE;
416 cam->trackingStatusIntervalUs = -1;
417 cam->trackingStatusLastSentMs = 0;
418 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId <<
"tracking stopped";
419 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
422 case MAV_CMD_SET_MESSAGE_INTERVAL:
424 const int msgId =
static_cast<int>(request.param1);
425 if (msgId == MAVLINK_MSG_ID_CAMERA_TRACKING_IMAGE_STATUS) {
426 cam->trackingStatusIntervalUs =
static_cast<qint64
>(request.param2);
427 cam->trackingStatusLastSentMs = 0;
428 qCDebug(MockLinkCameraLog) <<
"Camera" << targetCompId
429 <<
"tracking status interval" << cam->trackingStatusIntervalUs <<
"us";
430 _sendCommandAck(targetCompId, request.command, MAV_RESULT_ACCEPTED);
433 _sendCommandAck(targetCompId, request.command, MAV_RESULT_UNSUPPORTED);
446 const CameraState *cam = _findCamera(targetCompId);
451 const int msgId =
static_cast<int>(request.param1);
454 case MAVLINK_MSG_ID_CAMERA_INFORMATION:
455 _sendCameraInformation(targetCompId);
456 _sendCommandAck(targetCompId, MAV_CMD_REQUEST_MESSAGE, MAV_RESULT_ACCEPTED, msgId);
459 case MAVLINK_MSG_ID_CAMERA_SETTINGS:
460 _sendCameraSettings(targetCompId);
461 _sendCommandAck(targetCompId, MAV_CMD_REQUEST_MESSAGE, MAV_RESULT_ACCEPTED, msgId);
464 case MAVLINK_MSG_ID_STORAGE_INFORMATION:
465 _sendStorageInformation(targetCompId);
466 _sendCommandAck(targetCompId, MAV_CMD_REQUEST_MESSAGE, MAV_RESULT_ACCEPTED, msgId);
469 case MAVLINK_MSG_ID_CAMERA_CAPTURE_STATUS:
470 _sendCameraCaptureStatus(targetCompId);
471 _sendCommandAck(targetCompId, MAV_CMD_REQUEST_MESSAGE, MAV_RESULT_ACCEPTED, msgId);
474 case MAVLINK_MSG_ID_VIDEO_STREAM_INFORMATION:
476 if (!(cam->capFlags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM)) {
477 _sendCommandAck(targetCompId, MAV_CMD_REQUEST_MESSAGE, MAV_RESULT_DENIED, msgId);
480 const uint8_t streamId =
static_cast<uint8_t
>(request.param2);
482 for (uint8_t s = 1; s <= kNumStreams; s++) {
483 _sendVideoStreamInformation(targetCompId, s);
486 _sendVideoStreamInformation(targetCompId, streamId);
488 _sendCommandAck(targetCompId, MAV_CMD_REQUEST_MESSAGE, MAV_RESULT_ACCEPTED, msgId);
492 case MAVLINK_MSG_ID_VIDEO_STREAM_STATUS:
494 if (!(cam->capFlags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM)) {
495 _sendCommandAck(targetCompId, MAV_CMD_REQUEST_MESSAGE, MAV_RESULT_DENIED, msgId);
498 const uint8_t streamId =
static_cast<uint8_t
>(request.param2);
500 for (uint8_t s = 1; s <= kNumStreams; s++) {
501 _sendVideoStreamStatus(targetCompId, s);
504 _sendVideoStreamStatus(targetCompId, streamId);
506 _sendCommandAck(targetCompId, MAV_CMD_REQUEST_MESSAGE, MAV_RESULT_ACCEPTED, msgId);
517void MockLinkCamera::_sendCameraInformation(uint8_t compId)
519 const CameraState *cam = _findCamera(compId);
524 const int cameraIndex = compId - MAV_COMP_ID_CAMERA;
526 const uint8_t vendorName[32] =
"MockLink";
527 const char cameraDefinitionUri[MAVLINK_MSG_CAMERA_INFORMATION_FIELD_CAM_DEFINITION_URI_LEN] = {};
528 const QString model = QStringLiteral(
"MockCam %1").arg(cameraIndex + 1);
529 QByteArray modelBA = model.toLocal8Bit();
530 modelBA.resize(MAVLINK_MSG_CAMERA_INFORMATION_FIELD_MODEL_NAME_LEN);
533 (void) mavlink_msg_camera_information_pack_chan(
540 reinterpret_cast<const uint8_t *
>(modelBA.constData()),
555 qCDebug(MockLinkCameraLog) <<
"Sent CAMERA_INFORMATION for compId:" << compId <<
"model:" << model;
558void MockLinkCamera::_sendCameraSettings(uint8_t compId)
560 const CameraState *cam = _findCamera(compId);
566 (void) mavlink_msg_camera_settings_pack_chan(
578 qCDebug(MockLinkCameraLog) <<
"Sent CAMERA_SETTINGS for compId:" << compId
579 <<
"mode:" << cam->cameraMode
580 <<
"zoom:" << cam->zoomLevel
581 <<
"focus:" << cam->focusLevel;
584void MockLinkCamera::_sendStorageInformation(uint8_t compId)
586 const char storageName[MAVLINK_MSG_STORAGE_INFORMATION_FIELD_NAME_LEN] = {};
589 (void) mavlink_msg_storage_information_pack_chan(
597 STORAGE_STATUS_READY,
598 static_cast<float>(kStorageTotalMiB),
599 static_cast<float>(kStorageTotalMiB - kStorageFreeMiB),
600 static_cast<float>(kStorageFreeMiB),
608 qCDebug(MockLinkCameraLog) <<
"Sent STORAGE_INFORMATION for compId:" << compId;
611void MockLinkCamera::_sendCameraCaptureStatus(uint8_t compId)
613 const CameraState *cam = _findCamera(compId);
619 (void) mavlink_msg_camera_capture_status_pack_chan(
626 cam->recording ? 1 : 0,
629 static_cast<float>(kStorageFreeMiB),
634 qCDebug(MockLinkCameraLog) <<
"Sent CAMERA_CAPTURE_STATUS for compId:" << compId
635 <<
"status:" << _imageCaptureStatusToString(cam->image_status)
636 <<
"interval:" << cam->image_interval
637 <<
"recording:" << cam->recording
638 <<
"images:" << cam->imagesCaptured;
641void MockLinkCamera::_sendCameraImageCaptured(uint8_t compId)
643 const CameraState *cam = _findCamera(compId);
650 const int32_t lat =
static_cast<int32_t
>(_mockLink->
vehicleLatitude() * 1e7);
651 const int32_t lon =
static_cast<int32_t
>(_mockLink->
vehicleLongitude() * 1e7);
653 const float q[4] = {1.0f, 0.0f, 0.0f, 0.0f};
654 const char fileUrl[MAVLINK_MSG_CAMERA_IMAGE_CAPTURED_FIELD_FILE_URL_LEN] = {};
657 (void) mavlink_msg_camera_image_captured_pack_chan(
664 (compId - MAV_COMP_ID_CAMERA) + 1,
675 qCDebug(MockLinkCameraLog) <<
"Sent CAMERA_IMAGE_CAPTURED for compId:" << compId
676 <<
"index:" << cam->imagesCaptured;
679void MockLinkCamera::_sendVideoStreamInformation(uint8_t compId, uint8_t streamId)
681 const int cameraIndex = compId - MAV_COMP_ID_CAMERA;
682 const QString name = QStringLiteral(
"Stream %1-%2").arg(cameraIndex + 1).arg(streamId);
683 QByteArray nameBA = name.toLocal8Bit();
684 nameBA.resize(MAVLINK_MSG_VIDEO_STREAM_INFORMATION_FIELD_NAME_LEN);
686 const QString uri = QStringLiteral(
"udp://127.0.0.1:5600");
687 QByteArray uriBA = uri.toLocal8Bit();
688 uriBA.resize(MAVLINK_MSG_VIDEO_STREAM_INFORMATION_FIELD_URI_LEN);
691 (void) mavlink_msg_video_stream_information_pack_chan(
698 VIDEO_STREAM_TYPE_RTPUDP,
699 VIDEO_STREAM_STATUS_FLAGS_RUNNING,
708 VIDEO_STREAM_ENCODING_H264,
712 qCDebug(MockLinkCameraLog) <<
"Sent VIDEO_STREAM_INFORMATION for compId:" << compId <<
"stream:" << streamId;
715void MockLinkCamera::_sendVideoStreamStatus(uint8_t compId, uint8_t streamId)
718 (void) mavlink_msg_video_stream_status_pack_chan(
724 VIDEO_STREAM_STATUS_FLAGS_RUNNING,
734 qCDebug(MockLinkCameraLog) <<
"Sent VIDEO_STREAM_STATUS for compId:" << compId <<
"stream:" << streamId;
737void MockLinkCamera::_sendCameraTrackingImageStatus(uint8_t compId)
739 const CameraState *cam = _findCamera(compId);
740 if (!cam || cam->trackingMode == CAMERA_TRACKING_MODE_NONE) {
745 (void) mavlink_msg_camera_tracking_image_status_pack_chan(
750 CAMERA_TRACKING_STATUS_FLAGS_ACTIVE,
752 CAMERA_TRACKING_TARGET_DATA_EMBEDDED,
758 cam->trackRecBottomX,
759 cam->trackRecBottomY,
764void MockLinkCamera::_sendCommandAck(uint8_t compId, uint16_t command, uint8_t result,
int requestedMsgId)
767 (void) mavlink_msg_command_ack_pack_chan(
781 QString logMsg = QStringLiteral(
"Sent COMMAND_ACK for compId: %1 command: %2 result: %3")
782 .arg(compId).arg(commandName).arg(result);
784 if (command == MAV_CMD_REQUEST_MESSAGE && requestedMsgId >= 0) {
785 const mavlink_message_info_t* info = mavlink_get_message_info_by_id(
static_cast<uint32_t
>(requestedMsgId));
786 QString msgName = info ? info->name : QString::number(requestedMsgId);
787 logMsg += QStringLiteral(
" requestedMsg: %1").arg(msgName);
790 qCDebug(MockLinkCameraLog) << logMsg;
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
struct __mavlink_command_long_t mavlink_command_long_t
uint8_t mavlinkChannel() const
static MissionCommandTree * instance()
QString rawName(MAV_CMD command) const
Returns the raw name for the specified command.
Simulates MAVLink Camera Protocol v2 components for MockLink.
void sendCameraHeartbeats()
Send heartbeats for all simulated camera components (call from 1Hz tasks)
bool handleMavlinkMessage(const mavlink_message_t &msg)
void run10HzTasks()
Update camera states (call from 10Hz tasks)
@ ImageCaptureInProgress
Single image capture in progress.
@ ImageCaptureInterval
Interval capture enabled.
@ ImageCaptureIntervalCapture
Interval capture with capture in progress.
@ ImageCaptureIdle
No capture in progress.
double vehicleAltitudeAMSL() const
void respondWithMavlinkMessage(const mavlink_message_t &msg)
Sends the specified mavlink message to QGC.
double vehicleLatitude() const
double vehicleLongitude() const
Per-camera simulated state.
qint64 trackingStatusLastSentMs
Timestamp of last tracking status message.
float trackAnchorX
Original center X of tracked target.
qint64 singleShotStartMs
Timestamp when single-shot capture started (0 = not active)
qint64 trackingStatusIntervalUs
Interval for CAMERA_TRACKING_IMAGE_STATUS (-1 = disabled)
qint64 trackingStartMs
Timestamp when tracking was started (for drift animation)
uint8_t trackingMode
CAMERA_TRACKING_MODE enum.
float trackAnchorY
Original center Y of tracked target.
uint8_t image_status
ImageCaptureStatus enum.