Add java, cpp, and python examples
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
=======================
|
||||
Building locally on rPi
|
||||
=======================
|
||||
|
||||
1) Copy multiCameraServer.py and runCamera to /home/pi
|
||||
2) Run "./runInteractive" in /home/pi or "sudo svc -t /service/camera" to
|
||||
restart service.
|
||||
|
||||
|
||||
===================
|
||||
Building on desktop
|
||||
===================
|
||||
|
||||
1) Copy multiCameraServer.py and runCamera to /home/pi on the Pi
|
||||
2) On the Pi, run "./runInteractive" in /home/pi or
|
||||
"sudo svc -t /service/camera" to restart service.
|
||||
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
#----------------------------------------------------------------------------
|
||||
# Copyright (c) 2018 FIRST. All Rights Reserved.
|
||||
# Open Source Software - may be modified and shared by FRC teams. The code
|
||||
# must be accompanied by the FIRST BSD license file in the root directory of
|
||||
# the project.
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
|
||||
from cscore import CameraServer, VideoSource
|
||||
from networktables import NetworkTablesInstance
|
||||
|
||||
# JSON format:
|
||||
# {
|
||||
# "team": <team number>,
|
||||
# "ntmode": <"client" or "server", "client" if unspecified>
|
||||
# "cameras": [
|
||||
# {
|
||||
# "name": <camera name>
|
||||
# "path": <path, e.g. "/dev/video0">
|
||||
# "pixel format": <"MJPEG", "YUYV", etc> // optional
|
||||
# "width": <video mode width> // optional
|
||||
# "height": <video mode height> // optional
|
||||
# "fps": <video mode fps> // optional
|
||||
# "brightness": <percentage brightness> // optional
|
||||
# "white balance": <"auto", "hold", value> // optional
|
||||
# "exposure": <"auto", "hold", value> // optional
|
||||
# "properties": [ // optional
|
||||
# {
|
||||
# "name": <property name>
|
||||
# "value": <property value>
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
|
||||
configFile = "/boot/frc.json"
|
||||
|
||||
class CameraConfig: pass
|
||||
|
||||
team = None
|
||||
server = False
|
||||
cameras = []
|
||||
|
||||
"""Report parse error."""
|
||||
def parseError(str):
|
||||
print("config error in '" + configFile + "': " + str, file=sys.stderr)
|
||||
|
||||
"""Read single camera configuration."""
|
||||
def readCameraConfig(config):
|
||||
cam = CameraConfig()
|
||||
|
||||
# name
|
||||
try:
|
||||
cam.name = config["name"]
|
||||
except KeyError:
|
||||
parseError("could not read camera name")
|
||||
return False
|
||||
|
||||
# path
|
||||
try:
|
||||
cam.path = config["path"]
|
||||
except KeyError:
|
||||
parseError("camera '{}': could not read path".format(cam.name))
|
||||
return False
|
||||
|
||||
cam.config = config
|
||||
|
||||
cameras.append(cam)
|
||||
return True
|
||||
|
||||
"""Read configuration file."""
|
||||
def readConfig():
|
||||
global team
|
||||
global server
|
||||
|
||||
# parse file
|
||||
try:
|
||||
with open(configFile, "rt") as f:
|
||||
j = json.load(f)
|
||||
except OSError as err:
|
||||
print("could not open '{}': {}".format(configFile, err), file=sys.stderr)
|
||||
return False
|
||||
|
||||
# top level must be an object
|
||||
if not isinstance(j, dict):
|
||||
parseError("must be JSON object")
|
||||
return False
|
||||
|
||||
# team number
|
||||
try:
|
||||
team = j["team"]
|
||||
except KeyError:
|
||||
parseError("could not read team number")
|
||||
return False
|
||||
|
||||
# ntmode (optional)
|
||||
if "ntmode" in j:
|
||||
str = j["ntmode"]
|
||||
if str.lower() == "client":
|
||||
server = False
|
||||
elif str.lower() == "server":
|
||||
server = True
|
||||
else:
|
||||
parseError("could not understand ntmode value '{}'".format(str))
|
||||
|
||||
# cameras
|
||||
try:
|
||||
cameras = j["cameras"]
|
||||
except KeyError:
|
||||
parseError("could not read cameras")
|
||||
return False
|
||||
for camera in cameras:
|
||||
if not readCameraConfig(camera):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
"""Start running the camera."""
|
||||
def startCamera(config):
|
||||
print("Starting camera '{}' on {}".format(config.name, config.path))
|
||||
camera = CameraServer.getInstance() \
|
||||
.startAutomaticCapture(name=config.name, path=config.path)
|
||||
|
||||
camera.setConfigJson(json.dumps(config.config))
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) >= 2:
|
||||
configFile = sys.argv[1]
|
||||
|
||||
# read configuration
|
||||
if not readConfig():
|
||||
sys.exit(1)
|
||||
|
||||
# start NetworkTables
|
||||
ntinst = NetworkTablesInstance.getDefault()
|
||||
if server:
|
||||
print("Setting up NetworkTables server")
|
||||
ntinst.startServer()
|
||||
else:
|
||||
print("Setting up NetworkTables client for team {}".format(team))
|
||||
ntinst.startClientTeam(team)
|
||||
|
||||
# start cameras
|
||||
for camera in cameras:
|
||||
startCamera(camera)
|
||||
|
||||
# loop forever
|
||||
while True:
|
||||
time.sleep(10)
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
echo "Waiting 5 seconds..."
|
||||
sleep 5
|
||||
exec ./multiCameraServer.py
|
||||
Reference in New Issue
Block a user