news 2026/9/5 14:26:27

基于Python与Tello无人机的STEM课程设计:从编程到视觉追踪

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Python与Tello无人机的STEM课程设计:从编程到视觉追踪

简介:本资源是一套面向初中阶段STEM教育的Tello无人机Python编程课程源码,聚焦物联网、人工智能与项目式学习实践,帮助初学者通过真实硬件操控理解编程逻辑与跨学科知识融合。压缩包共38个文件,含17个Python核心脚本(如键盘控制、人脸/球体追踪、手势识别、视频流推送等)、4个XML配置文件(支撑IDE环境与项目管理)、3个drawio流程图(可视化程序逻辑)、3个PNG示意图、1个caffemodel及配套prototxt模型文件(支持轻量级视觉识别),另有gitignore、LICENSE、iml等工程规范文件,整体仅1.39MB,结构清晰、即开即用。已有426人学习下载,配套完整模块化代码与典型CV应用范例,覆盖从基础起飞悬停到多模态交互的进阶实践路径,特别适合作为信息技术课拓展实验、科创社团训练或青少年AI启蒙教学载体。

1. 项目缘起:为什么用Tello和Python做STEM教育?

这几年,无人机和编程教育的热度一直居高不下,但很多所谓的“课程”要么停留在遥控飞行,要么就是对着屏幕写几行控制小车的代码,学生玩过就忘,很难形成体系化的认知。我自己在带学生科创项目时,一直在寻找一个能真正融合硬件交互、编程逻辑、算法思维和工程实践的平台。直到遇到了大疆的Tello EDU无人机,配合Python,这个组合的潜力才真正被激发出来。

Tello EDU是一款面向教育的可编程无人机。它体积小巧、安全性高,在室内就能安全飞行。最关键的是,它开放了基于Wi-Fi的SDK,允许我们通过发送简单的文本指令来控制它。而Python,作为当下最流行的入门编程语言,语法简洁,库生态丰富,特别适合青少年上手。将两者结合,我们就能让学生写的代码“飞起来”,从抽象的语法学习,直接过渡到看得见、摸得着的物理反馈。这不仅仅是教编程或教无人机,而是构建一个完整的STEM(科学、技术、工程、数学)项目闭环:学生需要理解无人机的飞行原理(科学),掌握Python编程和通信协议(技术),设计并组装可能的扩展模块(工程),最后用数学知识去计算路径、分析传感器数据。

网上有很多零散的Tello Python代码片段,但大多不成体系。一个完整的课程设计,需要从零搭建环境开始,经历基础控制、传感器应用、算法引入,最终完成一个综合性的挑战项目。这正是我设计这套课程源码的初衷:提供一套开箱即用、循序渐进、且充满探索乐趣的STEM课程核心框架。它不仅仅是几段代码,更包含项目设计思路、分阶段的教学目标、以及我实际教学中总结的避坑指南。

2. 课程核心架构与环境搭建的“魔鬼细节”

一套能稳定运行的课程,基石是可靠的环境。很多教程在这一步就语焉不详,导致学生大部分时间卡在环境配置上,挫败感十足。我的课程设计从一开始就强调环境的可复现性。

2.1 硬件与软件选型背后的逻辑

硬件方面,首选Tello EDU版本,而非普通Tello。两者的核心区别在于,EDU版本支持更丰富的SDK命令,特别是“任务模式”和更多的传感器数据读取,这对于实现复杂的编队或交互项目至关重要。无人机本身就是一个集成度极高的教学平台:它包含飞控(工程)、IMU惯性测量单元(科学)、视觉定位系统(技术)、以及通信模块(技术)。

软件栈的核心是Python 3.7+。选择Python 3.7以上版本是为了更好地兼容现代异步编程库,这在处理无人机实时数据流时很有优势。主要的依赖库有三个:

  1. djitellopy:这是一个社区维护的、对官方SDK封装更友好的Python库。它用面向对象的方式将无人机抽象成一个Tello类,方法名更直观(如takeoff(),land()),并且内置了视频流处理支持。这是我们的主力库。
  2. opencv-python(OpenCV):用于处理Tello传回的视频流,实现物体识别、颜色追踪、人脸检测等计算机视觉应用。这是将课程从“控制”提升到“智能”的关键。
  3. numpy:进行数值计算,比如处理无人机姿态数据、计算目标坐标等。

为什么不用官方SDK?官方SDK更底层,需要直接拼接字符串指令和处理socket通信,对于教学来说增加了不必要的复杂度。djitellopy做了很好的封装,让学生能更关注业务逻辑。

2.2 一步到位的环境配置与验证

很多教程会让人用pip一个个安装,但依赖冲突和版本问题是新手噩梦。我强烈推荐使用requirements.txt文件进行环境管理。

首先,创建一个项目目录,并在其中创建requirements.txt文件,内容如下:

djitellopy==2.5.0 opencv-python==4.8.1.78 numpy==1.24.3

然后,在终端或命令提示符中,进入该目录,执行:

pip install -r requirements.txt

这一步能确保所有学生和不同电脑上的库版本一致,极大减少了“在我电脑上能跑”的问题。安装完成后,不要急着写复杂代码,先用一个最简单的“Hello Drone”程序验证整个链路是否通畅。

创建一个test_connection.py文件:

from djitellopy import Tello # 1. 创建Tello对象并连接 tello = Tello() tello.connect() # 这一步会让电脑连接到Tello的Wi-Fi # 2. 打印基础信息 print(f"电池电量: {tello.get_battery()}%") print(f"无人机温度: {tello.get_temperature()}°C") # 3. 结束连接 tello.end()

注意:运行此脚本前,务必先开启Tello无人机电源,并用电脑的Wi-Fi设置连接到Tello发出的热点(名称通常为TELLO-XXXXXX)。连接成功后,再运行脚本。如果看到电池电量被成功打印,恭喜你,硬件通信链路已经打通。如果连接失败,请检查防火墙设置,确保Python有网络访问权限。

这个简单的测试包含了整个项目最基础的三个操作:初始化、发送指令、获取反馈。它虽然简单,但验证了从代码到物理世界最关键的一步。

3. 课程第一阶段:从零到一的飞行控制与基础编程思维

第一阶段的目标是让学生建立“代码即指令”的直观感受,并熟悉程序的基本结构。我们设计四个循序渐进的关卡。

3.1 关卡一:单指令执行与顺序逻辑

首先,我们让学生实现一个“起飞-悬停-降落”的固定流程。这引入了顺序执行这一最基础的编程概念。

from djitellopy import Tello import time # 引入时间模块,用于控制延迟 tello = Tello() tello.connect() print(“准备起飞...”) tello.takeoff() # 发送起飞指令 print(“无人机已起飞,悬停中...”) time.sleep(5) # 让无人机在空中悬停5秒。这里可以讲解‘阻塞’的概念。 print(“开始降落...”) tello.land() # 发送降落指令 print(“无人机已降落”) tello.end()

教学要点:在这里要重点解释time.sleep(5)。它让程序“等待”5秒,期间不执行任何其他代码。这是一个很好的切入点,引出“同步”与“阻塞”的概念,为后续学习更复杂的异步控制埋下伏笔。同时,让学生思考:如果不加这行代码,飞机会怎样?(答案:会立刻执行降落,看起来像是“跳”了一下)。

3.2 关卡二:引入变量与循环控制

接下来,我们让无人机做一个正方形飞行。这需要引入变量来定义边长,以及for循环来控制重复动作。

from djitellopy import Tello import time tello = Tello() tello.connect() tello.takeoff() side_length = 50 # 定义正方形边长,单位:厘米 tello.set_speed(30) # 设置飞行速度,单位:厘米/秒 for i in range(4): # 循环4次,对应正方形的4条边 print(f“正在飞第 {i+1} 条边”) tello.move_forward(side_length) # 向前飞 time.sleep(1) # 等待飞行稳定 print(“正在旋转90度”) tello.rotate_clockwise(90) # 顺时针旋转90度 time.sleep(1) tello.land() tello.end()

实操心得move_forward指令是“相对位移”,无人机以当前机头方向为基准向前飞。而rotate_clockwise是“相对旋转”。这里学生常犯的错误是混淆“机头方向”和“飞行路径方向”。我通常会让学生先在纸上画出无人机每个步骤后的朝向,再写代码,强化空间思维。另外,set_speed很重要,室内飞行建议速度不要超过50cm/s,否则容易因惯性漂移。

3.3 关卡三:条件判断与用户交互

让飞行流程根据环境状态动态调整。例如,只有电池电量充足时才允许起飞。

from djitellopy import Tello tello = Tello() tello.connect() battery = tello.get_battery() print(f“当前电量:{battery}%”) # 条件判断:如果电量低于20%,则拒绝起飞并报警 if battery < 20: print(“电量过低!请充电后再试。”) tello.emergency() # 紧急停转电机(如果已起飞) else: print(“电量充足,准备起飞。”) tello.takeoff() # … 执行一些飞行任务 … tello.land() tello.end()

教学要点:这是条件分支(if/else)的绝佳应用场景。可以进一步扩展:如何实现“电量中等时执行简单任务,电量高时执行复杂任务”的多分支判断?引导学生使用elifemergency()指令是一个安全特性,必须向学生强调其重要性——它是失控时的最后物理屏障。

3.4 关卡四:函数封装与代码复用

当任务变复杂时,我们需要教学生如何组织代码。例如,将“飞一个正方形”封装成一个函数。

from djitellopy import Tello import time def fly_square(drone, length, speed): “”“让无人机飞一个正方形”“” drone.set_speed(speed) for _ in range(4): drone.move_forward(length) time.sleep(0.5) drone.rotate_clockwise(90) time.sleep(0.5) # 主程序 tello = Tello() tello.connect() try: tello.takeoff() fly_square(tello, 40, 25) # 调用函数,飞一个边长40cm,速度25cm/s的正方形 tello.land() except Exception as e: print(f“飞行中出现错误:{e}”) tello.emergency() finally: tello.end()

核心价值:这里引入了函数定义参数传递以及简单的异常处理(try-except)。通过封装,主程序变得非常清晰。更重要的是,fly_square函数可以被重复调用,也可以被修改为fly_trianglefly_circle,让学生体会模块化设计的好处。异常处理是工程实践中必不可少的一环,即使对学生,也要培养“永远要有Plan B”的思维。

4. 课程第二阶段:传感器应用与数据可视化

掌握了基础控制后,课程进入第二阶段:让无人机感知世界,并做出反应。这涉及到传感器数据读取和基于数据的决策。

4.1 读取并理解IMU与状态数据

Tello内置了IMU(惯性测量单元),可以实时返回姿态数据。我们可以编写一个程序,持续读取并显示这些数据。

from djitellopy import Tello import time tello = Tello() tello.connect() tello.takeoff() tello.move_up(50) # 先上升到一定高度,避免地面干扰 print(“开始读取传感器数据(按Ctrl+C终止)...”) try: while True: # 获取姿态角(单位:度) pitch = tello.get_pitch() # 俯仰角:机头上下倾 roll = tello.get_roll() # 横滚角:机身左右倾 yaw = tello.get_yaw() # 偏航角:机头左右转 # 获取高度(单位:厘米)和TOF(Time of Flight)距离 height = tello.get_height() tof = tello.get_distance_tof() # 底部TOF传感器测距 # 格式化输出 print(f“Pitch:{pitch:3d}°, Roll:{roll:3d}°, Yaw:{yaw:3d}° | Height:{height:4d}cm, TOF:{tof:4d}cm”) time.sleep(0.1) # 每100毫秒读取一次 except KeyboardInterrupt: print(“\n用户中断。”) finally: tello.land() tello.end()

数据分析与教学:运行这个程序,让学生手动轻微晃动无人机(在手中安全操作),观察数据变化。引导他们思考:

  • 什么是“姿态角”?如何用手机类比?(手机平放:roll和pitch为0;竖起:pitch接近90°)。
  • TOF测距和气压计高度get_height()有什么区别?(TOF是底部超声波/红外测距,精度高但范围有限;高度是气压计估算,有漂移但范围大)。这引入了传感器融合数据冗余的工程概念。

4.2 实现一个简单的姿态稳定器

