मुख्य कंटेंट तक स्किप करें

FTC Java और Blockly प्रोग्रामिंग गाइड

(Blockly स्क्रीनशॉट जल्द आ रहे हैं!)

सुनिश्चित करें कि आपने FTC Programming Quick Start पढ़ लिया है।

FTC Limelight Javadoc: Javadoc

बेसिक FTC उदाहरण: FTC Sample

पूर्ण उदाहरण रिपॉजिटरी: Limelight FTC Examples Repo

सफलता के लिए टिप्स

  • पहले सरल चीज़ करें। FRC में, हमने सीखा है कि सबसे अच्छी सॉफ्टवेयर टीमें अक्सर सबसे सरल तरीकों का उपयोग करती हैं। उदाहरण के लिए, 2024 में FRC Team 2056 ने गेम पीस को ट्रैक करने के लिए न्यूरल नेटवर्क के बजाय एक स्टैंडर्ड 90FPS कलर पाइपलाइन का उपयोग किया।

यहाँ एक उदाहरण है कि प्रोग्रामिंग शुरू करते समय किस प्रकार के प्रश्न पूछने चाहिए: टेलीऑप में, क्या आपको फील्ड पर अपने रोबोट की स्थिति जानने की आवश्यकता है, या आपको बस तब तक स्ट्रेफ करना है जब तक आपका क्रॉसहेयर किसी विशिष्ट टैग पर केंद्रित न हो जाए (strafeSpeed = result.getTx()*.03)?

मुख्य अवधारणाएं

1. इनिशियलाइज़ेशन

हमें अपने रोबोट कोड में Limelight3A सेट अप करना होगा।

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); // यह सेट करता है कि हम Limelight से कितनी बार डेटा मांगते हैं (प्रति सेकंड 100 बार)
limelight.start(); // यह Limelight को देखना शुरू करने के लिए कहता है!
}

2. पाइपलाइन प्रबंधन

पाइपलाइन छोटे, तुरंत स्वैप करने योग्य प्रोग्राम की तरह हैं जो बदलते हैं कि Limelight दुनिया को कैसे देखता है। आप Limelight वेब इंटरफेस में 10 अलग-अलग पाइपलाइन सेट कर सकते हैं, प्रत्येक एक अलग कार्य के लिए। यहाँ बताया गया है कि आप उनके बीच कैसे स्विच करते हैं:

limelight.pipelineSwitch(0); // पाइपलाइन नंबर 0 पर स्विच करें

यह fire-and-forget है। Limelight कुछ मिलीसेकंड में अपनी पाइपलाइन बदल देगा, लेकिन आपका कोड आगे बढ़ने से पहले इसका इंतजार नहीं करेगा। यदि आप वर्तमान पाइपलाइन इंडेक्स जांचना चाहते हैं, तो कॉल करें

result.getPipelineIndex()

LLResult ऑब्जेक्ट प्राप्त करने के बारे में जानने के लिए अगला सेक्शन देखें।

3. परिणाम प्राप्त करना और उपयोग करना

LLResult एक कंटेनर की तरह है जो Limelight जो देखता है उसके बारे में जानकारी से भरा होता है। यहाँ बताया गया है कि हम उस जानकारी को कैसे प्राप्त और उपयोग करते हैं:

LLResult result = limelight.getLatestResult();
if (result != null && result.isValid()) {
double tx = result.getTx(); // टारगेट कितना बाएं या दाएं है (डिग्री में)
double ty = result.getTy(); // टारगेट कितना ऊपर या नीचे है (डिग्री में)
double ta = result.getTa(); // टारगेट कितना बड़ा दिखता है (इमेज का 0%-100%)

telemetry.addData("Target X", tx);
telemetry.addData("Target Y", ty);
telemetry.addData("Target Area", ta);
} else {
telemetry.addData("Limelight", "No Targets");
}

4. Python SnapScripts से बात करना

आप वेब इंटरफेस में अपनी खुद की Python SnapScript पाइपलाइन लिख सकते हैं। अपना कोड लिखने में मदद के लिए हमारे LLM-आधारित SnapScript जनरेटर का उपयोग करें।

यहाँ बताया गया है कि आप रोबोट कोड से Python को नंबर कैसे भेजते हैं और वापस नंबर कैसे प्राप्त करते हैं:

