From f741e1be8dcdfb6a63feab1de8de69222c2e340a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Mon, 24 Jan 2022 10:46:45 +0100 Subject: [PATCH 1/9] Enable command line arguments parsing for apps --- apps/uvc/main.py | 6 +++++- depthai_helpers/arg_manager.py | 15 ++++++--------- requirements.txt | 1 - 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/uvc/main.py b/apps/uvc/main.py index 291183021..cc1760e6f 100644 --- a/apps/uvc/main.py +++ b/apps/uvc/main.py @@ -4,6 +4,10 @@ import depthai as dai import time +from depthai_helpers.arg_manager import parseArgs + +args = parseArgs() + if platform.machine() == 'aarch64': print("This app is temporarily disabled on AARCH64 systems due to an issue with stream preview. We are working on resolving this issue") raise SystemExit(0) @@ -29,7 +33,7 @@ cam_rgb.video.link(uvc.input) # Pipeline defined, now the device is connected to -with dai.Device(pipeline) as device: +with dai.Device(pipeline, usb2Mode=args.usbSpeed == "usb2") as device: print("\nDevice started, please keep this process running") print("and open an UVC viewer. Example on Linux:") print(" guvcview -d /dev/video0") diff --git a/depthai_helpers/arg_manager.py b/depthai_helpers/arg_manager.py index 19c6e6fb0..d295f0980 100644 --- a/depthai_helpers/arg_manager.py +++ b/depthai_helpers/arg_manager.py @@ -1,13 +1,6 @@ -import os import argparse from pathlib import Path -import cv2 import depthai as dai -try: - import argcomplete -except ImportError: - raise ImportError('\033[1;5;31m argcomplete module not found, run: python3 install_requirements.py \033[0m') -from depthai_sdk.previews import Previews def checkRange(minVal, maxVal): @@ -55,12 +48,16 @@ def orientationCast(arg): openvinoVersions = list(map(lambda name: name.replace("VERSION_", ""), filter(lambda name: name.startswith("VERSION_"), vars(dai.OpenVINO.Version)))) _streamChoices = ("nnInput", "color", "left", "right", "depth", "depthRaw", "disparity", "disparityColor", "rectifiedLeft", "rectifiedRight") -colorMaps = list(map(lambda name: name[len("COLORMAP_"):], filter(lambda name: name.startswith("COLORMAP_"), vars(cv2)))) +try: + import cv2 + colorMaps = list(map(lambda name: name[len("COLORMAP_"):], filter(lambda name: name.startswith("COLORMAP_"), vars(cv2)))) +except: + colorMaps = None projectRoot = Path(__file__).parent.parent def parseArgs(): parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument('-cam', '--camera', choices=[Previews.left.name, Previews.right.name, Previews.color.name], default=Previews.color.name, help="Use one of DepthAI cameras for inference (conflicts with -vid)") + parser.add_argument('-cam', '--camera', choices=["left", "right", "color"], default="color", help="Use one of DepthAI cameras for inference (conflicts with -vid)") parser.add_argument('-vid', '--video', type=str, help="Path to video file (or YouTube link) to be used for inference (conflicts with -cam)") parser.add_argument('-dd', '--disableDepth', action="store_true", help="Disable depth information") parser.add_argument('-dnn', '--disableNeuralNetwork', action="store_true", help="Disable neural network inference") diff --git a/requirements.txt b/requirements.txt index 24774d94c..f1d69376f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ requests==2.26.0 pyrebase4==4.5 -argcomplete==1.12.1 --extra-index-url https://www.piwheels.org/simple opencv-python==4.5.4.58 ; platform_machine != "aarch64" and platform_machine != "armv6l" and platform_machine != "armv7l" and python_version == "3.10" opencv-python==4.5.1.48 ; platform_machine != "aarch64" and platform_machine != "armv6l" and platform_machine != "armv7l" and python_version != "3.10" From b36022ba07849eff20ffe70b0f4d4ab7a889ccb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Mon, 24 Jan 2022 11:12:08 +0100 Subject: [PATCH 2/9] fix windows pathing issues --- depthai_helpers/app_manager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/depthai_helpers/app_manager.py b/depthai_helpers/app_manager.py index 475393f7d..6297793a0 100644 --- a/depthai_helpers/app_manager.py +++ b/depthai_helpers/app_manager.py @@ -43,19 +43,19 @@ def createVenv(self, force=False): else: print("Creating venv...") try: - subprocess.check_call(' '.join([quoted(sys.executable), '-m', 'venv', str(self.venvPath)]), shell=True, env=initEnv, cwd=self.appPath) + subprocess.check_call(' '.join([quoted(sys.executable), '-m', 'venv', quoted(str(self.venvPath.absolute()))]), shell=True, env=initEnv, cwd=self.appPath) except: print(f"Error creating a new virtual environment using \"venv\" module! Please try to install \"python3.{sys.version_info[1]}-venv\" again", file=sys.stderr) sys.exit(1) print("Installing requirements...") subprocess.check_call(' '.join([quoted(self.appInterpreter), '-m', 'pip', 'install', '-U', 'pip']), env=initEnv, shell=True, cwd=self.appPath) - subprocess.check_call(' '.join([quoted(self.appInterpreter), '-m', 'pip', 'install', '--prefer-binary', '-r', str(self.appRequirements)]), env=initEnv, shell=True, cwd=self.appPath) + subprocess.check_call(' '.join([quoted(self.appInterpreter), '-m', 'pip', 'install', '--prefer-binary', '-r', quoted(str(self.appRequirements))]), env=initEnv, shell=True, cwd=self.appPath) def runApp(self, shouldRun = lambda: True): if os.name == 'nt': - pro = subprocess.Popen(' '.join([quoted(self.appInterpreter), str(self.appEntrypoint)]), env=initEnv, shell=True, cwd=self.appPath) + pro = subprocess.Popen(' '.join([quoted(self.appInterpreter), quoted(str(self.appEntrypoint))]), env=initEnv, shell=True, cwd=self.appPath) else: - pro = subprocess.Popen(' '.join([quoted(self.appInterpreter), str(self.appEntrypoint)]), env=initEnv, shell=True, cwd=self.appPath, preexec_fn=os.setsid) + pro = subprocess.Popen(' '.join([quoted(self.appInterpreter), quoted(str(self.appEntrypoint))]), env=initEnv, shell=True, cwd=self.appPath, preexec_fn=os.setsid) while shouldRun(): try: time.sleep(1) From 47cb2cbbc2916903cf6a31fb85bc04aa2e9f123d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Mon, 24 Jan 2022 11:17:05 +0100 Subject: [PATCH 3/9] Add pythonpath to app manager --- apps/uvc/main.py | 2 -- depthai_helpers/app_manager.py | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/uvc/main.py b/apps/uvc/main.py index cc1760e6f..24ac8fdaa 100644 --- a/apps/uvc/main.py +++ b/apps/uvc/main.py @@ -1,9 +1,7 @@ #!/usr/bin/env python3 -import os import platform import depthai as dai import time - from depthai_helpers.arg_manager import parseArgs args = parseArgs() diff --git a/depthai_helpers/app_manager.py b/depthai_helpers/app_manager.py index 6297793a0..62bee2ccd 100644 --- a/depthai_helpers/app_manager.py +++ b/depthai_helpers/app_manager.py @@ -7,6 +7,7 @@ from pathlib import Path initEnv = os.environ.copy() +initEnv["PYTHONPATH"] = ":".join(initEnv.get("PYTHONPATH", "").split(":") + [str(Path(__file__).parent.parent.absolute())]) def quoted(val): From 9143ffb8658961a70ef7952cab6b5e91ed613081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Mon, 24 Jan 2022 11:30:56 +0100 Subject: [PATCH 4/9] fix python path and app termination --- apps/uvc/main.py | 1 + depthai_helpers/app_manager.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/uvc/main.py b/apps/uvc/main.py index 24ac8fdaa..12b6dd903 100644 --- a/apps/uvc/main.py +++ b/apps/uvc/main.py @@ -6,6 +6,7 @@ args = parseArgs() + if platform.machine() == 'aarch64': print("This app is temporarily disabled on AARCH64 systems due to an issue with stream preview. We are working on resolving this issue") raise SystemExit(0) diff --git a/depthai_helpers/app_manager.py b/depthai_helpers/app_manager.py index 62bee2ccd..c695d905b 100644 --- a/depthai_helpers/app_manager.py +++ b/depthai_helpers/app_manager.py @@ -7,7 +7,11 @@ from pathlib import Path initEnv = os.environ.copy() -initEnv["PYTHONPATH"] = ":".join(initEnv.get("PYTHONPATH", "").split(":") + [str(Path(__file__).parent.parent.absolute())]) +if "PYTHONPATH" in initEnv: + initEnv["PYTHONPATH"] += ":" + str(Path(__file__).parent.parent.absolute()) +else: + initEnv["PYTHONPATH"] = str(Path(__file__).parent.parent.absolute()) + def quoted(val): @@ -62,5 +66,8 @@ def runApp(self, shouldRun = lambda: True): time.sleep(1) except KeyboardInterrupt: break - os.killpg(os.getpgid(pro.pid), signal.SIGTERM) + if os.name == 'nt': + os.kill(pro.pid, signal.SIGTERM) + else: + os.killpg(os.getpgid(pro.pid), signal.SIGTERM) From 0965db1e4070df7eb8e71e8b3eb2a09424d56a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Mon, 24 Jan 2022 11:48:28 +0100 Subject: [PATCH 5/9] disable USB2 connection in UVC app --- apps/uvc/main.py | 4 ++++ depthai_helpers/app_manager.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/uvc/main.py b/apps/uvc/main.py index 12b6dd903..bf460d1f7 100644 --- a/apps/uvc/main.py +++ b/apps/uvc/main.py @@ -31,8 +31,12 @@ uvc = pipeline.createUVC() cam_rgb.video.link(uvc.input) + # Pipeline defined, now the device is connected to with dai.Device(pipeline, usb2Mode=args.usbSpeed == "usb2") as device: + if device.getDeviceInfo().desc.protocol == dai.XLinkProtocol.X_LINK_USB_VSC and device.getUsbSpeed() not in (dai.UsbSpeed.SUPER, dai.UsbSpeed.SUPER_PLUS): + print("This app is temporarily disabled with USB2 connection speed due to known issue. We're working on resolving it. In the meantime, please try again with a USB3 cable/port for the device connection") + raise SystemExit(0) print("\nDevice started, please keep this process running") print("and open an UVC viewer. Example on Linux:") print(" guvcview -d /dev/video0") diff --git a/depthai_helpers/app_manager.py b/depthai_helpers/app_manager.py index c695d905b..dc4809def 100644 --- a/depthai_helpers/app_manager.py +++ b/depthai_helpers/app_manager.py @@ -67,7 +67,7 @@ def runApp(self, shouldRun = lambda: True): except KeyboardInterrupt: break if os.name == 'nt': - os.kill(pro.pid, signal.SIGTERM) + subprocess.call(['taskkill', '/F', '/T', '/PID', str(pro.pid)]) else: os.killpg(os.getpgid(pro.pid), signal.SIGTERM) From 86d3a0f467e956a95df1446b1800036cd3ce9db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Mon, 24 Jan 2022 12:02:27 +0100 Subject: [PATCH 6/9] fix process wait logic in app manager --- depthai_helpers/app_manager.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/depthai_helpers/app_manager.py b/depthai_helpers/app_manager.py index dc4809def..16dcec06a 100644 --- a/depthai_helpers/app_manager.py +++ b/depthai_helpers/app_manager.py @@ -61,13 +61,14 @@ def runApp(self, shouldRun = lambda: True): pro = subprocess.Popen(' '.join([quoted(self.appInterpreter), quoted(str(self.appEntrypoint))]), env=initEnv, shell=True, cwd=self.appPath) else: pro = subprocess.Popen(' '.join([quoted(self.appInterpreter), quoted(str(self.appEntrypoint))]), env=initEnv, shell=True, cwd=self.appPath, preexec_fn=os.setsid) - while shouldRun(): + while shouldRun() and pro.poll() is None: try: time.sleep(1) except KeyboardInterrupt: break - if os.name == 'nt': - subprocess.call(['taskkill', '/F', '/T', '/PID', str(pro.pid)]) - else: - os.killpg(os.getpgid(pro.pid), signal.SIGTERM) + if pro.poll() is not None: + if os.name == 'nt': + subprocess.call(['taskkill', '/F', '/T', '/PID', str(pro.pid)]) + else: + os.kill(pro.pid, signal.SIGTERM) From 4f079aa00d5b95e1737a9ee39a59c1e0f6598fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Tue, 25 Jan 2022 20:20:22 +0100 Subject: [PATCH 7/9] Update exit codes --- apps/uvc/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/uvc/main.py b/apps/uvc/main.py index bf460d1f7..ff85e60b1 100644 --- a/apps/uvc/main.py +++ b/apps/uvc/main.py @@ -9,7 +9,7 @@ if platform.machine() == 'aarch64': print("This app is temporarily disabled on AARCH64 systems due to an issue with stream preview. We are working on resolving this issue") - raise SystemExit(0) + raise SystemExit(1) enable_4k = True # Will downscale 4K -> 1080p @@ -36,7 +36,7 @@ with dai.Device(pipeline, usb2Mode=args.usbSpeed == "usb2") as device: if device.getDeviceInfo().desc.protocol == dai.XLinkProtocol.X_LINK_USB_VSC and device.getUsbSpeed() not in (dai.UsbSpeed.SUPER, dai.UsbSpeed.SUPER_PLUS): print("This app is temporarily disabled with USB2 connection speed due to known issue. We're working on resolving it. In the meantime, please try again with a USB3 cable/port for the device connection") - raise SystemExit(0) + raise SystemExit(1) print("\nDevice started, please keep this process running") print("and open an UVC viewer. Example on Linux:") print(" guvcview -d /dev/video0") From cb38edb3b62e89d8df1af2f2b404ac58f2485717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Tue, 25 Jan 2022 20:23:11 +0100 Subject: [PATCH 8/9] send output to sys.stderr --- apps/uvc/main.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/uvc/main.py b/apps/uvc/main.py index ff85e60b1..4d0e50beb 100644 --- a/apps/uvc/main.py +++ b/apps/uvc/main.py @@ -2,13 +2,14 @@ import platform import depthai as dai import time +import sys from depthai_helpers.arg_manager import parseArgs args = parseArgs() if platform.machine() == 'aarch64': - print("This app is temporarily disabled on AARCH64 systems due to an issue with stream preview. We are working on resolving this issue") + print("This app is temporarily disabled on AARCH64 systems due to an issue with stream preview. We are working on resolving this issue", file=sys.stderr) raise SystemExit(1) enable_4k = True # Will downscale 4K -> 1080p @@ -35,7 +36,7 @@ # Pipeline defined, now the device is connected to with dai.Device(pipeline, usb2Mode=args.usbSpeed == "usb2") as device: if device.getDeviceInfo().desc.protocol == dai.XLinkProtocol.X_LINK_USB_VSC and device.getUsbSpeed() not in (dai.UsbSpeed.SUPER, dai.UsbSpeed.SUPER_PLUS): - print("This app is temporarily disabled with USB2 connection speed due to known issue. We're working on resolving it. In the meantime, please try again with a USB3 cable/port for the device connection") + print("This app is temporarily disabled with USB2 connection speed due to known issue. We're working on resolving it. In the meantime, please try again with a USB3 cable/port for the device connection", file=sys.stderr) raise SystemExit(1) print("\nDevice started, please keep this process running") print("and open an UVC viewer. Example on Linux:") From f15cf1bc8ef51677588dbebafbf66b3af138c49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pi=C5=82atowski?= Date: Tue, 25 Jan 2022 20:40:20 +0100 Subject: [PATCH 9/9] add ProcessLookupError handle --- depthai_helpers/app_manager.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/depthai_helpers/app_manager.py b/depthai_helpers/app_manager.py index 16dcec06a..68ec3c90b 100644 --- a/depthai_helpers/app_manager.py +++ b/depthai_helpers/app_manager.py @@ -67,8 +67,12 @@ def runApp(self, shouldRun = lambda: True): except KeyboardInterrupt: break if pro.poll() is not None: - if os.name == 'nt': - subprocess.call(['taskkill', '/F', '/T', '/PID', str(pro.pid)]) - else: - os.kill(pro.pid, signal.SIGTERM) + try: + if os.name == 'nt': + subprocess.call(['taskkill', '/F', '/T', '/PID', str(pro.pid)]) + else: + os.kill(pro.pid, signal.SIGTERM) + except ProcessLookupError: + pass +