diff --git a/package-lock.json b/package-lock.json index 4f5c1ff..2c416e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -616,7 +616,6 @@ "integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chalk": "^4.1.1", "fs-extra": "^9.0.1", @@ -1753,7 +1752,6 @@ "integrity": "sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@inquirer/checkbox": "^3.0.1", "@inquirer/confirm": "^4.0.1", @@ -2912,7 +2910,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2979,7 +2976,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -3197,7 +3193,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4504,6 +4499,17 @@ "dev": true, "license": "MIT" }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", @@ -8024,7 +8030,6 @@ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -8084,7 +8089,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.28.tgz", "integrity": "sha512-BRdrNfeoccSoIZeIhyPBfvWSLFP4q8J3u8Ju8Ug5vu3LdD+yTM13Sg4sKtljxozbnuMu1NB1X5HBHRYUzFocKg==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.28", "@vue/compiler-sfc": "3.5.28", @@ -8138,7 +8142,6 @@ "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", diff --git a/public/images/qr.jpg b/public/images/qr.jpg new file mode 100644 index 0000000..61474b1 Binary files /dev/null and b/public/images/qr.jpg differ diff --git a/public/shablons/color.txt b/public/shablons/color.txt index 15781cc..b61e0f9 100644 --- a/public/shablons/color.txt +++ b/public/shablons/color.txt @@ -1,51 +1,45 @@ -class ColorDetect(): - def __init__(self): - self.color = None +def color_detection(data, print_type='str'): + '''определение цвета''' - def getColor(self): - return self.color + frame = bridge.imgmsg_to_cv2(data, 'bgr8') + height, width = frame.shape[:2] + y_start = int(height * 0.33) + y_end = int(height * 0.67) + x_start = int(width * 0.31) + x_end = int(width * 0.69) - def detect_color_callback(self, data, print_type='str'): - '''определение цвета''' + cropped_frame = frame[y_start:y_end, x_start:x_end] + + if cropped_frame.size == 0: + return + - frame = bridge.imgmsg_to_cv2(data, 'bgr8') - height, width = frame.shape[:2] - y_start = int(height * 0.33) - y_end = int(height * 0.67) - x_start = int(width * 0.31) - x_end = int(width * 0.69) + if print_type == 'rgb': - cropped_frame = frame[y_start:y_end, x_start:x_end] + mean_bgr = cv2.mean(cropped_frame)[:3] + mean_rgb = (int(mean_bgr[2]), int(mean_bgr[1]), int(mean_bgr[0])) + color = str(mean_rgb) + + + elif print_type == 'str': + + # Получаем средние значения BGR + mean_bgr = cv2.mean(cropped_frame)[:3] + b, g, r = int(mean_bgr[0]), int(mean_bgr[1]), int(mean_bgr[2]) - if cropped_frame.size == 0: - return + if b > g + 20 and b > r + 20 and b > 100 + 20: + color = 'blue' + elif g > b + 20 and g > r + 20 and g > 100: + color = 'green' + elif r > b + 20 and r > g + 20 and r > 100: + color = 'red' + elif r > 150 and g > 150 and g > 150: + color= 'white' + else: + color = None - if print_type == 'rgb': - - mean_bgr = cv2.mean(cropped_frame)[:3] - mean_rgb = (int(mean_bgr[2]), int(mean_bgr[1]), int(mean_bgr[0])) - self.color = str(mean_rgb) - - - elif print_type == 'str': - - # Получаем средние значения BGR - mean_bgr = cv2.mean(cropped_frame)[:3] - b, g, r = int(mean_bgr[0]), int(mean_bgr[1]), int(mean_bgr[2]) - - - if b > g and b > r and b > 100: - self.color = 'blue' - elif g > b and g > r and g > 100: - self.color = 'green' - elif r > b and r > g and r > 100: - self.color = 'red' - else: - self.color = None <> - cd = ColorDetect() - color_sub = rospy.Subscriber('main_camera/image_raw', Image, lambda img: cd.detect_color_callback(img, print_type='rgb'), queue_size=1) - print(cd.getColor()) + color_sub = rospy.Subscriber('main_camera/image_raw', Image, lambda img: color_detection(img, print_type='rgb'), queue_size=1) rospy.sleep(2) - color_sub.unregister() + color_sub.unregister() \ No newline at end of file diff --git a/public/shablons/emergency_and_navigate.txt b/public/shablons/emergency_and_navigate.txt index c0475f7..b356e7e 100644 --- a/public/shablons/emergency_and_navigate.txt +++ b/public/shablons/emergency_and_navigate.txt @@ -17,7 +17,9 @@ get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry) #сеов navigate = rospy.ServiceProxy('navigate', srv.Navigate) #сервис для полета по указаным координатам land = rospy.ServiceProxy('land', Trigger) #сервис для посадки -<> +rospy.init_node('flight') +bridge = CvBridge() + def navigate_wait(x=0, y=0, z=1, speed=0.5, frame_id='aruco_map', auto_arm=False, tolerance=0.2,sleep=2): """ @@ -86,6 +88,8 @@ def signal_handler(sig, frame): signal.signal(signal.SIGINT, signal_handler) +<> +<> def main(): navigate_wait(z=1,frame_id='body',auto_arm=True) #должно быть. включает моторы и поднимает дрон на метр вверх diff --git a/public/shablons/qr.txt b/public/shablons/qr.txt index b31ddde..c877557 100644 --- a/public/shablons/qr.txt +++ b/public/shablons/qr.txt @@ -1,26 +1,12 @@ -class QrDetect(): - def __init__(self): - self.qr_data = '' - - def getQrData(self): - return self.qr_data +def qr_detection(data): + cv_image = bridge.imgmsg_to_cv2(data, 'bgr8') + barcodes = pyzbar.decode(cv_image) - def qr_detection(self,data): - '''сканирование qr кода''' - if self.qr_data!= '': - return - cv_image = bridge.imgmsg_to_cv2(data, 'bgr8') - barcodes = pyzbar.decode(cv_image) + if barcodes: + qr_data = barcodes[0].data.decode('utf-8') + return qr_data - if barcodes: - self.qr_data = barcodes[0].data.decode('utf-8') - - -#в MAIN для вызова функции необходимо следующее: -#1. создаём и вызываем подписчика, который вызывает функцию чтения кьюаркода -qd = QrDetect() -qr_sub = rospy.Subscriber('main_camera/image_raw',Image, qd.qr_detection,queue_size=1) -#2. задаём время работы подписчика (за 1 секунду примерно 20 раз вызывается функция) -rospy.sleep(2) -#3. выключаем подписчика -qr_sub.unregister() +<> + qr_sub = rospy.Subscriber('main_camera/image_raw', Image, qr_detection, queue_size=1) + rospy.sleep(2) + qr_sub.unregister() \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index 0dbba04..2f9b1d3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -21,6 +21,7 @@ onMounted(() => { y: 9 - Math.floor(i / 10), index: i, isPlatform: false, + isQR: false, BgImg: 'images/ArUco-marker.jpg' }); } @@ -52,8 +53,11 @@ async function saveResult() { finallyText.value = ""; const mainCode = ref(""); const colorDetectClass = ref(""); + const QRDetectClass = ref(""); const colorDetectCode = ref(""); + const QRDetectCode = ref(""); const isUsedPlatform = listOfTrips.value.some(item => item.isPlatform); + const isUsedQR = listOfTrips.value.some(item => item.isQR); if (isUsedPlatform) { const response = await fetch("/shablons/color.txt") @@ -63,11 +67,22 @@ async function saveResult() { colorDetectCode.value += `\t${textOfCode[1].trim()}\n`; } + if (isUsedQR) { + const response = await fetch("/shablons/qr.txt") + let textOfCode = await response.text() + textOfCode = textOfCode.split('<>') + QRDetectClass.value = textOfCode[0] + QRDetectCode.value += `\t${textOfCode[1].trim()}\n`; + } + for (const item of listOfTrips.value) { mainCode.value += `\tnavigate_wait(${item.x}, ${item.y})\n`; if (item.isPlatform) { mainCode.value += colorDetectCode.value + '\n' } + if (item.isQR) { + mainCode.value += QRDetectCode.value + '\n' + } } const response = await fetch("/shablons/emergency_and_navigate.txt") let textOfCode = await response.text() @@ -75,8 +90,11 @@ async function saveResult() { if (isUsedPlatform) { finallyText.value = finallyText.value.replace("<>", colorDetectClass.value); } - isModalVisible.value = true; -} + if (isUsedQR) { + finallyText.value = finallyText.value.replace("<>", QRDetectClass.value); + } + isModalVisible.value = true;} + function cancel() { @@ -159,6 +177,26 @@ function deletePlatform(item) { clickCount.value-- } +function createQR(item) { + if (!item.isQR) { + listOfTrips.value.push(item) + numbers.value[item.index].variable.push(clickCount.value); + } + item['isQR'] = true + numbers.value[item.index].BgImg = `images/qr.jpg` + clickCount.value++ +} + +function deleteQR(item) { + item['isQR'] = false + const index = listOfTrips.value.indexOf(item); + if (index !== -1) { + listOfTrips.value.splice(index, 1); + } + numbers.value[item.index].BgImg = 'images/ArUco-marker.jpg' + clickCount.value-- +} + function onContextMenu(e, item) { ContextMenu.showContextMenu({ theme: 'mac dark', @@ -191,11 +229,11 @@ function onContextMenu(e, item) { children: [ { label: "Добавить", - onClick: () => alert('Здесь ещё предстоит написать код') + onClick: () => createQR(item) }, { label: "Удалить", - onClick: () => alert('Здесь ещё предстоит написать код') + onClick: () => deleteQR(item) }, ], },