Ana içeriğe geç

FTC Java & Blockly Programlama Rehberi

(Blockly ekran görüntüleri yakında!)

FTC Programlama Hızlı Başlangıç sayfasını okuduğunuzdan emin olun.

FTC Limelight Javadoc: Javadoc

Temel FTC Örneği: FTC Örneği

Tam Örnekler Deposu: Limelight FTC Örnekleri Deposu

Başarı İçin İpuçları

  • Önce basit olanı yapın. FRC'de, en iyi yazılım takımlarının genellikle en basit yaklaşımları kullandığını öğrendik. Örneğin, 2024'te FRC Takım 2056, oyun parçalarını takip etmek için sinir ağı yerine standart 90FPS renk pipeline'ı kullandı.

İşte programlamaya başlarken sormanız gereken soru türüne bir örnek: Teleop'ta, robotunuzun sahadaki konumunu bilmeniz mi gerekiyor, yoksa sadece nişangahınız belirli bir etiketin üzerinde ortalanana kadar yana kaymanız mı gerekiyor (strafeSpeed = result.getTx()*.03)?

Temel Kavramlar

1. Başlatma

Robot kodumuzda Limelight3A'mızı kurmamız gerekiyor.

import com.qualcomm.hardware.limelightvision.LLResult;
import com.qualcomm.hardware.limelightvision.LLResultTypes;
import com.qualcomm.hardware.limelightvision.LLStatus;
import com.qualcomm.hardware.limelightvision.Limelight3A;
Limelight3A limelight;

@Override
public void init() {
limelight = hardwareMap.get(Limelight3A.class, "limelight");
limelight.setPollRateHz(100); // Bu, Limelight'tan ne sıklıkla veri istediğimizi ayarlar (saniyede 100 kez)
limelight.start(); // Bu, Limelight'a bakmaya başlamasını söyler!
}

2. Pipeline Yönetimi

Pipeline'lar, Limelight'ın dünyaya nasıl baktığını değiştiren küçük, anında değiştirilebilir programlar gibidir. Limelight web arayüzünde her biri farklı bir görev için 10 farklı pipeline kurabilirsiniz. İşte aralarında nasıl geçiş yapacağınız:

limelight.pipelineSwitch(0); // 0 numaralı pipeline'a geç

Bu, ateşle ve unut şeklindedir. Limelight pipeline'ını milisaniyeler içinde değiştirecektir, ancak kodunuz devam etmeden önce bunu beklemeyecektir. Mevcut pipeline indeksini kontrol etmek istiyorsanız, şunu çağırın:

result.getPipelineIndex()

LLResult nesnesini almayı öğrenmek için sonraki bölüme bakın.

3. Sonuçları Alma ve Kullanma

LLResult, Limelight'ın gördükleri hakkında bilgi dolu bir kap gibidir. İşte bu bilgiyi nasıl alıp kullanacağımız:

LLResult result = limelight.getLatestResult();
if (result != null && result.isValid()) {
double tx = result.getTx(); // Hedefin ne kadar sola veya sağa olduğu (derece)
double ty = result.getTy(); // Hedefin ne kadar yukarı veya aşağı olduğu (derece)
double ta = result.getTa(); // Hedefin ne kadar büyük göründüğü (görüntünün %0-%100'ü)

telemetry.addData("Hedef X", tx);
telemetry.addData("Hedef Y", ty);
telemetry.addData("Hedef Alan", ta);
} else {
telemetry.addData("Limelight", "Hedef Yok");
}

4. Python SnapScript'lerle İletişim

Web arayüzünde kendi Python SnapScript pipeline'larınızı yazabilirsiniz. Kodunuzu yazmanıza yardımcı olması için LLM tabanlı SnapScript oluşturucumuzu kullanın.

İşte Robot Kodundan Python'a sayı gönderme ve geri alma yöntemi:

// Python'a sayı gönderme
double[] inputs = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
limelight.updatePythonInputs(inputs);