// Python को नंबर भेजना
double[] inputs = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
limelight.updatePythonInputs(inputs);

// Python से नंबर प्राप्त करना
double[] pythonOutputs = result.getPythonOutput();
if (pythonOutputs != null && pythonOutputs.length > 0) {
double firstOutput = pythonOutputs[0];
telemetry.addData("Python output:", firstOutput);
}

5. मेरा रोबोट कहाँ है? (MegaTag 1)

Limelight AprilTags का उपयोग करके यह पता लगाने में मदद कर सकता है कि आपका रोबोट फील्ड पर कहाँ है। आपका Limelight वर्तमान गेम के लिए AprilTag Map के साथ पहले से इंस्टॉल आता है, लेकिन आप हमारे 3D Map Builder का उपयोग करके अपने खुद के मैप डिज़ाइन और अपलोड कर सकते हैं।

अपने रोबोट की स्थिति प्राप्त करने का प्रयास करने से पहले, निम्नलिखित करें:

  1. वेब इंटरफेस में अपनी AprilTag पाइपलाइन के "Advanced" टैब में "Full 3D" सक्षम करें।
  2. अपने कैमरे को अपने रोबोट के फुटप्रिंट के केंद्र के सापेक्ष स्थित करने के लिए वेब इंटरफेस का उपयोग करें।

botPose के लिए कोऑर्डिनेट सिस्टम स्टैंडर्ड FTC कोऑर्डिनेट सिस्टम से मेल खाता है।

  • (0,0,0) फील्ड फ्लोर का केंद्र है
  • नॉन-डायमंड कॉन्फ़िगरेशन के लिए, 0 डिग्री Yaw का मतलब है कि ब्लू एलायंस आपके रोबोट के बाईं ओर है, और रेड एलायंस आपके रोबोट के दाईं ओर है।
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 Location", "(" + x + ", " + y + ")");
}
}

6. मेरा रोबोट कहाँ है? (MegaTag 2)

MegaTag 2, MegaTag 1 की तरह है, लेकिन यह बढ़ी हुई सटीकता के लिए आपके IMU डेटा को फ्यूज़ करता है:

// पहले, Limelight को बताएं कि आपका रोबोट किस दिशा में है
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 Location:", "(" + x + ", " + y + ")");
}
}

7. इनर रिज़ल्ट्स टाइप्स

आपने अपनी पाइपलाइन को कैसे कॉन्फ़िगर किया है, इसके आधार पर आपके पास पैरेंट LLResults ऑब्जेक्ट के भीतर विभिन्न प्रकार की विस्तृत Results Lists तक पहुंच होगी।

आपको शायद इन Results Lists का उपयोग करने की आवश्यकता नहीं होगी। हम जब भी संभव हो बेस getTx(), getTy() का उपयोग करने की सलाह देते हैं।

7.1 कलर रिज़ल्ट्स

कलर रिज़ल्ट्स रंगीन टारगेट खोजने में मदद करते हैं:

List<ColorResult> colorTargets = result.getColorResults();
for (ColorResult colorTarget : colorTargets) {
double x = detection.getTargetXDegrees(); // यह कहाँ है (बाएं-दाएं)
double y = detection.getTargetYDegrees(); // यह कहाँ है (ऊपर-नीचे)
double area = colorTarget.getTargetArea(); // आकार (0-100)
telemetry.addData("Color Target", "takes up " + area + "% of the image");
}

7.2 Fiducial/AprilTag रिज़ल्ट्स

Fiducials विशेष मार्कर हैं (जैसे AprilTags) जो Limelight को यह पता लगाने में मदद करते हैं कि वह कहाँ है:

List<FiducialResult> fiducials = result.getFiducialResults();
for (FiducialResult fiducial : fiducials) {
int id = fiducial.getFiducialId(); // Fiducial का ID नंबर
double x = detection.getTargetXDegrees(); // यह कहाँ है (बाएं-दाएं)
double y = detection.getTargetYDegrees(); // यह कहाँ है (ऊपर-नीचे)
double StrafeDistance_3D = fiducial.getRobotPoseTargetSpace().getY();
telemetry.addData("Fiducial " + id, "is " + distance + " meters away");
}

