diff --git a/backend/Main.py b/backend/Main.py
index d1c752ba2..e1a47bc3e 100644
--- a/backend/Main.py
+++ b/backend/Main.py
@@ -4,9 +4,12 @@ from app.ChameleonVisionApp import ChameleonApplication
from app.classes.SettingsManager import SettingsManager
from tornado.options import options
from app.handlers.VisionHandler import VisionHandler
+import threading
+import asyncio
def run_server():
+ asyncio.set_event_loop(asyncio.new_event_loop())
tornado.options.parse_command_line()
app = ChameleonApplication()
print(f"Serving on port {options.port}")
@@ -19,7 +22,8 @@ if __name__ == "__main__":
SettingsManager()
VisionHandler().run()
- run_server()
+ server_thread = threading.Thread(target=run_server)
+ server_thread.start()
while True:
pass
diff --git a/backend/app/classes/SettingsManager.py b/backend/app/classes/SettingsManager.py
index 7de5badcd..76a1f0309 100644
--- a/backend/app/classes/SettingsManager.py
+++ b/backend/app/classes/SettingsManager.py
@@ -1,3 +1,4 @@
+import socket
import os
import json
import cv2
@@ -12,12 +13,12 @@ class SettingsManager(metaclass=Singleton):
usb_cameras = {}
usb_cameras_info = {}
general_settings = {}
+ cams_port = {}
default_pipeline = {
"exposure": 50,
"brightness": 50,
"orientation": "Normal",
- "resolution": [320, 160],
"hue": [0, 100],
"saturation": [0, 100],
"value": [0, 100],
@@ -36,7 +37,7 @@ class SettingsManager(metaclass=Singleton):
"connection_type": "DHCP",
"ip": "",
"gateway": "",
- "hostname": "Chameleon-Vision",
+ "hostname": "",
"curr_camera": "",
"curr_pipeline": ""
}
@@ -133,8 +134,10 @@ class SettingsManager(metaclass=Singleton):
"height": video_mode.height,
"pixel_format": str(video_mode.pixelFormat).split('.')[1]
}
- self.usb_cameras[camera_name].setVideoMode(self.usb_cameras[camera_name].enumerateVideoModes()[int(dic["resolution"])])
+ self.usb_cameras[camera_name].setVideoMode(self.usb_cameras[camera_name].enumerateVideoModes()[int(dic["resolution"])])
+ if "FOV" in dic:
+ self.cams[camera_name]["FOV"] = float(dic["FOV"])
# Access methods
def get_curr_pipeline(self):
@@ -163,7 +166,7 @@ class SettingsManager(metaclass=Singleton):
def set_curr_camera(self, cam_name):
if cam_name in self.cams:
self.general_settings["curr_camera"] = cam_name
- self.general_settings["curr_pipeline"] = self.get_curr_cam()["pipelines"].keys()[0]
+ self.general_settings["curr_pipeline"] = list(self.get_curr_cam()["pipelines"].keys())[0]
def set_curr_pipeline(self, pipe_name):
if pipe_name in self.get_curr_cam()["pipelines"]:
@@ -182,9 +185,13 @@ class SettingsManager(metaclass=Singleton):
self.cams[cam_name]["pipelines"][pipe_name][key] = dic[key]
def change_general_settings_values(self, dic):
- for key in dic:
+ for key in dic['change_general_settings_values']:
if self.default_general_settings[key]:
- self.general_settings[key] = dic[key]
+ self.general_settings[key] = dic['change_general_settings_values'][key]
+ self.settings_manager.save_settings()
+ #after all values has been set change settings
+ self.change_general_settings()
+
# Creators
@@ -218,8 +225,10 @@ class SettingsManager(metaclass=Singleton):
"fps": video_mode.fps,
"width": video_mode.width,
"height": video_mode.height,
- "pixel_format": str(video_mode.pixelFormat).split('.')[1]
+ "pixel_format": str(video_mode.pixelFormat).split('.')[1],
}
+ self.cams[cam_name]['resolution'] = 0
+ self.cams[cam_name]["FOV"] = 60.8
# Savers
@@ -242,3 +251,8 @@ class SettingsManager(metaclass=Singleton):
with open(os.path.join(self.settings_path, 'settings.json'), 'w+') as setting_file:
json.dump(self.general_settings, setting_file)
+
+ def change_general_settings(self):
+ pass
+
+
diff --git a/backend/app/classes/imagezmq.py b/backend/app/classes/imagezmq.py
deleted file mode 100644
index f05e6dbf5..000000000
--- a/backend/app/classes/imagezmq.py
+++ /dev/null
@@ -1,232 +0,0 @@
-""" imagezmq: Transport OpenCV images via ZMQ.
-
-Classes that transport OpenCV images from one computer to another. For example,
-OpenCV images gathered by a Raspberry Pi camera could be sent to another
-computer for displaying the images using cv2.imshow() or for further image
-processing. See API and Usage Examples for details.
-
-Copyright (c) 2017 by Jeff Bass.
-License: MIT, see LICENSE for more details.
-"""
-
-import zmq
-import numpy as np
-import cv2
-
-
-class ImageSender():
- """Opens zmq REQ socket and sends images.
-
- Opens a zmq REQ socket on the image sending computer, often a
- Raspberry Pi, that will be sending OpenCV images and
- related text messages to the hub computer. Provides methods to
- send images or send jpg compressed images.
-
- Arguments:
- connect_to: the tcp address:port of the hub computer.
- """
-
- def __init__(self, connect_to='tcp://127.0.0.1:5555'):
- """Initializes zmq socket for sending images to the hub.
-
- Expects an open socket at the connect_to tcp address; it will
- connect to that remote socket after setting up the REQ
- socket on this computer.
- """
-
- self.zmq_context = SerializingContext()
- self.zmq_socket = self.zmq_context.socket(zmq.REQ)
- self.zmq_socket.connect(connect_to)
-
- def send_image(self, msg, image):
- """Sends OpenCV image and msg to hub computer.
-
- Arguments:
- msg: text message or image name.
- image: OpenCV image to send to hub.
-
- Returns:
- A text reply from hub.
- """
-
- if image.flags['C_CONTIGUOUS']:
- # if image is already contiguous in memory just send it
- self.zmq_socket.send_array(image, msg, copy=False)
- else:
- # else make it contiguous before sending
- image = np.ascontiguousarray(image)
- self.zmq_socket.send_array(image, msg, copy=False)
- hub_reply = self.zmq_socket.recv() # receive the reply message
- return hub_reply
-
- def send_jpg(self, msg, jpg_buffer):
- """Sends msg text and jpg buffer to hub computer.
-
- Arguments:
- msg: image name or message text.
- jpg_buffer: bytestring containing the jpg image to send to hub.
- Returns:
- A text reply from hub.
- """
-
- self.zmq_socket.send_jpg(msg, jpg_buffer, copy=False)
- hub_reply = self.zmq_socket.recv() # receive the reply message
- return hub_reply
-
-
-class ImageHub():
- """Opens zmq REP socket and receives images.
-
- Opens a zmq REP socket on the hub compuer, for example,
- a Mac, that will be receiving and displaying or processing OpenCV images
- and related text messages. Provides methods to receive images or receive
- jpg compressed images.
-
- Arguments:
- open_port: (optional) the socket to open for receiving REQ requests.
- """
-
- def __init__(self, open_port='tcp://*:5555'):
- """Initializes zmq REP socket to receive images and text.
- """
-
- self.zmq_context = SerializingContext()
- self.zmq_socket = self.zmq_context.socket(zmq.REP)
- self.zmq_socket.bind(open_port)
-
- def recv_image(self, copy=False):
- """Receives OpenCV image and text msg.
-
- Arguments:
- copy: (optional) zmq copy flag.
-
- Returns:
- msg: text msg, often the image name.
- image: OpenCV image.
- """
-
- msg, image = self.zmq_socket.recv_array(copy=False)
- return msg, image
-
- def recv_jpg(self, copy=False):
- """Receives text msg, jpg buffer.
-
- Arguments:
- copy: (optional) zmq copy flag
- Returns:
- msg: text message, often image name
- jpg_buffer: bytestring jpg compressed image
- """
-
- msg, jpg_buffer = self.zmq_socket.recv_jpg(copy=False)
- return msg, jpg_buffer
-
- def send_reply(self, reply_message=b'OK'):
- """Sends the zmq REP reply message.
-
- Arguments:
- reply_message: reply message text, often just string 'OK'
- """
- self.zmq_socket.send(reply_message)
-
-
-class SerializingSocket(zmq.Socket):
- """Numpy array serialization methods.
-
- Modelled on PyZMQ serialization examples.
-
- Used for sending / receiving OpenCV images, which are Numpy arrays.
- Also used for sending / receiving jpg compressed OpenCV images.
- """
-
- def send_array(self, A, msg='NoName', flags=0, copy=True, track=False):
- """Sends a numpy array with metadata and text message.
-
- Sends a numpy array with the metadata necessary for reconstructing
- the array (dtype,shape). Also sends a text msg, often the array or
- image name.
-
- Arguments:
- A: numpy array or OpenCV image.
- msg: (optional) array name, image name or text message.
- flags: (optional) zmq flags.
- copy: (optional) zmq copy flag.
- track: (optional) zmq track flag.
- """
-
- md = dict(
- msg=msg,
- dtype=str(A.dtype),
- shape=A.shape,
- )
- self.send_json(md, flags | zmq.SNDMORE)
- return self.send(A, flags, copy=copy, track=track)
-
- def send_jpg(self,
- msg='NoName',
- jpg_buffer=b'00',
- flags=0,
- copy=True,
- track=False):
- """Send a jpg buffer with a text message.
-
- Sends a jpg bytestring of an OpenCV image.
- Also sends text msg, often the image name.
-
- Arguments:
- msg: image name or text message.
- jpg_buffer: jpg buffer of compressed image to be sent.
- flags: (optional) zmq flags.
- copy: (optional) zmq copy flag.
- track: (optional) zmq track flag.
- """
-
- md = dict(msg=msg, )
- self.send_json(md, flags | zmq.SNDMORE)
- return self.send(jpg_buffer, flags, copy=copy, track=track)
-
- def recv_array(self, flags=0, copy=True, track=False):
- """Receives a numpy array with metadata and text message.
-
- Receives a numpy array with the metadata necessary
- for reconstructing the array (dtype,shape).
- Returns the array and a text msg, often the array or image name.
-
- Arguments:
- flags: (optional) zmq flags.
- copy: (optional) zmq copy flag.
- track: (optional) zmq track flag.
-
- Returns:
- msg: image name or text message.
- A: numpy array or OpenCV image reconstructed with dtype and shape.
- """
-
- md = self.recv_json(flags=flags)
- msg = self.recv(flags=flags, copy=copy, track=track)
- A = np.frombuffer(msg, dtype=md['dtype'])
- return (md['msg'], A.reshape(md['shape']))
-
- def recv_jpg(self, flags=0, copy=True, track=False):
- """Receives a jpg buffer and a text msg.
-
- Receives a jpg bytestring of an OpenCV image.
- Also receives a text msg, often the image name.
-
- Arguments:
- flags: (optional) zmq flags.
- copy: (optional) zmq copy flag.
- track: (optional) zmq track flag.
-
- Returns:
- msg: image name or text message.
- jpg_buffer: bytestring, containing jpg image.
- """
-
- md = self.recv_json(flags=flags) # metadata text
- jpg_buffer = self.recv(flags=flags, copy=copy, track=track)
- return (md['msg'], jpg_buffer)
-
-
-class SerializingContext(zmq.Context):
- _socket_class = SerializingSocket
diff --git a/backend/app/handlers/CamerasHandler.py b/backend/app/handlers/CamerasHandler.py
deleted file mode 100644
index 9ab112722..000000000
--- a/backend/app/handlers/CamerasHandler.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import cscore
-import cv2
-from cscore._cscore import VideoMode
-
-class CamerasHandler:
-
- #@staticmethod
- # def get_cameras_info():
- #
- # if not getattr(CamerasHandler, "cams_info", False):
- #
- # arr = []
- #
- # usb_devices = cscore.UsbCamera.enumerateUsbCameras()
- #
- # for index in range(len(usb_devices)):
- # cap = cv2.VideoCapture(index)
- # if cap.isOpened():
- # arr.append(index)
- # cap.release()
- # index += 1
- #
- # setattr(CamerasHandler, "cams_info", [usb_devices[i] for i in arr])
- #
- # return getattr(CamerasHandler, "cams_info")
-
- # @staticmethod
- # def get_or_start_cameras(usb_devices):
- #
- # if not getattr(CamerasHandler, "cams", False):
- # cameras = {}
- # for device in usb_devices:
- # device_name = device.name
- #
- # if device.name in cameras:
- # suffix = 0
- # device_name = device.name + str(suffix)
- #
- # while device_name in cameras:
- # suffix += 1
- # device_name = "pipeline" + str(suffix)
- #
- # camera = cscore.UsbCamera(name=device_name, dev=device.dev)
- # camera.setPixelFormat(pixelFormat=
- # getattr(VideoMode.PixelFormat, SettingsManager()
- # .get_curr_cam()["video_mode"]["pixel_format"]))
- # camera.setFPS(SettingsManager().get_curr_cam()["video_mode"]["fps"])
- # camera.setResolution(width=SettingsManager().get_curr_cam()["video_mode"]["width"],
- # height=SettingsManager().get_curr_cam()["video_mode"]["height"])
- #
- # cameras[device_name] = camera
- #
- # setattr(CamerasHandler, "cams", cameras)
- #
- # return getattr(CamerasHandler, "cams")
-
- # @staticmethod
- # def init_camera():
- # return CamerasHandler.get_or_start_cameras(CamerasHandler.get_cameras_info())
- #
- # @staticmethod
- # def get_usb_camera_by_name(cam_name):
- # return CamerasHandler.get_or_start_cameras(CamerasHandler.get_cameras_info())[cam_name]
-
- @staticmethod
- def set_camera_settings(usb_camera: cscore.UsbCamera, dic):
-
- if "brightness" in dic:
- usb_camera.setBrightness(dic["brightness"])
-
- if "exposure" in dic:
- usb_camera.setExposureManual(dic["exposure"])
-
- if "video_mode" in dic:
- usb_camera.setVideoMode(dic["video_mode"])
diff --git a/backend/app/handlers/SocketHandler.py b/backend/app/handlers/SocketHandler.py
index 5db7edc60..618cbb84e 100644
--- a/backend/app/handlers/SocketHandler.py
+++ b/backend/app/handlers/SocketHandler.py
@@ -4,10 +4,27 @@ from ..classes.Exceptions import NoCameraConnectedException
from ..classes.SettingsManager import SettingsManager
+web_socket_clients = []
+
+
+def send_all_async(message):
+ for ws in web_socket_clients:
+ try:
+ if not ws.ws_connection.stream.socket:
+ web_socket_clients.remove(ws)
+ else:
+ try:
+ ws.write_message(message)
+ except AssertionError as a:
+ pass
+ except AssertionError:
+ pass
+
+
class ChameleonWebSocket(tornado.websocket.WebSocketHandler):
actions = {}
- set_this_camera_settings = ["exposure", "brightness", "resolution"]
+ set_this_camera_settings = ["exposure", "brightness"]
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
@@ -17,32 +34,44 @@ class ChameleonWebSocket(tornado.websocket.WebSocketHandler):
def init_actions(self):
self.actions["change_pipeline_values"] = self.change_pipeline_values
self.actions["change_general_settings_values"] = self.settings_manager.change_general_settings_values
- self.actions["change_cam"] = self.change_curr_camera
- self.actions["change_pipeline"] = self.change_curr_pipeline
+ self.actions["curr_camera"] = self.change_curr_camera
+ self.actions["curr_pipeline"] = self.change_curr_pipeline
+ self.actions['resolution'] = self.set_resolution
+ self.actions['FOV'] = self.set_fov
def open(self):
-
self.send_full_settings()
+ if self not in web_socket_clients:
+ web_socket_clients.append(self)
print("WebSocket opened")
def on_message(self, message):
-
message_dic = json.loads(message)
for key in message_dic:
self.actions.get(key, self.actions["change_pipeline_values"])(message_dic)
-
print(message)
def on_close(self):
self.settings_manager.save_settings()
-
+ if self in web_socket_clients:
+ web_socket_clients.remove(self)
print("WebSocket closed")
def check_origin(self, origin):
return True
+ def set_resolution(self, message):
+ self.settings_manager.get_curr_cam()['resolution'] = message['resolution']
+ SettingsManager().set_camera_settings(camera_name=SettingsManager().general_settings['curr_camera'],
+ dic=message)
+ self.settings_manager.save_settings()
+
+ def set_fov(self, message):
+ self.settings_manager.get_curr_cam()['FOV'] = message['FOV']
+ self.settings_manager.save_settings()
+
def send_curr_pipeline(self):
try:
self.write_message(self.settings_manager.get_curr_pipeline())
@@ -57,14 +86,21 @@ class ChameleonWebSocket(tornado.websocket.WebSocketHandler):
# TODO: return something if no camera connected
self.write_message("No camera connected")
+ def send_curr_port(self):
+ self.write_message({
+ 'port': self.settings_manager.cams_port[self.settings_manager.general_settings["curr_camera"]]
+ })
+
def send_full_settings(self):
full_settings = self.settings_manager.general_settings.copy()
full_settings["cameraList"] = list(self.settings_manager.cams.copy().keys())
-
try:
full_settings.update(self.settings_manager.get_curr_pipeline())
full_settings["pipelineList"] = list(self.settings_manager.cams[self.settings_manager.general_settings["curr_camera"]]["pipelines"].keys())
full_settings["resolutionList"] = self.settings_manager.get_resolution_list()
+ full_settings['resolution'] = self.settings_manager.get_curr_cam()['resolution']
+ full_settings['FOV'] = self.settings_manager.get_curr_cam()['FOV']
+ full_settings['port'] = self.settings_manager.cams_port[self.settings_manager.general_settings["curr_camera"]]
except NoCameraConnectedException:
# TODO: return something if no camera connected
full_settings["data"] = None
@@ -72,16 +108,16 @@ class ChameleonWebSocket(tornado.websocket.WebSocketHandler):
self.write_message(full_settings)
def change_curr_camera(self, dic):
- self.settings_manager.set_curr_camera(cam_name=dic["cam"])
+ self.settings_manager.set_curr_camera(cam_name=dic["curr_camera"])
+ self.send_curr_port()
self.send_curr_cam()
def change_curr_pipeline(self, dic):
- self.settings_manager.set_curr_pipeline(pipe_name=dic["pipeline"])
+ self.settings_manager.set_curr_pipeline(pipe_name=dic["curr_pipeline"])
self.send_curr_pipeline()
def change_pipeline_values(self, dic):
self.settings_manager.change_pipeline_values(dic)
-
for key in self.set_this_camera_settings:
if key in dic:
self.settings_manager.set_camera_settings(self.settings_manager.general_settings["curr_camera"],
diff --git a/backend/app/handlers/VisionHandler.py b/backend/app/handlers/VisionHandler.py
index 362d4b7f7..56c1433ba 100644
--- a/backend/app/handlers/VisionHandler.py
+++ b/backend/app/handlers/VisionHandler.py
@@ -1,3 +1,4 @@
+import asyncio
from networktables import NetworkTables
import networktables
import cv2
@@ -10,6 +11,7 @@ import threading
import zmq
import math
from enum import Enum, unique
+from ..handlers.SocketHandler import send_all_async
class VisionHandler(metaclass=Singleton):
@@ -252,7 +254,10 @@ class VisionHandler(metaclass=Singleton):
port += 1
def thread_proc(self, cs, cam_name, port=5557):
- pipeline = SettingsManager().cams[cam_name]["pipelines"]["pipeline0"]
+ asyncio.set_event_loop(asyncio.new_event_loop())
+ pipeline_name = 'pipeline0'
+ pipeline = SettingsManager().cams[cam_name]["pipelines"][pipeline_name]
+ FOV = SettingsManager().cams[cam_name]["FOV"]
def change_camera_values(pipline):
SettingsManager.usb_cameras[cam_name].setBrightness(pipeline['brightness'])
@@ -274,7 +279,7 @@ class VisionHandler(metaclass=Singleton):
flags=networktables.NetworkTablesInstance.NotifyFlags.UPDATE)
table.addEntryListenerEx(mode_listener, key="Driver_Mode",
flags=networktables.NetworkTablesInstance.NotifyFlags.UPDATE)
-
+ #gettings video from curent camera
cv_sink = cs.getVideo(camera=SettingsManager.usb_cameras[cam_name])
width = SettingsManager().cams[cam_name]["video_mode"]["width"]
@@ -282,34 +287,58 @@ class VisionHandler(metaclass=Singleton):
image = numpy.zeros(shape=(width, height, 3), dtype=numpy.uint8)
+ #setting up a video server for camera
cv_publish = cs.putVideo(name=cam_name, width=width, height=height)
+ # saving camera port in cam name dict for usage in client
+ SettingsManager().cams_port[cam_name] = cs._sinks['serve_'+cam_name].getPort()
+ #setting up a zmq connection to the opencv subprocess
context = zmq.Context()
socket = context.socket(zmq.PAIR)
socket.bind('tcp://*:%s' % str(port))
- p = Process(target=self.camera_process, args=(cam_name, port))
+ #starting the process with inital values
+ p = Process(target=self.camera_process, args=(cam_name, port, FOV))
p.start()
change_camera_values(pipeline)
+
while True:
_, image = cv_sink.grabFrame(image)
socket.send_json(dict(
pipeline=pipeline
))
+
socket.send_pyobj(image)
p_image = socket.recv_pyobj()
nt_data = socket.recv_json()
+ table.putBoolean('valid', nt_data['valid'])
+ # check if point is valid
if nt_data['valid']:
+ #send the point using network tables
table.putNumber('pitch', nt_data['pitch'])
table.putNumber('yaw', nt_data['yaw'])
- table.putBoolean('valid', nt_data['valid'])
+ #if the selected camera in ui is this cam send the point to the ui
+ if SettingsManager().general_settings['curr_camera'] == cam_name:
+ try:
+ if nt_data['raw_point'] is not None:
+ send_all_async({
+ 'raw_point': nt_data['raw_point'],
+ 'point': {
+ 'pitch': nt_data['pitch'],
+ 'yaw': nt_data['yaw']
+ }
+ })
+ except Exception as e:
+ print(e)
+ #send the image to the camera server
+
cv_publish.putFrame(p_image)
- def camera_process(self, cam_name, port):
+ def camera_process(self, cam_name, port, FOV):
from fractions import Fraction
- diagonalView = math.radians(68.5) #needs to be implemented in client
+ diagonalView = math.radians(FOV) #needs to be implemented in client
width = SettingsManager().cams[cam_name]["video_mode"]["width"]
height = SettingsManager().cams[cam_name]["video_mode"]["height"]
@@ -354,6 +383,7 @@ class VisionHandler(metaclass=Singleton):
yaw = self.calculate_yaw(pixel_x=center[0], center_x=centerX, h_focal_length=H_FOCAL_LENGTH)
valid = True
except IndexError:
+ center = None
pitch = None
yaw = None
valid = False
@@ -367,8 +397,8 @@ class VisionHandler(metaclass=Singleton):
socket.send_json(dict(
pitch=pitch,
yaw=yaw,
- valid= valid
-
+ valid=valid,
+ raw_point=center
))
diff --git a/backend/settings/cams/AN-VC500 Camera.json b/backend/settings/cams/AN-VC500 Camera.json
deleted file mode 100644
index 4d38cbed0..000000000
--- a/backend/settings/cams/AN-VC500 Camera.json
+++ /dev/null
@@ -1 +0,0 @@
-{"pipelines": {"pipeline0": {"exposure": 4, "brightness": 74, "orientation": "Normal", "resolution": [320, 160], "hue": [43, 80], "saturation": [159, 255], "value": [55, 255], "erode": false, "dilate": false, "area": [0, 100], "ratio": [0, 89.9], "extent": [61, 100], "is_binary": 0, "sort_mode": "Largest", "target_group": "Dual", "target_intersection": "Up"}}, "path": "/dev/v4l/by-path/pci-0000:02:03.0-usb-0:1:1.0-video-index0", "video_mode": {"fps": 30, "width": 640, "height": 480, "pixel_format": "kYUYV"}}
\ No newline at end of file
diff --git a/backend/settings/cams/USB Camera-B4.09.24.1.json b/backend/settings/cams/USB Camera-B4.09.24.1.json
index 4d9c86199..794e41662 100644
--- a/backend/settings/cams/USB Camera-B4.09.24.1.json
+++ b/backend/settings/cams/USB Camera-B4.09.24.1.json
@@ -1 +1 @@
-{"pipelines": {"pipeline0": {"exposure": 50, "brightness": 11, "orientation": "Normal", "resolution": [320, 160], "hue": [0, 100], "saturation": [0, 100], "value": [0, 100], "erode": false, "dilate": false, "area": [20, 34], "ratio": [0, 22.9], "extent": [13, 71], "is_binary": "Normal", "sort_mode": "Largest", "target_group": "Single", "target_intersection": "Up"}}, "path": "/dev/v4l/by-path/pci-0000:02:03.0-usb-0:1:1.0-video-index0", "video_mode": {"fps": 187, "width": 320, "height": 240, "pixel_format": "kYUYV"}}
\ No newline at end of file
+{"pipelines": {"pipeline0": {"exposure": 50, "brightness": 10, "orientation": "Normal", "hue": [0, 56], "saturation": [0, 47], "value": [0, 100], "erode": false, "dilate": false, "area": [0, 100], "ratio": [0, 99], "extent": [0, 100], "is_binary": 1, "sort_mode": "Rightmost", "target_group": "Single", "target_intersection": "Up"}}, "path": "/dev/v4l/by-path/pci-0000:02:03.0-usb-0:1:1.0-video-index0", "video_mode": {"fps": 15, "width": 640, "height": 480, "pixel_format": "kYUYV"}, "resolution": 14, "FOV": 56}
\ No newline at end of file
diff --git a/backend/settings/cams/USB2.0 PC CAMERA.json b/backend/settings/cams/USB2.0 PC CAMERA.json
new file mode 100644
index 000000000..c26acf48d
--- /dev/null
+++ b/backend/settings/cams/USB2.0 PC CAMERA.json
@@ -0,0 +1 @@
+{"pipelines": {"pipeline0": {"exposure": 50, "brightness": 50, "orientation": "Normal", "hue": [0, 100], "saturation": [0, 100], "value": [0, 100], "erode": false, "dilate": false, "area": [0, 100], "ratio": [0, 20], "extent": [0, 100], "is_binary": "Normal", "sort_mode": "Largest", "target_group": "Single", "target_intersection": "Up"}}, "path": "/dev/v4l/by-path/pci-0000:02:03.0-usb-0:2:1.0-video-index0", "video_mode": {"fps": 30, "width": 640, "height": 480, "pixel_format": "kYUYV"}, "resolution": 0, "FOV": 60.8}
\ No newline at end of file
diff --git a/backend/settings/settings.json b/backend/settings/settings.json
index 30370a80d..41fe0b582 100644
--- a/backend/settings/settings.json
+++ b/backend/settings/settings.json
@@ -1 +1 @@
-{"team_number": 1577, "connection_type": "DHCP", "ip": "", "gateway": "", "hostname": "Chameleon-Vision", "curr_camera": "AN-VC500 Camera", "curr_pipeline": "pipeline0"}
\ No newline at end of file
+{"team_number": 1567, "connection_type": "DHCP", "ip": "", "gateway": "", "hostname": "Chameleon-Vision", "curr_camera": "USB2.0 PC CAMERA", "curr_pipeline": "pipeline0"}
\ No newline at end of file
diff --git a/chameleon-client/src/App.vue b/chameleon-client/src/App.vue
index d01c6d84c..ba7f0c132 100644
--- a/chameleon-client/src/App.vue
+++ b/chameleon-client/src/App.vue
@@ -76,12 +76,17 @@
},
created () {
this.$options.sockets.onmessage = (data) => {
- console.log(data.data);
- let message = JSON.parse(data.data);
- for (var prop in message){
+ try{
+ let message = JSON.parse(data.data);
+ for (var prop in message){
if(message.hasOwnProperty(prop)){
this.$store.state[prop] = message[prop];
}
+ console.log(data.data);
+ }
+ }
+ catch{
+ console.log("error" + data.data)
}
} // console writes recived data
}
diff --git a/chameleon-client/src/components/CameraTab.vue b/chameleon-client/src/components/CameraTab.vue
index c265dacb9..e237466ab 100644
--- a/chameleon-client/src/components/CameraTab.vue
+++ b/chameleon-client/src/components/CameraTab.vue
@@ -1,18 +1,95 @@
- Camera
+ Resolution:
+
+ Diagonal FOV:
+
+ Please Restart the computer Manually after saving all cameras
+
+