基于读取的数据,我们可以让程序自动维持无人机水平。这是一个简单的反馈控制逻辑。

from djitellopy import Tello import time def keep_level(drone, duration=10): “”“尝试在固定时间内保持无人机水平”“” start_time = time.time() while time.time() - start_time < duration: roll = drone.get_roll() pitch = drone.get_pitch() # 简单的比例控制:如果倾斜超过阈值,则向反方向微调 if abs(roll) > 5: # 横滚角绝对值大于5度 adjust_speed = min(10, abs(roll) // 2) # 计算调整速度 if roll > 0: drone.send_rc_control(0, 0, 0, -adjust_speed) # 左滚 else: drone.send_rc_control(0, 0, 0, adjust_speed) # 右滚 else: drone.send_rc_control(0, 0, 0, 0) # 停止横滚调整 # 同理,可以添加对pitch(前后)的调整逻辑 # ... time.sleep(0.05) # 控制周期20Hz # 主程序 tello = Tello() tello.connect() tello.takeoff() keep_level(tello, 15) # 尝试保持水平15秒 tello.land() tello.end()

核心原理:这里引入了最基础的反馈控制(Feedback Control)思想,也就是经典的“感知-决策-执行”循环。我们感知到姿态角(get_roll),决策出需要施加的反向控制量(send_rc_control中的第四个参数控制左右滚转),然后执行。send_rc_control是底层RC(遥控器)控制指令,可以同时设置左右、前后、上下、旋转四个通道的速度,实现更精细、连续的控制。这是从高阶指令(如move_forward)到底层控制的跨越。

重要警告send_rc_control需要在一个循环中持续发送,否则无人机会进入“失控”状态并自动降落。循环间隔建议在20-50ms。这是一个关键的避坑点,务必向学生强调。

5. 课程第三阶段:计算机视觉与智能交互

这是课程的高潮部分,让无人机“长眼睛”。通过OpenCV处理Tello的实时视频流,实现目标跟踪、手势识别等酷炫功能。

5.1 开启视频流与颜色追踪

首先,我们需要获取并显示视频流,然后实现一个简单的颜色追踪器。

from djitellopy import Tello import cv2 import numpy as np # 初始化 tello = Tello() tello.connect() tello.streamon() # 开启视频流 frame_read = tello.get_frame_read() # 获取帧读取器 # 设置要追踪的HSV颜色范围(这里以追踪绿色为例) # HSV色彩空间对光线变化更鲁棒 lower_green = np.array([35, 50, 50]) upper_green = np.array([85, 255, 255]) try: while True: # 1. 获取当前帧 frame = frame_read.frame # 获取一帧BGR图像 if frame is None: break # 2. 图像预处理与颜色过滤 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 转换到HSV空间 mask = cv2.inRange(hsv, lower_green, upper_green) # 创建颜色掩膜 # 3. 找出目标轮廓和中心点 contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if contours: # 找到最大的轮廓 largest_contour = max(contours, key=cv2.contourArea) if cv2.contourArea(largest_contour) > 500: # 面积过滤,避免噪声 # 计算轮廓的外接矩形和中心点 x, y, w, h = cv2.boundingRect(largest_contour) center_x = x + w // 2 center_y = y + h // 2 # 在图像上画出矩形和中心点 cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) cv2.circle(frame, (center_x, center_y), 5, (0, 0, 255), -1) # 4. 简单的控制逻辑:让无人机向目标中心移动 frame_center_x = frame.shape[1] // 2 frame_center_y = frame.shape[0] // 2 # 计算目标中心与画面中心的偏差 error_x = center_x - frame_center_x error_y = center_y - frame_center_y # 根据偏差发送RC控制指令(这里只控制左右和前后) # 注意:需要在一个更精细的控制循环中实现,此处仅为逻辑演示 # tello.send_rc_control(left_right_velocity, forward_backward_velocity, up_down_velocity, yaw_velocity) # 5. 显示图像 cv2.imshow(‘Tello Camera - Color Tracking’, frame) cv2.imshow(‘Mask’, mask) # 显示掩膜,便于调试颜色阈值 # 按‘q’键退出 if cv2.waitKey(1) & 0xFF == ord(‘q’): break finally: # 清理资源 cv2.destroyAllWindows() tello.streamoff() tello.end()

