Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
c47886df
Unverified
Commit
c47886df
authored
Aug 21, 2020
by
Don Gagne
Committed by
GitHub
Aug 21, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8961 from profff/master
Distance sensors view in Map and vidéo view
parents
dbcf8173
0d4a3116
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
290 additions
and
5 deletions
+290
-5
qgroundcontrol.qrc
qgroundcontrol.qrc
+2
-0
FlyViewMap.qml
src/FlightDisplay/FlyViewMap.qml
+10
-1
FlyViewVideo.qml
src/FlightDisplay/FlyViewVideo.qml
+8
-2
ProximityRadarVideoView.qml
src/FlightDisplay/ProximityRadarVideoView.qml
+108
-0
ProximityRadarMapView.qml
src/FlightMap/MapItems/ProximityRadarMapView.qml
+148
-0
qmldir
src/QmlControls/QGroundControl/FlightDisplay/qmldir
+1
-0
qmldir
src/QmlControls/QGroundControl/FlightMap/qmldir
+1
-0
Vehicle.cc
src/Vehicle/Vehicle.cc
+5
-0
Vehicle.h
src/Vehicle/Vehicle.h
+7
-2
No files found.
qgroundcontrol.qrc
View file @
c47886df
...
...
@@ -272,6 +272,8 @@
<file alias="VibrationPage.qml">src/AnalyzeView/VibrationPage.qml</file>
<file alias="VirtualJoystick.qml">src/FlightDisplay/VirtualJoystick.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 prefix="/FirstRunPromptDialogs">
<file alias="UnitsFirstRunPrompt.qml">src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml</file>
...
...
src/FlightDisplay/FlyViewMap.qml
View file @
c47886df
...
...
@@ -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
...
...
src/FlightDisplay/FlyViewVideo.qml
View file @
c47886df
...
...
@@ -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
}
}
src/FlightDisplay/ProximityRadarVideoView.qml
0 → 100644
View file @
c47886df
/****************************************************************************
*
* (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
}
}
}
src/FlightMap/MapItems/ProximityRadarMapView.qml
0 → 100644
View file @
c47886df
/****************************************************************************
*
* (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
();
}
}
}
src/QmlControls/QGroundControl/FlightDisplay/qmldir
View file @
c47886df
...
...
@@ -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
src/QmlControls/QGroundControl/FlightMap/qmldir
View file @
c47886df
...
...
@@ -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
src/Vehicle/Vehicle.cc
View file @
c47886df
...
...
@@ -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"
;
...
...
src/Vehicle/Vehicle.h
View file @
c47886df
...
...
@@ -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
&
_rotationYaw
90
Fact
;
}
Fact
*
rotationYaw135
()
{
return
&
_rotationYaw
135
Fact
;
}
Fact
*
rotationYaw180
()
{
return
&
_rotationYaw180Fact
;
}
Fact
*
rotationYaw225
()
{
return
&
_rotationYaw
180
Fact
;
}
Fact
*
rotationYaw225
()
{
return
&
_rotationYaw
225
Fact
;
}
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
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment