用 .NET 启动你的 DJI Ryze Tello 无人机
大疆的 DJI Ryze Tello 是入门级的无人机,不仅在 STEM 教育中有非常广泛的应用,也可以作为编程入门的首选。通过 UDP 协议调用 DJI Ryze Tello SDK 可以让 DJI Ryze Tello 无人机执行起飞,降落,转向以及不同的花式动作。本文将会通过 .NET 创建应用控制 DJI Ryze Tello。
.NET UDP 编程
▍什么是 UDP
“UDP(用户数据报协议)是一个与IP 协议一起使用的长期协议,用于在传输速度和效率比安全性和可靠性更重要的场合下发送数据。UDP 使用一个简单的、具有最小协议机制的无连接通信模型。UDP 使用校验和保证数据完整性,使用端口号以区分数据发送方和接收方中不同的应用程序。它无需握手会话,即将不可靠的底层网络直接暴露给了用户的应用程序:不保证消息交付、不保证交付顺序也不保证消息不重复。如果需要网络接口层面的纠错功能,则应用程序可以使用为此目的设计的传输控制协议(TCP)或者流控制传输协议(SCTP)。”
在现场实时测控领域,如果有实时、抗干扰性、安全性等要求,都可以采用 UDP 传输数据。我想这也是 DJI Ryze Tello 为何使用 UDP 协议通信的原因。
▍C# 调用 UDP Client
在 System.Net.Sockets 下你可以通过类 UdpClient 来完成 UDP 协议的相关调用。这是官方给我们的例子。
UdpClient 类提供了在阻塞同步模式下发送和接收无连接 UDP 数据报的简单方法。因为 UDP 是一种无连接的传输协议,所以在发送和接收数据之前不需要建立远程主机连接。但是,您确实可以选择通过以下两种方式之一建立默认远程主机:
-
使用远程主机名和端口号作为参数创建 UdpClient 类的实例
-
创建 UdpClient 类的实例,然后调用 Connect 方法
您可以使用 UdpClient 中提供的任何发送方法将数据发送到远程设备。使用 Receive 方法从远程主机接收数据。
用 .NET Polyglot Notebook 连接 DJI Ryze Tello
用 .NET 封装 DJI Ryze Tello SDK 之前我们可以用 Notebooks 连接 DJI Ryze Tello 做相关原型测试。
要连通 DJI Ryze Tello SDK ,需要通过 UDP 连通 192.168.10.1 以及端口 11111.
通过 C# 调用 UDPClient 连接的方式如下:
string telloIP = "192.168.10.1";int telloPort = 8889;UdpClient udpClient = new UdpClient();udpClient.Connect(telloIP,telloPort);
并封装好指令执行的方法
public void Command(UdpClient udpClient,string cmd)
{Byte[] sendCmdBytes = null;sendCmdBytes = Encoding.UTF8.GetBytes(cmd);udpClient.Send(sendCmdBytes, sendCmdBytes.Length);
}
完成上面的设置,你就可以执行对应的指令完成控制 DJI Ryze Tello 的操作
Command(udpClient,"command");Command(udpClient,"takeoff");Command(udpClient,"land");
结合 .NET Polyglot Notebook 就可以完成对 DJI Ryze Tello 的操作以及相关技术测试。以下视频是 Notebooks 控制 DJI Ryze Tello 的具体效果:
用 .NET MAUI 构建 DJI Ryze Tello 应用
.NET MAUI 是跨平台,跨设备的前端应用技术,开发团队使用一种编程语言 C# 就可以完成 iOS / Android / macOS / Windows 的应用开发。现在是多终端的年代,通过不同设备控制你手上的 DJI Ryze Tello , 搭建多应用场景是非常棒的。本系列主要通过 iOS 和 Android 移动设备控制 DJI Ryze Tello, 以下是一些关键步骤:
▍通过 .NET Comet 构建前端 UI
Comet 是⼀种编写跨平台 UI 的现代⽅式 ( https://github.com/dotnet/Comet )。基于 .NET MAUI,它采⽤Model - Views - Update (MVU) 模式,和传统的 XAML 相⽐ , 它有⼏个显著的特点:
-
基于函数式编程;
-
Comet 参考了 SwiftUI 和 Flutter 描述界面的方式,更容易去编写页面层次逻辑,如:
-
用 Comet 开发 .NET MAUI 应用不仅可以在 Visual Studio 上开发 ,也可以在 Visual Studio Code 上开发。
注意:如果需要在 Visual Studio Code 调试 .NET MAUI 应用,请安装 C# 和 .NET Comet 组件
▍绑定 iOS/Android 原生库的技巧
一个好的应用需要整合非常多的场景,如支付,电商,地图等,作为开发团队不需要重复造车,直接可以调用不同的 SDK 来完成相关的操作。.NET MAUI 解决了跨平台应用界面和绝大多数页面逻辑以及业务逻辑的问题。但当我们使用第三方 SDK 时你会发现缺少相关 .NET MAUI 的原生库,通过 Binding 可以让 .NET MAUI 绑定 iOS / Android 的原生库。
从 DJI Ryze Tello SDK 文档可知通过 UDP 可以控制 DJI Ryze Tello , 也可以通过 UDP 实时图传 DJI Ryze Tello 的摄像头信号。这个时候我们需要通过 libVLC 库对 DJI Ryze Tello 摄像头提供的 UDP 信号进行 H264 编码解码的服务并显示在移动应用的界面上。
在 .NET MAUI 上,我一般通过命令行创建 iOS / Android 原生绑定项目,如下:
dotnet new iosbinding -o VLCSharp.iOS dotnet new android-bindinglib -o VLCSharp.Droid
▍绑定 iOS/Android 原生库的技巧
-
用 Sharpie 做初次转换
我们通过安装 Sharpie 针对 iOS 的 libVLC 库 MobileVLCKit.framework 进行绑定,通过执行以下命令可以快速转换 libVLC 的库。
sharpie bind -framework ./MobileVLCKit.framework --namespace MobileVLCKit -sdk iphoneos16.1
注意:iOS 原生库对应的 iOS 版本,否则你是没办法进行转换。
转换后替换项目中的 StructsAndEnums.cs 和 ApiDefinitions.cs 以及把 MobileVLCKit.framework 添加到 iOS 绑定的项目 VLCSharp.iOS 中
-
修改 csproj 文件,把原生库依赖的库都需要添加进去
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net7.0-ios</TargetFramework><RootNamespace>MobileVLCKit</RootNamespace><Nullable>enable</Nullable><ImplicitUsings>true</ImplicitUsings><IsBindingProject>true</IsBindingProject><AllowUnsafeBlocks>true</AllowUnsafeBlocks><NoBindingEmbedding>false</NoBindingEmbedding></PropertyGroup><ItemGroup><ObjcBindingApiDefinition Include="ApiDefinition.cs" /><ObjcBindingCoreSource Include="StructsAndEnums.cs" /></ItemGroup><ItemGroup><NativeReference Include="MobileVLCKit.framework"><Kind>Framework</Kind><IsCxx>True</IsCxx><ForceLoad>True</ForceLoad><SmartLink>True</SmartLink><Frameworks>MediaPlayer Accelerate AssetsLibrary AVFoundation CoreMedia AudioToolbox CoreData CoreMedia CoreSpotlight MobileCoreServices CoreAudio OpenGLES CFNetwork CoreText QuartzCore CoreGraphics UIKit Security StoreKit SystemConfiguration VideoToolbox</Frameworks><LinkerFlags>-lbz2 -liconv -lstdc++</LinkerFlags></NativeReference></ItemGroup>
</Project>
-
编译,请从 GitHub(https://github.com/kinfey/dotNETMauiHOL/tree/main/code/apps/02.Binding/TelloApp.Bindings/VLCSharp.iOS)下载并替换 StructsAndEnums.cs 和 ApiDefinitions.cs。
替换后编译就成功了
如果希望了解更多 iOS Binding 的知识和相关技巧,你可以通过该链接了解:https://github.com/kinfey/AMapMAUIControls/blob/main/tutorial/cn/01.iOSBinding.md
▍Android 绑定 libVLC 库相关技巧
-
创建 Jars 文件夹,把 Android 的 libVLC 的库 org.videolan.libvlc.aar 添加到绑定的项目 Jars 文件夹中
-
修改 .csproj 文件
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net7.0-android</TargetFramework><SupportedOSPlatformVersion>21</SupportedOSPlatformVersion><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings></PropertyGroup><ItemGroup><LibraryProjectZip Include="Jars\org.videolan.libvlc.aar" /></ItemGroup><ItemGroup><TransformFile Include="Transforms\Metadata.xml" /><TransformFile Include="Transforms\EnumFields.xml" /><TransformFile Include="Transforms\EnumMethods.xml" /></ItemGroup>
</Project>
-
编译,和 iOS ⼀样编译出错,请从 GitHub
(https://github.com/kinfey/dotNETMauiHOL/tree/main/code/apps/02.Binding/TelloApp.Bindings/VLCSharp.Droid)下载并替换 EnumMethods.xml。
替换后,编译成功了。
如果希望了解更多 Android Binding 的知识和相关技巧,你可以通过该链接了解:
https://github.com/kinfey/AMapMAUIControls/blob/main/tutorial/cn/02.DroidBinding.md
自定义界面控件
.NET MAUI 可以通过 Handler 构建自定义界面控件,我们通过 Handler 绑定 LibVLC 实现图传,而且和一般自定义页面控件不同虽然用的都是 libVLC 库,但在不同平台上调用方式以及构建方式是不同的,所以在 Platforms 上需要针对不同的控件来完成定义,分别定义 iOS 文件夹新增 VideoPlayerView.ios.cs , Android 文件夹新增 VideoPlayerView.android.cs。
之后再通过继承 Handler 的类分别调用来完成自定义 VLC 控件的定义。
我们可以无缝把自定义的 VLC 控件添加到我们的应用中,和 Commet UI 是无缝对接的。
new VStack{new VlcUI().Padding(20).Alignment(Alignment.TopLeading)
}.Frame(width:400,height:300).Alignment(Alignment.Center),
我们可以看看那安卓上的实现效果,通过图传可以实时在应用端获取 DJI Ryze Tello 的摄像头信号
当我们完成页面逻辑和业务逻辑构建后,我们就可以用 .NET MAUI 构建的 iOS / Android 应用快速启动 DJI Ryze Tello ,下图是在 iPhone 控制 DJI Ryze Tello 起降的效果,以及实时图传。
小结
这就是通过 .NET 控制 DJI Ryze Tello 的主要步骤,如果⼤家希望了解更多细节和更详细内容,请访问 https://github.com/kinfey/dotNETMauiHOL , 这⾥⾯包括了完整的学习内容,还有具体细节,希望各位能更好地掌握⽤ .NET MAUI 跨平台应⽤的技巧,做更多有趣的应⽤。你可以按照以下顺序,依次学习相关内容
相关文档:
1. ⽤ .NET MAUI 构建 DJI Ryze Tello ⽆⼈机应⽤系列
https://github.com/kinfey/dotNETMauiHOL
2. 学习 .NET MAUI
https://aka.ms/mauiBlog.Learn
3. 关于 .NET Polyglot Notebook
https://aka.ms/mauiBlog.Notebook
4. .NET MAUI 绑定 iOS 原⽣库
https://aka.ms/mauiBlog.iOSBinding
5. .NET MAUI 绑定 Android 原⽣库
https://aka.ms/mauiBlog.DroidBinding
6. .NET MAUI ⾃定义⻚⾯控件
https://aka.ms/mauiBlog.CustomUI
7. C# 调⽤ UDP
https://aka.ms/mauiBlog.UDP
相关文章:
用 .NET 启动你的 DJI Ryze Tello 无人机
大疆的 DJI Ryze Tello 是入门级的无人机,不仅在 STEM 教育中有非常广泛的应用,也可以作为编程入门的首选。通过 UDP 协议调用 DJI Ryze Tello SDK 可以让 DJI Ryze Tello 无人机执行起飞,降落,转向以及不同的花式动作。本文将会通…...
sed 功能详解
介绍sedsed是一种流编辑器,它一次处理一行内容,把当前处理的行存储在临时缓冲区中(buffer),称为"模式空间",接着sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕&#…...
整数二分思路详解
题目描述 给定一个按照升序排列的长度为n的整数数组,以及 q 个查询。 对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。 如果数组中不存在该元素,则返回“-1 -1”。 输入格式 第一行包含整数n和q&a…...
基于java的进销库存管理系统(Vue+Springboot+Mysql)前后端分离项目,附万字课设论文
1.3 系统实现的功能 本次设计任务是要设计一个超市进销存系统,通过这个系统能够满足超市进销存系统的管理及员工的超市进销存管理功能。系统的主要功能包括:首页、个人中心、员工管理、客户管理、供应商管理、承运商管理、仓库信息管理、商品类别管理、 …...
手动添加 Grub 启动项
1. 问题背景 自己的台式机上装了好几块硬盘,因为自己又菜又喜欢折腾,几乎每块上都有一个操作系统,其中两个 m.2 的硬盘上分别装着一个 windows11 和一个 Ubuntu20.04。但在另外一块机械硬盘中还装着更早的一个 Ubuntu18.04,我电脑…...
工人搬砖-课后程序(JAVA基础案例教程-黑马程序员编著-第八章-课后作业)
【案例8-4】 工人搬砖 【案例介绍】 1.任务描述 在某个工地,需要把100块砖搬运到二楼,现在有工人张三和李四,张三每次搬运3块砖,每趟需要10分钟,李四每次搬运5块砖,每趟需要12分钟。本案例要求编写程序分…...
深度学习中backbone、head、neck等概念
1.backbone 翻译为主干网络的意思,既然说是主干网络,就代表其是网络的一部分。这个主干网络大多时候指的是提取特征的网络,其作用就是提取图片中的信息,供后面的网络使用。这些网络经常使用的是ResNet VGG等,而不是我…...
华为OD机试用Python实现 -【Linux 发行版的数量】(2023-Q1 新题)
华为OD机试题 华为OD机试300题大纲Linux 发行版的数量题目描述输入描述输出描述说明示例一输入输出说明Python 代码实现代码编写逻辑华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:blog.csd…...
Http报文解析
http通信流程浏览器->已监听的web服务器->read->write->close http请求报文: a.请求方法: POST GET DELETE HEAD OPTIONS PUT TRACE b.请求地址: /xxx/yyy/zzz c.报文协议: HTTP/1.1 d.请求报文头: Accept Referer Accept-Language Content-Type Host Content-Len…...
Vue下载安装步骤的详细教程(亲测有效) 2 安装与创建默认项目
上篇请移步到Vue下载安装步骤的详细教程(亲测有效) 1_水w的博客-CSDN博客 上一篇博文已经对Node.js的安装与配置进行了详细介绍。 另外:文中项目存放的路径及项目名称可根据自身实际情况进行更改。 目录 三、Vue安装配置 1、搭建Vue脚手架 2、通过NPM安装Vue …...
TIA博途Wincc中自定义配方画面的具体方法示例
TIA博途Wincc中自定义配方画面的具体方法示例 前面和大家分享了通过TIA博途自带的配方视图组态配方功能的具体方法,具体内容可参考以下链接中的内容: TIA PORTAL wincc中配方recipe组态及配方视图的使用方法 但是,使用配方视图的时候感觉不是很方便,同时一部分使用人员也感…...
Java反射系列--方法大全
原文网址:Java反射系列--方法大全_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java反射相关的方法。 Class相关方法 方法 说明 getName() 返回String形式的该类的名称。 newInstance() 根据某个Class对象产生其对应类的实例,它调用的是此类的默认构…...
LeetCode 169. 多数元素
LeetCode 169. 多数元素 难度:easy\color{Green}{easy}easy 题目描述 给定一个大小为 nnn 的数组 numsnumsnums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊n/2⌋⌊ n/2 ⌋⌊n/2⌋ 的元素。 你可以假设数组是非空的,并且给…...
来了,metaIPC1.0
metaRTC推出metaIPC正式版1.0,基于metaRTC6.0最新版二次开发,metaIPC是为嵌入式/摄像头量身打造的webRTC版IPC Camera,可安装在国内大多数Soc芯片上,如在君正/瑞芯微/MSTAR/海思等等已经有多个成熟产品应用。 New Feature 支持M…...
WireShark如何进行USB包协议分析
USB协议学习的步骤之一就是从抓包看协议通信,进而学习usb设备开发是怎么回事。这里发现一个工具就是wireshark。 WireShark如果要抓取usb设备的包,需要在安装的时候,选择usbpcap一并进行安装。...
蒙特卡洛随机模拟
蒙特卡洛随机模拟 简介 蒙特卡洛模拟是在计算机上模拟项目实施了成千上万次,每次输入都随机选择输入值。由于每个输入很多时候本身就是一个估计区间,因此计算机模型会随机选取每个输入的该区间内的任意值,通过大量成千上万甚至百万次的模拟…...
Android从屏幕刷新到View的绘制(三)之Handler异步消息与同步屏障
0. 相关分享 Android从屏幕刷新到View的绘制(一)之 Window、WindowManager和WindowManagerService之间的关系 Android从屏幕刷新到View的绘制(二)之Choreographer、Vsync与屏幕刷新 1. 相关类 Handler Handler中维护着它所在的…...
最新版axios@1.3.x取消请求-AbortController-初体验-番茄出品
最新版axios1.3.x取消请求-AbortController-初体验-番茄出品 start 前文提到,axios 中的取消请求,包含两种方式: AbortController;CancelToken; 上篇文章讲解了 CancelToken,今天这篇文章来了解一下 Abor…...
Git的简述
Git 文章目录GitGit概述版本控制工具集中式管理控制工具分步式管理控制工具控制机制Git和代码托管中心安装Git软件Git常用命令Git概述 Git是一个免费的、开源的分步式版本控制系统,可以快速的处理从小型到大型的各种项目 Git 易于学习,占地面积小&…...
webpack实战,手写loader和plugin
序言 对于 webpack 来说, loader 和 plugin 可以算是需求程度最为广泛的配置项了。但是呢,单单止步于配置可能还不够。如果我们自己有时候想要 diy 一个需求,但是 webpack 又没有相关的 loader 和 plugin 。那这个时候我们可能就得开始造点轮…...
STM32CubeMX按键模块化 点灯
本文代码使用 HAL 库。 文章目录前言一、按键原理图二、CubeMX 创建工程三、代码讲解:1. GPIO的输入HAL库函数:2. 消抖:3. 详细代码四,实验现象:总结前言 我们继续讲解 stm32 f103,这篇文章将详细 为大家讲…...
C#专栏目录(长期更新)
文章目录C# 基础C#进阶C#应用WPF基础WPF 3D小游戏C# 基础 1996年,微软用年薪三百万美刀的价格从Borland挖来了大神海尔斯伯格,开始了J开发,用以对抗Java。但SUN公司认为此举违反了Java开发平台的中立性,对微软提出诉讼。C#正是在…...
BurpSuite配置抓取HTTPS数据包
简介 我们在渗透测试的过程中,经常会遇到HTTPS的网站,Burp默认是没有办法抓取HTTPS的包的,想要让Burp抓取Https的包也很好办,只需要浏览器安装相关的证书即可,接下来将配置过程做一个记录。 前置条件: 1.J…...
图片转base64格式返回给前端,前端如何展示?
图片以base64形式在页面上展示出来在这里要说到Data URI scheme,它可以直接将一些小的数据直接嵌入到网页中,不需要再引入。支持格式如下data:, 文本数据data:text/plain, 文本数据data:text/html, HTML代码data:text/html;base64, base64编码的HTML代码…...
C++入门知识【超详解】
目录1.认识Chello worldC关键字2.命名空间3.std标准库4.输入输出5.缺省参数6.函数重载7.引用7.1引用的概念7.2引用的场景1.作参数2.作返回值7.3引用的注意点7.4指针和引用的区别8.auto关键字9.基于范围的for循环10.内联函数10.1概念10.2特征11. C98中的指针空值1.认识C hello …...
零基础、非计算机系学Python该如何上手?
首先我觉得要放平心态,不用过多去纠结是不是专业出身这回事。 想学那就认真去学,我们最终目标是掌握Python这门技能。 非计算机专业同时零基础,想自学Python该如何上手?分享我自学Python的几点建议吧。 1、重视基础 Python是一…...
关于 vue3 模板引用
文章目录前言1.访问模板引用2.v-for中的模板引用3.组件上的ref前言 如果我们需要直接访问组件中的底层DOM元素,可使用vue提供特殊的ref属性来访问 1.访问模板引用 在视图元素中采用ref属性来设置需要访问的DOM元素 a. 该ref属性可采用字符值的执行设置 b. 该ref属…...
Redis | 安装Redis和启动Redis服务
目录 一、Redis简介 1.1 简介 二、Redis安装 2.1 Windows安装Redis 2.2 Linux安装Redis 三、Redis服务启动和停止 3.1 Windows启动Redis服务 3.2 Linux启动Redis服务 四、Redis设置密码远程连接 4.1 为Redis登陆设置密码 4.2 设置Redis允许远程连接 五、Redis常…...
博客要考虑的最佳WordPress主题
有太多的选择会瘫痪你做决定的能力。有太多的WordPress主题,但仅仅只需要一个并且它是要合适的。我们建立了数十个 WordPress 博客并安装了数百个主题。根据我们所有的经验,我们发现Newspaper是大多数用户的最佳WordPress博客主题。这个自适应、强大的主…...
C 学习笔记 —— 函数指针
函数指针 上面的第二个char (* f) (int);写法就是函数指针的声明; 首先,什么是函数指针?假设有一个指向 int类型变量的指针,该指针储存着这个int类型变量储存在内存位置的地址。 同样,函数也有地址,因为函…...
建设银行网站怎么登陆密码/全国疫情高峰感染进度
转载 :機器/深度學習: 物件偵測 Non-Maximum Suppression (NMS) 機器/深度學習: 物件偵測 Non-Maximum Suppression (NMS)基本上在影像物件偵測領域上,都是先會選出物件候選人,然後在物件候選人中判斷是不是物件,但有可能一個物件被很多候選…...
培训页面设计师/西安seo外包行者seo06
Oracle读取和修改数据块的过程Oracle数据库处理SQL都会经过三个过程:解析(parse)、执行(exec)、返回结果(fetch)。为了便于理解,我们首先省略的SQL的处理过程,而直接介绍数据块的读取或修改过程。物理读和逻辑读概念1.对要访问的块地址做HASHHASH(FILE#,…...
济南企业网站建设哪家好/电子商务沙盘seo关键词
宝塔查看登录地址 SSH登录后输入 bt default...
宝鸡网站建设的公司/什么时候友情链接
http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions001.htm#autoId2 本文内容 NLS 字符函数 附录 Oracle 字符函数包括: 返回字符值的字符函数 NLS 字符函数 返回数字值的字符函数 返回数字值的字符函数 返回数字值的函数可以把任何字符类型作为其参…...
网站免费推广方案/市场营销专业就业方向
我在听这张,真好听 很怀念那些听歌的日子...
wordpress菜单调用图片/c++线上培训机构哪个好
本文是读《Spring Boot2精髓-从构件小系统到架构分布式大系统》的读书笔记。 JavaEE简介 JavaEE对于如下的功能需求,有相应的规范实现与之对应: Web支持:Servlet规范,规定了Web容器、Servlet组件。 事务支持:JavaEE提…...