关键技术拆解

  1. streamon()get_frame_read():这是获取视频流的标准方式。视频流会消耗较多带宽,务必在程序结束时调用streamoff()关闭。
  2. HSV颜色空间:为什么不用RGB?因为HSV将颜色(Hue)、饱和度(Saturation)、明度(Value)分离,更容易设定颜色范围,对光照变化不敏感。通过cv2.cvtColor转换。
  3. cv2.inRange与掩膜(Mask):根据设定的HSV上下限,生成一个二值图像(掩膜),白色区域是目标颜色,黑色是其他。
  4. 轮廓检测cv2.findContours:在掩膜上找到白色区域的边界。我们通过cv2.contourArea过滤掉太小的噪声点。
  5. 控制逻辑:计算出目标中心与画面中心的偏差(error_x,error_y)。理论上,我们可以设计一个比例控制器,让无人机向减小偏差的方向飞行(例如,error_x为正,说明目标在画面右侧,就让无人机右移)。

避坑指南:颜色追踪对光照极其敏感。在实际教学中,最好在室内恒定光源下进行。可以先让学生用cv2.imshow显示HSV图像和掩膜,用鼠标实时获取目标颜色的HSV值,动态调整lower_greenupper_green这两个数组,这是调试的黄金步骤。

5.2 进阶项目:人脸追踪与自动构图

在颜色追踪的基础上,我们可以使用OpenCV预训练好的级联分类器进行人脸检测,实现更实用的“人脸追踪”或“自动构图”功能。

# ... 前面导入库和初始化Tello的部分与上例相同 ... tello.streamon() frame_read = tello.get_frame_read() # 加载OpenCV的人脸检测器(Haar Cascade) face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + ‘haarcascade_frontalface_default.xml’) try: while True: frame = frame_read.frame if frame is None: break # 转换为灰度图,人脸检测需要 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30)) # 找到最大的人脸 largest_face = None max_area = 0 for (x, y, w, h) in faces: area = w * h if area > max_area: max_area = area largest_face = (x, y, w, h) # 如果检测到人脸,进行追踪 if largest_face is not None: x, y, w, h = largest_face center_x = x + w // 2 center_y = y + h // 2 cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2) # 计算人脸框面积占画面比例,实现“推拉”控制 frame_area = frame.shape[0] * frame.shape[1] face_ratio = (w * h) / frame_area # 简单的决策逻辑 # 如果人脸太小,让无人机前进;太大则后退;偏左则左移;偏右则右移 # (此处为逻辑示意,实际需要更平滑的PID控制) # tello.send_rc_control(lr, fb, ud, yaw) cv2.imshow(‘Tello - Face Tracking’, frame) if cv2.waitKey(1) & 0xFF == ord(‘q’): break finally: cv2.destroyAllWindows() tello.streamoff() tello.end()

