@@ -3,13 +3,22 @@ import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
3
3
import { PipelineType } from " @/types/PipelineTypes" ;
4
4
import { useStateStore } from " @/stores/StateStore" ;
5
5
6
- const currentPipelineSettings = useCameraSettingsStore ().currentPipelineSettings ;
6
+ const calculateStdDev = (values : number []): number => {
7
+ if (values .length < 2 ) return 0 ;
8
+
9
+ const mean = values .reduce ((sum , number ) => sum + number , 0 ) / values .length ;
10
+
11
+ return Math .sqrt (values .map ((x ) => Math .pow (x - mean , 2 )).reduce ((a , b ) => a + b ) / values .length );
12
+ };
13
+ const resetCurrentBuffer = () => {
14
+ // Need to clear the array in place
15
+ while (useStateStore ().currentMultitagBuffer ?.length != 0 ) useStateStore ().currentMultitagBuffer ?.pop ();
16
+ };
7
17
</script >
8
18
9
19
<template >
10
20
<div >
11
21
<v-row align =" start" class =" pb-4" style =" height : 300px " >
12
- <!-- Simple table height must be set here and in the CSS for the fixed-header to work -->
13
22
<v-simple-table fixed-header dense dark >
14
23
<template #default >
15
24
<thead style =" font-size : 1.25rem " >
@@ -80,40 +89,119 @@ const currentPipelineSettings = useCameraSettingsStore().currentPipelineSettings
80
89
</template >
81
90
</v-simple-table >
82
91
</v-row >
83
- <v-row
92
+ <v-container
84
93
v-if ="
85
94
(useCameraSettingsStore().currentPipelineType === PipelineType.AprilTag ||
86
95
useCameraSettingsStore().currentPipelineType === PipelineType.Aruco) &&
87
- currentPipelineSettings.doMultiTarget &&
96
+ useCameraSettingsStore(). currentPipelineSettings.doMultiTarget &&
88
97
useCameraSettingsStore().isCurrentVideoFormatCalibrated &&
89
98
useCameraSettingsStore().currentPipelineSettings.solvePNPEnabled
90
99
"
91
- align =" start"
92
- class =" pb-4 white--text"
93
100
>
94
- <v-card-subtitle class =" ma-0 pa-0 pb-4" style =" font-size : 16px " >Multi-tag pose, field-to-camera</v-card-subtitle >
95
- <v-simple-table fixed-header height =" 100%" dense dark >
96
- <thead style =" font-size : 1.25rem " >
97
- <th class =" text-center" >X meters</th >
98
- <th class =" text-center" >Y meters</th >
99
- <th class =" text-center" >Z Angle &theta ;° ; </th >
100
- <th class =" text-center" >Tags</th >
101
- </thead >
102
- <tbody v-show =" useStateStore().currentPipelineResults?.multitagResult" >
103
- <td >{{ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.x.toFixed(2) }}  ; m</td >
104
- <td >{{ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.y.toFixed(2) }}  ; m</td >
105
- <td >
106
- {{
107
- (
108
- useStateStore().currentPipelineResults?.multitagResult?.bestTransform.angle_z *
109
- (180.0 / Math.PI)
110
- ).toFixed(2)
111
- }}° ;
112
- </td >
113
- <td >{{ useStateStore().currentPipelineResults?.multitagResult?.fiducialIDsUsed }}</td >
114
- </tbody >
115
- </v-simple-table >
116
- </v-row >
101
+ <v-row class =" pb-4 white--text" >
102
+ <v-card-subtitle class =" ma-0 pa-0 pb-4" style =" font-size : 16px "
103
+ >Multi-tag pose, field-to-camera</v-card-subtitle
104
+ >
105
+ <v-simple-table fixed-header height =" 100%" dense dark >
106
+ <thead style =" font-size : 1.25rem " >
107
+ <th class =" text-center" >X meters</th >
108
+ <th class =" text-center" >Y meters</th >
109
+ <th class =" text-center" >Z meters</th >
110
+ <th class =" text-center" >X Angle &theta ;° ; </th >
111
+ <th class =" text-center" >Y Angle &theta ;° ; </th >
112
+ <th class =" text-center" >Z Angle &theta ;° ; </th >
113
+ <th class =" text-center" >Tags</th >
114
+ </thead >
115
+ <tbody v-show =" useStateStore().currentPipelineResults?.multitagResult" >
116
+ <td >{{ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.x.toFixed(2) }}  ; m</td >
117
+ <td >{{ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.y.toFixed(2) }}  ; m</td >
118
+ <td >{{ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.z.toFixed(2) }}  ; m</td >
119
+ <td >
120
+ {{
121
+ (
122
+ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.angle_x *
123
+ (180.0 / Math.PI)
124
+ ).toFixed(2)
125
+ }}° ;
126
+ </td >
127
+ <td >
128
+ {{
129
+ (
130
+ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.angle_y *
131
+ (180.0 / Math.PI)
132
+ ).toFixed(2)
133
+ }}° ;
134
+ </td >
135
+ <td >
136
+ {{
137
+ (
138
+ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.angle_z *
139
+ (180.0 / Math.PI)
140
+ ).toFixed(2)
141
+ }}° ;
142
+ </td >
143
+ <td >{{ useStateStore().currentPipelineResults?.multitagResult?.fiducialIDsUsed }}</td >
144
+ </tbody >
145
+ </v-simple-table >
146
+ </v-row >
147
+ <v-row class =" pb-4 white--text" style =" display : flex ; flex-direction : column " >
148
+ <v-card-subtitle class =" ma-0 pa-0 pb-4 pr-4" style =" font-size : 16px "
149
+ >Multi-tag pose standard deviation over the last {{ useStateStore().currentMultitagBuffer.length }}/100
150
+ samples
151
+ </v-card-subtitle >
152
+ <v-btn color =" secondary" class =" mb-4 mt-1" style =" width : min-content " depressed @click =" resetCurrentBuffer"
153
+ >Reset Samples</v-btn
154
+ >
155
+ <v-simple-table fixed-header height =" 100%" dense dark >
156
+ <thead style =" font-size : 1.25rem " >
157
+ <th class =" text-center" >X meters</th >
158
+ <th class =" text-center" >Y meters</th >
159
+ <th class =" text-center" >Z meters</th >
160
+ <th class =" text-center" >X Angle &theta ;° ; </th >
161
+ <th class =" text-center" >Y Angle &theta ;° ; </th >
162
+ <th class =" text-center" >Z Angle &theta ;° ; </th >
163
+ </thead >
164
+ <tbody v-show =" useStateStore().currentPipelineResults?.multitagResult" >
165
+ <td >
166
+ {{
167
+ calculateStdDev(useStateStore().currentMultitagBuffer?.map((v) => v.bestTransform.x)).toFixed(5)
168
+ }}  ; m
169
+ </td >
170
+ <td >
171
+ {{
172
+ calculateStdDev(useStateStore().currentMultitagBuffer?.map((v) => v.bestTransform.y)).toFixed(5)
173
+ }}  ; m
174
+ </td >
175
+ <td >
176
+ {{
177
+ calculateStdDev(useStateStore().currentMultitagBuffer?.map((v) => v.bestTransform.z)).toFixed(5)
178
+ }}  ; m
179
+ </td >
180
+ <td >
181
+ {{
182
+ calculateStdDev(
183
+ useStateStore().currentMultitagBuffer?.map((v) => v.bestTransform.angle_x * (180.0 / Math.PI))
184
+ ).toFixed(5)
185
+ }}° ;
186
+ </td >
187
+ <td >
188
+ {{
189
+ calculateStdDev(
190
+ useStateStore().currentMultitagBuffer?.map((v) => v.bestTransform.angle_y * (180.0 / Math.PI))
191
+ ).toFixed(5)
192
+ }}° ;
193
+ </td >
194
+ <td >
195
+ {{
196
+ calculateStdDev(
197
+ useStateStore().currentMultitagBuffer?.map((v) => v.bestTransform.angle_z * (180.0 / Math.PI))
198
+ ).toFixed(5)
199
+ }}° ;
200
+ </td >
201
+ </tbody >
202
+ </v-simple-table >
203
+ </v-row >
204
+ </v-container >
117
205
</div >
118
206
</template >
119
207
0 commit comments