diff --git a/backend/app/classes/SettingsManager.py b/backend/app/classes/SettingsManager.py index 76a1f0309..80b89cb3f 100644 --- a/backend/app/classes/SettingsManager.py +++ b/backend/app/classes/SettingsManager.py @@ -30,7 +30,9 @@ class SettingsManager(metaclass=Singleton): "is_binary": "Normal", "sort_mode": "Largest", "target_group": 'Single', - "target_intersection": 'Up' + "target_intersection": 'Up', + "M": 1, + "B": 0 } default_general_settings = { "team_number": 1577, diff --git a/backend/app/handlers/VisionHandler.py b/backend/app/handlers/VisionHandler.py index 56c1433ba..50c4cd51d 100644 --- a/backend/app/handlers/VisionHandler.py +++ b/backend/app/handlers/VisionHandler.py @@ -1,4 +1,6 @@ import asyncio +import time + from networktables import NetworkTables import networktables import cv2 @@ -239,6 +241,7 @@ class VisionHandler(metaclass=Singleton): return pitch def calculate_yaw(self, pixel_x, center_x, h_focal_length): + yaw = math.degrees(math.atan((pixel_x - center_x) / h_focal_length)) return yaw @@ -326,7 +329,8 @@ class VisionHandler(metaclass=Singleton): 'raw_point': nt_data['raw_point'], 'point': { 'pitch': nt_data['pitch'], - 'yaw': nt_data['yaw'] + 'yaw': nt_data['yaw'], + 'fps': nt_data['fps'] } }) except Exception as e: @@ -360,6 +364,10 @@ class VisionHandler(metaclass=Singleton): socket = context.socket(zmq.PAIR) socket.connect('tcp://localhost:%s' % str(port)) filter_contours = self.Filter_Contours(center_x=centerX, center_y=centerY) + x = 1 + counter = 0 + start_time = time.time() + fps = 0 while True: obj = socket.recv_json() image = socket.recv_pyobj() @@ -379,8 +387,10 @@ class VisionHandler(metaclass=Singleton): final_contour = self.output_contour(filtered_contours) try: center = final_contour[0] - pitch = self.calculate_pitch(pixel_y=center[1], center_y=centerY, v_focal_length=V_FOCAL_LENGTH) - yaw = self.calculate_yaw(pixel_x=center[0], center_x=centerX, h_focal_length=H_FOCAL_LENGTH) + center_x = (center[1] - curr_pipeline['B']) / curr_pipeline["M"] + center_y = (center[0] * curr_pipeline["M"]) + curr_pipeline["B"] + pitch = self.calculate_pitch(pixel_y=center[1], center_y=center_x, v_focal_length=V_FOCAL_LENGTH) + yaw = self.calculate_yaw(pixel_x=center[0], center_x=center_y, h_focal_length=H_FOCAL_LENGTH) valid = True except IndexError: center = None @@ -398,7 +408,14 @@ class VisionHandler(metaclass=Singleton): pitch=pitch, yaw=yaw, valid=valid, - raw_point=center + raw_point=center, + fps=fps )) + counter += 1 + if (time.time() - start_time) > x: + fps = (counter / (time.time() - start_time)) + counter = 0 + start_time = time.time() + 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 794e41662..3f4f72410 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": 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 +{"pipelines": {"pipeline0": {"exposure": 50, "brightness": 16, "orientation": "Normal", "hue": [0, 127], "saturation": [0, 138], "value": [0, 122], "erode": false, "dilate": false, "area": [20, 37], "ratio": [0, 80.5], "extent": [0, 100], "is_binary": 1, "sort_mode": "Rightmost", "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 diff --git a/backend/settings/settings.json b/backend/settings/settings.json index 41fe0b582..4768b240f 100644 --- a/backend/settings/settings.json +++ b/backend/settings/settings.json @@ -1 +1 @@ -{"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 +{"team_number": 1567, "connection_type": "DHCP", "ip": "", "gateway": "", "hostname": "Chameleon-Vision", "curr_camera": "USB Camera-B4.09.24.1", "curr_pipeline": "pipeline0"} \ No newline at end of file diff --git a/chameleon-client/src/components/CameraTab.vue b/chameleon-client/src/components/CameraTab.vue index e237466ab..e7c48b2bc 100644 --- a/chameleon-client/src/components/CameraTab.vue +++ b/chameleon-client/src/components/CameraTab.vue @@ -23,8 +23,7 @@ - -

Please Restart the computer Manually after saving all cameras

+

Please Restart the computer Manually after saving all cameras

diff --git a/chameleon-client/src/components/Vision.vue b/chameleon-client/src/components/Vision.vue index ab20901ab..b61e10c7a 100644 --- a/chameleon-client/src/components/Vision.vue +++ b/chameleon-client/src/components/Vision.vue @@ -17,10 +17,11 @@ - - + + +

{{point}}

@@ -69,6 +70,12 @@ set: function(value){ this.$store.commit('is_binary',value) } + }, + point:{ + get:function(){ + let p = this.$store.state.point; + return ("Pitch: " + parseFloat(p['pitch']).toFixed(2) + " Yaw: " + parseFloat(p['yaw']).toFixed(2) + " FPS: " + parseFloat(p['fps']).toFixed(2)) + } } }, } @@ -81,4 +88,7 @@ width: 75%; height: 75%; } +.pointText{ + text-align: center; +} \ No newline at end of file diff --git a/chameleon-client/src/components/outputTab.vue b/chameleon-client/src/components/outputTab.vue index e8701d4f6..a49c1b1ae 100644 --- a/chameleon-client/src/components/outputTab.vue +++ b/chameleon-client/src/components/outputTab.vue @@ -2,7 +2,19 @@
-
calibrate crosshair
+ + + + + + + + + + + + +
@@ -19,11 +31,40 @@ import chrange from './ch-range.vue' chrange }, methods:{ - + takePointA:function(){ + this.pointA = this.raw_point; + this.calcSlope(); + }, + takePointB:function(){ + this.pointB = this.raw_point; + this.calcSlope(); + }, + calcSlope:function(){ + if(this.pointA !== undefined && this.pointB !== undefined){ + let m = (this.pointB[1] - this.pointA[1]) / (this.pointB[0] - this.pointA[0]); + let b = this.pointA[1] - (m * this.pointA[0]); + this.sendSlope(m,b); + } + }, + clearPoints:function(){ + this.sendSlope(1,0); + }, + sendSlope(m,b){ + this.$socket.sendObj({'M':m}); + this.$socket.sendObj({'B':b}); + } + }, + computed: { + raw_point:{ + get:function(){ + return this.$store.state.raw_point; + } + } }, data() { return { - + pointA:undefined, + pointB:undefined } } } diff --git a/chameleon-client/src/store.js b/chameleon-client/src/store.js index 29be7a60d..8ee4d5b0e 100644 --- a/chameleon-client/src/store.js +++ b/chameleon-client/src/store.js @@ -42,7 +42,9 @@ export const store = new Vuex.Store({ //live info port:1181, is_binary:0, - //camera lists + //points + raw_point:[], + point:{} }, mutations:{ @@ -75,7 +77,9 @@ export const store = new Vuex.Store({ target_group:set('target_group'), target_intersection:set('target_intersection'), FOV:set('FOV'), - port:set('port') + port:set('port'), + raw_point:set('raw_point'), + point:set('point') }, getters:{ curr_camera: state => state.curr_camera, @@ -104,7 +108,9 @@ export const store = new Vuex.Store({ target_group: state => state.target_group, target_intersection: state => state.target_intersection, FOV: state => state.FOV, - port: state => state.port + port: state => state.port, + raw_point:state => state.raw_point, + point: state => state.point }, }); \ No newline at end of file