البدء السريع لبرمجة FRC
يدعم Limelight بروتوكولات REST/HTTP و Websocket و Modbus و NetworkTables لبيانات الاستهداف وبيانات الحالة والتكوين المباشر. تتوفر تنسيقات الإخراج JSON والخام. راجع قسم واجهات برمجة التطبيقات (APIs) في ا لوثائق للحصول على مزيد من المعلومات.
بالنسبة لفرق FRC، البروتوكول الموصى به هو NetworkTables. ينشر Limelight جميع بيانات الاستهداف، بما في ذلك تفريغ JSON كامل، إلى NetworkTables بتردد 100 هرتز. يمكن للفرق أيضًا ضبط عناصر التحكم مثل وضع LED ونافذة الاقتصاص والمزيد عبر NetworkTables. يمكن لفرق FRC استخدام مكتبات Limelight Lib Java و C++ للبدء مع Limelight في ثوانٍ. Limelight Lib هي أسهل طريقة للبدء.
LimelightLib:
- Java
- C++
- Python
double tx = LimelightHelpers.getTX("");
#include "LimelightHelpers.h"
double tx = LimelightHelpers::getTX("");
double ty = LimelightHelpers::getTY("");
wip
إذا كنت ترغب في تخطي LimelightLib والانتقال مباشرة إلى البرمجة باستخدام NetworkTables:
- Java
- C++
- LabView
- Python
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
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.0);
double y = ty.getDouble(0.0);
double area = ta.getDouble(0.0);
//نشر على لوحة المعلومات الذكية دوريًا
SmartDashboard.putNumber("LimelightX", x);
SmartDashboard.putNumber("LimelightY", y);
SmartDashboard.putNumber("LimelightArea", area);
#include "frc/smartdashboard/Smartdashboard.h"
#include "networktables/NetworkTable.h"
#include "networktables/NetworkTableInstance.h"
#include "networktables/NetworkTableEntry.h"
#include "networktables/NetworkTableValue.h"
#include "wpi/span.h"
std::shared_ptr<nt::NetworkTable> table = nt::NetworkTableInstance::GetDefault().GetTable("limelight");
double targetOffsetAngle_Horizontal = table->GetNumber("tx",0.0);
double targetOffsetAngle_Vertical = table->GetNumber("ty",0.0);
double targetArea = table->GetNumber("ta",0.0);
double targetSkew = table->GetNumber("ts",0.0);
import cv2
import numpy as np
# يتم استدعاء runPipeline() في كل إطار بواسطة الخلفية الخاصة بـ Limelight.
def runPipeline(image, llrobot):
# تحويل الصورة المدخلة إلى مساحة ألوان HSV
img_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# تحويل HSV إلى صورة ثنائية عن طريق إزالة أي بكسل
# لا يقع ضمن قيم HSV الدنيا/القصوى التالية
img_threshold = cv2.inRange(img_hsv, (60, 70, 70), (85, 255, 255))
# البحث عن الحدود في الصورة الثنائية الجديدة
contours, _ = cv2.findContours(img_threshold,
cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
largestContour = np.array([[]])
# تهيئة مصفوفة فارغة من القيم لإرسالها مرة أخرى إلى الروبوت
llpython = [0,0,0,0,0,0,0,0]
# إذا تم اكتشاف حدود، قم برسمها
if len(contours) > 0:
cv2.drawContours(image, contours, -1, 255, 2)
# تسجيل أكبر حد
largestContour = max(contours, key=cv2.contourArea)
# الحصول على المربع المحيط غير المدور الذي يحيط بالحد
x,y,w,h = cv2.boundingRect(largestContour)
# رسم المربع المحيط غير المدور
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,255),2)
# تسجيل بعض البيانات المخصصة لإرسالها مرة أخرى إلى الروبوت
llpython = [1,x,y,w,h,9,8,7]
# إرجاع أكبر حد لعلامة التقاطع الخاصة بـ LL، والصورة المعدلة، وبيانات الروبوت المخصصة
return largestContour, image, llpython