diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index d02a006c57c6afd930e5840bbb79b556605b07de..2a6078c58b0eee4a332d82f4ce44f8231fa06e53 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -273,6 +273,8 @@ src/AnalyzeView/VibrationPage.qml src/FlightDisplay/VirtualJoystick.qml src/PlanView/VTOLLandingPatternEditor.qml + src/FlightMap/MapItems/ProximityRadarMapView.qml + src/FlightDisplay/ProximityRadarVideoView.qml src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml diff --git a/src/FlightDisplay/FlyViewMap.qml b/src/FlightDisplay/FlyViewMap.qml index f38f8bf0dac2842d6609a417cd881501feafece4..f3e79932cac3d214957d25a906376b71f4d032e8 100644 --- a/src/FlightDisplay/FlyViewMap.qml +++ b/src/FlightDisplay/FlyViewMap.qml @@ -253,7 +253,16 @@ FlightMap { z: QGroundControl.zOrderVehicles } } - + // Add distance sensor view + MapItemView{ + model: QGroundControl.multiVehicleManager.vehicles + delegate: ProximityRadarMapView { + vehicle: object + coordinate: object.coordinate + map: _root + z: QGroundControl.zOrderVehicles + } + } // Add ADSB vehicles to the map MapItemView { model: QGroundControl.adsbVehicleManager.adsbVehicles diff --git a/src/FlightDisplay/FlyViewVideo.qml b/src/FlightDisplay/FlyViewVideo.qml index f90613aaac7d3a784965378f67aa33ad79338b58..0fa32bd115b6e810c571498bc3b07c0728500f46 100644 --- a/src/FlightDisplay/FlyViewVideo.qml +++ b/src/FlightDisplay/FlyViewVideo.qml @@ -9,8 +9,9 @@ import QtQuick 2.12 -import QGroundControl 1.0 -import QGroundControl.Controls 1.0 +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.Controllers 1.0 Item { id: _root @@ -67,4 +68,9 @@ Item { enabled: pipState.state === pipState.fullState onDoubleClicked: QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen } + + ProximityRadarVideoView{ + anchors.fill: parent + vehicle: QGroundControl.multiVehicleManager.activeVehicle + } } diff --git a/src/FlightDisplay/ProximityRadarVideoView.qml b/src/FlightDisplay/ProximityRadarVideoView.qml new file mode 100644 index 0000000000000000000000000000000000000000..ea5d0e71c4c0773a2a818cda649105b5fe2e2a36 --- /dev/null +++ b/src/FlightDisplay/ProximityRadarVideoView.qml @@ -0,0 +1,108 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.12 +import QtLocation 5.3 +import QtPositioning 5.3 +import QtGraphicalEffects 1.0 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Vehicle 1.0 +import QGroundControl.Controls 1.0 +//import QGroundControl.Controllers 1.0 + + + +/// Marker for displaying a vehicle location on the map +Item { + id: _root + anchors.fill: parent + + property var vehicle /// Vehicle object, undefined for ADSB vehicle + property var range + + property var _distanceSensor: vehicle?vehicle.distanceSensors:null + property var _range: range?range:6 // default 6m view + + property var _rotationNone: _distanceSensor?_distanceSensor.rotationNone.value:0 + property var _rotationYaw45: _distanceSensor?_distanceSensor.rotationYaw45.value:0 + property var _rotationYaw90: _distanceSensor?_distanceSensor.rotationYaw90.value:0 + property var _rotationYaw135: _distanceSensor?_distanceSensor.rotationYaw135.value:0 + property var _rotationYaw180: _distanceSensor?_distanceSensor.rotationYaw180.value:0 + property var _rotationYaw225: _distanceSensor?_distanceSensor.rotationYaw225.value:0 + property var _rotationYaw270: _distanceSensor?_distanceSensor.rotationYaw270.value:0 + property var _rotationYaw315: _distanceSensor?_distanceSensor.rotationYaw315.value:0 + property var _rottab: [_rotationNone,_rotationYaw45,_rotationYaw90,_rotationYaw135,_rotationYaw180,_rotationYaw225,_rotationYaw270,_rotationYaw315] + +// on_RottabChanged: _sectorViewEllipsoid.requestPaint() + on_RotationNoneChanged: _sectorViewEllipsoid.requestPaint() + on_RotationYaw45Changed: _sectorViewEllipsoid.requestPaint() + on_RotationYaw90Changed: _sectorViewEllipsoid.requestPaint() + on_RotationYaw135Changed: _sectorViewEllipsoid.requestPaint() + on_RotationYaw180Changed: _sectorViewEllipsoid.requestPaint() + on_RotationYaw225Changed: _sectorViewEllipsoid.requestPaint() + on_RotationYaw270Changed: _sectorViewEllipsoid.requestPaint() + on_RotationYaw315Changed: _sectorViewEllipsoid.requestPaint() + + property var _minlength: Math.min(_root.width,_root.height) + property var _ratio: (_minlength/2)/_root._range + + Canvas{ + id:_sectorViewEllipsoid + anchors.fill: _root + opacity: 0.5 + visible: _distanceSensor?true:false + onPaint: { + if(_distanceSensor) { + var ctx = getContext("2d"); + ctx.reset(); + ctx.translate(width/2,height/2) + ctx.strokeStyle = Qt.rgba(1, 0, 0, 1); + ctx.lineWidth = width/100; + ctx.scale(_root.width / _minlength,_root.height / _minlength); + ctx.rotate(-Math.PI/2-Math.PI/8); + for(var i=0; i< _rottab.length; i++) + { + var a=Math.PI/4*i; + ctx.beginPath(); + ctx.arc(0,0,_rottab[i]*_ratio,0+a+Math.PI/50,Math.PI/4+a-Math.PI/50,false); + ctx.stroke(); + } + } + } + } + Item{ + anchors.fill: parent + visible: _distanceSensor?true:false + Repeater{ + model: _rottab + QGCLabel{ + x: _sectorViewEllipsoid.width / 2-width/2 + y: _sectorViewEllipsoid.height / 2-height/2 + text: modelData + font.family: ScreenTools.demiboldFontFamily + transform: Translate { + x: Math.cos(-Math.PI/2+Math.PI/4*index)*(modelData*_ratio) + y: Math.sin(-Math.PI/2+Math.PI/4*index)*(modelData*_ratio) + } + } + } + transform: Scale { + origin.x: _sectorViewEllipsoid.width / 2 + origin.y: _sectorViewEllipsoid.height / 2 + xScale: _root.width / _minlength + yScale: _root.height / _minlength + } + + + } + +} + diff --git a/src/FlightMap/MapItems/ProximityRadarMapView.qml b/src/FlightMap/MapItems/ProximityRadarMapView.qml new file mode 100644 index 0000000000000000000000000000000000000000..71273981610b96ec66a53c0ff75d2868ac0d2d23 --- /dev/null +++ b/src/FlightMap/MapItems/ProximityRadarMapView.qml @@ -0,0 +1,148 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.12 +import QtLocation 5.3 +import QtPositioning 5.3 +import QtGraphicalEffects 1.0 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Vehicle 1.0 +import QGroundControl.Controls 1.0 + + + +/// Marker for displaying a vehicle location on the map +MapQuickItem { + id: _root + property var vehicle /// Vehicle object, undefined for ADSB vehicle + property var map + property double heading: vehicle ? vehicle.heading.value : Number.NaN ///< Vehicle heading, NAN for none + + anchorPoint.x: vehicleItem.width / 2 + anchorPoint.y: vehicleItem.height / 2 + visible: coordinate.isValid + + property bool _adsbVehicle: vehicle ? false : true + property real _uavSize: ScreenTools.defaultFontPixelHeight * 5 + property real _adsbSize: ScreenTools.defaultFontPixelHeight * 2.5 + property var _map: map + property bool _multiVehicle: QGroundControl.multiVehicleManager.vehicles.count > 1 + property real _ratio: 1 + + property var _distanceSensor: vehicle?vehicle.distanceSensors:null + property var _maxSensor: _distanceSensor?_distanceSensor.maxDistance.value:1 //need to change in cc + property var _rotationNone: _distanceSensor?_distanceSensor.rotationNone.value:0 + property var _rotationYaw45: _distanceSensor?_distanceSensor.rotationYaw45.value:0 + property var _rotationYaw90: _distanceSensor?_distanceSensor.rotationYaw90.value:0 + property var _rotationYaw135: _distanceSensor?_distanceSensor.rotationYaw135.value:0 + property var _rotationYaw180: _distanceSensor?_distanceSensor.rotationYaw180.value:0 + property var _rotationYaw225: _distanceSensor?_distanceSensor.rotationYaw225.value:0 + property var _rotationYaw270: _distanceSensor?_distanceSensor.rotationYaw270.value:0 + property var _rotationYaw315: _distanceSensor?_distanceSensor.rotationYaw315.value:0 + property var _rottab: [_rotationNone,_rotationYaw45,_rotationYaw90,_rotationYaw135,_rotationYaw180,_rotationYaw225,_rotationYaw270,_rotationYaw315] + + function calcSize(){ + if(_map) { + var scaleLinePixelLength = 100 + var leftCoord = _map.toCoordinate(Qt.point(0, 0), false /* clipToViewPort */) + var rightCoord = _map.toCoordinate(Qt.point(scaleLinePixelLength, 0), false /* clipToViewPort */) + var scaleLineMeters = Math.round(leftCoord.distanceTo(rightCoord)) + } + _ratio=scaleLinePixelLength/scaleLineMeters; + } + + on_RotationNoneChanged: vehicleSensors.requestPaint() + on_RotationYaw45Changed: vehicleSensors.requestPaint() + on_RotationYaw90Changed: vehicleSensors.requestPaint() + on_RotationYaw135Changed: vehicleSensors.requestPaint() + on_RotationYaw180Changed: vehicleSensors.requestPaint() + on_RotationYaw225Changed: vehicleSensors.requestPaint() + on_RotationYaw270Changed: vehicleSensors.requestPaint() + on_RotationYaw315Changed: vehicleSensors.requestPaint() + + + + Connections { + target: map + onWidthChanged: scaleTimer.restart() + onHeightChanged: scaleTimer.restart() + onZoomLevelChanged: scaleTimer.restart() + } + + Timer { + id: scaleTimer + interval: 100 + running: false + repeat: false + onTriggered: calcSize() + } + + sourceItem: Item { + id: vehicleItem + width: detectionLimitCircle.width + height: detectionLimitCircle.height + opacity: 0.5 + + Canvas{ + id: vehicleSensors + anchors.fill: detectionLimitCircle + transform: Rotation { + origin.x: detectionLimitCircle.width / 2 + origin.y: detectionLimitCircle.height / 2 + angle: isNaN(heading) ? 0 : heading + } + function deg2rad(degrees) + { + var pi = Math.PI; + return degrees * (pi/180); + } + onPaint: { + if(_distanceSensor) + { + var ctx = getContext("2d"); + ctx.reset(); + ctx.translate(width/2,height/2) + ctx.rotate(-Math.PI/2); + ctx.lineWidth = 5; + ctx.strokeStyle = Qt.rgba(1, 0, 0, 1); + for(var i=0; i<_rottab.length;i++){ + var a=deg2rad(360-22.5)+Math.PI/4*i; + ctx.beginPath(); + ctx.arc(0,0,_rottab[i]*_ratio, a,a+Math.PI/4,false); + ctx.stroke(); + } + + } + } + } + + Rectangle { + id: detectionLimitCircle + width: _maxSensor*2*_ratio + height: _maxSensor*2*_ratio + anchors.fill: detectionLimitCircle + color: Qt.rgba(1,1,1,0) + border.color: Qt.rgba(1,1,1,1) + border.width: 5 + radius: width*0.5 + transform: Rotation { + origin.x: detectionLimitCircle.width / 2 + origin.y: detectionLimitCircle.height / 2 + angle: isNaN(heading) ? 0 : heading + } + } + + Component.onCompleted: { + calcSize(); + } + } +} + diff --git a/src/QmlControls/QGroundControl/FlightDisplay/qmldir b/src/QmlControls/QGroundControl/FlightDisplay/qmldir index 5cf441110e21c00531949447d7be84df5b3ae859..0da559c1cd0c449c6b195f78a149c457d58a8491 100644 --- a/src/QmlControls/QGroundControl/FlightDisplay/qmldir +++ b/src/QmlControls/QGroundControl/FlightDisplay/qmldir @@ -28,6 +28,7 @@ PreFlightGPSCheck 1.0 PreFlightGPSCheck.qml PreFlightRCCheck 1.0 PreFlightRCCheck.qml PreFlightSensorsHealthCheck 1.0 PreFlightSensorsHealthCheck.qml PreFlightSoundCheck 1.0 PreFlightSoundCheck.qml +ProximityRadarVideoView 1.0 ProximityRadarVideoView.qml TerrainProgress 1.0 TerrainProgress.qml TelemetryValuesBar 1.0 TelemetryValuesBar.qml VehicleWarnings 1.0 VehicleWarnings.qml diff --git a/src/QmlControls/QGroundControl/FlightMap/qmldir b/src/QmlControls/QGroundControl/FlightMap/qmldir index 1d863ace4ecc8ae367ba40bc369e403aaf1f4d48..bf52d1de4a402525e361c8425248c468cb2ab0cb 100644 --- a/src/QmlControls/QGroundControl/FlightMap/qmldir +++ b/src/QmlControls/QGroundControl/FlightMap/qmldir @@ -28,5 +28,6 @@ MissionItemView 1.0 MissionItemView.qml MissionLineView 1.0 MissionLineView.qml PlanMapItems 1.0 PlanMapItems.qml PolygonEditor 1.0 PolygonEditor.qml +ProximityRadarMapView 1.0 ProximityRadarMapView.qml SplitIndicator 1.0 SplitIndicator.qml VehicleMapItem 1.0 VehicleMapItem.qml diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index e3083c13ad3565de942c964010301423fa2ed738..f5be62ef85da2db22d315abc7dd36bf5f62d691f 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -1139,6 +1139,7 @@ void Vehicle::_handleDistanceSensor(mavlink_message_t& message) if (orientation2Fact.orientation == distanceSensor.orientation) { orientation2Fact.fact->setRawValue(distanceSensor.current_distance / 100.0); // cm to meters } + _distanceSensorFactGroup.maxDistance()->setRawValue(distanceSensor.max_distance/100.0); } } @@ -4483,6 +4484,7 @@ const char* VehicleDistanceSensorFactGroup::_rotationYaw270FactName = "rotatio const char* VehicleDistanceSensorFactGroup::_rotationYaw315FactName = "rotationYaw315"; const char* VehicleDistanceSensorFactGroup::_rotationPitch90FactName = "rotationPitch90"; const char* VehicleDistanceSensorFactGroup::_rotationPitch270FactName = "rotationPitch270"; +const char* VehicleDistanceSensorFactGroup::_maxDistanceFactName = "maxDistance"; VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent) : FactGroup (1000, ":/json/Vehicle/DistanceSensorFact.json", parent) @@ -4496,6 +4498,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent) , _rotationYaw315Fact (0, _rotationYaw315FactName, FactMetaData::valueTypeDouble) , _rotationPitch90Fact (0, _rotationPitch90FactName, FactMetaData::valueTypeDouble) , _rotationPitch270Fact (0, _rotationPitch270FactName, FactMetaData::valueTypeDouble) + , _maxDistanceFact (0, _maxDistanceFactName, FactMetaData::valueTypeDouble) { _addFact(&_rotationNoneFact, _rotationNoneFactName); _addFact(&_rotationYaw45Fact, _rotationYaw45FactName); @@ -4507,6 +4510,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent) _addFact(&_rotationYaw315Fact, _rotationYaw315FactName); _addFact(&_rotationPitch90Fact, _rotationPitch90FactName); _addFact(&_rotationPitch270Fact, _rotationPitch270FactName); + _addFact(&_maxDistanceFact, _maxDistanceFactName); // Start out as not available "--.--" _rotationNoneFact.setRawValue(qQNaN()); @@ -4518,6 +4522,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent) _rotationYaw270Fact.setRawValue(qQNaN()); _rotationPitch90Fact.setRawValue(qQNaN()); _rotationPitch270Fact.setRawValue(qQNaN()); + _maxDistanceFact.setRawValue(qQNaN()); } const char* VehicleEstimatorStatusFactGroup::_goodAttitudeEstimateFactName = "goodAttitudeEsimate"; diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index 9044fcdf7aac28ab53c0418d7d3c90e92d7149da..f8790850ee0a90a91402014908553a229fd1ae90 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -73,17 +73,19 @@ public: Q_PROPERTY(Fact* rotationYaw315 READ rotationYaw315 CONSTANT) Q_PROPERTY(Fact* rotationPitch90 READ rotationPitch90 CONSTANT) Q_PROPERTY(Fact* rotationPitch270 READ rotationPitch270 CONSTANT) + Q_PROPERTY(Fact* maxDistance READ maxDistance CONSTANT) Fact* rotationNone () { return &_rotationNoneFact; } Fact* rotationYaw45 () { return &_rotationYaw45Fact; } Fact* rotationYaw90 () { return &_rotationYaw90Fact; } - Fact* rotationYaw135 () { return &_rotationYaw90Fact; } + Fact* rotationYaw135 () { return &_rotationYaw135Fact; } Fact* rotationYaw180 () { return &_rotationYaw180Fact; } - Fact* rotationYaw225 () { return &_rotationYaw180Fact; } + Fact* rotationYaw225 () { return &_rotationYaw225Fact; } Fact* rotationYaw270 () { return &_rotationYaw270Fact; } Fact* rotationYaw315 () { return &_rotationYaw315Fact; } Fact* rotationPitch90 () { return &_rotationPitch90Fact; } Fact* rotationPitch270 () { return &_rotationPitch270Fact; } + Fact* maxDistance () { return &_maxDistanceFact; } static const char* _rotationNoneFactName; static const char* _rotationYaw45FactName; @@ -95,6 +97,7 @@ public: static const char* _rotationYaw315FactName; static const char* _rotationPitch90FactName; static const char* _rotationPitch270FactName; + static const char* _maxDistanceFactName; private: Fact _rotationNoneFact; @@ -107,6 +110,7 @@ private: Fact _rotationYaw315Fact; Fact _rotationPitch90Fact; Fact _rotationPitch270Fact; + Fact _maxDistanceFact; }; class VehicleSetpointFactGroup : public FactGroup @@ -698,6 +702,7 @@ public: Q_PROPERTY(FactGroup* setpoint READ setpointFactGroup CONSTANT) Q_PROPERTY(FactGroup* estimatorStatus READ estimatorStatusFactGroup CONSTANT) Q_PROPERTY(FactGroup* terrain READ terrainFactGroup CONSTANT) + Q_PROPERTY(FactGroup* distanceSensors READ distanceSensorFactGroup CONSTANT) Q_PROPERTY(int firmwareMajorVersion READ firmwareMajorVersion NOTIFY firmwareVersionChanged) Q_PROPERTY(int firmwareMinorVersion READ firmwareMinorVersion NOTIFY firmwareVersionChanged)