מדריך תכנות FTC Java & Blockly
(צילומי מסך של Blockly יגיעו בקרוב!)
וודאו שקראתם את מדריך ההתחלה המהירה לתכנות FTC.
תיעוד Javadoc של FTC Limelight: Javadoc
דוגמה בסיסית ל-FTC: דוגמת FTC
מאגר דוגמאות מלא: מאגר דוגמאות Limelight FTC
טיפים להצלחה
- עשו קודם את הדבר הפשוט. ב-FRC, למדנו שצוותי התוכנה הטובים ביותר משתמשים לעתים קרובות בגישות הפשוטות ביותר. לדוגמה, צוות FRC 2056 ב-2024 השתמש ב-pipeline צבע סטנדרטי של 90FPS במקום רשת נוירונים למעקב אחר חלקי משחק.
הנה דוגמה לסוג השאלה שכדאי לשאול כשמתחילים לתכנת: ב-teleop, האם אתם צריכים לדעת את מיקום הרובוט שלכם על המגרש, או שאתם פשוט צריכים לנוע לצדדים עד שהכוונת שלכם ממורכזת על תג ספציפי (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. ניהול Pipelines
Pipelines הם כמו תוכניות קטנות שניתן להחליף מיידית ומשנות את האופן שבו Limelight רואה את העולם. אתם יכולים להגדיר 10 pipelines שונים בממשק הווב של Limelight, כל אחד למשימה שונה. הנה איך מחליפים ביניהם:
limelight.pipelineSwitch(0); // מעבר ל-pipeline מספר 0
זה fire-and-forget. Limelight ישנה את ה-pipeline שלו תוך אלפיות שנייה, אבל הקוד שלכם לא יחכה לזה לפני שימשיך. אם אתם רוצים לבדוק את אינדקס ה-pipeline הנוכחי, קראו ל-
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
אתם יכולים לכתוב pipelines משלכם ב-Python SnapScript בממשק הווב. השתמשו במחולל ה-SnapScript מבוסס LLM שלנו כדי לעזור לכם לכתוב את הקוד.
הנה איך שולחים מספרים מקוד הרובוט ל-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 למשחק הנוכחי, אבל אתם יכולים לעצב ולהעלות מפות משלכם באמצעות בונה המפות התלת-ממדי שלנו.
לפני שתנסו לקבל את מיקום הרובוט שלכם, עשו את הדברים הבאים:
- הפעילו "Full 3D" בלשונית "Advanced" של pipeline ה-AprilTag שלכם בממשק הווב.
- השתמשו בממשק הווב למקם את המצלמה שלכם ביחס למרכז טביעת הרגל של הרובוט שלכם.
מערכת הקואורדינטות של 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. סוגי תוצאות פנימיים
בהתאם לאופן שבו הגדרתם את ה-pipelines שלכם, תהיה לכם גישה לסוגים שונים של רשימות תוצאות מפורטות בתוך אובייקט LLResults הראשי.
כנראה שלא תצטרכו להשתמש ברשימות תוצאות אלה. אנחנו ממליצים להשתמש ב-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
double x = detection.getTargetXDegrees(); // איפה זה נמצא (שמאל-ימין)
double y = detection.getTargetYDegrees(); // איפה זה נמצא (למעלה-למטה)
double StrafeDistance_3D = fiducial.getRobotPoseTargetSpace().getY();
telemetry.addData("Fiducial " + id, "is " + distance + " meters away");
}
אם אתם רוצים להשתמש במידע ה-pose התלת-ממדי בתוך כל FiducialResult, אתם יכולים להשתמש בשיטות הבאות:
fiducial.getRobotPoseTargetSpace(); // מיקום הרובוט ביחס למערכת הקואורדינטות של ה-AprilTag (הכי שימושי)
fiducial.getCameraPoseTargetSpace(); // מיקום המצלמה ביחס ל-AprilTag (שימושי)
fiducial.getRobotPoseFieldSpace(); // מיקום הרובוט במערכת הקואורדינטות של המגרש בהתבסס על תג זה בלבד (שימושי)
fiducial.getTargetPoseCameraSpace(); // מיקום ה-AprilTag במערכת הקואורדינטות של המצלמה (לא מאוד שימושי)
fiducial.getTargetPoseRobotSpace(); // מיקום ה-AprilTag במערכת הקואורדינטות של הרובוט (לא מאוד שימושי)
7.3 תוצאות ברקוד
ה-pipeline של ברקוד של Limelight טוב בזיהוי ומעקב אחר קודי QR.
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 יכול לצלם תמונות כדי לעזור לכם לדבג pipelines מחוץ למגרש:
limelight.captureSnapshot("auto_pov_10s");
בלשונית Input של ממשק הווב, אתם יכולים לבחור את התמונה הזו כ-"image source" כדי לבדוק/לכוונן את ה-pipelines שלכם.
לניקוי תמונות ישנות:
limelight.deleteSnapshots();
telemetry.addData("Snapshots", "All cleared out!");