diff --git a/backend/app/classes/SettingsManager.py b/backend/app/classes/SettingsManager.py index 80b89cb3f..9e74507cc 100644 --- a/backend/app/classes/SettingsManager.py +++ b/backend/app/classes/SettingsManager.py @@ -14,6 +14,7 @@ class SettingsManager(metaclass=Singleton): usb_cameras_info = {} general_settings = {} cams_port = {} + cams_curr_pipeline = {} default_pipeline = { "exposure": 50, @@ -217,7 +218,8 @@ class SettingsManager(metaclass=Singleton): def create_new_cam(self, cam_name): self.cams[cam_name] = {} self.cams[cam_name]["pipelines"] = {} - self.create_new_pipeline(cam_name=cam_name) + for i in range(10): + self.create_new_pipeline(cam_name=cam_name) self.cams[cam_name]["path"] = self.usb_cameras_info[cam_name].otherPaths[0] if len( self.usb_cameras_info[cam_name].otherPaths) == 1 else self.usb_cameras_info[cam_name].otherPaths[1] diff --git a/backend/app/handlers/SocketHandler.py b/backend/app/handlers/SocketHandler.py index bd018deb3..35c5750ee 100644 --- a/backend/app/handlers/SocketHandler.py +++ b/backend/app/handlers/SocketHandler.py @@ -11,16 +11,10 @@ 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(json.dumps(message)) - except AssertionError as a: - pass - except AssertionError: - pass + try: + ws.write_message(json.dumps(message)) + except AssertionError as a: + pass class ChameleonWebSocket(tornado.websocket.WebSocketHandler): @@ -119,6 +113,7 @@ class ChameleonWebSocket(tornado.websocket.WebSocketHandler): def change_curr_pipeline(self, dic): self.settings_manager.set_curr_pipeline(pipe_name=dic["curr_pipeline"]) + self.settings_manager.cams_curr_pipeline[self.settings_manager.general_settings['curr_camera']] = dic["curr_pipeline"] self.send_curr_pipeline() def change_pipeline_values(self, dic): diff --git a/backend/app/handlers/VisionHandler.py b/backend/app/handlers/VisionHandler.py index dc2bca4ef..faac557cd 100644 --- a/backend/app/handlers/VisionHandler.py +++ b/backend/app/handlers/VisionHandler.py @@ -257,8 +257,8 @@ class VisionHandler(metaclass=Singleton): def thread_proc(self, cs, cam_name, port=5557): asyncio.set_event_loop(asyncio.new_event_loop()) - pipeline_name = 'pipeline0' - pipeline = SettingsManager().cams[cam_name]["pipelines"][pipeline_name] + SettingsManager.cams_curr_pipeline[cam_name] = "pipeline0" + pipeline = SettingsManager().cams[cam_name]["pipelines"][SettingsManager.cams_curr_pipeline[cam_name]] FOV = SettingsManager().cams[cam_name]["FOV"] def change_camera_values(pipline): @@ -267,16 +267,23 @@ class VisionHandler(metaclass=Singleton): SettingsManager.usb_cameras[cam_name].setWhiteBalanceAuto() def pipeline_listener(table, key, value, is_new): - global pipeline - if is_new: - pipeline = SettingsManager.cams[cam_name]["pipelines"][value] - change_camera_values() + asyncio.set_event_loop(asyncio.new_event_loop()) + SettingsManager.cams_curr_pipeline[cam_name] = value + change_camera_values(pipeline) + if cam_name == SettingsManager().general_settings['curr_camera']: + SettingsManager().general_settings['curr_pipeline'] = value + update_settings = SettingsManager().get_curr_pipeline() + update_settings['curr_pipeline'] = SettingsManager().general_settings["curr_pipeline"] + send_all_async(update_settings) def mode_listener(table, key, value, is_new): - pass + change_camera_values({ + 'brightness': 25, + 'exposure': 15 + }) table = NetworkTables.getTable("/Chameleon-Vision/" + cam_name) - + table.putString('Pipeline', SettingsManager.cams_curr_pipeline[cam_name]) table.addEntryListenerEx(pipeline_listener, key="Pipeline", flags=networktables.NetworkTablesInstance.NotifyFlags.UPDATE) table.addEntryListenerEx(mode_listener, key="Driver_Mode", @@ -306,21 +313,26 @@ class VisionHandler(metaclass=Singleton): change_camera_values(pipeline) while True: + pipeline = SettingsManager().cams[cam_name]["pipelines"][SettingsManager.cams_curr_pipeline[cam_name]] _, image = cv_sink.grabFrame(image) socket.send_json(dict( pipeline=pipeline - )) + ), zmq.SNDMORE) 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 + + # print(nt_data['fps']) + if nt_data['valid']: #send the point using network tables table.putNumber('pitch', nt_data['pitch']) table.putNumber('yaw', nt_data['yaw']) #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: @@ -371,6 +383,9 @@ class VisionHandler(metaclass=Singleton): obj = socket.recv_json() image = socket.recv_pyobj() curr_pipeline = obj["pipeline"] + if curr_pipeline['orientation'] == "Inverted": + M = cv2.getRotationMatrix2D((width / 2, height / 2), 180, 1) + image = cv2.warpAffine(image, M, (width, height)) hsv_image = self._hsv_threshold(curr_pipeline["hue"], curr_pipeline["saturation"], curr_pipeline["value"], image, curr_pipeline["erode"], curr_pipeline["dilate"]) 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 3dc902d88..2dd7aa24f 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": 3, "brightness": 0, "orientation": "Normal", "hue": [85, 136], "saturation": [115, 175], "value": [190, 255], "erode": false, "dilate": false, "area": [0, 99], "ratio": [0, 94.4], "extent": [0, 100], "is_binary": 1, "sort_mode": "Largest", "target_group": "Single", "target_intersection": "Up", "M": 1, "B": 0}}, "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"}, "resolution": 0, "FOV": 56} \ No newline at end of file +{"pipelines": {"pipeline0": {"exposure": 50, "brightness": 15, "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": 0, "sort_mode": "Largest", "target_group": "Single", "target_intersection": "Up", "M": 1, "B": 0}, "pipeline1": {"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": 0, "sort_mode": "Largest", "target_group": "Single", "target_intersection": "Up", "M": 1, "B": 0}, "pipeline2": {"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", "M": 1, "B": 0}, "pipeline3": {"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", "M": 1, "B": 0}, "pipeline4": {"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", "M": 1, "B": 0}, "pipeline5": {"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", "M": 1, "B": 0}, "pipeline6": {"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", "M": 1, "B": 0}, "pipeline7": {"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", "M": 1, "B": 0}, "pipeline8": {"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", "M": 1, "B": 0}, "pipeline9": {"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": 0, "sort_mode": "Largest", "target_group": "Single", "target_intersection": "Up", "M": 1, "B": 0}}, "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"}, "resolution": 0, "FOV": 60.8} \ No newline at end of file diff --git a/chameleon-client/src/components/ch-select.vue b/chameleon-client/src/components/ch-select.vue index 244195dd2..5b0848a13 100644 --- a/chameleon-client/src/components/ch-select.vue +++ b/chameleon-client/src/components/ch-select.vue @@ -3,7 +3,7 @@

{{title.charAt(0).toUpperCase() + title.slice(1)}} :

- + {{item}} diff --git a/chameleon-client/src/store.js b/chameleon-client/src/store.js index 8ee4d5b0e..e42e35de3 100644 --- a/chameleon-client/src/store.js +++ b/chameleon-client/src/store.js @@ -52,7 +52,7 @@ export const store = new Vuex.Store({ state['curr_camera'] = value; state['pipeline'] = "0"; }, - pipeline: set('curr_pipeline'), + curr_pipeline: set('curr_pipeline'), brightness: set('brightness'), exposure: set('exposure'), orientation:set('orientation'), @@ -83,7 +83,7 @@ export const store = new Vuex.Store({ }, getters:{ curr_camera: state => state.curr_camera, - pipeline: state => state.pipeline, + curr_pipeline: state => state.curr_pipeline, brightness: state => state.brightness, exposure: state => state.exposure, orientation: state => state.orientation,