Merge branch 'bugfixes' into 'dev'

Bugfixes

See merge request oriagranat9/Chameleon-Vision!2
This commit is contained in:
ori agranat
2019-08-09 10:31:33 +00:00
19 changed files with 254 additions and 394 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"])

View File

@@ -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"],

View File

@@ -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
))

View File

@@ -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"}}

View File

@@ -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"}}
{"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}

View File

@@ -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}

View File

@@ -1 +1 @@
{"team_number": 1577, "connection_type": "DHCP", "ip": "", "gateway": "", "hostname": "Chameleon-Vision", "curr_camera": "AN-VC500 Camera", "curr_pipeline": "pipeline0"}
{"team_number": 1567, "connection_type": "DHCP", "ip": "", "gateway": "", "hostname": "Chameleon-Vision", "curr_camera": "USB2.0 PC CAMERA", "curr_pipeline": "pipeline0"}

View File

@@ -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
}

View File

@@ -1,18 +1,95 @@
<template>
<h4>Camera</h4>
<div id="cameraTab" class="spacing">
<chselect title="select camera" :list="cameraList" Xkey="curr_camera"></chselect>
<Row type="flex" justify="start" align="middle" :gutter="1" class="spacing">
<Col span="4">
<h4>Resolution:</h4>
</Col>
<Col span="4">
<i-select v-model="resolution" size="small" >
<i-option v-for="(item,index) in resolutionList" :value="index" :key="index">{{item}}</i-option>
</i-select>
</Col>
</Row>
<Row type="flex" justify="start" align="middle" :gutter="1" class="spacing">
<Col span="4">
<h4>Diagonal FOV:</h4>
</Col>
<Col span="4">
<InputNumber :min="0" v-model="FOV" size="small"></InputNumber>
</Col>
</Row>
<Button type="primary" size="small" class="buttonClass spacing" v-on:click="socketSendAll">Save settings to current camera</Button>
<h4 class="spacing">Please Restart the computer Manually after saving all cameras</h4>
</div>
</template>
<script>
import chselect from './ch-select.vue'
import chIndexSelect from './ch-IndexSelect.vue'
export default {
name: '',
name: 'cameraTab',
components: {
chselect,
chIndexSelect
},
data() {
return {
}
},
methods: {
socketSendAll: function(){
this.$socket.sendObj({'resolution':this.resolution});
this.$socket.sendObj({'FOV':this.FOV});
}
},
computed: {
cameraList:{
get:function(){
return this.$store.state.cameraList;
}
},
resolutionList:{
get:function(){
return this.$store.state.resolutionList;
}
},
resolution:{
get: function(){
return this.$store.state.resolution;
},
set: function(value){
this.$store.commit('resolution',value);
}
},
FOV:{
get: function(){
return this.$store.state.FOV;
},
set: function(value){
this.$store.commit('FOV',value);
}
}
}
}
</script>
<style lang="" scoped>
<style scoped>
.title{
text-align:left;
color: aliceblue
}
.spacing{
margin-top: 10px;
}
.buttonClass{
display: flex;
text-align: left;
}
</style>

View File

@@ -4,7 +4,6 @@
<chslider class="spacing" title="exposure" Xkey="exposure"></chslider>
<chslider class="spacing" title="Brightness" Xkey="brightness"></chslider>
<chselect class="spacing" title="Orientation" Xkey="orientation" :list="['Normal','Inverted']"></chselect>
<ch-index-select class="spacing" title="Resolution" Xkey="resolution" :list="resolutionList"></ch-index-select>
</div>
</template>

View File

