FTC Java & Blockly プログラミングガイド
(Blocklyのスクリーンショットは近日公開予定!)
FTCプログラミングクイックスター トを必ず読んでください。
FTC Limelight Javadoc: Javadoc
基本的なFTCの例: FTCサンプル
完全な例のリポジトリ: Limelight FTC 例リポジトリ
成功のためのヒント
- まずは簡単なことから始めましょう。FRCでは、最高のソフトウェアチームはしばしば最もシンプルなアプローチを使用することを学びました。例えば、FRCチーム2056は2024年に、ゲームピースを追跡するために神経ネットワークの代わりに標準的な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からデータを要求する頻度を設定します(1秒間に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("ターゲットX", tx);
telemetry.addData("ターゲットY", ty);
telemetry.addData("ターゲット面積", ta);
} else {
telemetry.addData("Limelight", "ターゲットなし");
}
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出力:", firstOutput);
}
5. ロボットの位置は?(MegaTag 1)
LimelightはAprilTagを使用してフィールド上のロボットの位置を特定するのに役立ちます。LimelightにはAprilTagマップが現在のゲーム用にプリインストールされていますが、3Dマップビルダーを使用して独自のマップを設計・アップロードすることもできます。
ロボットの位置を取得する前に、以下を行ってください:
- ウェブインターフェースのAprilTagパイプラインの「Advanced」タブで「Full 3D」を有効にします。
- ウェブインターフェースを使用して、カメラをロボットの足跡の中心に対して位置付けます。
botPoseの座標系は標準のFTC座標系と一致します。
- (0,0,0)はフィールドの床の中心です
- 非ダイヤモンド構成では、Yaw 0度はロボットの左側に青色アライアンス、右側に赤色アライアンスがあることを意味します。
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位置", "(" + 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位置:", "(" + x + ", " + y + ")");
}
}
7. 内部結果タイプ
パイプラインの設定方法によって、親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("カラーターゲット", "画像の " + area + "% を占めています");
}