mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-22 01:11:42 +00:00
GitOrigin-RevId: ac60fd3cf4a24023184376687da28373d14b781a This mirrors the robotpy files for the following projects: - apriltag - datalog - hal - ntcore - romiVendordep - wpilibc - wpimath - xrpVendordep This excludes cscore and the halsim wrappers for at this time. NOTE: This does not hook these projects up to the build system, just simply mirrors the files. The building will take place in a follow up PR to make it easier to review the changes necessary to build.
95 lines
3.0 KiB
Python
95 lines
3.0 KiB
Python
from typing import Optional
|
|
|
|
import hal
|
|
import subprocess
|
|
import threading
|
|
|
|
import logging
|
|
|
|
logger = logging.getLogger("wpilib.cs")
|
|
|
|
__all__ = ["CameraServer"]
|
|
|
|
|
|
class CameraServer:
|
|
"""
|
|
Provides a way to launch an out of process cscore-based camera
|
|
service instance, for streaming or for image processing.
|
|
|
|
.. note:: This does not correspond directly to the wpilib
|
|
CameraServer object; that can be found as
|
|
:class:`cscore.CameraServer`. However, you should
|
|
not use cscore directly from your robot code, see
|
|
the documentation for details
|
|
"""
|
|
|
|
_alive = False
|
|
_launched = False
|
|
|
|
@classmethod
|
|
def is_alive(cls) -> bool:
|
|
""":returns: True if the CameraServer is still alive"""
|
|
return cls._alive
|
|
|
|
@classmethod
|
|
def launch(cls, vision_py: Optional[str] = None) -> None:
|
|
"""
|
|
Launches the CameraServer process in autocapture mode or
|
|
using a user-specified python script
|
|
|
|
:param vision_py: If specified, this is the relative path to
|
|
a filename with a function in it
|
|
|
|
Example usage::
|
|
|
|
wpilib.CameraServer.launch("vision.py:main")
|
|
|
|
.. warning:: You must have robotpy-cscore installed, or this
|
|
function will fail without returning an error
|
|
(you will see an error in the console).
|
|
|
|
"""
|
|
|
|
if cls._launched:
|
|
return
|
|
|
|
cls._launched = True
|
|
from ._wpilib import RobotBase
|
|
|
|
if RobotBase.isSimulation():
|
|
logger.info("Would launch CameraServer with vision_py=%s", vision_py)
|
|
cls._alive = True
|
|
else:
|
|
logger.info("Launching CameraServer process")
|
|
|
|
# Launch the cscore launcher in a separate process
|
|
import sys
|
|
|
|
args = [sys.executable, "-m", "cscore"]
|
|
|
|
# TODO: Get accurate reporting data from the other cscore process. For
|
|
# now, just differentiate between users with a custom py file and those
|
|
# who do not. cscore handle values indicate type with bits 24-30
|
|
|
|
if vision_py:
|
|
hal.reportUsage("RobotPy/CameraServer", vision_py)
|
|
if not vision_py.startswith("/"):
|
|
vision_py = "/home/systemcore/py/" + vision_py
|
|
args.append(vision_py)
|
|
else:
|
|
hal.reportUsage("RobotPy/CameraServer", "")
|
|
|
|
# We open a pipe to it so that when this process exits, it dies
|
|
proc = subprocess.Popen(
|
|
args, close_fds=True, stdin=subprocess.PIPE, cwd="/home/systemcore/py"
|
|
)
|
|
th = threading.Thread(target=cls._monitor_child, args=(proc,))
|
|
th.daemon = True
|
|
th.start()
|
|
|
|
@classmethod
|
|
def _monitor_child(cls, proc: subprocess.Popen) -> None:
|
|
proc.wait()
|
|
logger.warning("CameraServer process exited with exitcode %s", proc.returncode)
|
|
cls._alive = False
|