@luxonis/visualizer-protobuf 2.67.2 → 2.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-CCsfCpZT.js → index-7BbbXb7C.js} +1 -1
- package/dist/{index-CZkF1YCY.js → index-B5d7u70w.js} +1 -1
- package/dist/{index-FM6vEyS1.js → index-BGrghyc8.js} +1 -1
- package/dist/{index-CaE-gPi_.js → index-BSEL9eaF.js} +1 -1
- package/dist/{index-CZ6h7zpz.js → index-Bjwf7lc9.js} +1 -1
- package/dist/{index-BNMXWFDA.js → index-Bndiqw1t.js} +1 -1
- package/dist/{index-CRTwfb76.js → index-BzPticWU.js} +1 -1
- package/dist/{index-B3cHfrcw.js → index-C99kj7Bj.js} +1 -1
- package/dist/{index-ugbolO1H.js → index-CO2KzlVr.js} +1 -1
- package/dist/{index-BuGHi09K.js → index-CfGQhG__.js} +1 -1
- package/dist/{index-C92x9EiC.js → index-CwMsPSeQ.js} +2 -2
- package/dist/{index-D7JYN_IN.js → index-D5xb8lsX.js} +914 -486
- package/dist/{index-BhLYvhjo.js → index-D9b6Lu-5.js} +1 -1
- package/dist/{index-KDfpYD4q.js → index-DEr2t1uV.js} +1 -1
- package/dist/{index-BzAo-6Ol.js → index-DXgxTZSz.js} +1 -1
- package/dist/{index-DW9FJFJz.js → index-DoCri7UR.js} +1 -1
- package/dist/{index-2Ajz1Y1F.js → index-DtErPDFb.js} +1 -1
- package/dist/{index-CLHPbWo6.js → index-DycPqoQx.js} +37 -24
- package/dist/{index-HcH5t5Pw.js → index-pfvcsvrO.js} +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/src/connection/connection.d.ts +3 -1
- package/dist/lib/src/connection/connection.d.ts.map +1 -1
- package/dist/lib/src/connection/connection.js +3 -2
- package/dist/lib/src/connection/connection.js.map +1 -1
- package/dist/lib/src/output.css +4 -2
- package/dist/lib/src/utils/config-store.d.ts +3 -0
- package/dist/lib/src/utils/config-store.d.ts.map +1 -1
- package/dist/lib/src/utils/config-store.js +8 -0
- package/dist/lib/src/utils/config-store.js.map +1 -1
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/ImageMode.d.ts.map +1 -1
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/ImageMode.js +2 -2
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/ImageMode.js.map +1 -1
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandler.d.ts +3 -3
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandler.d.ts.map +1 -1
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandler.js +1 -1
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandler.js.map +1 -1
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerFactory.d.ts +11 -0
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerFactory.d.ts.map +1 -0
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerFactory.js +24 -0
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerFactory.js.map +1 -0
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerV2.d.ts +94 -0
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerV2.d.ts.map +1 -0
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerV2.js +410 -0
- package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerV2.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at http://mozilla.org/MPL/2.0/
|
|
4
|
+
import { getTimestampFromImage, } from "@foxglove/studio-base/panels/ThreeDeeRender/renderables/Images/ImageTypes";
|
|
5
|
+
import { normalizeCompressedImage, normalizeRawImage, normalizeRosCompressedImage, normalizeRosImage, } from "@foxglove/studio-base/panels/ThreeDeeRender/renderables/Images/imageNormalizers";
|
|
6
|
+
import { normalizeCameraInfo } from "@foxglove/studio-base/panels/ThreeDeeRender/renderables/projections";
|
|
7
|
+
import { normalizeAnnotations } from "./annotations/normalizeAnnotations";
|
|
8
|
+
import { IMAGE_MODE_HUD_GROUP_ID, WAITING_FOR_BOTH_MESSAGES_HUD_ID, WAITING_FOR_CALIBRATION_HUD_ID, WAITING_FOR_IMAGES_EMPTY_HUD_ID, WAITING_FOR_IMAGES_NOTICE_ID, WAITING_FOR_SYNC_EMPTY_HUD_ID, WAITING_FOR_SYNC_NOTICE_HUD_ID, } from "./constants";
|
|
9
|
+
import { t3D } from "../../t3D";
|
|
10
|
+
const syncToleranceSec = 0.15; // maximum acceptable time difference for selecting a “closest” annotation.
|
|
11
|
+
const maxStalenessSec = 1.1; // how long we can hold the last older annotation if no better match is available. 1s corresponds to 1 FPS + 100ms window for jitter.
|
|
12
|
+
const hysteresisSec = 0.1; // how much “stickiness” we allow before switching candidates.
|
|
13
|
+
const imageRetentionSec = 5; // keep small window of recent images
|
|
14
|
+
const maxImageBuffer = 150; // cap number of stored images
|
|
15
|
+
// Have constants for the HUD items so that they don't need to be recreated and GCed every message
|
|
16
|
+
export const WAITING_FOR_BOTH_HUD_ITEM = {
|
|
17
|
+
id: WAITING_FOR_BOTH_MESSAGES_HUD_ID,
|
|
18
|
+
group: IMAGE_MODE_HUD_GROUP_ID,
|
|
19
|
+
getMessage: () => t3D("waitingForCalibrationAndImages"),
|
|
20
|
+
displayType: "empty",
|
|
21
|
+
};
|
|
22
|
+
export const WAITING_FOR_CALIBRATION_HUD_ITEM = {
|
|
23
|
+
id: WAITING_FOR_CALIBRATION_HUD_ID,
|
|
24
|
+
group: IMAGE_MODE_HUD_GROUP_ID,
|
|
25
|
+
getMessage: () => t3D("waitingForCalibration"),
|
|
26
|
+
displayType: "empty",
|
|
27
|
+
};
|
|
28
|
+
export const WAITING_FOR_IMAGE_NOTICE_HUD_ITEM = {
|
|
29
|
+
id: WAITING_FOR_IMAGES_NOTICE_ID,
|
|
30
|
+
group: IMAGE_MODE_HUD_GROUP_ID,
|
|
31
|
+
getMessage: () => t3D("waitingForImages"),
|
|
32
|
+
displayType: "notice",
|
|
33
|
+
};
|
|
34
|
+
export const WAITING_FOR_IMAGE_EMPTY_HUD_ITEM = {
|
|
35
|
+
id: WAITING_FOR_IMAGES_EMPTY_HUD_ID,
|
|
36
|
+
group: IMAGE_MODE_HUD_GROUP_ID,
|
|
37
|
+
getMessage: () => t3D("waitingForImages"),
|
|
38
|
+
displayType: "empty",
|
|
39
|
+
};
|
|
40
|
+
export const WAITING_FOR_SYNC_NOTICE_HUD_ITEM = {
|
|
41
|
+
id: WAITING_FOR_SYNC_NOTICE_HUD_ID,
|
|
42
|
+
group: IMAGE_MODE_HUD_GROUP_ID,
|
|
43
|
+
getMessage: () => t3D("waitingForSyncAnnotations"),
|
|
44
|
+
displayType: "notice",
|
|
45
|
+
};
|
|
46
|
+
export const WAITING_FOR_SYNC_EMPTY_HUD_ITEM = {
|
|
47
|
+
id: WAITING_FOR_SYNC_EMPTY_HUD_ID,
|
|
48
|
+
group: IMAGE_MODE_HUD_GROUP_ID,
|
|
49
|
+
getMessage: () => t3D("waitingForSyncAnnotations"),
|
|
50
|
+
displayType: "empty",
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Processes and normalizes incoming messages and manages state of
|
|
54
|
+
* messages to be rendered given the ImageMode config. A large part of this responsibility
|
|
55
|
+
* is managing state in synchronized mode and ensuring that the a synchronized set of image and
|
|
56
|
+
* annotations are handed off to the SceneExtension for rendering.
|
|
57
|
+
*/
|
|
58
|
+
export class MessageHandlerV2 {
|
|
59
|
+
/** settings that should reflect image mode config */
|
|
60
|
+
#config;
|
|
61
|
+
/** Allows message handler push messages to overlay on top of the canvas */
|
|
62
|
+
#hud;
|
|
63
|
+
/** last state passed to listeners */
|
|
64
|
+
#oldRenderState;
|
|
65
|
+
/** internal state of last received messages */
|
|
66
|
+
#lastReceivedMessages;
|
|
67
|
+
/** listener functions that are called when the state changes. */
|
|
68
|
+
#listeners = [];
|
|
69
|
+
/** Holds what annotations are currently available on the given source. These are needed because annotations
|
|
70
|
+
* that are marked as visible may be present in the layout/config, but are not present on the source.
|
|
71
|
+
* This can cause synchronized annotations to never resolve if the source does not have the annotation topic
|
|
72
|
+
* with no indication to the user that the annotation is not available.
|
|
73
|
+
*/
|
|
74
|
+
#onAnnotationReceivedEvent;
|
|
75
|
+
#annotationsFpsRefreshInterval = null;
|
|
76
|
+
lastImage;
|
|
77
|
+
// New: keep a buffer of recent images for annotation-prioritized synchronization
|
|
78
|
+
imagesBuffer = [];
|
|
79
|
+
// Store a small buffer of recent annotations per topic with computed seconds timestamps
|
|
80
|
+
annotationsMap = new Map();
|
|
81
|
+
// Track last selected annotation per topic to add hysteresis and reduce flicker
|
|
82
|
+
lastSelectedByTopic = new Map();
|
|
83
|
+
availableAnnotationTopics;
|
|
84
|
+
/**
|
|
85
|
+
* Create a MessageHandler
|
|
86
|
+
* @param {Immutable<MessageHandlerConfig>} config - subset of ImageMode settings required for message handling
|
|
87
|
+
* @param {HUDItemManager} hud - HUD manager used to display informational messages on the canvas
|
|
88
|
+
*/
|
|
89
|
+
constructor(config, hud) {
|
|
90
|
+
this.#config = config;
|
|
91
|
+
this.#hud = hud;
|
|
92
|
+
this.#lastReceivedMessages = {
|
|
93
|
+
annotationsByTopic: new Map(),
|
|
94
|
+
};
|
|
95
|
+
this.availableAnnotationTopics = new Set();
|
|
96
|
+
}
|
|
97
|
+
dispose() {
|
|
98
|
+
if (this.#annotationsFpsRefreshInterval) {
|
|
99
|
+
clearInterval(this.#annotationsFpsRefreshInterval);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
addListener(listener) {
|
|
103
|
+
this.#listeners.push(listener);
|
|
104
|
+
}
|
|
105
|
+
addAnnotationReceivedEventHandler(handler) {
|
|
106
|
+
this.#onAnnotationReceivedEvent = handler;
|
|
107
|
+
}
|
|
108
|
+
removeListener(listener) {
|
|
109
|
+
this.#listeners = this.#listeners.filter((fn) => fn !== listener);
|
|
110
|
+
}
|
|
111
|
+
handleRosRawImage = (messageEvent) => {
|
|
112
|
+
this.handleImage(messageEvent, normalizeRosImage(messageEvent.message));
|
|
113
|
+
};
|
|
114
|
+
handleRosCompressedImage = (messageEvent) => {
|
|
115
|
+
this.handleImage(messageEvent, normalizeRosCompressedImage(messageEvent.message));
|
|
116
|
+
};
|
|
117
|
+
handleRawImage = (messageEvent) => {
|
|
118
|
+
this.handleImage(messageEvent, normalizeRawImage(messageEvent.message));
|
|
119
|
+
};
|
|
120
|
+
handleCompressedImage = (messageEvent) => {
|
|
121
|
+
this.handleImage(messageEvent, normalizeCompressedImage(messageEvent.message));
|
|
122
|
+
};
|
|
123
|
+
handleImage(message, image) {
|
|
124
|
+
this.lastImage = {
|
|
125
|
+
...message,
|
|
126
|
+
message: image,
|
|
127
|
+
};
|
|
128
|
+
// Compute timestamp seconds for buffer storage (prefer image stamp, then receiveTime, then wall clock)
|
|
129
|
+
const stamp = getTimestampFromImage(image);
|
|
130
|
+
let stampTimeSec;
|
|
131
|
+
const stampSec = stamp?.sec;
|
|
132
|
+
const stampNsec = stamp?.nsec;
|
|
133
|
+
if (typeof stampSec === "number" && typeof stampNsec === "number") {
|
|
134
|
+
stampTimeSec = stampSec + stampNsec / 1e9;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const recv = message.receiveTime;
|
|
138
|
+
const recvSec = recv?.sec;
|
|
139
|
+
const recvNsec = recv?.nsec;
|
|
140
|
+
if (typeof recvSec === "number" && typeof recvNsec === "number") {
|
|
141
|
+
stampTimeSec = recvSec + recvNsec / 1e9;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const arrivalSec = performance.now() / 1000;
|
|
145
|
+
if (this.#hasVisibleAnnotationTopics()) {
|
|
146
|
+
this.imagesBuffer.push({ image: this.lastImage, stampTimeSec, arrivalSec });
|
|
147
|
+
// Trim by arrival time and length (do not use stamped time for retention)
|
|
148
|
+
const nowSec = performance.now() / 1000;
|
|
149
|
+
const cutoffArrival = nowSec - imageRetentionSec;
|
|
150
|
+
this.imagesBuffer = this.imagesBuffer.filter((e) => e.arrivalSec >= cutoffArrival);
|
|
151
|
+
if (this.imagesBuffer.length > maxImageBuffer) {
|
|
152
|
+
this.imagesBuffer.splice(0, this.imagesBuffer.length - maxImageBuffer);
|
|
153
|
+
}
|
|
154
|
+
// Do not emit here; when annotations are visible we render on annotation arrival
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// No visible annotations -> render immediately
|
|
158
|
+
this.#emitState();
|
|
159
|
+
}
|
|
160
|
+
handleCameraInfo = (message) => {
|
|
161
|
+
this.#lastReceivedMessages.cameraInfo = normalizeCameraInfo(message.message);
|
|
162
|
+
this.#emitState();
|
|
163
|
+
};
|
|
164
|
+
handleAnnotations = (messageEvent) => {
|
|
165
|
+
const list = normalizeAnnotations(messageEvent.message, messageEvent.schemaName);
|
|
166
|
+
const arrivalSec = performance.now() / 1000;
|
|
167
|
+
if (list.length > 0 && messageEvent.topic) {
|
|
168
|
+
this.#onAnnotationReceivedEvent?.();
|
|
169
|
+
// Prefer timestamps embedded in the annotations themselves
|
|
170
|
+
const stampTimes = [];
|
|
171
|
+
for (const a of list) {
|
|
172
|
+
const sec = a.stamp?.sec;
|
|
173
|
+
const nsec = a.stamp?.nsec;
|
|
174
|
+
if (typeof sec === "number" && typeof nsec === "number") {
|
|
175
|
+
stampTimes.push(sec + nsec / 1e9);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const timeSec = stampTimes.length > 0 ? Math.max(...stampTimes) : arrivalSec;
|
|
179
|
+
const entry = {
|
|
180
|
+
annotation: {
|
|
181
|
+
originalMessage: messageEvent,
|
|
182
|
+
annotations: list,
|
|
183
|
+
},
|
|
184
|
+
timeSec,
|
|
185
|
+
arrivalSec,
|
|
186
|
+
};
|
|
187
|
+
const topic = messageEvent.topic;
|
|
188
|
+
const buffer = this.annotationsMap.get(topic) ?? [];
|
|
189
|
+
buffer.push(entry);
|
|
190
|
+
// Keep unlimited buffer length, but drop entries older than 20 seconds based on arrival time
|
|
191
|
+
const retentionSec = 20;
|
|
192
|
+
const nowSec = performance.now() / 1000;
|
|
193
|
+
const cutoffArrival = nowSec - retentionSec;
|
|
194
|
+
const trimmed = buffer.filter((e) => e.arrivalSec >= cutoffArrival);
|
|
195
|
+
this.annotationsMap.set(topic, trimmed);
|
|
196
|
+
}
|
|
197
|
+
// Always emit; render selection logic will pick appropriate annotations for the last image
|
|
198
|
+
this.#emitState();
|
|
199
|
+
if (this.#config.synchronize === false) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// synchronized mode does selection in #getRenderState
|
|
203
|
+
};
|
|
204
|
+
setConfig(newConfig) {
|
|
205
|
+
let changed = false;
|
|
206
|
+
if (newConfig.synchronize != undefined && newConfig.synchronize !== this.#config.synchronize) {
|
|
207
|
+
this.#oldRenderState = undefined;
|
|
208
|
+
changed = true;
|
|
209
|
+
}
|
|
210
|
+
if ("imageTopic" in newConfig && this.#config.imageTopic !== newConfig.imageTopic) {
|
|
211
|
+
this.#lastReceivedMessages.image = undefined;
|
|
212
|
+
changed = true;
|
|
213
|
+
}
|
|
214
|
+
if (this.#config.calibrationTopic !== newConfig.calibrationTopic) {
|
|
215
|
+
this.#lastReceivedMessages.cameraInfo = undefined;
|
|
216
|
+
changed = true;
|
|
217
|
+
}
|
|
218
|
+
if (newConfig.annotations != undefined &&
|
|
219
|
+
this.#config.annotations &&
|
|
220
|
+
this.#config.annotations !== newConfig.annotations) {
|
|
221
|
+
const newVisibleTopics = new Set();
|
|
222
|
+
for (const [topic, settings] of Object.entries(newConfig.annotations)) {
|
|
223
|
+
if (settings?.visible === true) {
|
|
224
|
+
newVisibleTopics.add(topic);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
for (const topic of this.#lastReceivedMessages.annotationsByTopic.keys()) {
|
|
228
|
+
if (!newVisibleTopics.has(topic)) {
|
|
229
|
+
this.#lastReceivedMessages.annotationsByTopic.delete(topic);
|
|
230
|
+
changed = true;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
this.#config = newConfig;
|
|
235
|
+
if (changed) {
|
|
236
|
+
this.#emitState();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
setAvailableAnnotationTopics(topicNames) {
|
|
240
|
+
this.availableAnnotationTopics = new Set(topicNames);
|
|
241
|
+
this.#emitState();
|
|
242
|
+
}
|
|
243
|
+
clear() {
|
|
244
|
+
this.#lastReceivedMessages = {
|
|
245
|
+
annotationsByTopic: new Map(),
|
|
246
|
+
};
|
|
247
|
+
this.annotationsMap.clear();
|
|
248
|
+
this.lastSelectedByTopic.clear();
|
|
249
|
+
this.lastImage = undefined;
|
|
250
|
+
this.imagesBuffer = [];
|
|
251
|
+
this.#oldRenderState = undefined;
|
|
252
|
+
this.#emitState();
|
|
253
|
+
}
|
|
254
|
+
#emitState() {
|
|
255
|
+
const state = this.getRenderStateAndUpdateHUD();
|
|
256
|
+
this.#listeners.forEach((fn) => {
|
|
257
|
+
fn(state, this.#oldRenderState);
|
|
258
|
+
});
|
|
259
|
+
this.#oldRenderState = state;
|
|
260
|
+
}
|
|
261
|
+
/** Check if there are any visible annotation topics configured */
|
|
262
|
+
#hasVisibleAnnotationTopics() {
|
|
263
|
+
if (!this.#config.annotations) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
for (const settings of Object.values(this.#config.annotations)) {
|
|
267
|
+
if (settings?.visible === true) {
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
/** Do not use. only public for testing */
|
|
274
|
+
getRenderStateAndUpdateHUD() {
|
|
275
|
+
const state = this.#getRenderState();
|
|
276
|
+
this.#updateHUDFromState(state);
|
|
277
|
+
return state;
|
|
278
|
+
}
|
|
279
|
+
#updateHUDFromState(state) {
|
|
280
|
+
const calibrationRequired = this.#config.calibrationTopic != undefined;
|
|
281
|
+
const waitingForImage = this.#lastReceivedMessages.image == undefined && state.image == undefined;
|
|
282
|
+
const waitingForCalibration = calibrationRequired && state.cameraInfo == undefined;
|
|
283
|
+
const waitingForBoth = waitingForImage && waitingForCalibration;
|
|
284
|
+
this.#hud.displayIfTrue(waitingForBoth, WAITING_FOR_BOTH_HUD_ITEM);
|
|
285
|
+
this.#hud.displayIfTrue(waitingForCalibration && !waitingForBoth, WAITING_FOR_CALIBRATION_HUD_ITEM);
|
|
286
|
+
this.#hud.displayIfTrue(waitingForImage && !calibrationRequired && !waitingForBoth, WAITING_FOR_IMAGE_EMPTY_HUD_ITEM);
|
|
287
|
+
this.#hud.displayIfTrue(waitingForImage && calibrationRequired, WAITING_FOR_IMAGE_NOTICE_HUD_ITEM);
|
|
288
|
+
}
|
|
289
|
+
#getRenderState() {
|
|
290
|
+
// Visible topics
|
|
291
|
+
const visibleTopics = new Set();
|
|
292
|
+
if (this.#config.annotations) {
|
|
293
|
+
for (const [topic, settings] of Object.entries(this.#config.annotations)) {
|
|
294
|
+
if (settings?.visible)
|
|
295
|
+
visibleTopics.add(topic);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// If there are no visible annotation topics, just render the latest image
|
|
299
|
+
if (visibleTopics.size === 0) {
|
|
300
|
+
return {
|
|
301
|
+
image: this.lastImage,
|
|
302
|
+
annotationsByTopic: new Map(),
|
|
303
|
+
presentAnnotationTopics: undefined,
|
|
304
|
+
missingAnnotationTopics: undefined,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
// If annotations are visible but we have no buffered images yet, we cannot render
|
|
308
|
+
if (this.imagesBuffer.length === 0) {
|
|
309
|
+
return {
|
|
310
|
+
annotationsByTopic: new Map(),
|
|
311
|
+
presentAnnotationTopics: undefined,
|
|
312
|
+
missingAnnotationTopics: undefined,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
// Required topics (available & visible)
|
|
316
|
+
const requiredTopics = [];
|
|
317
|
+
for (const t of visibleTopics) {
|
|
318
|
+
if (this.availableAnnotationTopics.size === 0 || this.availableAnnotationTopics.has(t)) {
|
|
319
|
+
requiredTopics.push(t);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// New policy: always start from newest image by arrival (do not freeze on older frame).
|
|
323
|
+
const newestImageEntry = this.imagesBuffer[this.imagesBuffer.length - 1];
|
|
324
|
+
const imageTimestampSec = typeof newestImageEntry.stampTimeSec === "number"
|
|
325
|
+
? newestImageEntry.stampTimeSec
|
|
326
|
+
: newestImageEntry.arrivalSec;
|
|
327
|
+
const selectedAnnotations = new Map();
|
|
328
|
+
const presentTopics = [];
|
|
329
|
+
const missingTopics = [];
|
|
330
|
+
for (const topic of visibleTopics) {
|
|
331
|
+
const buffer = this.annotationsMap.get(topic);
|
|
332
|
+
if (!buffer || buffer.length === 0) {
|
|
333
|
+
// No annotations yet for this topic
|
|
334
|
+
if (requiredTopics.includes(topic)) {
|
|
335
|
+
// waiting, but we still render image
|
|
336
|
+
// do not classify as missing because no candidate arrived yet
|
|
337
|
+
}
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
// Find preferred (newest <= image time within staleness)
|
|
341
|
+
let preferred;
|
|
342
|
+
for (let i = buffer.length - 1; i >= 0; i--) {
|
|
343
|
+
const entry = buffer[i];
|
|
344
|
+
const age = imageTimestampSec - entry.timeSec;
|
|
345
|
+
if (age >= 0 && age <= maxStalenessSec) {
|
|
346
|
+
preferred = entry;
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Fallback: closest within tolerance window
|
|
351
|
+
let closest = buffer[0];
|
|
352
|
+
let closestDelta = Math.abs(closest.timeSec - imageTimestampSec);
|
|
353
|
+
for (let i = 1; i < buffer.length; i++) {
|
|
354
|
+
const entry = buffer[i];
|
|
355
|
+
const delta = Math.abs(entry.timeSec - imageTimestampSec);
|
|
356
|
+
if (delta < closestDelta) {
|
|
357
|
+
closest = entry;
|
|
358
|
+
closestDelta = delta;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
let candidate = preferred ?? closest;
|
|
362
|
+
if (!candidate)
|
|
363
|
+
continue;
|
|
364
|
+
const candidateDelta = Math.abs(candidate.timeSec - imageTimestampSec);
|
|
365
|
+
const candidateAge = imageTimestampSec - candidate.timeSec;
|
|
366
|
+
const acceptable = (preferred && candidateAge >= 0 && candidateAge <= maxStalenessSec) ||
|
|
367
|
+
(!preferred && candidateDelta <= syncToleranceSec);
|
|
368
|
+
const notFutureFar = candidate.timeSec <= imageTimestampSec + syncToleranceSec;
|
|
369
|
+
if (!acceptable || !notFutureFar) {
|
|
370
|
+
// can't use for now
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
// Hysteresis: keep previous if close
|
|
374
|
+
const prevTime = this.lastSelectedByTopic.get(topic);
|
|
375
|
+
if (prevTime != undefined) {
|
|
376
|
+
const prevEntry = buffer.find((e) => Math.abs(e.timeSec - prevTime) < 1e-6);
|
|
377
|
+
if (prevEntry) {
|
|
378
|
+
const prevDelta = Math.abs(prevEntry.timeSec - imageTimestampSec);
|
|
379
|
+
const prevAge = imageTimestampSec - prevEntry.timeSec;
|
|
380
|
+
const prevValid = (prevAge >= 0 && prevAge <= maxStalenessSec) || prevDelta <= syncToleranceSec;
|
|
381
|
+
if (prevValid && Math.abs(prevEntry.timeSec - candidate.timeSec) <= hysteresisSec) {
|
|
382
|
+
candidate = prevEntry;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
selectedAnnotations.set(topic, candidate.annotation);
|
|
387
|
+
presentTopics.push(topic);
|
|
388
|
+
this.lastSelectedByTopic.set(topic, candidate.timeSec);
|
|
389
|
+
}
|
|
390
|
+
// Determine missing topics (we have at least some annotation messages for them but could not align one this frame)
|
|
391
|
+
for (const t of requiredTopics) {
|
|
392
|
+
if (!presentTopics.includes(t)) {
|
|
393
|
+
const buf = this.annotationsMap.get(t);
|
|
394
|
+
if (buf && buf.length > 0) {
|
|
395
|
+
// We received data but could not synchronize within tolerance -> mark missing
|
|
396
|
+
missingTopics.push(t);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// Always return newest image; do not block rendering if annotations incomplete
|
|
401
|
+
return {
|
|
402
|
+
image: newestImageEntry.image,
|
|
403
|
+
annotationsByTopic: selectedAnnotations,
|
|
404
|
+
// Provide mismatch info only if we have both present and missing; otherwise undefined to reduce HUD noise
|
|
405
|
+
presentAnnotationTopics: presentTopics.length > 0 && missingTopics.length > 0 ? presentTopics.sort() : undefined,
|
|
406
|
+
missingAnnotationTopics: presentTopics.length > 0 && missingTopics.length > 0 ? missingTopics.sort() : undefined,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=MessageHandlerV2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageHandlerV2.js","sourceRoot":"","sources":["../../../../../../../../../packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandlerV2.ts"],"names":[],"mappings":"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"}
|