diff --git a/README.md b/README.md index 221bb51..73ff1bd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # DJITelloPy +## [中文文档](README_CN.md) + DJI Tello drone python interface using the official [Tello SDK](https://dl-cdn.ryzerobotics.com/downloads/tello/20180910/Tello%20SDK%20Documentation%20EN_1.3.pdf) and [Tello EDU SDK](https://dl-cdn.ryzerobotics.com/downloads/Tello/Tello%20SDK%202.0%20User%20Guide.pdf). This library has the following features: - implementation of all tello commands diff --git a/README_CN.md b/README_CN.md new file mode 100644 index 0000000..69a16c8 --- /dev/null +++ b/README_CN.md @@ -0,0 +1,87 @@ +# DJITelloPy +这是一个大疆Tello无人机的Python接口, +使用官方 [Tello SDK](https://dl-cdn.ryzerobotics.com/downloads/tello/20180910/Tello%20SDK%20Documentation%20EN_1.3.pdf) 和 [Tello EDU SDK](https://dl-cdn.ryzerobotics.com/downloads/Tello/Tello%20SDK%202.0%20User%20Guide.pdf)。 这个库有以下功能: + +- 支持使用所有的tello命令 +- 轻松获取视频流 +- 接受并解析状态包 +- 操控多架无人机 +- 支持Python3.6以上版本 + +欢迎随时捐献! + +## 使用pip安装 +``` +pip install djitellopy +``` +> 译者注:国内使用pip安装速度较慢,可能出现超时错误\ +> 建议使用国内镜像(此处为清华源): +> ``` +> pip install djitellopy -i https://pypi.tuna.tsinghua.edu.cn/simple/ +> ``` + +对于同时安装了python2与python3的Linux发行版(Ubuntu、Debian等),使用: +``` +pip3 install djitellopy +``` + +## 以开发者模式安装 +你可以使用下面的命令以 *可编辑模式* 安装此项目。这允许你修改此库并像正常安装的一样使用它。 + +``` +git clone https://github.com/damiafuentes/DJITelloPy.git +cd DJITelloPy +pip install -e . +``` + +## 使用 +### 查阅API +查看 [djitellopy.readthedocs.io](https://djitellopy.readthedocs.io/en/latest/) 以获取所有可用的类与方法。 + +### 简单示例 +```python +from djitellopy import Tello + +tello = Tello() + +tello.connect() +tello.takeoff() + +tello.move_left(100) +tello.rotate_counter_clockwise(90) +tello.move_forward(100) + +tello.land() +``` + +### 更多示例 +在 [示例](examples/) 有一些代码示例: + +- [拍张照](examples/take-picture.py) +- [记录视频](examples/record-video.py) +- [一次控制多架无人机](examples/simple-swarm.py) +- [使用键盘简单控制无人机](examples/manual-control-opencv.py) +- [识别任务卡(应该是指挑战卡)](examples/mission-pads.py) +- [使用Pygame实现键盘控制飞机](examples/manual-control-pygame.py) + +### 提示 +- 如果你使用 ```streamon``` 命令时返回 ```Unknown command```,你需要通过Tello app升级固件。 +- 挑战卡识别与导航只支持Tello EDU +- 必须在明亮的环境下识别挑战卡 +- 只有Tello EDU支持连接一个已存在的wifi +- 当连接一个已存在wifi时视频流不可用 + +## 作者 + +* **Damià Fuentes Escoté** +* **Jakob Löw** +* [更多](https://github.com/damiafuentes/DJITelloPy/graphs/contributors) + +## 译者 +* [C0derGeorge](https://github.com/C0derGeorge) + + +## 许可证 + +此项目遵循 MIT License - 查看 [LICENSE.txt](LICENSE.txt) 获取详情 + diff --git a/examples/manual-control-opencv.py b/examples/manual-control-opencv.py index f4b389b..ae7236a 100644 --- a/examples/manual-control-opencv.py +++ b/examples/manual-control-opencv.py @@ -5,6 +5,13 @@ # When starting the script the Tello will takeoff, pressing ESC makes it land # and the script exit. +# 简单的演示如何用键盘控制Tello +# 欲使用全手动控制请查看 manual-control-pygame.py +# +# W, A, S, D 移动, E, Q 转向,R、F上升与下降. +# 开始运行程序时Tello会自动起飞,按ESC键降落 +# 并且程序会退出 + from djitellopy import Tello import cv2, math, time @@ -19,6 +26,7 @@ while True: # In reality you want to display frames in a seperate thread. Otherwise # they will freeze while the drone moves. + # 在实际开发里请在另一个线程中显示摄像头画面,否则画面会在无人机移动时静止 img = frame_read.frame cv2.imshow("drone", img) @@ -42,4 +50,4 @@ elif key == ord('f'): tello.move_down(30) -tello.land() \ No newline at end of file +tello.land() diff --git a/examples/manual-control-pygame.py b/examples/manual-control-pygame.py index 5fc81da..67651f3 100644 --- a/examples/manual-control-pygame.py +++ b/examples/manual-control-pygame.py @@ -5,9 +5,12 @@ import time # Speed of the drone +# 无人机的速度 S = 60 # Frames per second of the pygame window display # A low number also results in input lag, as input information is processed once per frame. +# pygame窗口显示的帧数 +# 较低的帧数会导致输入延迟,因为一帧只会处理一次输入信息 FPS = 120 @@ -20,20 +23,34 @@ class FrontEnd(object): - Arrow keys: Forward, backward, left and right. - A and D: Counter clockwise and clockwise rotations (yaw) - W and S: Up and down. + + 保持Tello画面显示并用键盘移动它 + 按下ESC键退出 + 操作说明: + T:起飞 + L:降落 + 方向键:前后左右 + A和D:逆时针与顺时针转向 + W和S:上升与下降 + """ def __init__(self): # Init pygame + # 初始化pygame pygame.init() # Creat pygame window + # 创建pygame窗口 pygame.display.set_caption("Tello video stream") self.screen = pygame.display.set_mode([960, 720]) # Init Tello object that interacts with the Tello drone + # 初始化与Tello交互的Tello对象 self.tello = Tello() # Drone velocities between -100~100 + # 无人机各方向速度在-100~100之间 self.for_back_velocity = 0 self.left_right_velocity = 0 self.up_down_velocity = 0 @@ -43,6 +60,7 @@ def __init__(self): self.send_rc_control = False # create update timer + # 创建上传定时器 pygame.time.set_timer(pygame.USEREVENT + 1, 1000 // FPS) def run(self): @@ -51,6 +69,7 @@ def run(self): self.tello.set_speed(self.speed) # In case streaming is on. This happens when we quit this program without the escape key. + # 防止视频流已开启。这会在不使用ESC键退出的情况下发生。 self.tello.streamoff() self.tello.streamon() @@ -78,6 +97,7 @@ def run(self): self.screen.fill([0, 0, 0]) frame = frame_read.frame + # battery n. 电池 text = "Battery: {}%".format(self.tello.get_battery()) cv2.putText(frame, text, (5, 720 - 5), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) @@ -92,12 +112,17 @@ def run(self): time.sleep(1 / FPS) # Call it always before finishing. To deallocate resources. + # 通常在结束前调用它以释放资源 self.tello.end() def keydown(self, key): """ Update velocities based on key pressed Arguments: key: pygame key + + 基于键的按下上传各个方向的速度 + 参数: + key:pygame事件循环中的键事件 """ if key == pygame.K_UP: # set forward velocity self.for_back_velocity = S @@ -120,6 +145,10 @@ def keyup(self, key): """ Update velocities based on key released Arguments: key: pygame key + + 基于键的松开上传各个方向的速度 + 参数: + key:pygame事件循环中的键事件 """ if key == pygame.K_UP or key == pygame.K_DOWN: # set zero forward/backward velocity self.for_back_velocity = 0 @@ -137,7 +166,10 @@ def keyup(self, key): self.send_rc_control = False def update(self): - """ Update routine. Send velocities to Tello.""" + """ Update routine. Send velocities to Tello. + + 向Tello发送各方向速度信息 + """ if self.send_rc_control: self.tello.send_rc_control(self.left_right_velocity, self.for_back_velocity, self.up_down_velocity, self.yaw_velocity) @@ -147,6 +179,7 @@ def main(): frontend = FrontEnd() # run frontend + frontend.run() diff --git a/examples/mission-pads.py b/examples/mission-pads.py index edf89a3..671e3c0 100644 --- a/examples/mission-pads.py +++ b/examples/mission-pads.py @@ -1,18 +1,21 @@ from djitellopy import Tello # create and connect +# 创建Tello对象并连接 tello = Tello() tello.connect() # configure drone +# 设置无人机 tello.enable_mission_pads() -tello.set_mission_pad_detection_direction(1) # forward detection only +tello.set_mission_pad_detection_direction(1) # forward detection only 只识别前方 tello.takeoff() pad = tello.get_mission_pad_id() # detect and react to pads until we see pad #1 +# 发现并识别挑战卡直到看见1号挑战卡 while pad != 1: if pad == 3: tello.move_back(30) @@ -25,6 +28,7 @@ pad = tello.get_mission_pad_id() # graceful termination +# 安全结束程序 tello.disable_mission_pads() tello.land() tello.end() diff --git a/examples/record-video.py b/examples/record-video.py index 7206a92..d8f1c0f 100644 --- a/examples/record-video.py +++ b/examples/record-video.py @@ -12,6 +12,7 @@ def videoRecorder(): # create a VideoWrite object, recoring to ./video.avi + # 创建一个VideoWrite对象,存储画面至./video.avi height, width, _ = frame_read.frame.shape video = cv2.VideoWriter('video.avi', cv2.VideoWriter_fourcc(*'XVID'), 30, (width, height)) @@ -23,6 +24,7 @@ def videoRecorder(): # we need to run the recorder in a seperate thread, otherwise blocking options # would prevent frames from getting added to the video +# 我们需要在另一个线程中记录画面视频文件,否则其他的阻塞操作会阻止画面记录 recorder = Thread(target=videoRecorder) recorder.start() diff --git a/examples/simple-swarm.py b/examples/simple-swarm.py index 5e5793e..ec97b3e 100644 --- a/examples/simple-swarm.py +++ b/examples/simple-swarm.py @@ -10,12 +10,15 @@ swarm.takeoff() # run in parallel on all tellos +# 同时在所有Tello上执行 swarm.move_up(100) # run by one tello after the other +# 让Tello一个接一个执行 swarm.sequential(lambda i, tello: tello.move_forward(i * 20 + 20)) # making each tello do something unique in parallel +# 让每一架Tello单独执行不同的操作 swarm.parallel(lambda i, tello: tello.move_left(i * 100 + 20)) swarm.land()