Commit 0d4a3116 authored by gaste olivier's avatar gaste olivier Committed by profff

- bug fix in distance sensor message handler

- add NOTIFY for distanceSensor property
- add DistanceSensorReadingsChange() callback prototype

- revert excessive NOTIFY
- adding MaxSensor into DistanceSensor frame handling

- add proximity radar view in map view
- add proximity radar view in video view

change distance label positioning in video view

clean up unwanted comments

- space up proximity sectors
- revert unwanted changes in qgroundcontrol.qrc

squashed commits
parent b94bafe0
...@@ -273,6 +273,8 @@ ...@@ -273,6 +273,8 @@
<file alias="VibrationPage.qml">src/AnalyzeView/VibrationPage.qml</file> <file alias="VibrationPage.qml">src/AnalyzeView/VibrationPage.qml</file>
<file alias="VirtualJoystick.qml">src/FlightDisplay/VirtualJoystick.qml</file> <file alias="VirtualJoystick.qml">src/FlightDisplay/VirtualJoystick.qml</file>
<file alias="VTOLLandingPatternEditor.qml">src/PlanView/VTOLLandingPatternEditor.qml</file> <file alias="VTOLLandingPatternEditor.qml">src/PlanView/VTOLLandingPatternEditor.qml</file>
<file alias="QGroundControl/FlightMap/ProximityRadarMapView.qml">src/FlightMap/MapItems/ProximityRadarMapView.qml</file>
<file alias="QGroundControl/FlightDisplay/ProximityRadarVideoView.qml">src/FlightDisplay/ProximityRadarVideoView.qml</file>
</qresource> </qresource>
<qresource prefix="/FirstRunPromptDialogs"> <qresource prefix="/FirstRunPromptDialogs">
<file alias="UnitsFirstRunPrompt.qml">src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml</file> <file alias="UnitsFirstRunPrompt.qml">src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml</file>
......
...@@ -253,7 +253,16 @@ FlightMap { ...@@ -253,7 +253,16 @@ FlightMap {
z: QGroundControl.zOrderVehicles 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 // Add ADSB vehicles to the map
MapItemView { MapItemView {
model: QGroundControl.adsbVehicleManager.adsbVehicles model: QGroundControl.adsbVehicleManager.adsbVehicles
......
...@@ -11,6 +11,7 @@ import QtQuick 2.12 ...@@ -11,6 +11,7 @@ import QtQuick 2.12
import QGroundControl 1.0 import QGroundControl 1.0
import QGroundControl.Controls 1.0 import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
Item { Item {
id: _root id: _root
...@@ -67,4 +68,9 @@ Item { ...@@ -67,4 +68,9 @@ Item {
enabled: pipState.state === pipState.fullState enabled: pipState.state === pipState.fullState
onDoubleClicked: QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen onDoubleClicked: QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen
} }
ProximityRadarVideoView{
anchors.fill: parent
vehicle: QGroundControl.multiVehicleManager.activeVehicle
}
} }
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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
}
}
}
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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();
}
}
}
...@@ -28,6 +28,7 @@ PreFlightGPSCheck 1.0 PreFlightGPSCheck.qml ...@@ -28,6 +28,7 @@ PreFlightGPSCheck 1.0 PreFlightGPSCheck.qml
PreFlightRCCheck 1.0 PreFlightRCCheck.qml PreFlightRCCheck 1.0 PreFlightRCCheck.qml
PreFlightSensorsHealthCheck 1.0 PreFlightSensorsHealthCheck.qml PreFlightSensorsHealthCheck 1.0 PreFlightSensorsHealthCheck.qml
PreFlightSoundCheck 1.0 PreFlightSoundCheck.qml PreFlightSoundCheck 1.0 PreFlightSoundCheck.qml
ProximityRadarVideoView 1.0 ProximityRadarVideoView.qml
TerrainProgress 1.0 TerrainProgress.qml TerrainProgress 1.0 TerrainProgress.qml
TelemetryValuesBar 1.0 TelemetryValuesBar.qml TelemetryValuesBar 1.0 TelemetryValuesBar.qml
VehicleWarnings 1.0 VehicleWarnings.qml VehicleWarnings 1.0 VehicleWarnings.qml
...@@ -28,5 +28,6 @@ MissionItemView 1.0 MissionItemView.qml ...@@ -28,5 +28,6 @@ MissionItemView 1.0 MissionItemView.qml
MissionLineView 1.0 MissionLineView.qml MissionLineView 1.0 MissionLineView.qml
PlanMapItems 1.0 PlanMapItems.qml PlanMapItems 1.0 PlanMapItems.qml
PolygonEditor 1.0 PolygonEditor.qml PolygonEditor 1.0 PolygonEditor.qml
ProximityRadarMapView 1.0 ProximityRadarMapView.qml
SplitIndicator 1.0 SplitIndicator.qml SplitIndicator 1.0 SplitIndicator.qml
VehicleMapItem 1.0 VehicleMapItem.qml VehicleMapItem 1.0 VehicleMapItem.qml
...@@ -1139,6 +1139,7 @@ void Vehicle::_handleDistanceSensor(mavlink_message_t& message) ...@@ -1139,6 +1139,7 @@ void Vehicle::_handleDistanceSensor(mavlink_message_t& message)
if (orientation2Fact.orientation == distanceSensor.orientation) { if (orientation2Fact.orientation == distanceSensor.orientation) {
orientation2Fact.fact->setRawValue(distanceSensor.current_distance / 100.0); // cm to meters 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 ...@@ -4483,6 +4484,7 @@ const char* VehicleDistanceSensorFactGroup::_rotationYaw270FactName = "rotatio
const char* VehicleDistanceSensorFactGroup::_rotationYaw315FactName = "rotationYaw315"; const char* VehicleDistanceSensorFactGroup::_rotationYaw315FactName = "rotationYaw315";
const char* VehicleDistanceSensorFactGroup::_rotationPitch90FactName = "rotationPitch90"; const char* VehicleDistanceSensorFactGroup::_rotationPitch90FactName = "rotationPitch90";
const char* VehicleDistanceSensorFactGroup::_rotationPitch270FactName = "rotationPitch270"; const char* VehicleDistanceSensorFactGroup::_rotationPitch270FactName = "rotationPitch270";
const char* VehicleDistanceSensorFactGroup::_maxDistanceFactName = "maxDistance";
VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent) VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent)
: FactGroup (1000, ":/json/Vehicle/DistanceSensorFact.json", parent) : FactGroup (1000, ":/json/Vehicle/DistanceSensorFact.json", parent)
...@@ -4496,6 +4498,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent) ...@@ -4496,6 +4498,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent)
, _rotationYaw315Fact (0, _rotationYaw315FactName, FactMetaData::valueTypeDouble) , _rotationYaw315Fact (0, _rotationYaw315FactName, FactMetaData::valueTypeDouble)
, _rotationPitch90Fact (0, _rotationPitch90FactName, FactMetaData::valueTypeDouble) , _rotationPitch90Fact (0, _rotationPitch90FactName, FactMetaData::valueTypeDouble)
, _rotationPitch270Fact (0, _rotationPitch270FactName, FactMetaData::valueTypeDouble) , _rotationPitch270Fact (0, _rotationPitch270FactName, FactMetaData::valueTypeDouble)
, _maxDistanceFact (0, _maxDistanceFactName, FactMetaData::valueTypeDouble)
{ {
_addFact(&_rotationNoneFact, _rotationNoneFactName); _addFact(&_rotationNoneFact, _rotationNoneFactName);
_addFact(&_rotationYaw45Fact, _rotationYaw45FactName); _addFact(&_rotationYaw45Fact, _rotationYaw45FactName);
...@@ -4507,6 +4510,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent) ...@@ -4507,6 +4510,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent)
_addFact(&_rotationYaw315Fact, _rotationYaw315FactName); _addFact(&_rotationYaw315Fact, _rotationYaw315FactName);
_addFact(&_rotationPitch90Fact, _rotationPitch90FactName); _addFact(&_rotationPitch90Fact, _rotationPitch90FactName);
_addFact(&_rotationPitch270Fact, _rotationPitch270FactName); _addFact(&_rotationPitch270Fact, _rotationPitch270FactName);
_addFact(&_maxDistanceFact, _maxDistanceFactName);
// Start out as not available "--.--" // Start out as not available "--.--"
_rotationNoneFact.setRawValue(qQNaN()); _rotationNoneFact.setRawValue(qQNaN());
...@@ -4518,6 +4522,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent) ...@@ -4518,6 +4522,7 @@ VehicleDistanceSensorFactGroup::VehicleDistanceSensorFactGroup(QObject* parent)
_rotationYaw270Fact.setRawValue(qQNaN()); _rotationYaw270Fact.setRawValue(qQNaN());
_rotationPitch90Fact.setRawValue(qQNaN()); _rotationPitch90Fact.setRawValue(qQNaN());
_rotationPitch270Fact.setRawValue(qQNaN()); _rotationPitch270Fact.setRawValue(qQNaN());
_maxDistanceFact.setRawValue(qQNaN());
} }
const char* VehicleEstimatorStatusFactGroup::_goodAttitudeEstimateFactName = "goodAttitudeEsimate"; const char* VehicleEstimatorStatusFactGroup::_goodAttitudeEstimateFactName = "goodAttitudeEsimate";
......
...@@ -73,17 +73,19 @@ public: ...@@ -73,17 +73,19 @@ public:
Q_PROPERTY(Fact* rotationYaw315 READ rotationYaw315 CONSTANT) Q_PROPERTY(Fact* rotationYaw315 READ rotationYaw315 CONSTANT)
Q_PROPERTY(Fact* rotationPitch90 READ rotationPitch90 CONSTANT) Q_PROPERTY(Fact* rotationPitch90 READ rotationPitch90 CONSTANT)
Q_PROPERTY(Fact* rotationPitch270 READ rotationPitch270 CONSTANT) Q_PROPERTY(Fact* rotationPitch270 READ rotationPitch270 CONSTANT)
Q_PROPERTY(Fact* maxDistance READ maxDistance CONSTANT)
Fact* rotationNone () { return &_rotationNoneFact; } Fact* rotationNone () { return &_rotationNoneFact; }
Fact* rotationYaw45 () { return &_rotationYaw45Fact; } Fact* rotationYaw45 () { return &_rotationYaw45Fact; }
Fact* rotationYaw90 () { return &_rotationYaw90Fact; } Fact* rotationYaw90 () { return &_rotationYaw90Fact; }
Fact* rotationYaw135 () { return &_rotationYaw90Fact; } Fact* rotationYaw135 () { return &_rotationYaw135Fact; }
Fact* rotationYaw180 () { return &_rotationYaw180Fact; } Fact* rotationYaw180 () { return &_rotationYaw180Fact; }
Fact* rotationYaw225 () { return &_rotationYaw180Fact; } Fact* rotationYaw225 () { return &_rotationYaw225Fact; }
Fact* rotationYaw270 () { return &_rotationYaw270Fact; } Fact* rotationYaw270 () { return &_rotationYaw270Fact; }
Fact* rotationYaw315 () { return &_rotationYaw315Fact; } Fact* rotationYaw315 () { return &_rotationYaw315Fact; }
Fact* rotationPitch90 () { return &_rotationPitch90Fact; } Fact* rotationPitch90 () { return &_rotationPitch90Fact; }
Fact* rotationPitch270 () { return &_rotationPitch270Fact; } Fact* rotationPitch270 () { return &_rotationPitch270Fact; }
Fact* maxDistance () { return &_maxDistanceFact; }
static const char* _rotationNoneFactName; static const char* _rotationNoneFactName;
static const char* _rotationYaw45FactName; static const char* _rotationYaw45FactName;
...@@ -95,6 +97,7 @@ public: ...@@ -95,6 +97,7 @@ public:
static const char* _rotationYaw315FactName; static const char* _rotationYaw315FactName;
static const char* _rotationPitch90FactName; static const char* _rotationPitch90FactName;
static const char* _rotationPitch270FactName; static const char* _rotationPitch270FactName;
static const char* _maxDistanceFactName;
private: private:
Fact _rotationNoneFact; Fact _rotationNoneFact;
...@@ -107,6 +110,7 @@ private: ...@@ -107,6 +110,7 @@ private:
Fact _rotationYaw315Fact; Fact _rotationYaw315Fact;
Fact _rotationPitch90Fact; Fact _rotationPitch90Fact;
Fact _rotationPitch270Fact; Fact _rotationPitch270Fact;
Fact _maxDistanceFact;
}; };
class VehicleSetpointFactGroup : public FactGroup class VehicleSetpointFactGroup : public FactGroup
...@@ -698,6 +702,7 @@ public: ...@@ -698,6 +702,7 @@ public:
Q_PROPERTY(FactGroup* setpoint READ setpointFactGroup CONSTANT) Q_PROPERTY(FactGroup* setpoint READ setpointFactGroup CONSTANT)
Q_PROPERTY(FactGroup* estimatorStatus READ estimatorStatusFactGroup CONSTANT) Q_PROPERTY(FactGroup* estimatorStatus READ estimatorStatusFactGroup CONSTANT)
Q_PROPERTY(FactGroup* terrain READ terrainFactGroup 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 firmwareMajorVersion READ firmwareMajorVersion NOTIFY firmwareVersionChanged)
Q_PROPERTY(int firmwareMinorVersion READ firmwareMinorVersion NOTIFY firmwareVersionChanged) Q_PROPERTY(int firmwareMinorVersion READ firmwareMinorVersion NOTIFY firmwareVersionChanged)
......
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