Skip to content

Commit 4529ef0

Browse files
authored
Merge branch 'main' into sbel/scene_circular_dependency
2 parents a606c28 + 0411ae3 commit 4529ef0

File tree

34 files changed

+1790
-478
lines changed

34 files changed

+1790
-478
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
# SPDX-FileCopyrightText: (C) 2026 Intel Corporation
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
name: "Setup Cache Targets"
6+
description: "Setup environment variables for caching image layers"
7+
outputs:
8+
cache_registry:
9+
description: "The cache registry path"
10+
value: ${{ steps.cache.outputs.CACHE_REGISTRY }}
11+
cache_tag:
12+
description: "The cache tag"
13+
value: ${{ steps.cache.outputs.CACHE_TAG }}
14+
github_actions_cache:
15+
description: "Whether GitHub Actions cache is enabled"
16+
value: ${{ steps.cache.outputs.GITHUB_ACTIONS_CACHE }}
17+
runs:
18+
using: "composite"
19+
steps:
20+
- name: Setup Cache Targets
21+
id: cache
22+
shell: bash
23+
env:
24+
TAG_BASE: ${{ github.head_ref || github.ref_name }}
25+
run: |
26+
CACHE_TAG=$(echo "$TAG_BASE" | tr '/' '_' | tr '-' '_')
27+
echo "CACHE_REGISTRY=${{ github.repository }}" >> "$GITHUB_OUTPUT"
28+
echo "CACHE_TAG=${CACHE_TAG}" >> "$GITHUB_OUTPUT"
29+
echo "GITHUB_ACTIONS_CACHE=true" >> "$GITHUB_OUTPUT"

.github/skills/python.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,15 @@ result = client.getScene(scene_id)
147147

148148
### Logging
149149

150+
- Use f-strings for interpolated log messages.
151+
- Do not use printf-style placeholders (for example `%s`, `%d`) in log statements.
152+
150153
```python
151154
from scene_common import log
152155

153156
log.info("Processing started")
154-
log.error("Failed to process")
155-
log.debug("Debug information")
157+
log.error(f"Failed to process scene {scene_id}")
158+
log.debug(f"Debug information: {debug_payload}")
156159
```
157160

158161
## Type Hints

.github/workflows/tests-all.yml

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ concurrency:
4343
env:
4444
DOCKER_BUILDKIT: 1
4545
SUPASS: demo
46-
GITHUB_ACTIONS_CACHE: true
47-
CACHE_REGISTRY: ${{ github.repository }}
48-
CACHE_TAG: ${{ github.head_ref || github.ref_name }}
4946

5047
permissions:
5148
contents: read
@@ -82,10 +79,18 @@ jobs:
8279
username: ${{ github.actor }}
8380
password: ${{ secrets.GITHUB_TOKEN }}
8481

82+
- name: "Setup Cache Targets"
83+
id: setup-cache
84+
uses: ./.github/actions/setup-cache
85+
8586
- name: "Run Setup"
8687
uses: ./.github/actions/setup-env
8788

8889
- name: Run Functional Tests
90+
env:
91+
CACHE_REGISTRY: ${{ steps.setup-cache.outputs.cache_registry }}
92+
CACHE_TAG: ${{ steps.setup-cache.outputs.cache_tag }}
93+
GITHUB_ACTIONS_CACHE: ${{ steps.setup-cache.outputs.github_actions_cache }}
8994
run: |
9095
make clean-all
9196
make run_functional_tests
@@ -129,10 +134,18 @@ jobs:
129134
username: ${{ github.actor }}
130135
password: ${{ secrets.GITHUB_TOKEN }}
131136

137+
- name: "Setup Cache Targets"
138+
id: setup-cache
139+
uses: ./.github/actions/setup-cache
140+
132141
- name: "Run Setup"
133142
uses: ./.github/actions/setup-env
134143

135144
- name: Run Non-Functional Tests
145+
env:
146+
CACHE_REGISTRY: ${{ steps.setup-cache.outputs.cache_registry }}
147+
CACHE_TAG: ${{ steps.setup-cache.outputs.cache_tag }}
148+
GITHUB_ACTIONS_CACHE: ${{ steps.setup-cache.outputs.github_actions_cache }}
136149
run: |
137150
make clean-all
138151
make run_non_functional_tests
@@ -176,10 +189,18 @@ jobs:
176189
username: ${{ github.actor }}
177190
password: ${{ secrets.GITHUB_TOKEN }}
178191

