Skip to content

Commit 66cba8f

Browse files
author
Mohammed Sufiyan Saqib
committed
Nokia: Controller multiprocessing, time chunking, cache safety, tracking
Adds parallel scene processing and performance improvements to Intel SceneScape 2025.2 controller. No Triton/GPU dependencies. For a detailed technical walkthrough of all changes with code references, see docs/controller-enhancements-technical-reference.md - scene_controller.py: ProcessPoolExecutor per scene, overwrite buffer, semaphore admission control, async MQTT publish, crash recovery watchdog - time_chunking.py: SceneAwareCategoryBuffer with hybrid dispatch (event- driven when all cameras arrive, 200ms timer fallback for partial scenes) - cache_manager.py: thread-safe _fast lookup methods, background HTTP refresh thread prevents MQTT callback thread from blocking on HTTP - ilabs_tracking.py: O(1) object association via pre-built hash maps; UUID stability fix includes unreliable/suspended tracks in pruning - robot_vision: expose getSuspendedTracks/getUnreliableTracks via C++ bindings (required for UUID stability fix) - metadata.schema.json: add reid, facemask, color, age, hat, gender fields - tracker-config.json: retune for 10 FPS operation - rest_client.py: fix token assignment, url=None guard, rootcert TLS verify - controller/Dockerfile + Makefile: default to public Ubuntu image; Nokia mirror overridable via RUNTIME_OS_IMAGE build arg / env var Signed-off-by: Mohammed Sufiyan Saqib <mohammed.sufiyan_saqib@nokia.com>
1 parent a0d1ccb commit 66cba8f

37 files changed

+4366
-486
lines changed

controller/Dockerfile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# SPDX-FileCopyrightText: (C) 2021 - 2025 Intel Corporation
22
# SPDX-License-Identifier: Apache-2.0
3+
# Modifications:
4+
# Nokia VPOD (Emerging Products, BLR), 2026
35

4-
ARG RUNTIME_OS_IMAGE=ubuntu:24.04@sha256:a08e551cb33850e4740772b38217fc1796a66da2506d312abe51acda354ff061
6+
ARG RUNTIME_OS_IMAGE=ubuntu:noble-20260113@sha256:cd1dba651b3080c3686ecf4e3c4220f026b521fb76978881737d24f200828b2b
57

68
# -------------- Common Base Stage (ported to Ubuntu 24.04) --------------
7-
FROM ubuntu:24.04@sha256:a08e551cb33850e4740772b38217fc1796a66da2506d312abe51acda354ff061 AS scenescape-common-base-24-04
9+
FROM ${RUNTIME_OS_IMAGE} AS scenescape-common-base-24-04
810

911
# We use root for runtime init. The command in ENTRYPOINT will drop to an unprivileged user.
1012
# hadolint ignore=DL3002
@@ -113,6 +115,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
113115

114116
USER root
115117

118+
# Nokia addition: install ps, htop for easier resource usage / performance measurement inside the container
116119
RUN : \
117120
&& apt-get update \
118121
&& apt-get install -y --no-install-recommends \
@@ -124,6 +127,7 @@ RUN : \
124127
netbase \
125128
python3-pip \
126129
sudo \
130+
procps htop \
127131
&& rm -rf /usr/lib/x86_64-linux-gnu/libLLVM-15.so.1 \
128132
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
129133

controller/Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
# SPDX-FileCopyrightText: (C) 2025 Intel Corporation
1+
# SPDX-FileCopyrightText: (C) 2025 - 2026 Intel Corporation
22
# SPDX-License-Identifier: Apache-2.0
3+
# Modifications:
4+
# Nokia VPOD (Emerging Products, BLR), 2026
35

46
IMAGE := scenescape-controller
5-
RUNTIME_OS_IMAGE := ubuntu:24.04@sha256:a08e551cb33850e4740772b38217fc1796a66da2506d312abe51acda354ff061
7+
RUNTIME_OS_IMAGE ?= ubuntu:noble-20260113@sha256:cd1dba651b3080c3686ecf4e3c4220f026b521fb76978881737d24f200828b2b
68
TARGET = scenescape-controller-runtime
79

10+
# PROJECT_RELATIVE_DIRS is needed for GIT_REVISION and GIT_REVISION_SHORT.
11+
# Some projects might depend on some other directory outside of their "top folder".
12+
# Set this before including common.mk, do not put these into quotes
13+
PROJECT_RELATIVE_DIRS:=. ../scene_common
14+
815
include ../common.mk
916

1017
.PHONY: test-build
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
2-
"max_unreliable_frames": 10,
3-
"non_measurement_frames_dynamic": 8,
4-
"non_measurement_frames_static": 16,
5-
"baseline_frame_rate": 30,
2+
"baseline_frame_rate": 10,
3+
"max_unreliable_frames": 5,
4+
"non_measurement_frames_dynamic": 20,
5+
"non_measurement_frames_static": 30,
66
"time_chunking_enabled": false,
7-
"time_chunking_interval_milliseconds": 50,
7+
"time_chunking_interval_milliseconds": 200,
88
"suspended_track_timeout_secs": 60.0
99
}
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
# SPDX-FileCopyrightText: (C) 2025 Intel Corporation
1+
# SPDX-FileCopyrightText: (C) 2025 - 2026 Intel Corporation
22
# SPDX-License-Identifier: Apache-2.0
33
# This file is licensed under Apache 2.0 License.
4+
# Modifications:
5+
# Nokia VPOD (Emerging Products, BLR), 2026
46