// Python'dan sayı alma
double[] pythonOutputs = result.getPythonOutput();
if (pythonOutputs != null && pythonOutputs.length > 0) {
double firstOutput = pythonOutputs[0];
telemetry.addData("Python çıktısı:", firstOutput);
}

5. Robotum Nerede? (MegaTag 1)

Limelight, AprilTag'leri kullanarak robotunuzun sahada nerede olduğunu bulmaya yardımcı olabilir. Limelight'ınız mevcut oyun için önceden yüklenmiş bir AprilTag Haritası ile gelir, ancak 3D Harita Oluşturucumuzu kullanarak kendi haritalarınızı tasarlayıp yükleyebilirsiniz.

Robotunuzun konumunu almaya çalışmadan önce şunları yapın:

  1. Web arayüzünde AprilTag pipeline'ınızın "Gelişmiş" sekmesinde "Full 3D"yi etkinleştirin.
  2. Kameranızı robotunuzun taban alanının merkezine göre konumlandırmak için web arayüzünü kullanın.

botPose için koordinat sistemi standart FTC koordinat sistemiyle eşleşir.

  • (0,0,0) saha zemininin merkezidir
  • Elmas olmayan konfigürasyonlar için, 0 derece Yaw, mavi ittifakın robotunuzun sol tarafında ve kırmızı ittifakın robotunuzun sağ tarafında olduğu anlamına gelir.
if (result != null && result.isValid()) {
Pose3D botpose = result.getBotpose();
if (botpose != null) {
double x = botpose.getPosition().x;
double y = botpose.getPosition().y;
telemetry.addData("MT1 Konum", "(" + x + ", " + y + ")");
}
}

6. Robotum Nerede? (MegaTag 2)

MegaTag 2, MegaTag 1 gibidir, ancak artan doğruluk için IMU verilerinizi birleştirir:

// Önce, Limelight'a robotunuzun hangi yöne baktığını söyleyin
double robotYaw = imu.getAngularOrientation().firstAngle;
limelight.updateRobotOrientation(robotYaw);
if (result != null && result.isValid()) {
Pose3D botpose_mt2 = result.getBotpose_MT2();
if (botpose_mt2 != null) {
double x = botpose_mt2.getPosition().x;
double y = botpose_mt2.getPosition().y;
telemetry.addData("MT2 Konum:", "(" + x + ", " + y + ")");
}
}

7. İç Sonuç Türleri

Pipeline'larınızı nasıl yapılandırdığınıza bağlı olarak, ana LLResults Nesnesi içinde farklı türde ayrıntılı Sonuç Listelerine erişiminiz olacaktır.

Muhtemelen bu Sonuç Listelerini kullanmanız gerekmeyecek. Mümkün olduğunda temel getTx(), getTy() kullanmanızı öneririz.

7.1 Renk Sonuçları

Renk sonuçları renkli hedefleri bulmaya yardımcı olur:

List<ColorResult> colorTargets = result.getColorResults();
for (ColorResult colorTarget : colorTargets) {
double x = detection.getTargetXDegrees(); // Nerede olduğu (sol-sağ)
double y = detection.getTargetYDegrees(); // Nerede olduğu (yukarı-aşağı)
double area = colorTarget.getTargetArea(); // boyut (0-100)
telemetry.addData("Renk Hedefi", "görüntünün %" + area + "'ini kaplıyor");
}

7.2 Fiducial/AprilTag Sonuçları