192+
- name: "Setup Cache Targets"
193+
id: setup-cache
194+
uses: ./.github/actions/setup-cache
195+
179196
- name: "Run Setup"
180197
uses: ./.github/actions/setup-env
181198

182199
- name: Run Metric Tests
200+
env:
201+
CACHE_REGISTRY: ${{ steps.setup-cache.outputs.cache_registry }}
202+
CACHE_TAG: ${{ steps.setup-cache.outputs.cache_tag }}
203+
GITHUB_ACTIONS_CACHE: ${{ steps.setup-cache.outputs.github_actions_cache }}
183204
run: |
184205
make clean-all
185206
make run_metric_tests
@@ -223,10 +244,18 @@ jobs:
223244
username: ${{ github.actor }}
224245
password: ${{ secrets.GITHUB_TOKEN }}
225246

247+
- name: "Setup Cache Targets"
248+
id: setup-cache
249+
uses: ./.github/actions/setup-cache
250+
226251
- name: "Run Setup"
227252
uses: ./.github/actions/setup-env
228253

229254
- name: Run UI Tests
255+
env:
256+
CACHE_REGISTRY: ${{ steps.setup-cache.outputs.cache_registry }}
257+
CACHE_TAG: ${{ steps.setup-cache.outputs.cache_tag }}
258+
GITHUB_ACTIONS_CACHE: ${{ steps.setup-cache.outputs.github_actions_cache }}
230259
run: |
231260
make clean-all
232261
make run_ui_tests
@@ -270,10 +299,18 @@ jobs:
270299
username: ${{ github.actor }}
271300
password: ${{ secrets.GITHUB_TOKEN }}
272301

302+
- name: "Setup Cache Targets"
303+
id: setup-cache
304+
uses: ./.github/actions/setup-cache
305+
273306
- name: "Run Setup"
274307
uses: ./.github/actions/setup-env
275308

276309
- name: Run Unit Tests
310+
env:
311+
CACHE_REGISTRY: ${{ steps.setup-cache.outputs.cache_registry }}
312+
CACHE_TAG: ${{ steps.setup-cache.outputs.cache_tag }}
313+
GITHUB_ACTIONS_CACHE: ${{ steps.setup-cache.outputs.github_actions_cache }}
277314
run: |
278315
make clean-all
279316
make run_unit_tests

.github/workflows/tests-bat.yml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
# SPDX-FileCopyrightText: (C) 2025 Intel Corporation
2+
# SPDX-FileCopyrightText: (C) 2025-2026 Intel Corporation
33
# SPDX-License-Identifier: Apache-2.0
44

55
name: "[Tests] Basic Acceptance Tests"
@@ -44,9 +44,6 @@ concurrency:
4444
env:
4545
DOCKER_BUILDKIT: 1
4646
SUPASS: demo
47-
GITHUB_ACTIONS_CACHE: true
48-
CACHE_REGISTRY: ${{ github.repository }}
49-
CACHE_TAG: ${{ github.head_ref || github.ref_name }}
5047

5148
permissions:
5249
contents: read
@@ -145,9 +142,16 @@ jobs:
145142
username: ${{ github.actor }}
146143
password: ${{ secrets.GITHUB_TOKEN }}
147144

145+
- name: "Setup Cache Targets"
146+
id: setup-cache
147+
uses: ./.github/actions/setup-cache
148+
148149
- name: "Run Basic Acceptance Tests (BAT)"
150+
env:
151+
CACHE_REGISTRY: ${{ steps.setup-cache.outputs.cache_registry }}
152+
CACHE_TAG: ${{ steps.setup-cache.outputs.cache_tag }}
153+
GITHUB_ACTIONS_CACHE: ${{ steps.setup-cache.outputs.github_actions_cache }}
149154
run: |
150-
export CACHE_TAG=$(echo $CACHE_TAG | tr '/' '_')
151155
make clean-all
152156
git clean -fdx
153157
make run_basic_acceptance_tests
@@ -188,9 +192,16 @@ jobs:
188192
username: ${{ github.actor }}
189193
password: ${{ secrets.GITHUB_TOKEN }}
190194