@@ -6,31 +6,31 @@
<h4>Team Number:</h4>
</Col>
<col span="4">
<InputNumber :min="0" v-model="teamNum" size="small"></InputNumber>
<InputNumber :min="0" v-model="team_number" size="small"></InputNumber>
</col>
</row>
</div>
<Divider class="divdiv" orientation="left">Networking</Divider>
<div>
<RadioGroup v-model="connectionType" style="display: flex;">
<RadioGroup v-model="connection_type" style="display: flex;">
<Radio label="DHCP"></Radio>
<Radio label="Static"></Radio>
</RadioGroup>
<div class="ipSettings">
<row type="flex" justify="start" align="middle" class="spacing">
<Col span="4">
<h4>IP:</h4>
<h4>IP:</h4>
</Col>
<Col span="10">
<Input v-model="IP" size="small" :disabled="isConnection"></Input>
<Input v-model="ip" size="small" :disabled="isConnection"></Input>
</Col>
</row>
<row type="flex" justify="start" align="middle" class="spacing">
<Col span="4">
<h4>Gateway:</h4>
<h4>Gateway:</h4>
</Col>
<Col span="10">
<Input v-model="gateWay" size="small" :disabled="isConnection"></Input>
<Input v-model="gateway" size="small" :disabled="isConnection"></Input>
</Col>
</row>
<row type="flex" justify="start" align="middle" class="spacing">
@@ -38,7 +38,7 @@
<h4>Hostname:</h4>
</Col>
<Col span="10">
<Input v-model="hostName" size="small">
<Input v-model="hostname" size="small">
<span slot="prepend">http://Chameleon-Vision</span>
<span slot="append">.local</span>
</Input>
@@ -69,32 +69,33 @@
},
methods: {
socketSendAll: function(){
this.$socket.sendObj([
{'team_number':this.teamNum},
{'connection_type':this.connectionType},
{'ip':this.ip},
{'gateway':this.gateWay},
{'hostname':this.hostName}]);
this.$socket.sendObj(
{'change_general_settings_values':{
'team_number':this.team_number,
'connection_type':this.connection_type,
'ip':this.ip,
'gateway':this.gateway,
'hostname':this.hostname}});
}
},
computed: {
teamNum:{
team_number:{
get: function(){
return this.$store.state.teamValue;
return this.$store.state.team_number;
},
set: function(value){
this.$store.commit('teamValue',value);
this.$store.commit('team_number',value);
}
},
connectionType:{
connection_type:{
get: function(){
return this.$store.state.connectionType;
return this.$store.state.connection_type;
},
set: function(value){
this.$store.commit('connectionType',value);
this.$store.commit('connection_type',value);
}
},
IP:{
ip:{
get: function(){
return this.$store.state.ip;
},
@@ -102,20 +103,20 @@
this.$store.commit('ip',value);
}
},
gateWay:{
gateway:{
get: function(){
return this.$store.state.gateWay;
return this.$store.state.gateway;
},
set: function(value){
this.$store.commit('gateWay',value);
this.$store.commit('gateway',value);
}
},
hostName:{
hostname:{
get: function(){
return this.$store.state.hostName;
return this.$store.state.hostname;
},
set: function(value){
this.$store.commit('hostName',value);
this.$store.commit('hostname',value);
}
},
isConnection: function(){

View File

@@ -59,7 +59,7 @@
},
steamAdress: {
get: function(){
return this.$store.state.streamAdress;
return "http://"+location.hostname + ":"+ this.$store.state.port +"/stream.mjpg";
}
},
isBinary: {

View File

@@ -2,7 +2,7 @@
<div id="OutputTab">
<chselect class="spacing" title="Sort Mode" Xkey="sort_mode"
:list="['Largest','Smallest','Highest','Lowest','Rightmost','Leftmost','Closest']"></chselect>
<h4>calibrate crosshair</h4>
<h6>calibrate crosshair</h6>
</div>
</template>
@@ -34,4 +34,5 @@ import chrange from './ch-range.vue'
.spacing{
margin-top: 20px;
}
</style>

View File

@@ -19,6 +19,7 @@ export const store = new Vuex.Store({
orientation:0,
resolution:0,
resolutionList:[],
FOV:0,
//threshold
hue:[0,10],
saturation:[0,10],
@@ -33,20 +34,20 @@ export const store = new Vuex.Store({
target_group:'Single', //
target_intersection:'Up', //
//Settings
teamValue:0,
connectionType:"DHCP",
team_number:0,
connection_type:"DHCP",
ip:0,
gateWay:0,
hostName:"",
hostname:"",
//live info
streamAdress:("http://"+location.hostname + ":1181/stream.mjpg"),
port:1181,
is_binary:0,
//camera lists
},
mutations:{
camera (state,value){
state['camera'] = value;
curr_camera (state,value){
state['curr_camera'] = value;
state['pipeline'] = "0";
},
pipeline: set('curr_pipeline'),
@@ -62,21 +63,22 @@ export const store = new Vuex.Store({
area: set('area'),
ratio: set('ratio'),
extent: set('extent'),
teamValue: set('team_number'),
connectionType: set('connection_type'),
team_number: set('team_number'),
connection_type: set('connection_type'),
ip: set('ip'),
gateWay : set('gateway'),
hostName : set('hostname'),
streamAdress : set('streamAdress'),
hostname : set('hostname'),
is_binary: set('is_binary'),
cameraList : set('cameraList'),
pipelineList: set('piplineList'),
sort_mode: set('sort_mode'),
target_group:set('target_group'),
target_intersection:set('target_intersection')
target_intersection:set('target_intersection'),
FOV:set('FOV'),
port:set('port')
},
getters:{
camera: state => state.camera,
curr_camera: state => state.curr_camera,
pipeline: state => state.pipeline,
brightness: state => state.brightness,
exposure: state => state.exposure,
@@ -90,19 +92,19 @@ export const store = new Vuex.Store({
area: state =>state.area,
ratio: state =>state.ratio,
extent: state =>state.extent,
teamValue: state => state.teamValue,
connectionType: state => state.connectionType,
team_number: state => state.teamValue,
connection_type: state => state.connectionType,
ip: state => state.ip,
gateWay: state => state.gateWay,
hostName: state => state.hostName,
streamAdress: state => state.streamAdress,
hostname: state => state.hostName,
is_binary: state => state.is_binary,
cameraList: state => state.cameraList,
pipelineList: state => state.pipelineList,
sort_mode: state => state.sort_mode,
target_group: state => state.target_group,
target_intersection: state => state.target_intersection
target_intersection: state => state.target_intersection,
FOV: state => state.FOV,
port: state => state.port
},
});

View File

@@ -1 +0,0 @@
{"pipelines": {"pipeline0": {"exposure": 50, "brightness": 50, "orientation": "Normal", "resolution": [320, 160], "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"}}, "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"}}

View File

@@ -1 +0,0 @@
{"team_number": 1577, "connection_type": "DHCP", "ip": "", "gateway": "", "hostname": "Chameleon-Vision", "curr_camera": "USB Camera-B4.09.24.1", "curr_pipeline": "pipeline0"}