Fiducial'lar, Limelight'ın nerede olduğunu anlamasına yardımcı olan özel işaretlerdir (AprilTag'ler gibi):

List<FiducialResult> fiducials = result.getFiducialResults();
for (FiducialResult fiducial : fiducials) {
int id = fiducial.getFiducialId(); // Fiducial'ın ID numarası
double x = detection.getTargetXDegrees(); // Nerede olduğu (sol-sağ)
double y = detection.getTargetYDegrees(); // Nerede olduğu (yukarı-aşağı)
double StrafeDistance_3D = fiducial.getRobotPoseTargetSpace().getY();
telemetry.addData("Fiducial " + id, distance + " metre uzakta");
}

Her FiducialResult içindeki 3D poz bilgisini kullanmak istiyorsanız, aşağıdaki metodları kullanabilirsiniz:

fiducial.getRobotPoseTargetSpace(); // AprilTag Koordinat Sistemine göre robot pozu (En Kullanışlı)
fiducial.getCameraPoseTargetSpace(); // AprilTag'e göre kamera pozu (kullanışlı)
fiducial.getRobotPoseFieldSpace(); // Yalnızca bu etikete dayalı saha koordinat sistemindeki robot pozu (kullanışlı)
fiducial.getTargetPoseCameraSpace(); // Kameranın koordinat sistemindeki AprilTag pozu (çok kullanışlı değil)
fiducial.getTargetPoseRobotSpace(); // Robotun koordinat sistemindeki AprilTag pozu (çok kullanışlı değil)

7.3 Barkod Sonuçları

Limelight'ın barkod pipeline'ı QR Kodlarını algılama ve takip etmede iyidir.

List<BarcodeResult> barcodes = result.getBarcodeResults();
for (BarcodeResult barcode : barcodes) {
String data = barcode.getData(); // Barkodun ne söylediği
String family = barcode.getFamily(); // Ne tür bir barkod olduğu
telemetry.addData("Barkod", data + " (" + family + ")");
}

7.4 Sınıflandırıcı Sonuçları

Sinir Ağı Sınıflandırıcıları, Limelight'ın "Bence bu bir ... görüntüsü" demesini sağlar.

List<ClassifierResult> classifications = result.getClassifierResults();
for (ClassifierResult classification : classifications) {
String className = classification.getClassName(); // Limelight'ın gördüğünü düşündüğü şey
double confidence = classification.getConfidence(); // Güven Puanı
telemetry.addData("Görüyorum", className + " (%" + confidence + ")");
}

7.5 Dedektör Sonuçları

Dedektörler belirli nesneleri bulur ve nerede olduklarını söyler:

List<DetectorResult> detections = result.getDetectorResults();
for (DetectorResult detection : detections) {
String className = detection.getClassName(); // Ne algılandı
double x = detection.getTargetXDegrees(); // Nerede olduğu (sol-sağ)
double y = detection.getTargetYDegrees(); // Nerede olduğu (yukarı-aşağı)
telemetry.addData(className, "(" + x + ", " + y + ") derecede");
}

8. Veri Taze mi?

Bazen, sonuç verilerimizin yaşını (milisaniye cinsinden) bilmek isteriz.

long staleness = result.getStaleness();
if (staleness < 100) { // 100 milisaniyeden daha az eski
telemetry.addData("Veri", "İyi");
} else {
telemetry.addData("Veri", "Eski (" + staleness + " ms)");
}

9. Özel Saha Haritaları

Limelight'a belirli saha düzeninizi söyleyebilirsiniz:

LLFieldMap fieldMap = new LLFieldMap(); // Bunu saha verileriyle doldurmanız gerekecek
boolean success = limelight.uploadFieldmap(fieldMap, null); // null varsayılan slotu kullan demektir
if (success) {
telemetry.addData("Saha Haritası", "Başarıyla yüklendi!");
} else {
telemetry.addData("Saha Haritası", "Hay aksi, yükleme başarısız");
}

10. Anlık Görüntü Alma:

Limelight, saha dışında pipeline'ları hata ayıklamanıza yardımcı olmak için anlık görüntüler alabilir:

limelight.captureSnapshot("auto_pov_10s");

Web arayüzünün Giriş Sekmesinde, pipeline'larınızı kontrol etmek/ayarlamak için bu anlık görüntüyü "görüntü kaynağı" olarak seçebilirsiniz.

Eski anlık görüntüleri temizlemek için:

limelight.deleteSnapshots();
telemetry.addData("Anlık Görüntüler", "Hepsi temizlendi!");