Merhabalar, bu içerikte sizlerle daha önceden geliştirdiğimiz görüntü işleme komutlarını paylaşacağım. Öncelikle kodların tamamına ulaşmak isterseniz : https://github.com/enisgetmez/FRC-Vision-Processing buradan ulaşabilirsiniz.
Bu kısmı buradan daha detaylı bir şekilde izleyebilirsiniz:
Co-Processor olarak Raspberry PI kullanacağız.
Öncelikle görüntü işleme yapacağımız için OpenCV kütüphanelerinden faydalanacağız. OpenCV kütüphanelerinin çalışması için aynı zamanda Numpy kütüphanesini de kurmamız gerekmektedir.
Konsola girmemiz gereken komutlar şu şekildedir:
sudo apt install python-numpy python-opencv libopencv-dev
y/n seçeneğine y yanıtını verelim. Bu işlem yaklaşık 5 dakika sürebilir.
Python için pip yani paket yöneticimizi indirmemiz gerekmektedir.
sudo apt install python python-pip
y/n seçeneğine y yanıtını verelim. Ardından
pip install opencv-python
pip install pynetworktables
pip install imutils
komutlarını girelim. Eğer Python 3 kullanıyorsanız, pip komutlarınız şu şekilde olmalı:
pip3 install opencv-python
pip3 install pynetworktables
pip3 install imutils
Her şey tamamlandıktan sonra bu adımda bitmiş demektir. Bir sonraki adıma geçebiliriz.
En başta renk işlememiz için bize tanımlayacağımız rengin alt ve üst sınırları dediğimiz renk kodu gerekmektedir. Bunun için bir converter yazılımı mevcut. Kodlar bu şekildedir:
Dilerseniz bu kodlara ulaşabilirsiniz. Github üzerinden kolayca wget komutu ile indirebilirsiniz.
wget
Kullanımı ise şu şekildedir :
Algılatmak istediğiniz rengin kırmızı, yeşil, mavi renk değerlerini almalısınız. Ardından şu komutu kullanmalısınız:
convert.py red green blue
Lower bound ve upper bound dediğimiz renkleri kopyalayın. İleride kullanacağız.
Raspberry PI için python yazılımımız şu şekildedir :
Komutların açıklamaları kod içerisinde bulunmaktadır. Eğer Raspberry PI için komutu otomatik olarak indirmek isterseniz wget komutunu kullanabilirsiniz.
Artık Java kodlarınızıda yazdıktan sonra robotunuzu enable ettiğinizde , Raspberry PI üzerinden yazılımımızı çalıştırdığımızda değerler otomatik olarak SmartDashboarda düşmeye başlayacaktır.
Kodunuzu Raspberry PI üzerinden çalıştırmak için:
python yazilimadi.py
Şeklinde kullanmanız gerekmektedir. Eğer wget komutunu kullandıysanız yazılım otomatik olarak vision.py olarak gelecektir. Yani çalıştırmak için:
python vision.py
komutunu kullanmanız yeterli olacaktır.
Raspberry Pi ile gelen kodu düzenlemek isterseniz nano komutunu kullanarak düzenleyebilirsiniz.
nano vision.py
Komutunu girip düzenleyeceğiniz satırı düzenledikten sonra ctrl-x tuşlarıyla çıkış yapabilirsiniz.
Komutların açıklamaları kod içerisinde bulunmaktadır. Eğer Raspberry PI için komutu otomatik olarak indirmek isterseniz wget komutunu kullanabilirsiniz.
Artık robotunuzu enable ettiğinizde , Raspberry PI üzerinden yazılımımızı çalıştırdığımızda değerler otomatik olarak smart dashboarda düşmeye başlayacaktır.
Kodunuzu Raspberry PI üzerinden çalıştırmak için:
python yazilimadi.py
Şeklinde kullanmanız gerekmektedir. Eğer wget komutunu kullandıysanız yazılım otomatik olarak vision.py olarak gelecektir. Yani çalıştırmak için:
python circle.py
komutunu kullanmanız yeterli olacaktır.
Kütüphaneleri import edin
Class'ınızın altına networktables'i tanımlayın
Değerleri okumak için 2 tane void oluşturalım.
Değerleri SmartDashboard'a yazdıralım.
Motorlarımız Değerlere göre haraket ettirelim!
Kodların tamamına buradan ulaşabilirsiniz :
Artık robotunuzu enable ettiğinizde , yazılımımızı çalıştırdığımızda değerler otomatik olarak SmartDashboard düşmeye başlayacaktır.
import sys
import numpy as np
import cv2
blue = sys.argv[1]
green = sys.argv[2]
red = sys.argv[3]
color = np.uint8([[[blue, green, red]]])
hsv_color = cv2.cvtColor(color, cv2.COLOR_BGR2HSV)
hue = hsv_color[0][0][0]
print("Lower bound is :"),
print("[" + str(hue-10) + ", 100, 100]\n")
print("Upper bound is :"),
print("[" + str(hue + 10) + ", 255, 255]")#!/usr/bin/env python
# -*- coding: utf-8 -*-
from collections import deque
from networktables import NetworkTables
import numpy as np
import argparse
import cv2
import time
import imutils
x = 0 #programın ileride hata vermemesi için x 0 olarak tanımlıyorum
y = 0 # programın ileride hata vermemesi için y 0 olarak tanımlıyorum
NetworkTables.initialize(server='roborio-6025-frc.local') # Roborio ile iletişim kuruyoruz
table = NetworkTables.getTable("Vision") # table oluşturuyoruz
#sari rengin algilanmasi
colorLower = (24, 100, 100)
colorUpper = (44, 255, 255)
#converter.py ile convert ettiğiniz rengi buraya giriniz
camera = cv2.VideoCapture(0) # webcamin bagli oldugu port varsayilan 0
while True: #yazılımımız çalıştığı sürece aşağıdaki işlemleri tekrarla
(grabbed, frame) = camera.read() # grabbed ve frame değişkenini camera.read olarak tanımlıyoruz.
frame = imutils.resize(frame, width=600) # görüntü genişliğini 600p yapıyoruz
frame = imutils.rotate(frame, angle=0) # görüntüyü sabitliyoruz
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # görüntüyü hsv formatına çeviriyoruz
mask = cv2.inRange(hsv, colorLower, colorUpper) # hsv formatına dönen görüntünün bizim belirttiğimiz renk sınırları içerisinde olanları belirliyor
mask = cv2.erode(mask, None, iterations=2) # bizim renklerimizi işaretliyor
mask = cv2.dilate(mask, None, iterations=2) # bizim renklerimizin genişliğini alıyor
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)[-2]
center = None
if len(cnts) > 0:
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
if radius > 10: #algılanacak hedefin minumum boyutu
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
else:
x = 0 ##değerlerin sıfırlanması
y = 0
print("x : ")
print(x) # kameradan gelen görüntüde bizim rengimiz varsa x kordinatı
print("y : ")
print(y) # kameradan gelen görüntüde bizim rengimiz varsa y kordinatı
table.putNumber("X", x) # roborioya değeri göndermek
table.putNumber("Y", y)wget https://raw.githubusercontent.com/enisgetmez/FRC-Vision-Processing/master/Color%20Detect/vision.py#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import argparse
import cv2
import cv2 as CV
from networktables import NetworkTables
NetworkTables.initialize(server='roborio-6025-frc.local') # Roborio ile iletişim kuruyoruz
table = NetworkTables.getTable("Vision") # table oluşturuyoruz
cap = cv2.VideoCapture(0) # webcamin bagli oldugu port
while(True):
# goruntu yakalama
ret, frame = cap.read()
# goruntuyu grilestir
output = frame.copy()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# goruntuyu blurlastir
gray = cv2.GaussianBlur(gray,(5,5),0);
gray = cv2.medianBlur(gray,5)
gray = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,3.5)
kernel = np.ones((5,5),np.uint8)
gray = cv2.erode(gray,kernel,iterations = 1)
gray = cv2.dilate(gray,kernel,iterations = 1)
circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0) #python2 icin
# circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, param1=40, param2=45, minRadius=0, maxRadius=0) # python3 icin
# (x−xcenter)2+(y−ycenter)2=r2 (xcenter,ycenter)
# kalibre
# daireyi isle
if circles is not None:
circles = np.round(circles[0, :]).astype("int")
for (x, y, r) in circles:
cv2.circle(output, (x, y), r, (0, 255, 0), 4)
cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
print ("X kordinat: ")
print (x) # x kordinatı
print ("Y Kordinat: ")
print (y) # y kordinatı
print ("Radius: ")
print (r) # cisimin büyüklüğü
table.putNumber("X", x) # roborioya değeri göndermek
table.putNumber("Y", y)
#cv2.imshow('frame',output) # ekranda göster
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()wget https://raw.githubusercontent.com/enisgetmez/FRC-Vision-Processing/master/Figure%20Detect/circle.pyimport edu.wpi.first.wpilibj.networktables.NetworkTable; // Networktables kütüphanesi
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; // smartdashboardan verileri görmek için
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; public static NetworkTable table1 = NetworkTable.getTable("Vision"); // vision adında table çekiliyorpublic static double konumX()
{
return table1.getNumber("X", 0.0); //raspberry pi den gelen x kordinatları
}
public static double konumY()
{
return table1.getNumber("Y", 0.0); //raspberry pi den gelen y kordinatları
} public void teleopPeriodic() {
SmartDashboard.putNumber("Nesnenin X konumu: ", konumX()); // smartdashboarda x konumu yazdır
SmartDashboard.putNumber("Nesnenin Y konumu: ", konumY()); // smartdashboarda y konumunu yazdır
} public void autonomousPeriodic() {
if(konumX() == 0)
{
sagmotor1.set(0);
sagmotor2.set(0);
solmotor1.set(0);
solmotor2.set(0);
}
else if(konumX() < 285) // degerler 285'ten kucukse saga don
{
sagmotor1.set(0.5); // sag motorları calistir
sagmotor2.set(0.5);
}
else if (konumX() > 295) // degerler 295'ten buyukse sola don
{
solmotor1.set(0.5); //sol motorlari calistir
solmotor2.set(0.5);
}
}Vision Processing kullanmak, robotunuzun alandaki öğelere duyarlı olmasını ve daha fazla özerk olmasını sağlamanın harika bir yoludur. Genellikle FRC oyunlarında, topların veya diğer oyun parçalarının otonom olarak hedeflenmesi veya sahadaki yerlere gitmesi için bonus puanlar vardır. Vision Processing, bu sorunların çoğunu çözmenin harika bir yoludur.Eğer meydan okuyan özerk bir kodunuz varsa, o zaman insan sürücülerine yardım etmek için teleop döneminde de kullanılabilir.
Görme işlemi için ve vizyon programının çalışması gereken bileşenleri seçmek için birçok seçenek vardır. WPILib ve ilgili araçlar bir dizi seçeneği destekler ve ekiplere ne yapacağına karar vermek için çok fazla esneklik sağlar. Bu makalede, mevcut olan birçok seçenek ile ilgili bazı bilgiler verilecektir.
OpenCV, akademi ve endüstri genelinde yaygın olarak kullanılan açık kaynaklı bir görüntü işleme kütüphanesidir. GPU hızlandırılmış işlem sağlayan bir desteğe sahip, C ++, Java ve Python da dahil olmak üzere birçok dil için uygun kütüphanelere sahiptir. Ayrıca birçok web sitesi, kitap, video ve eğitim kursları ile belgelenmiştir, böylece nasıl kullanılacağını öğrenmenize yardımcı olacak birçok kaynak bulunmaktadır. Bu nedenlerle ve daha fazlası için WPILib'in C ++ ve Java sürümleriyle kullanım için OpenCV'yi kabul ettik. 2017'den başlayarak WPILib ile birlikte gelen OpenCV kütüphaneleri, video yakalama, işleme ve vision için kütüphanede destek ve vision algoritmalarınızı oluşturmanıza yardımcı olacak araçlar hazırladık. OpenCV hakkında daha fazla bilgi için bkz.
RoboRIO üzerinde vision kodu
Vision programı, genel robot programının sadece bir parçası olduğu için programlama oldukça basittir. Program elle veya GRIP tarafından C ++ veya Java ile yazılabilir. Dezavantajı, robot programı ile aynı işlemci üzerinde çalışan vision kodunun performans sorunları yaşayabilmesidir. Bu, robot ve vision programınızın gereksinimlerine bağlı olarak değerlendirmeniz gereken bir şeydir.
Vision kodu, robot kodunun kullandığı sonuçları üretir. Bir görüş dizisinden değer alan robot kodu yazarken senkronizasyon sorunlarına dikkat edin. GRIP tarafından üretilen kod ve WPILib'deki VisionRunner sınıfı bunu daha kolay hale getirecektir.
Video akışı kamera operatörü arayüzünü kullanarak SmartDashboard'a gönderilebilir, böylece operatörler kameranın gördüklerini görebilir. Buna ek olarak, OpenCV komutlarını kullanarak görüntülere ek açıklamalar ekleyebilirsiniz, böylece kontrol panelinde hedefler veya diğer ilginç nesneler tanımlanabilir.
DS bilgisayarında vision kodu
Görüntü, işlem yapmak için Driver Station dizüstü bilgisayarına geri akışa alınmıştır. Classmate dizüstü bilgisayarlar vision işlemede roboRIO'dan daha hızlıdır fakat üzerinde çalışan gerçek zamanlı programlara sahip değildir. GRIP, dizüstü bilgisayarında doğrudan NetworkTables kullanarak robota gönderilen sonuçlarla birlikte çalıştırılabilir. Alternatif olarak, kendi vision programınızı seçtiğiniz bir dili kullanarak yazabilirsiniz. Yerel bir NetworkTables uygulaması ve OpenCV bağlantısı çok iyi olduğundan Python iyi bir seçimdir.
Görüntüler işlendikten sonra, hedef konum, mesafe veya ihtiyacınız olan herhangi bir şey gibi anahtar değerler, NetworkTables ile robota geri gönderilebilir. Gecikme sizler için bir sorun olabilir çünkü dizüstü bilgisayardaki görüntülerde gecikmeler ve sonuçların geri gelmesi biraz zaman alabilir.
Görüntü akışı SmartDashboard veya GRIP'de görüntülenebilir.
Bir işlemci üzerinde vision kodu
Raspberry PI veya Kangaroo gibi iş süreçleri, görüntü kodunun desteklenmesi için idealdir. Avantajı, tam hız çalıştırabilmeleri ve robot programına müdahale etmemeleridir. Bu durumda, kamera büyük olasılıkla işlemciye(Raspberry pi vb.) veya (ethernet kamera kullanıyorsanız) robotun üzerindeki bir ethernet girişine bağlanır. Program, herhangi bir dilde yazılabilir, ancak OpenCV ve NetworkTable'lar için basit bağlantılardan dolayı Python iyi bir seçimdir. Bazı takımlar ve deneyimsiz programcılar için çok karmaşık olabilse de, Nvidia Jetson gibi işlemciler en yüksek hız ve en yüksek çözünürlük için yüksek performans sağlayabilmesi için kullanılabilir.
Veri, ağ işlemcisi üzerindeki vision programından, NetworkTables veya seri bağlantı üzerinden özel bir protokol kullanılarak robota gönderilebilir.
WPILib tarafından desteklenen bir dizi kamera seçeneği vardır. Kameralar, nasıl çalıştığını belirleyebilecek bir dizi parametreye sahiptir. Örneğin, kare hızı ve görüntü çözünürlüğü, alınan görüntülerin kalitesini etkiler, ancak çok yüksek etkili işlem süresi , robot programınızda ciddi etkiye sahip olabilecek bant genişliğinin oluşmasını sağlar.
2017'de yeni olan, C ++ ve Java'da mevcut olan ve robota bağlı kameralarla arayüz sağlayan bir CameraServer sınıfı var. Bir Kaynak nesnesi aracılığıyla yerel işlem için görüntüler alır ve orada görüntülemek veya işlem yapmak için akışınızı sürücü istasyonunuza gönderir. Video akışı CameraServer tarafından işlenir.
WPILib ile kameraların kullanımı ile ilgili detaylar bir sonraki bölümde detaylandırılmıştır.
Kavramlar
Genellikle FRC'de kullanılan kameralar (Axis kamera gibi USB ve Ethernet kameraları) nispeten sınırlı çalışma modları sunar. Genel olarak, tek bir çözünürlük ve kare hızında yalnızca tek bir görüntü çıktısı (tipik olarak JPG gibi sıkıştırılmış biçimde bir RGB görüntüsü ) sağlarlar. USB kameralar, sadece birden fazla uygulama kameranıza aynı anda erişemeyeceği için sınırlıdır.
2017 CameraServer çoklu kameraları destekler. Bir kamera bağlantısı kesildiğinde otomatik olarak yeniden bağlanma gibi ayrıntıları ele alır ve aynı zamanda kameranın sunduğu görüntüleri çoklu "istemciler" haline getirir (örn. Hem robot kodunuz hem de gösterge panosu kameranıza aynı anda bağlanabilir).
CameraServer'daki her kamera benzersiz bir şekilde adlandırılmalıdır. Bu ayrıca, Panodaki kamera için görünen addır. CameraServer startAutomaticCapture () ve addAxisCamera () işlevlerinin bazı türevleri otomatik olarak kamerayı (ör. "USB Camera 0" veya "Axis Camera") adlandırır veya kameraya daha açıklayıcı bir ad verebilirsiniz (örn. "Intake Cam"). Tek gereksinim, her kameranın kendine özgü bir adı olmasıdır.
CameraServer ile CPU Kullanımı, gerektiğinde sadece sıkıştırma ve açma işlemlerini gerçekleştirerek , herhangi bir istemci bağlı olmadığında akışı otomatik olarak devre dışı bırakarak CPU kullanımını en aza indirecek şekilde tasarlanmıştır.
CPU kullanımını en aza indirmek için, gösterge paneli çözünürlüğü kamerayla aynı çözünürlüğe ayarlanmalıdır; Bu, CameraServer'ın görüntüyü sıkıştırmasını ve yeniden sıkıştırmasını sağlamaz, bunun yerine resim gösterge panelinden alınan JPEG görüntüsünü doğrudan panoya iletebilir. Kontrol panelindeki çözünürlüğü değiştirmenin * kamera çözünürlüğünü değiştirmediğini unutmayın. kamera çözünürlüğünü değiştirmek, NetworkTables üzerinden veya robot kodunuzda (kamera nesnesinde setResolution öğesini çağırarak) yapılabilir.
Roborio, USB arabirimleri üzerinden tek seferde çok fazla veri iletebilir ve alabilir. Kamera görüntüleri çok fazla veri gerektirebilir ve bu yüzden bant genişliği limitini aşmak nispeten kolaydır. Bir USB bant genişliği hatasının en yaygın nedeni, özellikle birden çok kamera bağlı olduğunda, JPEG olmayan bir video modunun seçilmesi veya çok yüksek çözünürlükte çalışmasıdır.
2017 için CameraServer iki katmandan, yüksek seviyeli WPILib CameraServer sınıfından ve düşük seviyeli cscore kitaplığından oluşmaktadır.
CameraServer sınıfı (WPILib'in bir parçası) robot kodunuza kamera eklemek için yüksek düzeyde bir arabirim sağlar. Ayrıca kameralar ve kamera sunucuları hakkındaki bilgileri NetworkTable'lara yayınlamaktan sorumludur, böylece LabView Dashboard ve SmartDashboard gibi Sürücü İstasyonu kontrol panelleri kameraları listeleyebilir ve akışlarının nerede bulunduğunu belirleyebilir. Oluşturulan tüm kameraların ve sunucuların bir veritabanını korumak için tek bir desen kullanır.
CameraServer'daki bazı temel işlevler şunlardır:
startAutomaticCapture (): Bir USB kamera (ör. Microsoft LifeCam) ekleyin ve bunun için bir sunucu başlatır, böylece panodan görüntülenebilir.
addAxisCamera (): Bir axis kamerası eklemek için kullanılır. Robot kodunuzda Axis kameranın görüntülerini işlemiyor olsanız bile, bu işlevi Axis kamerasının Pano'nun açılır menü listesinde görünmesi için kullanabilirsiniz. Aynı zamanda bir sunucu başlatır, böylece sürücü istasyonunuz USB üzerinden roboRio'ya bağlandığında axis akışı hala görüntülenebilir (hem Axis kameranız hem de iki robot radyo Ethernet portuna bağlı roboRio varsa yarışmada kullanışlıdır).
getVideo (): Bir kameraya OpenCV erişimi edinin. Bu, roboRio'da (robot kodunuzda) görüntü işleme için kameradan görüntüler almanızı sağlar.
Cscore kütüphanesi alt seviye uygulamasına aşağıdakileri sağlar:
USB ve HTTP (örneğin, axis kamera) kameralarından görüntüler alın
Kamera ayarlarını değiştir (ör. Kontrast ve parlaklık)
Kamera video modlarını değiştir (piksel formatı, çözünürlük ve kare hızı)
Bir web sunucusu olarak hareket edin ve görüntüleri standart bir M-JPEG akışı olarak sunun
Kaynaklar ve Havuz
Cscore kütüphanesinin temel mimarisi, kaynaklarla havuzlar arasında bölünmüş işlevselliğe sahip MJPGStreamer'inkine benzer. Aynı anda oluşturulmuş ve çalışan birden çok kaynak ve çoklu havuz olabilir.
Görüntü üreten bir nesne bir kaynaktır ve görüntüleri kabul eden / tüketen bir nesne bir havuzdur. Üretmek / tüketmek kütüphanenin perspektifinden. Böylece kameralar kaynaklardır (görüntü üretirler). MJPEG web sunucusu bir havuzdur çünkü program içindeki görüntüleri kabul eder (bu görüntüleri bir web tarayıcısına veya kontrol paneline yönlendiriyor olabilir). Kaynaklar birden fazla havuza bağlanabilir, ancak havuzlar tek bir kaynağa bağlanabilir. Bir kaynağa bağlandığında, cscore kütüphanesi her bir görüntüyü kaynağından havuza geçirmekten sorumludur.
Kaynaklar çerçeveler elde eder (örneğin USB kamerasından görüntü alır) ve yeni bir çerçeve mevcut olduğunda herhangi bir olayı tetikler. Hiçbir havuz belirli bir kaynağı dinlemiyorsa, işlemciyi ve G / Ç kaynaklarını kaydetmek için bir işlemi duraklatabilir veya bağlantısını kesebilir. Kütüphane, olayların tetiklenmesini ve durdurulmasını sağlayarak kamera bağlantılarını / yeniden bağlanmalarını özerk olarak yönetir.
Havuzlar belirli bir kaynağın olayını dinler, en son görüntüyü yakalar ve hedefine uygun biçimde iletir. Kaynaklara benzer şekilde, belirli bir havuz devre dışı ise (ör. İstemci HTTP sunucusu üzerinden yapılandırılmış bir M-JPEG'e bağlı değildir), kütüphane, işlemci kaynaklarını kaydetmek için işlemin bazı bölümlerini devre dışı bırakabilir.
Kullanıcı kodu (bir FRC robot programında kullanılanlar gibi), OpenCV kaynağı ve dağıtma nesneleri aracılığıyla bir kaynak (bir fotoğraf makinesiymiş gibi işlenmiş çerçeveler sağlar) veya bir havuz (işleme için bir çerçeve alır) olarak işlev görebilir. Böylece, bir kameradan görüntü alan ve işlenen görüntüleri dışarıdan görüntüleyen bir görüntü işleme hattı aşağıdaki gibi görünür:
UsbCamera (VideoSource) --> (cscore internal) --> CvSink (VideoSink)
--> (your OpenCV processing code) --> CvSource (VideoSource)
--> (cscore internal) --> MjpegServer (VideoSink)
Kaynaklar bağlı birden fazla havuza sahip olduğundan, bu hat daha fazla alt işleme ayrılabilir. Örneğin, orijinal kamera görüntüsü, UsbCamera kaynağının CvSink'e ek olarak ikinci bir MjpegServer havuzuna bağlanmasıyla da sunulabilir, sonuçta aşağıdaki grafik elde edilir:
UsbCamera --> CvSink --> (your code) --> CvSource --> MjpegServer [2]
\-> MjpegServer [1]
Kamera tarafından yeni bir görüntü yakalandığında, hem CvSink hem de MjpegServer [1] bunu alır.
Yukarıdaki grafik, aşağıdaki CameraServer snippet'inin yarattığı grafiktir:
// UsbCamera ve MjpegServer [1] oluşturur ve bunları bağlar
CameraServer.getInstance().startAutomaticCapture()
// CvSink'i oluşturur ve UsbCamera CvSink'e bağlar. CvSink =CameraServer.getInstance().getVideo()
// CvSource ve MjpegServer [2] 'yi oluşturur ve bunları CvSource outputStream = ile bağlar. CameraServer.getInstance().putVideo("Blur", 640, 480);
CameraServer uygulaması, cscore seviyesinde aşağıdakileri etkin bir şekilde yapar (açıklama amacıyla). CameraServer, tüm cscore nesnelerine benzersiz isimler oluşturma ve otomatik olarak port numaralarını seçme gibi birçok ayrıntıya dikkat çeker. Ayrıca CameraServer oluşturulmuş nesnelerin tekil kayıtlarını tutar, böylece kapsam dışına çıkarlarsa yok olmazlar.
UsbCamera usbCamera = new UsbCamera("USB Camera 0", 0);
MjpegServer mjpegServer1 = new MjpegServer("serve_USB Camera 0", 1181);
mjpegServer1.setSource(usbCamera); CvSink cvSink = new CvSink("opencv_USB Camera 0");
cvSink.setSource(usbCamera);
CvSource outputStream = new CvSource("Blur", PixelFormat.kMJPEG, 640, 480, 30);
MjpegServer mjpegServer2 = new MjpegServer("serve_Blur", 1182);
mjpegServer2.setSource(outputStream);
Referans sayımı
Tüm cscore nesneleri dahili olarak referans sayılır. Bir havuzun kaynağa bağlanması kaynağın referans sayısını artırır, bu nedenle havuzu kapsam dahilinde tutmak kesinlikle gereklidir. CameraServer sınıfı, CameraServer işlevleriyle oluşturulmuş tüm nesnelerin bir kaydını tutar, bu şekilde oluşturulan kaynaklar ve havuzlar etkin bir şekilde kapsam dışında kalmaz (açıkça kaldırılmadıkça).
2017 LabVIEW Vizyon Örneği, diğer LabVIEW örnekleriyle birlikte sunulmuştur. Açılış ekranından, Destek -> FRC Örneklerini Bul'u veya başka herhangi bir LabVIEW penceresini tıklayın, Help->Find Examples tıklayın ve 2017 Vision Örneğini bulmak için Vision klasörünü bulun. Örnek görüntüler örnekle birlikte paketlenmiştir.
C++/Java
Daha eksiksiz bir örnek yakında geliyor.
Şimdilik, bir GRIP projesini ve aşağıdaki açıklamayı ve
GRIP tarafından oluşturulan kodun robot programınıza entegre edilmesiyle ilgili ayrıntılar burada:
GRIP projesi tarafından oluşturulan kod, bu ZIP'in Görsel Görüntüler klasöründe bulunanlar gibi resimlerdeki yeşil parçacıklar için OpenCV konturlarını bulacaktır. Burada, hedef olup olmadığını değerlendirmek için bu konturları daha fazla işlemek isteyebilirsiniz. Bunu yapmak için:
Sınırların etrafında sınırlayıcı dikdörtgenler çizmek için boundingRect yöntemini kullanın
LabVIEW örnek kodu, hedef için 5 ayrı oran hesaplar. Bu oranların her biri, nominal olarak 1.0'a eşit olmalıdır. Bunu yapmak için, konturları boyutlarına göre sıralar, sonra en büyük ile başlayarak, bu değerler, hedef olabilecek her bir çift kontür için hesaplar ve bir hedef bulduğunda veya bulduğu en iyi çifti döndürürse durur.
Aşağıdaki formüllerde, bir harfin ardından bir harf, birinci konturun sınırlayıcı rektininin koordinatını ifade eder, ki bu, ikiden daha büyük olan (örneğin, 1L = 1. kontur sol kenar) ve bir harfle 2, 2 konturdur. (H = Yükseklik, L = Sol, T = Üst, B = Alt, W = Genişlik)
Grup Yüksekliği = 1H / ((2B - 1T) * .4) Üst yükseklik toplam yüksekliğin% 40'ı (4 inç / 10 inç) olmalıdır.
dTop = (2T - 1T) / ((2B - 1T) * .6) Üstteki şeridin tepesine kadar toplam yüksekliğinin% 60'ı (6 inç / 10 inç) olmalıdır.
LEdge = ((1L - 2L) / 1W) + 1 Kontürün (1) sol kenarı ile konturun (2) sol kenarı arasındaki mesafe, 1. konturun genişliğine göre küçük olmalıdır.o zaman, oranın ortalanmasını sağlamak için 1 ekliyoruz.
Bu oranların her biri daha sonra hesaplanarak 0-100 arasında bir değere dönüştürülür: 100 - (100 * abs (1 - Val))
Mesafeyi belirlemek için, üst sınırlayıcı kutunun üstünden pikselleri alt sınırlayıcı kutunun altına ölçün
distance = Hedef yükseklik ft. (10/12) YRes / (2 PixelHeight * tan (kamera görünümü))
LabVIEW örneği, yuvarlak hedefin kenarlarının algılamadaki gürültüye en fazla maruz kalması nedeniyle yüksekliği kullanır (kameradan daha fazla olan açı noktaları daha az yeşil gözüktüğü için). Bunun dezavantajı, görüntüdeki hedefin piksel yüksekliğinin kamera açısının perspektif bozulmasından etkilenmesidir. Olası düzeltmeler şunları içerir:
Bunun yerine instead kullanmayı deneyin
Çeşitli mesafelerde ölçüm yapın ve bir lookup tablosu veya regresyon fonksiyonu oluşturun
Kamerayı bir servoya monte edin, görüntüde dikey olarak hedefi ortalayın ve mesafe hesaplaması için servo açısını kullanın (kendinize uygun bir şekilde çalışmanız veya bir matematik öğretmeni bulmanız gerekir!)
OpenCV kullanarak perspektif bozulmasını düzeltin. Bunu yapmak için kameranızı OpenCV ile burada açıklandığı şekilde kalibre etmeniz gerekecektir:
putVideo (): OpenCV görüntülerini besleyebileceğiniz bir sunucu başlatın. Bu, özel işlenmiş ve / veya açıklamalı görüntüleri panoya aktarmanıza olanak tanır.
Görüntü işleme için görüntüleri OpenCV "Mat" nesnelerine dönüştürün
Yükseklik oranı = 1H / (2H * 2) Daha büyük şerit, daha küçük olandan iki kat daha uzun olmalıdır.
pip install pillow
pip install opencv-python
pip install pynetworktables
pip install imutils
Kodunuzu yazıp kaydettikten sonra çalıştırmak için konsoldan şu komutu girmeniz gerekmektedir:
python yazilimadi.py
Kütüphaneleri import edin
Class'ınızın altına networktables'i tanımlayın
Değerleri okumak için 2 tane void oluşturalım.
Değerleri SmartDashboard'a yazdıralım.
Motorlarımız Değerlere göre haraket ettirelim!
Kodların tamamına buradan ulaşabilirsiniz :
Artık robotunuzu enable ettiğinizde , yazılımımızı çalıştırdığımızda değerler otomatik olarak SmartDashboard'a düşmeye başlayacaktır.
import edu.wpi.first.wpilibj.networktables.NetworkTable; // Networktables kütüphanesi
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; // smartdashboardan verileri görmek için
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;Limelight, FIRST Robotik Yarışması için özel olarak tasarlanmış bir tak-çalıştır akıllı kameradır . Vision Processing tecrübesi gerektirmez. Vision deneyimi olmayan veya yeterli seviyede mentör hocaları olmayan takımlar için Limelight yeterince kolaydır. Vision processing'e ihtiyaç duyan takımlar için bir alternatiftir.
Limelight'ınızı monte etmek için nylock somunlarıyla birlikte dört adet 1/4 ”10-32 vida kullanın.
Not : Limelight bir 12V giriş alır, ancak 6V'a kadar çalışacak şekilde üretilmiştir. LED'leri 7V'a kadar sabit bir parlaklığa sahiptir.
Voltaj Regülatörü Modülü ile kullanmayın!
Limelight iki kablonnuzu PDP'nizdeki herhangi bir yuvaya geçirin.
herhangi bir sigortayı (5A, 10A, 20A, vb.) PDP'deki Aynı yuvaya ekleyin.
Limelight'ınızdan bir ethernet kablosunu robot radyonuza bağlayın.
Windows7 kullanmayın.
Güç kaynağınızdan çıkarın.
En güncel flash aracını ve image 'ndan indirin.
Flash aracını kurun.
Güvenilirlik için statik bir IP adresi almamıza rağmen, bazı ekipler dinamik olarak atanan IP adreslerini tercih eder.
Statik IP Adresi (önerilir)
Bonjour'u adresinden yükleyin
Robotunuza güç verin ve dizüstü bilgisayarınızı robotunuzun ağına bağlayın.
Limelight'ınızın LED dizisini yaktıktan sonra, http: //limelight.local:5801'e gidin. Burası Limelight yönetim Paneli
"Networking" sekmesine gidin.
Şimdilik, sadece kameradan robotunuza veri almamız gerekiyor. 100hz'de Ağ Tablolarına veri hedefleyen Limelight yayınları. NetworkTable'lar için varsayılan güncelleme hızı 10hz'dir, ancak Limelight daha sık veri aktarımına izin vermek için otomatik olarak üzerine yazar.
Başlamak için, “limelight” Ağ Tablosundan en az 100hz'de dört değer okumayı öneririz. Kod örneklerimiz bunu nasıl yapacağınızı tam olarak gösterir. Hedefinize olan uzaklıklar (derece olarak) “tx” ve “ty” olarak gönderilir. Bunlar robotunuzu döndürmek, tareti çevirmek vb. İçin kullanılabilir. Hedef alan, “ta” olarak gönderilir, hedefinize uzak bir mesafe göstergesi olarak kullanılabilir. Alan, 0 ile 100 arasında bir değerdir, burada 0, hedefinizin gövde alanı, toplam görüntü alanının% 0'ı anlamına gelir ve 100, hedefinizin gövdesinin tüm görüntünün dolduğu anlamına gelir. Hedefinizin dönüşü veya “eğilmesi” “ts” olarak döndürülür. Tüm değerler sıfıra eşitse, hedef yoktur.
Ek olarak, NetworkTables'taki değerleri ayarlayarak belirli özellikleri kontrol edebilirsiniz.
“Limelight” tablosundan aşağıdakileri okuyabilirsiniz:
Aşağıdakileri “limelight” tablosuna yazabilirsiniz :
Bunları import etmeyi unutmayın :
Labview:
C++
Python
Java Hedef Hizalama
import numpy as np
from PIL import ImageGrab
from collections import deque
from networktables import NetworkTables
import cv2
import time
import imutils
import argparse
import cv2 as CV
x = 0 #programın ileride hata vermemesi için x 0 olarak tanımlıyorum
y = 0 # programın ileride hata vermemesi için y 0 olarak tanımlıyorum
NetworkTables.initialize(server='roborio-6025-frc.local') # Roborio ile iletişim kuruyoruz
table = NetworkTables.getTable("Vision") # table oluşturuyoruz
#sari rengin algilanmasi
colorLower = (24, 100, 100)
colorUpper = (44, 255, 255)
#converter.py ile convert ettiğiniz rengi buraya giriniz
def screen_record():
x = 0
y = 0
r = 0
last_time = time.time()
while(True):
# 800x600 windowed mode
printscreen = np.array(ImageGrab.grab(bbox=(0,40,1024,768)))
print('Tekrarlanma süresi : {} saniye'.format(time.time()-last_time))
last_time = time.time()
frame = printscreen
frame = imutils.resize(frame, width=600)
frame = imutils.rotate(frame, angle=0)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, colorLower, colorUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)[-2]
center = None
if len(cnts) > 0:
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
if radius > 10:
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
else:
x = 0
y = 0
print("x : ")
print(x)
print("y : ")
print(y)
table.putNumber("X", x) # roborioya değeri göndermek
table.putNumber("Y", y) # roborioya değeri göndermek
cv2.imshow('frame', frame)
cv2.waitKey(1)
screen_record() public static NetworkTable table1 = NetworkTable.getTable("Vision"); // vision adında table çekiliyorpublic static double konumX()
{
return table1.getNumber("X", 0.0); //raspberry pi den gelen x kordinatları
}
public static double konumY()
{
return table1.getNumber("Y", 0.0); //raspberry pi den gelen y kordinatları
} public void teleopPeriodic() {
SmartDashboard.putNumber("Nesnenin X konumu: ", konumX()); // smartdashboarda x konumu yazdır
SmartDashboard.putNumber("Nesnenin Y konumu: ", konumY()); // smartdashboarda y konumunu yazdır
}public void autonomousPeriodic() {
if(konumX() == 0)
{
sagmotor1.set(0);
sagmotor2.set(0);
solmotor1.set(0);
solmotor2.set(0);
}
else if(konumX() < 285) // degerler 285'ten kucukse saga don
{
sagmotor1.set(0.5); // sag motorları calistir
sagmotor2.set(0.5);
}
else if (konumX() > 295) // degerler 295'ten buyukse sola don
{
solmotor1.set(0.5); //sol motorlari calistir
solmotor2.set(0.5);
}
}Dizüstü bilgisayarınızdan bir USB-MicroUSB kablosuyla ışığınızı ayarlayın.
Limelight'e güç verin.
Windows arama çubuğundan “Limelight Flash Tool” uygulamasını çalıştırın. Ayrıca, başlangıç menüsü uygulamaları klasörünün altındaki “Limelight” klasörünün altında görünecektir.
Windows'un kamerayı tanıması 20 saniye kadar sürebilir. Sonraki tüm Windows diyaloglarında “iptal” tuşuna basın.
İndirilenler klasörünüzdeki en son .zip dosyasını seçin
“Limelights” menüsünde bir “RPI” cihazı seçin
“Flash” a tıklayın
Bir kez yanıp sönme tamamlandığında, güç kaynağınızdaki gücü kaldırın
Takım numaranızı girin.
“IP Assignment” ınızı “Static” olarak değiştirin.
Limelight'ın IP adresini “10.TE.AM.11” olarak ayarlayın.
Ağ Maskesini “255.255.255.0” olarak ayarlayın.
Ağ Geçidini “10.TE.AM.1” olarak ayarlayın.
Update butonuna basın.
Robotunuza güç verin.
Artık http://10.TE.AM.11:5801 adresindeki yönetim panelinize ve kamera akışınıza http://10.TE.AM.11:5800 adresinden erişebileceksiniz.
tv
Limelight'ın geçerli herhangi bir hedefi olup olmadığı (0 veya 1)
tx
Crosshair'den Hedefe Yatay Ofset (-27 derece ila 27 derece)
ty
Crosshair'den Hedefe Dikey Ofset (-20.5 derece ila 20.5 derece)
ta
Hedef Alan (görüntünün% 0'ı görüntünün% 100'ü)
ts
yamukluk veya açı (-90 derece 0 derece)
tl
Gecikme süresi (ms) Görüntü yakalama gecikmesi için en az 11ms ekleyin.
ledMode
Led Durumunu Ayarlama
0
Aç
1
Kapat
2
Aç Kapa(Blink)
camMode
Limelight Çalışma Modunu Ayarlama
0
Görüntü işlemeyi etkinleştir
1
Sürücü kamerası ( Görüntü işlemeyi durdurur)
pipeline
Limelight'in pipeline hattını ayarlar
0 .. 9
0 ile 9 arasında bir seçim yapabilirsiniz.


Raspberry Pi İle Pixy Kullanımı içeriğinde sağladığı kaynaklar için #6025 Adroit Anroids takımına teşekkürler!
Pixy, nesneleri en hızlı şekilde tanıtarak onları bulmak için tasarlanmış bütünleşik bir kamera modülü diyebiliriz. Üzerinde NXP Firmasının LPC4330 Çift çekirdekli mikrodenetleyici, 204Mhz de çalışan 32bit ARM Cortex-M4 ün yanında ayrıca 204Mhz de çalışan 32bit ARM Cortex-M0 işlemcisi bulunmakta.Nesneleri tanıtmak için yapmanız gereken tek şey, nesneyi kameraya gösterip üzerinde bulunan butona basmak. Modül, turuncu, sarı, kırmızı, mavi, açık mavi, yeşil ve mor olmak üzere 7 rengi tanıyabiliyor. (kaynak : https://www.robimek.com/nesnelerin-rengini-ve-konumunu-algilayan-pixy-kamera-modul/)
İşlemci: NXP LPC4330, 204 MHz, dual core Görüntü Sensörü: Omnivision OV9715, 1/4″, 1280×800 Lens Görüş Alanı: 75 degrees horizontal, 47 degrees vertical Lens Tipi: standard M12 (several different types available) Güç Tüketimi: 140 mA typical Güç Girişi: USB input (5V) or unregulated input (6V to 10V) RAM: 264K bytes Flaş: 1M bytes Kullanılabilir Veri Çıktıları: UART serial, SPI, I2C, USB, digital, analog Boyutlar: 2.1″ x 1.75″ x 1.4″
Bir megapixel çözünürlüğe sahip sensör, 60FPS’de 640×400(WXGA), 30FPS de ise 1280×800(WXGA) çözünürlükte resim alabiliyor.
Pixy Modülün Kullanımı ve Ayarları
Pixy wiki sayfasını açın >>
Wiki sayfasında PixyMon adlı programı işletim sisteminize uyumlu linkten indirin.
Pixy ‘ye nesne tanıtma işlemini iki şekilde yapabilirsiniz. Birincisi PixyMon programı ile ekrandan fare ile nesneyi seçerek, ikincisi ise modül üzerinde bulunan butona basarak nesneyi tanıtabilirsiniz.
1.Adım: Şimdi öğretmek istediğiniz nesneyi Pixy’nin önünde tutun ve açılan menüden Action-> Set signature 1‘i seçin.
2.Adım: Fareyi kullanarak, Pixy’nin nesneyi öğrenmek için kullanmasını istediğiniz bölgeyi seçmek için tıklatın ve sürükleyin.
3.Adım: Bölgeyi seçtikten sonra, Pixy, nesnenizi öğrenir ve otomatik olarak video moduna girer, böylece renk imzanızın ne kadar iyi çalıştığını doğrulayabilirsiniz.
Pixy, nesneyi daha net hatlarıyla tanıması için birkaç ayar yapılmalıdır. Dişli çark simgesini tıklayın ve Pixy Parameters altındaki Signature Tuning bölmesini seçin.
Signature 1 kısmından uygun görünümü yakalayana kadar değerleri değiştirin.
Tüm imza için algılama doğruluğunu en üst düzeye çıkarmak için yedi renk imzasını bu şekilde ayarlayabilirsiniz. Kaydırıcı aralıklarını kaydetmek için Uygula’ya veya Tamam’a basmayı unutmayın! Ayarlamış olduğunuz değerler, İptal düğmesine basarsanız veya iletişim kutusunu kapattığınızda kaydedilmeyecektir.
Pixy ‘nin en avantajlı yönlerinden biri üzerinde bulunan butona basarak nesneyi tanıtabiliyoruz. Modüle enerji verin. Önünde bulunan rgb led beyaz yandıktan sonra sönecektir. Söndükten sonra tanıtmak istediğimiz nesneyi kameraya gösterin ve butonu yaklaşık 1.5 saniye basılı tutun. Önünde bulunan ledin beyaz yandığını göreceksiniz. Bu durum modülün öğrenme modunu aktif ettiği anlamına gelir. Basılı tuttuğunuz sürece ledin rengi kırmızı, turuncu, sarı, açık mavi, mavi, mor şeklinde yanmaya devam eder ve tekrar beyaz renge dönerek tekrarlar. Bu renkler pxymoon programındaki Set Signature 1, Set Signature 2, Set Signature 3, Set Signature 4, Set Signature 5, Set Signature 6, Set Signature 7 adet öğrenme hafızasını temsil eder. Şimdi led renk değiştirirken butonu bıraktığınız anda hangi renk yanıyorsa o rengin karşılığı olan öğrenme hafızasına kaydeder. Örnek verecek olursak, turuncu renk yandığında butonu bırakırsanız ledin rengi kamera önüne koyduğunuz cismin rengine döner ve butona tekrar basıp bıraktığınızda led parlak bir şekilde turuncu flaş yaparak 2. hafıza bölgesine kayıt olur. Bu şekilde diğer hafıza bölgelerine de cisim kaydedebilirsiniz.
Pixy doğrudan Roborio'ya bağlanamaz. Çünkü Pixy kütüphaneleri Roborio'yu desteklememektedir. FRC'de Pixy kullanabilmek için 2 yol vardır.
Pixy Raspberry pi ile çalıştırıp verileri networktables ile Roborio 'ya aktarmak..
Pixy Arduino ile çalıştırıp verileri I2c portu veya SPI portu ile Roborio 'ya aktarmak.
Yani Pixy donanımını tek başına kullanamazsınız. Eğer Pixy kullanmak istiyorsanız 1 adet Raspberry Pi veya Arduino 'ya ihtiyacınız vardır.
Python SWIG modülü oluşturmak için bağımlılıkları kurun
Bir uçbirim penceresine şunu yazın:
sudo apt-get install swig
Libusb-1.0-0-dev'i kurun.
sudo apt-get install libusb-1.0-0-dev
G ++ (derleyici) yükleyin.
sudo apt-get install g++
Libboost'u yükleyin.
sudo apt-get install libboost-all-dev
Pixy kaynak kodunu indirin.
git clone https://github.com/charmedlabs/pixy.git
Python modülünü oluşturun.
cd pixy/scripts
./build_libpixyusb_swig.sh
Kodun olduğu dizine gidin.
cd ../build/libpixyusb_swig
Ardından wget komutu ile Pixy kodlarımızı indirelim.
Artık kodlarınız hazır. Kodlarınızı python pixy.py komutuyla çalıştırabilirsiniz.
Kütüphaneleri import edin
Class'ınızın altına networktables'i tanımlayın
Değerleri okumak için 2 tane void oluşturalım.
Değerleri SmartDashboard'a yazdıralım.
Motorlarımız Değerlere göre haraket ettirelim!
Kodların tamamına buradan ulaşabilirsiniz :
Artık Pixy yazılımınızı Raspberry Pi 'den çalıştırdığınızda robotunuz otomatik olarak roborio ile haberleşmeye başlayacaktır.

NetworkTable table = NetworkTableInstance.getDefault().getTable("limelight");
NetworkTableEntry tx = table.getEntry("tx");
NetworkTableEntry ty = table.getEntry("ty");
NetworkTableEntry ta = table.getEntry("ta");
double x = tx.getDouble(0);
double y = ty.getDouble(0);
double area = ta.getDouble(0);import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;std::shared_ptr<NetworkTable> table = NetworkTable::GetTable("limelight");
float targetOffsetAngle_Horizontal = table->GetNumber("tx");
float targetOffsetAngle_Vertical = table->GetNumber("ty");
float targetArea = table->GetNumber("ta");
float targetSkew = table->GetNumber("ts");from networktables import NetworkTables
table = NetworkTables.getTable("limelight")
tx = table.getNumber('tx',None)
ty = table.getNumber('ty',None)
ta = table.getNumber('ta',None)
ts = table.getNumber('ts',Noneif (limelight.angleOffset > 10) { // eğer hedef solda kalıyorsa
RightMotorMaster.setPower(0.30); // 30% throttle
LeftMotorMaster.setPower(-0.30); // -30% throttle
} else if (limelight.angleOffset < -10) { // Eğer Hedef Sağda Kaalıyorsa
RightMotorMaster.setPower(-0.30); // -30% throttle
LeftMotorMaster.setPower(0.30); // 30% throttle
} else {
// Robot hizalanmış yavaşça ileri gidin
RightMotorMaster.setPower(0.30); // 30% throttle
LeftMotorMaster.setPower(0.30); // 30% throttle
}wget https://raw.githubusercontent.com/enisgetmez/FRC-Vision-Processing/master/Pixy/pixy.pyimport edu.wpi.first.wpilibj.networktables.NetworkTable; // Networktables kütüphanesi
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; // smartdashboardan verileri görmek için
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; public static NetworkTable table1 = NetworkTable.getTable("Vision"); // vision adında table çekiliyorpublic static double konumX()
{
return table1.getNumber("X", 0.0); //raspberry pi den gelen x kordinatları
}
public static double konumY()
{
return table1.getNumber("Y", 0.0); //raspberry pi den gelen y kordinatları
} public void teleopPeriodic() {
SmartDashboard.putNumber("Nesnenin X konumu: ", konumX()); // smartdashboarda x konumu yazdır
SmartDashboard.putNumber("Nesnenin Y konumu: ", konumY()); // smartdashboarda y konumunu yazdır
}public void autonomousPeriodic() {
if(konumX() == 0)
{
sagmotor1.set(0);
sagmotor2.set(0);
solmotor1.set(0);
solmotor2.set(0);
}
else if(konumX() < 285) // degerler 285'ten kucukse saga don
{
sagmotor1.set(0.5); // sag motorları calistir
sagmotor2.set(0.5);
}
else if (konumX() > 295) // degerler 295'ten buyukse sola don
{
solmotor1.set(0.5); //sol motorlari calistir
solmotor2.set(0.5);
}
}














