QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
ObstacleDistanceOverlayVideo.qml
Go to the documentation of this file.
1import QtQuick
2
3import QGroundControl
4
5Item {
6 id: root
7 anchors.fill: parent
8 property var showText: obstacleDistance._showText
9
10 function drawSegment(ctx, range, centerX, centerY, lengthFrom, lengthTo, radFrom, radTo, grad) {
11 // Qt expects the angles to be in respect of the X axis, The Incoming Angles are in FRD From Front goind Clockwise
12 // Transform coordinates to Qt XY
13 radFrom -= Math.PI / 2
14 radTo -= Math.PI / 2
15 const topSrcX = centerX + lengthFrom * Math.cos(radFrom)
16 const topSrcY = centerY + lengthFrom * Math.sin(radFrom)
17 const topDstX = centerX + lengthFrom * Math.cos(radTo)
18 const topDstY = centerY + lengthFrom * Math.sin(radTo)
19
20 ctx.save()
21 ctx.setTransform(2, 0, 0, 1, -centerX, 0)
22 ctx.beginPath()
23 ctx.fillStyle = grad
24 ctx.moveTo(topSrcX, topSrcY)
25 ctx.arc(centerX, centerY, lengthFrom, radFrom, radTo, false)
26 ctx.arc(centerX, centerY, lengthTo, radTo, radFrom, true)
27 ctx.lineTo(topSrcX, topSrcY)
28 ctx.fill()
29 ctx.closePath()
30 ctx.restore()
31
32 if (range > 0) {
33 ctx.save()
34 ctx.setTransform(2, 0, 0, 2, -centerX, 0)
35 ctx.beginPath()
36 ctx.strokeStyle = Qt.rgba(0, 0, 0, 0.8)
37 ctx.font = "bold 10px sans-serif"
38 ctx.lineWidth = 2
39 ctx.fillStyle = Qt.rgba(1, 1, 1, 0.8)
40 const text = obstacleDistance._rangeToShow(range)
41 const textX = topSrcX + (topDstX - topSrcX) / 2
42 const textY = topSrcY + (topDstY - topSrcY) / 2
43 ctx.strokeText(text, textX, textY / 2)
44 ctx.fillText(text, textX, textY / 2)
45 ctx.closePath()
46 ctx.restore()
47 }
48 }
49
50 function paintObstacleOverlay(ctx) {
51 const centerX = root.width / 2
52 const centerY = root.height / 2
53 const maxRadiusPixels = 0.9 * root.height / 2 // Max pixels to center
54 const minRadiusPixels = maxRadiusPixels * 0.2 // Min radius in pixels to center
55 const minGradPixels = minRadiusPixels
56 const maxGradPixels = maxRadiusPixels
57 const segmentHeightPixels = minRadiusPixels / 8
58 const levelMeters = 10
59 const levelNum = obstacleDistance._maxRadiusMeters / levelMeters
60
61 var grad = ctx.createRadialGradient(centerX, centerY, maxGradPixels - segmentHeightPixels * levelNum * 2, centerX, centerY, maxGradPixels)
62 grad.addColorStop(0, Qt.rgba(1, 0, 0, 0.9))
63 grad.addColorStop(0.1, Qt.rgba(1, 0, 0, 0.3))
64 grad.addColorStop(0.5, Qt.rgba(1, 0.64, 0, 0.3))
65 grad.addColorStop(0.65, Qt.rgba(1, 0.64, 0, 0.2))
66 grad.addColorStop(0.95, Qt.rgba(0, 1, 0, 0.1))
67 grad.addColorStop(1, Qt.rgba(0, 1, 0, 0))
68
69 const segNum = 16
70 const incDeg = 360 / segNum
71 for (var s = 0; s < segNum; ++s) {
72 const deg = s * 360.0 / segNum
73 const rad = deg * Math.PI / 180.0
74 const i = obstacleDistance._degToRangeIdx(deg, false)
75 const iNext = obstacleDistance._degToRangeIdx(deg + incDeg, false)
76 var rangeMin = obstacleDistance._maxRadiusMeters
77
78 const end = i < iNext ? iNext : obstacleDistance._rangesLen + iNext
79 for (var ii = i; ii < end; ++ii) {
80 const r = obstacleDistance._ranges[ii % obstacleDistance._rangesLen] / 100
81 if (r < rangeMin)
82 rangeMin = r
83 }
84
85 const lengthFrom = maxRadiusPixels
86 const radFrom = rad
87 const radTo = radFrom + incDeg * Math.PI / 180.0 - 0.03
88 var range = obstacleDistance._maxRadiusMeters
89 for (var ii = 0; ii < levelNum; ++ii) {
90 const from = lengthFrom - ii * segmentHeightPixels * 2
91 const to = from - segmentHeightPixels
92 const rangeInLevel = obstacleDistance._maxRadiusMeters - (ii + 1) * levelMeters
93 const isLast = ii >= levelNum - 1
94 if (rangeMin > rangeInLevel || isLast)
95 range = rangeMin
96 const rangeToShow = showText && range < obstacleDistance._maxRadiusMeters ? range : 0
97 drawSegment(ctx, rangeToShow, centerX, centerY, from, to, radFrom, radTo, grad)
98 if (range == rangeMin)
99 break
100 }
101 }
102 }
103
104 ObstacleDistanceOverlay {
105 id: obstacleDistance
106 }
107}