项目升华:这个项目综合了计算机视觉、反馈控制和决策逻辑。可以引导学生思考更复杂的策略:

  • 如何让人脸始终保持在画面中央特定区域(而不仅仅是一个点)?
  • 如何实现平滑的移动,避免无人机“抽搐”?(引入PID控制概念)
  • 除了追踪,能否实现人脸识别,让无人机对特定人做出不同反应?(引入人脸识别库如face_recognition

6. 课程第四阶段:综合挑战与项目拓展

在掌握了单项技能后,需要设计综合性的挑战项目,让学生分组协作,解决一个更复杂的工程问题。

6.1 挑战项目设计:“智能仓库巡检员”

项目背景:模拟一个小型仓库,地面贴有不同颜色的二维码(代表货架区域),无人机需要自主巡航,识别二维码颜色,飞到对应区域上空并悬停报告(通过LED灯或语音模拟),最后返回起点。

技术栈整合

  1. 路径规划:使用预设航点(waypoints)或基于颜色识别的实时决策。
  2. 视觉识别:用OpenCV识别颜色区域或真正的二维码(使用pyzbar库)。
  3. 状态机管理:无人机需要在不同状态间切换(起飞、巡航、识别、悬停报告、返航、降落),适合用有限状态机(FSM)模型来组织代码,让逻辑更清晰。
  4. 异常处理:电量监控、视觉丢失处理、失控保护。

示例代码框架(状态机示意)

class DroneState: TAKEOFF = 1 CRUISING = 2 SCANNING = 3 REPORTING = 4 RETURNING = 5 LANDING = 6 def warehouse_inspection(): tello = Tello() tello.connect() current_state = DroneState.TAKEOFF mission_complete = False while not mission_complete: if current_state == DroneState.TAKEOFF: tello.takeoff() tello.move_up(100) current_state = DroneState.CRUISING elif current_state == DroneState.CRUISING: # 飞向下一个目标点 if fly_to_next_waypoint(tello): current_state = DroneState.SCANNING elif current_state == DroneState.SCANNING: color = detect_color(tello) if color is not None: log_inspection(color) # 记录巡检结果 current_state = DroneState.REPORTING else: # 未识别到,执行搜索策略 execute_search_pattern(tello) elif current_state == DroneState.REPORTING: tello.send_rc_control(0,0,0,0) # 悬停 blink_led(tello, color) # 用LED灯闪烁报告颜色 time.sleep(2) if all_targets_checked(): # 检查是否所有点都巡检完毕 current_state = DroneState.RETURNING else: current_state = DroneState.CRUISING elif current_state == DroneState.RETURNING: if return_to_home(tello): current_state = DroneState.LANDING elif current_state == DroneState.LANDING: tello.land() mission_complete = True # 全局异常检查(如低电量) if tello.get_battery() < 15: print(“低电量,紧急返航!”) current_state = DroneState.RETURNING tello.end()

工程思维培养:这个项目迫使学生思考软件架构。他们需要设计fly_to_next_waypointdetect_colorreturn_to_home等具体函数,并处理好它们之间的接口和数据传递。状态机的引入,让复杂的流程变得可管理、可调试。

6.2 扩展方向与高级课题

对于学有余力的学生或更高年级的课程,可以引导他们探索以下方向:

  • 多机编队:使用多台Tello EDU,通过一台主机(电脑或树莓派)集中控制,实现简单的编队飞行。这涉及到多线程/异步编程、任务分配和协同避障的初级概念。
  • SLAM与自主导航:虽然Tello本身不具备强大的SLAM能力,但可以结合外部摄像头(如Intel RealSense)和ROS(机器人操作系统),在电脑端构建环境地图,实现更真正的自主导航。这是一个通向现代机器人学的桥梁。
  • AI模型集成:在电脑端运行轻量化的AI模型(如YOLO、MobileNet),通过Tello的视频流进行实时目标检测(识别特定物品、手势等),并做出反应。这展示了边缘计算与端云协同的一种形态。
  • 物联网(IoT)集成:让无人机在巡检过程中,将识别到的数据(如仪表读数、设备状态)通过Wi-Fi发送到服务器或云平台(如MQTT),构成一个完整的物联网应用原型。

7. 教学实施中的关键问题与解决方案

在实际开设这门课程的过程中,我积累了一些非常具体的经验教训,这些往往是文档里不会写的。

问题一:Wi-Fi连接不稳定,经常断连。

  • 根因:Tello的Wi-Fi模块功率有限,且2.4GHz频段容易受到干扰(如教室里的多个路由器、手机热点)。
  • 解决方案
    1. 专用路由器:使用一个便携式路由器,让所有学生电脑和Tello都连接到这个路由器上,形成一个稳定的局域网。这是最有效的方法。
    2. 代码健壮性:在所有飞行指令外围增加重试机制和异常捕获。例如,发送指令后检查响应,如果超时或失败,尝试重新连接或执行安全降落流程。
    3. 指令间隔:在连续发送指令之间增加短暂的time.sleep(0.05),避免指令队列堵塞导致失控。

问题二:视频流延迟高、卡顿。

  • 根因:视频流传输需要较大带宽,且OpenCV的imshow在高分辨率下很耗资源。
  • 解决方案
    1. 降低分辨率tello.set_video_resolution(‘low’)tello.set_video_bitrate(1)
    2. 使用多线程:将视频流的获取和显示放在一个独立的线程中,避免主控制循环被阻塞。这是提升流畅度的关键技巧。
    3. 减少处理开销:在图像处理循环中,只对感兴趣区域(ROI)进行处理,而不是整帧图像。

问题三:学生代码导致无人机“炸机”(撞墙、坠落)。

  • 安全第一:这是物理设备教学的最大风险。
  • 解决方案
    1. 物理防护:在室内体育馆或空旷教室进行,周围用安全网围住。给无人机安装桨叶保护罩。
    2. 软件限高限远:在课程初期,通过代码限制飞行高度(tello.move_up(最大高度))和活动区域。
    3. 紧急开关:教会学生第一个要写的代码就是tello.emergency()的调用,并设计一个全局键盘监听(如按空格键触发),作为“紧急制动”。
    4. 模拟器先行:复杂算法(如路径规划)先在模拟器(如AirSim配合Tello模型)中验证,再上真机。

问题四:课程进度参差不齐。

  • 分层任务设计:将每个阶段的任务分为“基础必做”、“进阶挑战”和“探索创新”三个层次。例如,在颜色追踪阶段,基础是能识别并框出颜色,进阶是实现追踪飞行,创新是让无人机根据颜色图案执行不同动作。
  • 项目小组制:将学生分为小组,能力强的负责核心算法和架构,能力稍弱的负责测试、数据记录和报告撰写,让每个人都能参与并贡献。

这套基于Python和Tello的STEM课程设计源码与框架,其价值远不止于教会学生控制一台无人机。它是一条贯穿了硬件交互、软件编程、算法思维和系统工程的完整学习路径。从一行代码让飞机起飞时的兴奋,到调试视觉算法时的专注,再到完成综合项目后的成就感,这个过程点燃了许多学生对工程和计算机科学的真正兴趣。作为教育者,我们提供的不是玩具,而是一个充满可能性的微型实验室。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 14:26:11

夯实C++20底层基本功:移动语义、RAII与类型推导

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 14:22:14

相位偏折术(PMD)原理与实现:从光学模型到Python/C++代码实战

简介&#xff1a;本资源面向机器视觉、光学测量与工业自动化领域的研究人员及工程师&#xff0c;聚焦高反光表面三维形貌精准重建难题&#xff0c;提供基于相位偏折算法的2.5D成像系统完整实现方案。资源包含Python与C双语言可运行代码&#xff0c;覆盖图像采集、相位解包裹、法…

作者头像 李华
网站建设 2026/9/5 14:21:33

走出 GIL 迷宫:现代 Python 并发选型与系统设计实战

走出 GIL 迷宫&#xff1a;现代 Python 并发选型与系统设计实战 在 Python 面试与架构评审中&#xff0c;有一道经典考题困扰了开发者十数载&#xff1a;“这里有两个函数&#xff1a;一个 cpu_task()&#xff0c;一个 io_task()。在 Python 中&#xff0c;你该用多线程、多进程…

作者头像 李华
网站建设 2026/9/5 14:21:00

开源域名防封系统:动态跳转与流量伪装技术实践

简介&#xff1a;这是一套专为微信生态内COS域名防红防封需求设计的轻量级前端工具&#xff0c;面向小程序开发者、H5运营人员及需要快速规避微信外链拦截的技术人员。资源通过纯静态HTML页面实现域名防封链接一键生成&#xff0c;无需后端部署或复杂配置&#xff0c;输入目标域…

作者头像 李华
网站建设 2026/9/5 14:19:49

C51单片机驱动1-Wire总线与DS18B20传感器实战指南

简介&#xff1a;本资源是一套面向嵌入式初学者与8051单片机开发者的1-Wire总线通信实战代码包&#xff0c;聚焦于单总线协议在温度传感等低功耗场景中的底层实现。资源以C51语言为核心&#xff0c;完整呈现主控端&#xff08;如8051&#xff09;对DS18B20等典型1-Wire器件的初…

作者头像 李华
网站建设 2026/9/5 14:09:09

Codepilot SubAgent模型指定:提升智能编码工具的专业化分工效率

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华