نسخهی شبیهسازیشدهی مسابقهی FIRA Air Autonomous Race. هر تیم برای یک DJI Tello مجازی برنامه مینویسد که بدون خلبان انسانی از سکوی برخاست بلند شود، بهترتیب از دروازهها عبور کند، به هیچچیز نخورد و روی سکوی فرود «H» بنشیند. همان کد و همان کتابخانهی Tello واقعی (DJITelloPy) کار میکند؛ بدون پهپاد، بدون سالن پرواز، بدون خطر سقوط.

پیست یک سالن سهبعدی است با سکوی برخاست، تعدادی دروازهی رنگی با نشانگر AprilTag زیر هر دروازه، یک یا چند ناحیهی امتیازی و یک یا چند سکوی فرود. هر تیم یک جلسهی رسمی ۱۵ دقیقهای دارد و در این مدت میتواند هر تعداد تلاش انجام دهد؛ هر تلاش ناموفق (برخورد، جا انداختن دروازه، ترتیب اشتباه، خروج از محدوده، فرود بیرون سکو) یک امتیاز منفی دارد.
تکمیل کامل مسیر ۲۵ امتیاز پایه دارد. امتیاز نهایی S = (B − P) × Ka است که B بهترین امتیاز پایه، P تعداد تلاشهای ناموفق و Ka = 1 (پردازش خارج از پهپاد). در U19 رتبهبندی با امتیاز و سپس کمترین زمان؛ در U14 دو پهپاد همزمان در دو مسیر یکسان (Lane A و Lane B) مسابقه میدهند، با مسیر سادهتر و سکوی فرود ثابت.
تصاویر از نسخهی رسمی Windows (FIRA Air Studio 0.0.1) گرفته شدهاند.