195+
- name: "Setup Cache Targets"
196+
id: setup-cache
197+
uses: ./.github/actions/setup-cache
198+
191199
- name: Install chart with timeout
200+
env:
201+
CACHE_REGISTRY: ${{ steps.setup-cache.outputs.cache_registry }}
202+
CACHE_TAG: ${{ steps.setup-cache.outputs.cache_tag }}
203+
GITHUB_ACTIONS_CACHE: ${{ steps.setup-cache.outputs.github_actions_cache }}
192204
run: |
193-
export CACHE_TAG=$(echo $CACHE_TAG | tr '/' '_')
194205
KUBERNETES=1 DEPLOYMENT_TEST=1 ./deploy.sh
195206
196207
- name: Stability test (2m)

controller/src/controller/detections_builder.py

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import numpy as np
55

66
from controller.scene import TripwireEvent
7+
from scene_common import log
78
from scene_common.earth_lla import convertXYZToLLA, calculateHeading
89
from scene_common.geometry import DEFAULTZ, Point, Size
910
from scene_common.timestamp import get_iso_time
@@ -134,23 +135,53 @@ def computeCameraBounds(scene, aobj, obj_dict):
134135
camera_bounds = {}
135136
for cameraID in obj_dict['visibility']:
136137
bounds = None
137-
if aobj and len(aobj.vectors) > 0 and hasattr(aobj.vectors[0].camera, 'cameraID') \
138-
and cameraID == aobj.vectors[0].camera.cameraID:
138+
projected = False
139+
is_source_camera = (
140+
aobj and len(aobj.vectors) > 0 and hasattr(aobj.vectors[0].camera, 'cameraID')
141+
and cameraID == aobj.vectors[0].camera.cameraID
142+
)
143+
144+
# Prefer source detector pixel bbox when available. This preserves the
145+
# detector-provided 2D box instead of a reprojected estimate.
146+
if is_source_camera:
139147
bounds = getattr(aobj, 'boundingBoxPixels', None)
140-
elif scene:
148+
projected = False
149+
if bounds is None:
150+
log.debug(
151+
f"computeCameraBounds: source camera {cameraID} has no boundingBoxPixels; "
152+
"falling back to projected bounds when possible."
153+
)
154+
155+
# For non-source cameras (or source camera without pixel bbox), project
156+
# 3D/metric object state into each visible camera image plane.
157+
if bounds is None and scene:
141158
camera = scene.cameraWithID(cameraID)
142-
if camera is not None and 'bb_meters' in obj_dict:
143-
obj_translation = None
144-
obj_size = None
145-
if aobj:
146-
obj_translation = aobj.sceneLoc
147-
obj_size = aobj.bbMeters.size
148-
else:
149-
obj_translation = Point(obj_dict['translation'])
150-
obj_size = Size(obj_dict['bb_meters']['width'], obj_dict['bb_meters']['height'])
151-
bounds = camera.pose.projectEstimatedBoundsToCameraPixels(obj_translation,
152-
obj_size)
159+
if camera is None:
160+
log.debug(
161+
f"computeCameraBounds: camera {cameraID} not found in scene; cannot project bounds."
162+
)
163+
continue
164+
elif 'bb_meters' not in obj_dict and (not aobj or not hasattr(aobj, 'bbMeters') or aobj.bbMeters is None):
165+
log.debug(
166+
f"computeCameraBounds: missing bb_meters for camera {cameraID}; cannot project bounds."
167+
)
168+
continue
169+
170+
obj_translation = None
171+
obj_size = None
172+
if aobj and hasattr(aobj, 'bbMeters') and aobj.bbMeters is not None:
173+
obj_translation = aobj.sceneLoc
174+
obj_size = aobj.bbMeters.size
175+
else:
176+
obj_translation = Point(obj_dict['translation'])
177+
obj_size = Size(obj_dict['bb_meters']['width'], obj_dict['bb_meters']['height'])
178+
bounds = camera.pose.projectEstimatedBoundsToCameraPixels(obj_translation,
179+
obj_size)
180+
projected = True
181+
153182
if bounds:
154-
camera_bounds[cameraID] = bounds.asDict
183+
bound_dict = dict(bounds.asDict)
184+
bound_dict['projected'] = projected
185+
camera_bounds[cameraID] = bound_dict
155186
obj_dict['camera_bounds'] = camera_bounds
156187
return