57
mapbox_earcut==1.0.3
68
ntplib==0.4.0
79
numpy==1.26.4
810
open3d-cpu==0.19.0
911
opencv-python-headless==4.11.0.86
10-
orjson==3.11.3
12+
orjson==3.11.5
1113
paho-mqtt==2.1.0
1214
scipy==1.16.1
1315
shapely==2.1.1
@@ -16,3 +18,4 @@ vdms==0.0.22
1618
opentelemetry-api==1.38.0
1719
opentelemetry-sdk==1.38.0
1820
opentelemetry-exporter-otlp-proto-grpc==1.38.0
21+
requests==2.32.3

controller/src/controller-cmd

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,37 @@
22

33
# SPDX-FileCopyrightText: (C) 2024 - 2025 Intel Corporation
44
# SPDX-License-Identifier: Apache-2.0
5+
# Modifications:
6+
# Nokia VPOD (Emerging Products, BLR), 2026
57

68
import argparse
79
import os
10+
import threading
11+
from http.server import BaseHTTPRequestHandler, HTTPServer
812

913
from controller.scene_controller import SceneController
1014
from controller.observability import metrics, tracing
15+
from controller.controller_mode import ControllerMode
16+
17+
class HealthCheckHandler(BaseHTTPRequestHandler):
18+
def do_GET(self):
19+
if self.path == '/healthz':
20+
self.send_response(200)
21+
self.send_header('Content-type', 'text/plain')
22+
self.end_headers()
23+
self.wfile.write(b'OK')
24+
else:
25+
self.send_response(404)
26+
self.end_headers()
27+
28+
def log_message(self, format, *args):
29+
pass
30+
31+
def start_health_server(port):
32+
server = HTTPServer(('0.0.0.0', port), HealthCheckHandler)
33+
thread = threading.Thread(target=server.serve_forever, daemon=True)
34+
thread.start()
35+
return server
1136

1237
def build_argparser():
1338
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
@@ -18,9 +43,6 @@ def build_argparser():
1843
parser.add_argument("--maxlag", help="Maximum amount of lag in seconds",
1944
default=1.0, type=float)
2045

21-
# FIXME - configure mosquitto to authenticate against REST so that
22-
# same user/pass can be used for both REST and MQTT
23-
# https://pypi.org/project/django-mqtt/
2446
parser.add_argument("--broker", default="broker.scenescape.intel.com:1883",
2547
help="hostname or IP of MQTT broker, optional :port")
2648
parser.add_argument("--brokerauth", default="/run/secrets/controller.auth",
@@ -43,19 +65,53 @@ def build_argparser():
4365
parser.add_argument("--visibility_topic", help="Which topic to publish visibility on."
4466
"Valid options are 'unregulated', 'regulated', or 'none'",
4567
default="regulated")
68+
parser.add_argument("--profile", action="store_true",
69+
help="Enable cProfile profiling of controller (disabled by default)")
70+
parser.add_argument("--profile-output", type=str, default="/dev/shm/controller_profile.stats",
71+
help="Output file for profile stats (default: /dev/shm/controller_profile.stats)")
72+
parser.add_argument("--reid_config_file", help="JSON file with reid configuration",
73+
default=None)
74+
parser.add_argument("--analytics-only", dest="analytics_only", action="store_true",
75+
default=os.environ.get("CONTROLLER_ENABLE_ANALYTICS_ONLY", "false").lower() == "true",
76+
help="Run controller in analytics-only mode (tracker disabled)")
77+
parser.add_argument("--healthcheck_port", type=int,
78+
default=int(os.environ.get("CONTROLLER_HEALTHCHECK_PORT", "0")),
79+
help="HTTP port for /healthz endpoint (0 disables)")
4680
return parser
4781

4882
def main():
4983
args = build_argparser().parse_args()
84+
85+
# Initialize profiler if requested
86+
profiler = None
87+
if args.profile:
88+
import cProfile
89+
profiler = cProfile.Profile()
90+
profiler.enable()
91+
print(f"[PROFILER] cProfile enabled, output: {args.profile_output}")
92+
5093
metrics.init()
5194
tracing.init()
52-
controller = SceneController(args.rewriteBadTime, args.rewriteAllTime,
53-
args.maxlag, args.broker,
54-
args.brokerauth, args.resturl,
55-
args.restauth, args.cert,
56-
args.rootcert, args.ntp, args.tracker_config_file, args.schema_file,
57-
args.visibility_topic, args.data_source)
58-
controller.loopForever()
95+
96+
ControllerMode.initialize(analytics_only=args.analytics_only)
97+
98+
if args.healthcheck_port > 0:
99+
start_health_server(args.healthcheck_port)
100+
101+
try:
102+
controller = SceneController(args.rewriteBadTime, args.rewriteAllTime,
103+
args.maxlag, args.broker,
104+
args.brokerauth, args.resturl,
105+
args.restauth, args.cert,
106+
args.rootcert, args.ntp, args.tracker_config_file, args.schema_file,
107+
args.visibility_topic, args.data_source)
108+
controller.loopForever()
109+
finally:
110+
# Save profile on clean exit
111+
if profiler is not None:
112+
profiler.disable()
113+
profiler.dump_stats(args.profile_output)
114+
print(f"[PROFILER] Profile saved to: {args.profile_output}")
59115

60116
return
61117

0 commit comments

Comments
 (0)