Python 3.10 یا جدیدتر را نصب کنید (در نصب، گزینهی Add to PATH را بزنید). سپس در ترمینال:
python -m pip install djitellopy pupil-apriltags opencv-pythonDJITelloPy فرمانهای واقعی Tello را با متدهای ساده میفرستد؛ pupil-apriltags نشانگرها را تشخیص میدهد؛ OpenCV تصویر را پردازش میکند.
فایل FIRA-Air-Studio-0.0.1.exe (حدود ۲۰۰ مگابایت) را دانلود کنید و اجرا کنید. اگر ویندوز پیام «Windows protected your PC» داد: More info ← Run anyway. برنامه کاملاً آفلاین کار میکند. در اولین اجرا، Studio بهطور خودکار Python نصبشده روی سیستم را پیدا میکند («بررسی محیط»)؛ اگر خطایی گزارش داد، نصب Python را بررسی کنید.
روی Practice بزنید تا صفحهی پیست باز شود. پهپاد روی سکوی H داخل Safe Zone است. تا وقتی پهپاد از Safe Zone بیرون نرفته، پروازهای تمرینی بهعنوان تلاش رسمی شمرده نمیشوند.
با Open file فایل Python خود (مثلاً first_flight.py) یا با Open folder پوشهی پروژه را باز کنید و اجرا کنید. کد شما دقیقاً مثل یک Tello واقعی با Tello() و connect() وصل میشود؛ Studio ارتباط شبکه را به پهپاد مجازی هدایت میکند (شبکهی پهپاد مجازی، VDN). لازم نیست هیچ کد شبکهای بنویسید یا آدرس IP تغییر دهید.
در جلسهی مسابقه، پیش از هر تلاش Start attempt [Space] را بزنید (اعلام تلاش). داور داخلی عبور از دروازهها، برخورد، فرود و زمان را ثبت میکند و امتیاز را با فرمول S = (B − P) × Ka نشان میدهد. Judge a match همین حالت را برای داوران فراهم میکند. Import package بستهی کد تحویلی یک تیم را بارگذاری میکند.
from djitellopy import Tello
drone = Tello()
drone.connect()
print("Battery:", drone.get_battery(), "%")
try:
drone.takeoff()
drone.move_forward(100) # 100 cm
drone.land()
finally:
drone.end()
from djitellopy import Tello
from pupil_apriltags import Detector
import cv2
drone = Tello()
detector = Detector(families="tag36h11")
drone.connect()
drone.streamon()
try:
camera = drone.get_frame_read()
while True:
frame = camera.frame
if frame is None:
continue
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
for tag in detector.detect(gray):
x, y = map(int, tag.center)
print("AprilTag ID:", tag.tag_id)
cv2.circle(frame, (x, y), 5, (0, 255, 0), -1)
cv2.imshow("AprilTag Detector", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
finally:
drone.end()
cv2.destroyAllWindows()
از اولین برخاستن تا اسکلت یک تلاش کامل مسابقه. همه با DJITelloPy نوشته شدهاند و بدون هیچ تغییری روی Tello واقعی هم کار میکنند.
python -m pip install -r requirements.txtسه کتابخانه: djitellopy، pupil-apriltags، opencv-python.
FIRA Air Studio را باز کنید و Practice را بزنید، سپس فایل را با Open file در Studio یا با python first_flight.py در ترمینال اجرا کنید. Studio ارتباط Tello را خودش به پهپاد مجازی وصل میکند.
در race_base.py لیست ROUTE را با اندازههای پیست رسمی پر کنید (U14 همین کافی است). برای U19، USE_VISION = True و شناسهی AprilTag هر دروازه را در GATE_TAG_IDS بنویسید تا پیش از هر دروازه با دوربین تراز شود.
| فایل | چه کار میکند | درس |
|---|---|---|
first_flight.py | برخاستن، ۱۰۰ سانتیمتر جلو، فرود | ۱ |
telemetry.py | خواندن باتری/ارتفاع/yaw و نگه داشتن ارتفاع با حلقهی تناسبی و send_rc_control | ۳ |
camera_apriltag.py | نمایش دوربین، تشخیص AprilTag 36h11 و محاسبهی خطای افقی | ۴–۶ |
race_base.py | اسکلت تلاش مسابقه: مسیر دستوری + تراز اختیاری با AprilTag + فرود ایمن در خطا | ۷–۱۱ |
بر پایهی «راهنمای برنامهنویسی دانشآموزی FIRA Air Simulation، نسخهی ۱.۱ (اکتبر ۲۰۲۶)». هر جلسه حدود ۹۰ دقیقه. U14 میتواند با دنبالهی ثابت فرمانها مسیر را کامل کند؛ U19 بینایی ماشین و تصحیح خودکار را اضافه میکند.
Tello()، connect()، takeoff()، move_forward(cm)، land()، end().move_forward(5) معتبر نیست.move_back / move_left / move_right / move_up / move_down بر حسب سانتیمتر؛ جهت نسبت به روی پهپاد است: بعد از چرخش، «جلو» عوض میشود.rotate_clockwise(90) چرخش ۹۰ درجه، نه ۹۰ سانتیمتر؛ set_speed(30) سرعت پیشفرض به cm/s (۱۰ تا ۱۰۰).drone.move_up(50)
drone.rotate_clockwise(90)
drone.move_forward(80)
drone.rotate_counter_clockwise(90)
drone.set_speed(30)
get_battery()، get_height()، get_yaw()، get_flight_time(). این مقادیر تقریبیاند و مختصات پنهان شبیهساز را نشان نمیدهند.send_rc_control(lr, fb, ud, yaw) در یک حلقه؛ حلقهی تناسبی ساده برای نگه داشتن ارتفاع: ud = k * (target - height).move_up و yaw را قبل و بعد از چرخش چاپ کنید.streamon() و get_frame_read().frame تصویر دوربین جلو را میدهد (در Studio ۶۴۰×۴۸۰؛ همیشه frame.shape را بخوانید).(tag_x - width/2) / (width/2)؛ منفی یعنی تگ سمت چپ تصویر.def horizontal_error(tag_x, image_width):
center_x = image_width / 2
return (tag_x - center_x) / center_x
connect() موفق بوده؟ از قبل در پرواز نیست؟ پیام خطا را بخوانید.streamon() صدا زده شده؟Tello(), connect(), end()
takeoff(), land()
move_forward(cm), move_back(cm), move_left(cm), move_right(cm), move_up(cm), move_down(cm)
rotate_clockwise(deg), rotate_counter_clockwise(deg), set_speed(cm_per_s)
get_battery(), get_height(), get_yaw(), get_flight_time()
streamon(), get_frame_read(), streamoff()
send_rc_control(left_right, forward_back, up_down, yaw) # پیشرفته
emergency() # فقط توقف اضطراری موتور؛ فرود ایمن نیست
متن کامل (PDF) را از بخش دانلود بگیرید. ردهی U19 از قوانین FIRA Air – Autonomous Race (U19) مورخ ۵ دسامبر ۲۰۲۵ پیروی میکند، با تطبیق برای شبیهسازی.
پیشنیاز: Python 3.10+ و pip install djitellopy pupil-apriltags opencv-python. بهروزترین نسخهی فایلها همیشه ابتدا در کانال کمیته داوران منتشر میشود.
برای دریافت فایلها، اطلاعیهها و پرسیدن سؤال از کمیته داوران جوین شوید.