controller/src/controller/scene.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,6 @@ def _deserializeTrackedObjects(self, serialized_objects):
502502
'confidence': obj.confidence,
503503
}
504504

505-
if 'center_of_mass' in obj_data:
506-
obj.info['center_of_mass'] = obj_data['center_of_mass']
507-
508505
if 'camera_bounds' in obj_data and obj_data['camera_bounds']:
509506
obj._camera_bounds = obj_data['camera_bounds']
510507
else:

controller/src/controller/time_chunking.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ def run(self):
130130
class TimeChunkedIntelLabsTracking(IntelLabsTracking):
131131
"""Time-chunked version of IntelLabsTracking."""
132132

133+
EMPTY_FRAME_CAMERA_ID = "__empty_frame__"
134+
133135
def __init__(self, max_unreliable_time, non_measurement_time_dynamic, non_measurement_time_static, time_chunking_rate_fps, suspended_track_timeout_secs=DEFAULT_SUSPENDED_TRACK_TIMEOUT_SECS, reid_config_data=None):
134136
# Call parent constructor to initialize IntelLabsTracking
135137
super().__init__(max_unreliable_time, non_measurement_time_dynamic, non_measurement_time_static, time_chunking_rate_fps, suspended_track_timeout_secs, reid_config_data)
@@ -150,18 +152,19 @@ def trackObjects(self, objects, already_tracked_objects, when, categories,
150152
# Create IntelLabs trackers if not already created
151153
self._createIlabsTrackers(categories, max_unreliable_time, non_measurement_time_dynamic, non_measurement_time_static)
152154

153-
if len(objects) == 0:
154-
return
155-
156155
if not categories:
157156
categories = self.trackers.keys()
158157

159158
# Extract camera_id from objects - required for time chunking
160-
try:
161-
camera_id = objects[0].camera.cameraID
162-
except (AttributeError, IndexError):
163-
log.warning("No camera ID found in objects, skipping time chunking processing")
164-
return
159+
if len(objects) > 0:
160+
try:
161+
camera_id = objects[0].camera.cameraID
162+
except (AttributeError, IndexError):
163+
log.warning("No camera ID found in objects, skipping time chunking processing")
164+
return
165+
else:
166+
# Keep retirement moving when a camera/category has no detections.
167+
camera_id = self.EMPTY_FRAME_CAMERA_ID
165168

166169
for category in categories:
167170
# Use time chunking

controller/src/schema/metadata.schema.json

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,6 @@
9090
},
9191
"required": ["x", "y", "width", "height"]
9292
},
93-
"center_of_mass": {
94-
"title": "Center of Mass",
95-
"type": "object",
96-
"description": "Center of mass region of a detected object in pixel coordinates of a detected object in an image frame. It is a smaller bounding box that is used for determining average distance from the camera when using RealSense, for example.",
97-
"properties": {
98-
"x": {
99-
"type": "number",
100-
"description": "Number of horizontal pixels from the left side of the image to the center of mass bounding box."
101-
},
102-
"y": {
103-
"type": "number",
104-
"description": "Number of vertical pixels from the top of the image to the center of mass bounding box."
105-
},
106-
"width": {
107-
"type": "number",
108-
"description": "Horizontal width of the center of mass bounding box in pixels.",
109-
"minimum": 0
110-
},
111-
"height": {
112-
"type": "number",
113-
"description": "Vertical height of the center of mass bounding box in pixels.",
114-
"minimum": 0
115-
}
116-
},
117-
"required": ["x", "y", "width", "height"]
118-
},
11993
"semantic_metadata_attribute": {
12094
"type": "object",
12195
"title": "Semantic Metadata Attribute",
@@ -233,9 +207,6 @@
233207
"$ref": "#/definitions/semantic_metadata",
234208
"description": "Semantic metadata describing what an object is (age, gender, clothing, embedding vectors, etc)."
235209
},
236-
"center_of_mass": {
237-
"$ref": "#/definitions/center_of_mass"
238-
},
239210
"distance": {
240211
"title": "Distance to Object",
241212
"type": "number",

0 commit comments

Comments
 (0)