यदि आप प्रत्येक FiducialResult के भीतर 3D pose जानकारी का उपयोग करना चाहते हैं, तो आप निम्नलिखित मेथड्स का उपयोग कर सकते हैं:

fiducial.getRobotPoseTargetSpace(); // AprilTag कोऑर्डिनेट सिस्टम के सापेक्ष रोबोट pose (सबसे उपयोगी)
fiducial.getCameraPoseTargetSpace(); // AprilTag के सापेक्ष कैमरा pose (उपयोगी)
fiducial.getRobotPoseFieldSpace(); // केवल इस टैग के आधार पर फील्ड कोऑर्डिनेट सिस्टम में रोबोट pose (उपयोगी)
fiducial.getTargetPoseCameraSpace(); // कैमरे के कोऑर्डिनेट सिस्टम में AprilTag pose (बहुत उपयोगी नहीं)
fiducial.getTargetPoseRobotSpace(); // रोबोट के कोऑर्डिनेट सिस्टम में AprilTag pose (बहुत उपयोगी नहीं)

7.3 बारकोड रिज़ल्ट्स

Limelight की बारकोड पाइपलाइन QR Codes का पता लगाने और ट्रैक करने में अच्छी है।

List<BarcodeResult> barcodes = result.getBarcodeResults();
for (BarcodeResult barcode : barcodes) {
String data = barcode.getData(); // बारकोड क्या कहता है
String family = barcode.getFamily(); // यह किस प्रकार का बारकोड है
telemetry.addData("Barcode", data + " (" + family + ")");
}

7.4 क्लासिफायर रिज़ल्ट्स

न्यूरल क्लासिफायर Limelight को यह कहने की अनुमति देते हैं "मुझे लगता है यह एक... की इमेज है"।

List<ClassifierResult> classifications = result.getClassifierResults();
for (ClassifierResult classification : classifications) {
String className = classification.getClassName(); // Limelight को क्या लगता है कि वह देख रहा है
double confidence = classification.getConfidence(); // कॉन्फिडेंस स्कोर
telemetry.addData("I see a", className + " (" + confidence + "%)");
}

7.5 डिटेक्टर रिज़ल्ट्स

डिटेक्टर विशिष्ट ऑब्जेक्ट्स खोजते हैं और हमें बताते हैं कि वे कहाँ हैं:

List<DetectorResult> detections = result.getDetectorResults();
for (DetectorResult detection : detections) {
String className = detection.getClassName(); // क्या डिटेक्ट हुआ
double x = detection.getTargetXDegrees(); // यह कहाँ है (बाएं-दाएं)
double y = detection.getTargetYDegrees(); // यह कहाँ है (ऊपर-नीचे)
telemetry.addData(className, "at (" + x + ", " + y + ") degrees");
}

8. क्या डेटा ताज़ा है?

कभी-कभी, हम अपने रिज़ल्ट्स डेटा की उम्र (मिलीसेकंड में) जानना चाहते हैं।

long staleness = result.getStaleness();
if (staleness < 100) { // 100 मिलीसेकंड से कम पुराना
telemetry.addData("Data", "Good");
} else {
telemetry.addData("Data", "Old (" + staleness + " ms)");
}

9. कस्टम फील्ड मैप्स

आप Limelight को अपने विशिष्ट फील्ड लेआउट के बारे में बता सकते हैं:

LLFieldMap fieldMap = new LLFieldMap(); // आपको इसे फील्ड डेटा से भरना होगा
boolean success = limelight.uploadFieldmap(fieldMap, null); // null का मतलब है डिफ़ॉल्ट स्लॉट का उपयोग करें
if (success) {
telemetry.addData("Field Map", "Uploaded successfully!");
} else {
telemetry.addData("Field Map", "Oops, upload failed");
}

10. स्नैपशॉट लेना:

Limelight फील्ड से बाहर पाइपलाइन डीबग करने में मदद के लिए स्नैपशॉट ले सकता है:

limelight.captureSnapshot("auto_pov_10s");

वेब इंटरफेस के Input Tab में, आप अपनी पाइपलाइन को चेक/ट्यून करने के लिए इस स्नैपशॉट को "image source" के रूप में चुन सकते हैं।

पुराने स्नैपशॉट साफ़ करने के लिए:

limelight.deleteSnapshots();
telemetry.addData("Snapshots", "All cleared out!");