Commit 5776de49 authored by Gus Grubba's avatar Gus Grubba

Handle mode change through (known) parameter (if it exists)

Keep track of recording time if camera doesn't provide it.
Make sure camera info is received (if camera ACKs the request)
Keep track of camera's heartbeat. Remove camera if not heard from after a while.
Update MAVLink
parent f5d6ff4d
Subproject commit 90d9b285e01fe8bfa3b4e8868ca71c5537d43302 Subproject commit c847642263deefa584691eebade8b29a25264442
...@@ -67,6 +67,7 @@ static const char *kCAM_ISO = "CAM_ISO"; ...@@ -67,6 +67,7 @@ static const char *kCAM_ISO = "CAM_ISO";
static const char* kCAM_SHUTTER = "CAM_SHUTTER"; static const char* kCAM_SHUTTER = "CAM_SHUTTER";
static const char* kCAM_APERTURE = "CAM_APERTURE"; static const char* kCAM_APERTURE = "CAM_APERTURE";
static const char* kCAM_WBMODE = "CAM_WBMODE"; static const char* kCAM_WBMODE = "CAM_WBMODE";
static const char* kCAM_MODE = "CAM_MODE";
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QGCCameraOptionExclusion::QGCCameraOptionExclusion(QObject* parent, QString param_, QString value_, QStringList exclusions_) QGCCameraOptionExclusion::QGCCameraOptionExclusion(QObject* parent, QString param_, QString value_, QStringList exclusions_)
...@@ -176,16 +177,9 @@ QGCCameraControl::QGCCameraControl(const mavlink_camera_information_t *info, Veh ...@@ -176,16 +177,9 @@ QGCCameraControl::QGCCameraControl(const mavlink_camera_information_t *info, Veh
_photoMode = static_cast<PhotoMode>(settings.value(kPhotoMode, static_cast<int>(PHOTO_CAPTURE_SINGLE)).toInt()); _photoMode = static_cast<PhotoMode>(settings.value(kPhotoMode, static_cast<int>(PHOTO_CAPTURE_SINGLE)).toInt());
_photoLapse = settings.value(kPhotoLapse, 1.0).toDouble(); _photoLapse = settings.value(kPhotoLapse, 1.0).toDouble();
_photoLapseCount = settings.value(kPhotoLapseCount, 0).toInt(); _photoLapseCount = settings.value(kPhotoLapseCount, 0).toInt();
//-- Check for video streaming _recTimer.setSingleShot(false);
if(_info.flags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM) { _recTimer.setInterval(333);
connect(&_streamInfoTimer, &QTimer::timeout, this, &QGCCameraControl::_streamTimeout); connect(&_recTimer, &QTimer::timeout, this, &QGCCameraControl::_recTimerHandler);
_streamInfoTimer.setSingleShot(false);
connect(&_streamStatusTimer, &QTimer::timeout, this, &QGCCameraControl::_streamStatusTimeout);
_streamStatusTimer.setSingleShot(true);
//-- Request all streams
_requestStreamInfo(0);
_streamInfoTimer.start(2000);
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -204,6 +198,7 @@ QGCCameraControl::_initWhenReady() ...@@ -204,6 +198,7 @@ QGCCameraControl::_initWhenReady()
if(isBasic()) { if(isBasic()) {
qCDebug(CameraControlLog) << "Basic, MAVLink only messages."; qCDebug(CameraControlLog) << "Basic, MAVLink only messages.";
_requestCameraSettings(); _requestCameraSettings();
QTimer::singleShot(250, this, &QGCCameraControl::_checkForVideoStreams);
} else { } else {
_requestAllParameters(); _requestAllParameters();
//-- Give some time to load the parameters before going after the camera settings //-- Give some time to load the parameters before going after the camera settings
...@@ -233,6 +228,13 @@ QGCCameraControl::firmwareVersion() ...@@ -233,6 +228,13 @@ QGCCameraControl::firmwareVersion()
return ver; return ver;
} }
//-----------------------------------------------------------------------------
QString
QGCCameraControl::recordTimeStr()
{
return QTime(0, 0).addMSecs(static_cast<int>(recordTime())).toString("hh:mm:ss");
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QGCCameraControl::VideoStatus QGCCameraControl::VideoStatus
QGCCameraControl::videoStatus() QGCCameraControl::videoStatus()
...@@ -267,11 +269,6 @@ QGCCameraControl::setCameraMode(CameraMode mode) ...@@ -267,11 +269,6 @@ QGCCameraControl::setCameraMode(CameraMode mode)
} else { } else {
qCDebug(CameraControlLog) << "setCameraMode() Invalid mode:" << mode; qCDebug(CameraControlLog) << "setCameraMode() Invalid mode:" << mode;
} }
//-- Update stream status
QGCVideoStreamInfo* pInfo = currentStreamInstance();
if(pInfo) {
_requestStreamStatus(static_cast<uint8_t>(pInfo->streamID()));
}
} }
} }
...@@ -311,8 +308,12 @@ QGCCameraControl::setPhotoLapseCount(int count) ...@@ -311,8 +308,12 @@ QGCCameraControl::setPhotoLapseCount(int count)
void void
QGCCameraControl::_setCameraMode(CameraMode mode) QGCCameraControl::_setCameraMode(CameraMode mode)
{ {
if(_cameraMode != mode) {
_cameraMode = mode; _cameraMode = mode;
emit cameraModeChanged(); emit cameraModeChanged();
//-- Update stream status
_streamStatusTimer.start(1000);
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -410,7 +411,7 @@ QGCCameraControl::startVideo() ...@@ -410,7 +411,7 @@ QGCCameraControl::startVideo()
_vehicle->sendMavCommand( _vehicle->sendMavCommand(
_compID, // Target component _compID, // Target component
MAV_CMD_VIDEO_START_CAPTURE, // Command id MAV_CMD_VIDEO_START_CAPTURE, // Command id
true, // ShowError false, // Don't Show Error (handle locally)
0, // Reserved (Set to 0) 0, // Reserved (Set to 0)
0); // CAMERA_CAPTURE_STATUS Frequency 0); // CAMERA_CAPTURE_STATUS Frequency
return true; return true;
...@@ -429,7 +430,7 @@ QGCCameraControl::stopVideo() ...@@ -429,7 +430,7 @@ QGCCameraControl::stopVideo()
_vehicle->sendMavCommand( _vehicle->sendMavCommand(
_compID, // Target component _compID, // Target component
MAV_CMD_VIDEO_STOP_CAPTURE, // Command id MAV_CMD_VIDEO_STOP_CAPTURE, // Command id
true, // ShowError false, // Don't Show Error (handle locally)
0); // Reserved (Set to 0) 0); // Reserved (Set to 0)
return true; return true;
} }
...@@ -441,9 +442,18 @@ QGCCameraControl::stopVideo() ...@@ -441,9 +442,18 @@ QGCCameraControl::stopVideo()
void void
QGCCameraControl::setVideoMode() QGCCameraControl::setVideoMode()
{ {
if(!_resetting) { if(!_resetting && hasModes()) {
if(hasModes() && _cameraMode != CAM_MODE_VIDEO) {
qCDebug(CameraControlLog) << "setVideoMode()"; qCDebug(CameraControlLog) << "setVideoMode()";
//-- Does it have a mode parameter?
Fact* pMode = mode();
if(pMode) {
if(cameraMode() != CAM_MODE_VIDEO) {
pMode->setRawValue(CAM_MODE_VIDEO);
_setCameraMode(CAM_MODE_VIDEO);
}
} else {
//-- Use MAVLink Command
if(_cameraMode != CAM_MODE_VIDEO) {
//-- Use basic MAVLink message //-- Use basic MAVLink message
_vehicle->sendMavCommand( _vehicle->sendMavCommand(
_compID, // Target component _compID, // Target component
...@@ -454,15 +464,25 @@ QGCCameraControl::setVideoMode() ...@@ -454,15 +464,25 @@ QGCCameraControl::setVideoMode()
_setCameraMode(CAM_MODE_VIDEO); _setCameraMode(CAM_MODE_VIDEO);
} }
} }
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
QGCCameraControl::setPhotoMode() QGCCameraControl::setPhotoMode()
{ {
if(!_resetting) { if(!_resetting && hasModes()) {
if(hasModes() && _cameraMode != CAM_MODE_PHOTO) {
qCDebug(CameraControlLog) << "setPhotoMode()"; qCDebug(CameraControlLog) << "setPhotoMode()";
//-- Does it have a mode parameter?
Fact* pMode = mode();
if(pMode) {
if(cameraMode() != CAM_MODE_PHOTO) {
pMode->setRawValue(CAM_MODE_PHOTO);
_setCameraMode(CAM_MODE_PHOTO);
}
} else {
//-- Use MAVLink Command
if(_cameraMode != CAM_MODE_PHOTO) {
//-- Use basic MAVLink message //-- Use basic MAVLink message
_vehicle->sendMavCommand( _vehicle->sendMavCommand(
_compID, // Target component _compID, // Target component
...@@ -473,6 +493,7 @@ QGCCameraControl::setPhotoMode() ...@@ -473,6 +493,7 @@ QGCCameraControl::setPhotoMode()
_setCameraMode(CAM_MODE_PHOTO); _setCameraMode(CAM_MODE_PHOTO);
} }
} }
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -693,9 +714,26 @@ QGCCameraControl::_setVideoStatus(VideoStatus status) ...@@ -693,9 +714,26 @@ QGCCameraControl::_setVideoStatus(VideoStatus status)
if(_video_status != status) { if(_video_status != status) {
_video_status = status; _video_status = status;
emit videoStatusChanged(); emit videoStatusChanged();
if(status == VIDEO_CAPTURE_STATUS_RUNNING) {
_recordTime = 0;
_recTime.start();
_recTimer.start();
} else {
_recTimer.stop();
_recordTime = 0;
emit recordTimeChanged();
}
} }
} }
//-----------------------------------------------------------------------------
void
QGCCameraControl::_recTimerHandler()
{
_recordTime = static_cast<uint32_t>(_recTime.elapsed());
emit recordTimeChanged();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
QGCCameraControl::_setPhotoStatus(PhotoStatus status) QGCCameraControl::_setPhotoStatus(PhotoStatus status)
...@@ -1412,6 +1450,12 @@ QGCCameraControl::handleCaptureStatus(const mavlink_camera_capture_status_t& cap ...@@ -1412,6 +1450,12 @@ QGCCameraControl::handleCaptureStatus(const mavlink_camera_capture_status_t& cap
_storageFree = a; _storageFree = a;
emit storageFreeChanged(); emit storageFreeChanged();
} }
//-- Do we have recording time?
if(cap.recording_time_ms) {
_recordTime = cap.recording_time_ms;
_recTime = _recTime.addMSecs(_recTime.elapsed() - static_cast<int>(cap.recording_time_ms));
emit recordTimeChanged();
}
//-- Video/Image Capture Status //-- Video/Image Capture Status
uint8_t vs = cap.video_status < static_cast<uint8_t>(VIDEO_CAPTURE_STATUS_LAST) ? cap.video_status : static_cast<uint8_t>(VIDEO_CAPTURE_STATUS_UNDEFINED); uint8_t vs = cap.video_status < static_cast<uint8_t>(VIDEO_CAPTURE_STATUS_LAST) ? cap.video_status : static_cast<uint8_t>(VIDEO_CAPTURE_STATUS_UNDEFINED);
uint8_t ps = cap.image_status < static_cast<uint8_t>(PHOTO_CAPTURE_LAST) ? cap.image_status : static_cast<uint8_t>(PHOTO_CAPTURE_STATUS_UNDEFINED); uint8_t ps = cap.image_status < static_cast<uint8_t>(PHOTO_CAPTURE_LAST) ? cap.image_status : static_cast<uint8_t>(PHOTO_CAPTURE_STATUS_UNDEFINED);
...@@ -1441,6 +1485,7 @@ QGCCameraControl::handleVideoInfo(const mavlink_video_stream_information_t* vi) ...@@ -1441,6 +1485,7 @@ QGCCameraControl::handleVideoInfo(const mavlink_video_stream_information_t* vi)
qCDebug(CameraControlLog) << "handleVideoInfo:" << vi->stream_id << vi->uri; qCDebug(CameraControlLog) << "handleVideoInfo:" << vi->stream_id << vi->uri;
_expectedCount = vi->count; _expectedCount = vi->count;
if(!_findStream(vi->stream_id)) { if(!_findStream(vi->stream_id)) {
qCDebug(CameraControlLog) << "Create stream handler for stream ID:" << vi->stream_id;
QGCVideoStreamInfo* pStream = new QGCVideoStreamInfo(this, vi); QGCVideoStreamInfo* pStream = new QGCVideoStreamInfo(this, vi);
QQmlEngine::setObjectOwnership(pStream, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(pStream, QQmlEngine::CppOwnership);
_streams.append(pStream); _streams.append(pStream);
...@@ -1451,8 +1496,10 @@ QGCCameraControl::handleVideoInfo(const mavlink_video_stream_information_t* vi) ...@@ -1451,8 +1496,10 @@ QGCCameraControl::handleVideoInfo(const mavlink_video_stream_information_t* vi)
_streamInfoTimer.start(1000); _streamInfoTimer.start(1000);
} else { } else {
//-- Done //-- Done
qCDebug(CameraControlLog) << "All stream handlers done";
_streamInfoTimer.stop(); _streamInfoTimer.stop();
emit autoStreamChanged(); emit autoStreamChanged();
emit _vehicle->dynamicCameras()->streamChanged();
} }
} }
...@@ -1608,6 +1655,11 @@ QGCCameraControl::_streamTimeout() ...@@ -1608,6 +1655,11 @@ QGCCameraControl::_streamTimeout()
if(_requestCount > count) { if(_requestCount > count) {
qCWarning(CameraControlLog) << "Giving up requesting video stream info"; qCWarning(CameraControlLog) << "Giving up requesting video stream info";
_streamInfoTimer.stop(); _streamInfoTimer.stop();
//-- If we have at least one stream, work with what we have.
if(_streams.count()) {
emit autoStreamChanged();
emit _vehicle->dynamicCameras()->streamChanged();
}
return; return;
} }
for(uint8_t i = 0; i < _expectedCount; i++) { for(uint8_t i = 0; i < _expectedCount; i++) {
...@@ -1867,6 +1919,23 @@ QGCCameraControl::_paramDone() ...@@ -1867,6 +1919,23 @@ QGCCameraControl::_paramDone()
//-- All parameters loaded (or timed out) //-- All parameters loaded (or timed out)
_paramComplete = true; _paramComplete = true;
emit parametersReady(); emit parametersReady();
//-- Check for video streaming
_checkForVideoStreams();
}
//-----------------------------------------------------------------------------
void
QGCCameraControl::_checkForVideoStreams()
{
if(_info.flags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM) {
connect(&_streamInfoTimer, &QTimer::timeout, this, &QGCCameraControl::_streamTimeout);
_streamInfoTimer.setSingleShot(false);
connect(&_streamStatusTimer, &QTimer::timeout, this, &QGCCameraControl::_streamStatusTimeout);
_streamStatusTimer.setSingleShot(true);
//-- Request all streams
_requestStreamInfo(0);
_streamInfoTimer.start(2000);
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -1937,6 +2006,13 @@ QGCCameraControl::wb() ...@@ -1937,6 +2006,13 @@ QGCCameraControl::wb()
return (_paramComplete && _activeSettings.contains(kCAM_WBMODE)) ? getFact(kCAM_WBMODE) : nullptr; return (_paramComplete && _activeSettings.contains(kCAM_WBMODE)) ? getFact(kCAM_WBMODE) : nullptr;
} }
//-----------------------------------------------------------------------------
Fact*
QGCCameraControl::mode()
{
return _paramComplete ? getFact(kCAM_MODE) : nullptr;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QGCVideoStreamInfo::QGCVideoStreamInfo(QObject* parent, const mavlink_video_stream_information_t *si) QGCVideoStreamInfo::QGCVideoStreamInfo(QObject* parent, const mavlink_video_stream_information_t *si)
: QObject(parent) : QObject(parent)
......
...@@ -147,6 +147,7 @@ public: ...@@ -147,6 +147,7 @@ public:
Q_PROPERTY(Fact* shutter READ shutter NOTIFY parametersReady) Q_PROPERTY(Fact* shutter READ shutter NOTIFY parametersReady)
Q_PROPERTY(Fact* aperture READ aperture NOTIFY parametersReady) Q_PROPERTY(Fact* aperture READ aperture NOTIFY parametersReady)
Q_PROPERTY(Fact* wb READ wb NOTIFY parametersReady) Q_PROPERTY(Fact* wb READ wb NOTIFY parametersReady)
Q_PROPERTY(Fact* mode READ mode NOTIFY parametersReady)
Q_PROPERTY(QStringList activeSettings READ activeSettings NOTIFY activeSettingsChanged) Q_PROPERTY(QStringList activeSettings READ activeSettings NOTIFY activeSettingsChanged)
Q_PROPERTY(VideoStatus videoStatus READ videoStatus NOTIFY videoStatusChanged) Q_PROPERTY(VideoStatus videoStatus READ videoStatus NOTIFY videoStatusChanged)
...@@ -159,6 +160,8 @@ public: ...@@ -159,6 +160,8 @@ public:
Q_PROPERTY(bool autoStream READ autoStream NOTIFY autoStreamChanged) Q_PROPERTY(bool autoStream READ autoStream NOTIFY autoStreamChanged)
Q_PROPERTY(QmlObjectListModel* streams READ streams NOTIFY streamsChanged) Q_PROPERTY(QmlObjectListModel* streams READ streams NOTIFY streamsChanged)
Q_PROPERTY(QGCVideoStreamInfo* currentStreamInstance READ currentStreamInstance NOTIFY currentStreamChanged) Q_PROPERTY(QGCVideoStreamInfo* currentStreamInstance READ currentStreamInstance NOTIFY currentStreamChanged)
Q_PROPERTY(quint32 recordTime READ recordTime NOTIFY recordTimeChanged)
Q_PROPERTY(QString recordTimeStr READ recordTimeStr NOTIFY recordTimeChanged)
Q_INVOKABLE virtual void setVideoMode (); Q_INVOKABLE virtual void setVideoMode ();
Q_INVOKABLE virtual void setPhotoMode (); Q_INVOKABLE virtual void setPhotoMode ();
...@@ -213,6 +216,8 @@ public: ...@@ -213,6 +216,8 @@ public:
virtual int currentStream () { return _currentStream; } virtual int currentStream () { return _currentStream; }
virtual void setCurrentStream (int stream); virtual void setCurrentStream (int stream);
virtual bool autoStream (); virtual bool autoStream ();
virtual quint32 recordTime () { return _recordTime; }
virtual QString recordTimeStr ();
virtual Fact* exposureMode (); virtual Fact* exposureMode ();
virtual Fact* ev (); virtual Fact* ev ();
...@@ -220,6 +225,7 @@ public: ...@@ -220,6 +225,7 @@ public:
virtual Fact* shutter (); virtual Fact* shutter ();
virtual Fact* aperture (); virtual Fact* aperture ();
virtual Fact* wb (); virtual Fact* wb ();
virtual Fact* mode ();
virtual void setZoomLevel (qreal level); virtual void setZoomLevel (qreal level);
virtual void setFocusLevel (qreal level); virtual void setFocusLevel (qreal level);
...@@ -261,6 +267,7 @@ signals: ...@@ -261,6 +267,7 @@ signals:
void streamsChanged (); void streamsChanged ();
void currentStreamChanged (); void currentStreamChanged ();
void autoStreamChanged (); void autoStreamChanged ();
void recordTimeChanged ();
protected: protected:
virtual void _setVideoStatus (VideoStatus status); virtual void _setVideoStatus (VideoStatus status);
...@@ -283,6 +290,8 @@ protected slots: ...@@ -283,6 +290,8 @@ protected slots:
virtual void _paramDone (); virtual void _paramDone ();
virtual void _streamTimeout (); virtual void _streamTimeout ();
virtual void _streamStatusTimeout (); virtual void _streamStatusTimeout ();
virtual void _recTimerHandler ();
virtual void _checkForVideoStreams ();
private: private:
bool _handleLocalization (QByteArray& bytes); bool _handleLocalization (QByteArray& bytes);
...@@ -336,6 +345,9 @@ protected: ...@@ -336,6 +345,9 @@ protected:
int _storageInfoRetries = 0; int _storageInfoRetries = 0;
int _captureInfoRetries = 0; int _captureInfoRetries = 0;
bool _resetting = false; bool _resetting = false;
QTimer _recTimer;
QTime _recTime;
uint32_t _recordTime = 0;
//-- Parameters that require a full update //-- Parameters that require a full update
QMap<QString, QStringList> _requestUpdates; QMap<QString, QStringList> _requestUpdates;
QStringList _updatesToRequest; QStringList _updatesToRequest;
......
...@@ -11,6 +11,12 @@ ...@@ -11,6 +11,12 @@
QGC_LOGGING_CATEGORY(CameraManagerLog, "CameraManagerLog") QGC_LOGGING_CATEGORY(CameraManagerLog, "CameraManagerLog")
//-----------------------------------------------------------------------------
QGCCameraManager::CameraStruct::CameraStruct(QObject* parent)
: QObject(parent)
{
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QGCCameraManager::QGCCameraManager(Vehicle *vehicle) QGCCameraManager::QGCCameraManager(Vehicle *vehicle)
: _vehicle(vehicle) : _vehicle(vehicle)
...@@ -19,8 +25,11 @@ QGCCameraManager::QGCCameraManager(Vehicle *vehicle) ...@@ -19,8 +25,11 @@ QGCCameraManager::QGCCameraManager(Vehicle *vehicle)
qCDebug(CameraManagerLog) << "QGCCameraManager Created"; qCDebug(CameraManagerLog) << "QGCCameraManager Created";
connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::parameterReadyVehicleAvailableChanged, this, &QGCCameraManager::_vehicleReady); connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::parameterReadyVehicleAvailableChanged, this, &QGCCameraManager::_vehicleReady);
connect(_vehicle, &Vehicle::mavlinkMessageReceived, this, &QGCCameraManager::_mavlinkMessageReceived); connect(_vehicle, &Vehicle::mavlinkMessageReceived, this, &QGCCameraManager::_mavlinkMessageReceived);
connect(&_cameraTimer, &QTimer::timeout, this, &QGCCameraManager::_cameraTimeout);
_cameraTimer.setSingleShot(false);
_lastZoomChange.start(); _lastZoomChange.start();
_lastCameraChange.start(); _lastCameraChange.start();
_cameraTimer.start(500);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -97,12 +106,36 @@ QGCCameraManager::_handleHeartbeat(const mavlink_message_t &message) ...@@ -97,12 +106,36 @@ QGCCameraManager::_handleHeartbeat(const mavlink_message_t &message)
{ {
mavlink_heartbeat_t heartbeat; mavlink_heartbeat_t heartbeat;
mavlink_msg_heartbeat_decode(&message, &heartbeat); mavlink_msg_heartbeat_decode(&message, &heartbeat);
//-- If this heartbeat is from a different node within the vehicle //-- If this heartbeat is from a different component within the vehicle
if(_vehicleReadyState && _vehicle->id() == message.sysid && _vehicle->defaultComponentId() != message.compid) { if(_vehicleReadyState && _vehicle->id() == message.sysid && _vehicle->defaultComponentId() != message.compid) {
if(!_cameraInfoRequested.contains(message.compid)) { //-- First time hearing from this one?
_cameraInfoRequested[message.compid] = true; if(!_cameraInfoRequest.contains(message.compid)) {
CameraStruct* pInfo = new CameraStruct(this);
pInfo->lastHeartbeat.start();
_cameraInfoRequest[message.compid] = pInfo;
//-- Request camera info //-- Request camera info
_requestCameraInfo(message.compid); _requestCameraInfo(message.compid);
} else {
//-- Check if we have indeed received the camera info
if(_cameraInfoRequest[message.compid]->infoReceived) {
//-- We have it. Just update the heartbeat timeout
_cameraInfoRequest[message.compid]->lastHeartbeat.start();
} else {
//-- Try again. Maybe.
if(_cameraInfoRequest[message.compid]->lastHeartbeat.elapsed() > 2000) {
if(_cameraInfoRequest[message.compid]->tryCount > 3) {
if(!_cameraInfoRequest[message.compid]->gaveUp) {
_cameraInfoRequest[message.compid]->gaveUp = true;
qWarning() << "Giving up requesting camera info from" << _vehicle->id() << message.compid;
}
} else {
_cameraInfoRequest[message.compid]->tryCount++;
//-- Request camera info. Again. It could be something other than a camera, in which
// case, we won't ever receive it.
_requestCameraInfo(message.compid);
}
}
}
} }
} }
} }
...@@ -155,9 +188,9 @@ void ...@@ -155,9 +188,9 @@ void
QGCCameraManager::_handleCameraInfo(const mavlink_message_t& message) QGCCameraManager::_handleCameraInfo(const mavlink_message_t& message)
{ {
//-- Have we requested it? //-- Have we requested it?
if(_cameraInfoRequested.contains(message.compid) && _cameraInfoRequested[message.compid]) { if(_cameraInfoRequest.contains(message.compid) && !_cameraInfoRequest[message.compid]->infoReceived) {
//-- Flag it as done //-- Flag it as done
_cameraInfoRequested[message.compid] = false; _cameraInfoRequest[message.compid]->infoReceived = true;
mavlink_camera_information_t info; mavlink_camera_information_t info;
mavlink_msg_camera_information_decode(&message, &info); mavlink_msg_camera_information_decode(&message, &info);
qCDebug(CameraManagerLog) << "_handleCameraInfo:" << reinterpret_cast<const char*>(info.model_name) << reinterpret_cast<const char*>(info.vendor_name) << "Comp ID:" << message.compid; qCDebug(CameraManagerLog) << "_handleCameraInfo:" << reinterpret_cast<const char*>(info.model_name) << reinterpret_cast<const char*>(info.vendor_name) << "Comp ID:" << message.compid;
...@@ -172,6 +205,51 @@ QGCCameraManager::_handleCameraInfo(const mavlink_message_t& message) ...@@ -172,6 +205,51 @@ QGCCameraManager::_handleCameraInfo(const mavlink_message_t& message)
} }
} }
//-----------------------------------------------------------------------------
void
QGCCameraManager::_cameraTimeout()
{
//-- Iterate cameras
for(int i = 0; i < _cameraInfoRequest.count(); i++) {
if(_cameraInfoRequest[i]) {
//-- Have we received a camera info message?
if(_cameraInfoRequest[i]->infoReceived) {
//-- Has the camera stopped talking to us?
if(_cameraInfoRequest[i]->lastHeartbeat.elapsed() > 5000) {
//-- Camera is gone. Remove it.
QGCCameraControl* pCamera = _findCamera(i);
qWarning() << "Camera" << pCamera->modelName() << "stopped transmitting. Removing from list.";
int idx = _cameraLabels.indexOf(pCamera->modelName());
if(idx >= 0) {
_cameraLabels.removeAt(idx);
}
idx = _cameras.indexOf(pCamera);
if(idx >= 0) {
_cameras.removeAt(idx);
}
bool autoStream = pCamera->autoStream();
pCamera->deleteLater();
delete _cameraInfoRequest[i];
_cameraInfoRequest.remove(i);
emit cameraLabelsChanged();
//-- If we have another camera, switch current camera.
if(_cameras.count()) {
setCurrentCamera(0);
} else {
//-- We're out of cameras
emit camerasChanged();
if(autoStream) {
emit streamChanged();
}
}
//-- Exit loop.
return;
}
}
}
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
QGCCameraManager::_handleCaptureStatus(const mavlink_message_t &message) QGCCameraManager::_handleCaptureStatus(const mavlink_message_t &message)
......
...@@ -29,8 +29,8 @@ public: ...@@ -29,8 +29,8 @@ public:
Q_PROPERTY(QmlObjectListModel* cameras READ cameras NOTIFY camerasChanged) Q_PROPERTY(QmlObjectListModel* cameras READ cameras NOTIFY camerasChanged)
Q_PROPERTY(QStringList cameraLabels READ cameraLabels NOTIFY cameraLabelsChanged) Q_PROPERTY(QStringList cameraLabels READ cameraLabels NOTIFY cameraLabelsChanged)
Q_PROPERTY(int currentCamera READ currentCamera WRITE setCurrentCamera NOTIFY currentCameraChanged)
Q_PROPERTY(QGCCameraControl* currentCameraInstance READ currentCameraInstance NOTIFY currentCameraChanged) Q_PROPERTY(QGCCameraControl* currentCameraInstance READ currentCameraInstance NOTIFY currentCameraChanged)
Q_PROPERTY(int currentCamera READ currentCamera WRITE setCurrentCamera NOTIFY currentCameraChanged)
//-- Return a list of cameras provided by this vehicle //-- Return a list of cameras provided by this vehicle
virtual QmlObjectListModel* cameras () { return &_cameras; } virtual QmlObjectListModel* cameras () { return &_cameras; }
...@@ -57,6 +57,7 @@ protected slots: ...@@ -57,6 +57,7 @@ protected slots:
virtual void _stepZoom (int direction); virtual void _stepZoom (int direction);
virtual void _stepCamera (int direction); virtual void _stepCamera (int direction);
virtual void _stepStream (int direction); virtual void _stepStream (int direction);
virtual void _cameraTimeout ();
protected: protected:
virtual QGCCameraControl* _findCamera (int id); virtual QGCCameraControl* _findCamera (int id);
...@@ -72,14 +73,25 @@ protected: ...@@ -72,14 +73,25 @@ protected:
virtual void _handleVideoStreamStatus(const mavlink_message_t& message); virtual void _handleVideoStreamStatus(const mavlink_message_t& message);
protected: protected:
class CameraStruct : public QObject {
public:
CameraStruct(QObject* parent);
QTime lastHeartbeat;
bool infoReceived = false;
bool gaveUp = false;
int tryCount = 0;
};
Vehicle* _vehicle = nullptr; Vehicle* _vehicle = nullptr;
Joystick* _activeJoystick = nullptr; Joystick* _activeJoystick = nullptr;
bool _vehicleReadyState = false; bool _vehicleReadyState = false;
int _currentTask = 0; int _currentTask = 0;
QmlObjectListModel _cameras; QmlObjectListModel _cameras;
QStringList _cameraLabels; QStringList _cameraLabels;
QMap<int, bool> _cameraInfoRequested;
int _currentCamera = 0; int _currentCamera = 0;
QTime _lastZoomChange; QTime _lastZoomChange;
QTime _lastCameraChange; QTime _lastCameraChange;
QTimer _cameraTimer;
QMap<int, CameraStruct*> _cameraInfoRequest;
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment