当前位置: 首页 > news >正文

[无人机sdk] `FlightController` | startTakeoffSync() | actionSync()

第二章:飞行控制器

在第一章:飞行器中,我们了解到Vehicle对象是无人机的中央大脑,是连接所有系统的主遥控器

现在我们的Vehicle已经激活并准备就绪,如何让它真正起飞呢?这就是**飞行控制器(FlightController)**的用武之地

什么是"飞行控制器"?(无人机的自动驾驶管理器)

想象你是无人机的机长,有一位熟练的自动驾驶副驾驶。你不会告诉副驾驶"将电机1的功率增加X量,将电机3的功率减少Y量,调整倾斜Z度"。

相反,你会给出高级指令,如"起飞"、“降落”、“返航"或"飞到这个位置”。

Onboard-SDK中,FlightController对象正是这样的自动驾驶副驾驶。它是一个抽象层,为你提供对无人机飞行行为的高级控制。它将你的简单指令转换为无人机实际飞行计算机所需的复杂底层指令,而无需你操心电机转速或精确传感器读数等繁琐细节。

(还是我们经典的封装思想~)

为什么需要FlightController

控制无人机飞行涉及大量复杂的物理原理和实时调整

如果你必须直接向每个电机发送指令或不断计算完美角度,这将极其困难且容易出错。

FlightController极大地简化了这一过程。它提供了一个干净、易用的API(应用程序编程接口),让你专注于想要无人机做什么,而不是如何实现。它管理基本的飞行功能,使编程控制无人机移动变得安全高效。

FlightController的主要职责

FlightController处理无人机飞行的各个方面。可以将其视为拥有多个专业部门,每个部门负责不同类型的飞行指令:

组件职责示例动作
FlightActions执行预定义的高级飞行行为。起飞、降落、返航、启动/停止电机。
FlightJoystick提供直接的实时控制(类似物理遥控器)。设置速度、位置或姿态指令。
FlightAssistant管理飞行辅助功能和设置。启用/禁用避障、设置RTK偏好、调整返航高度。

所有这些职责都捆绑在FlightController对象下,使其成为与无人机移动相关的所有操作的首选接口

第一次飞行:起飞和降落

让我们让无人机执行一个基本的飞行序列:起飞、短暂悬停,然后降落。这是任何无人机操作的常见第一步

首先,确保已经准备好Vehicle对象,如我们在第一章:飞行器中创建的那样。

#include <dji_vehicle.hpp>
#include <dji_linux_helpers.hpp> // Linux设置
#include <iostream>// ... 在主函数中 ...LinuxSetup linuxEnvironment(argc, argv);
DJI::OSDK::Vehicle* vehicle = linuxEnvironment.getVehicle();if (vehicle == NULL) {std::cout << "飞行器未初始化,退出。\n";return -1;
}// 假设激活已完成(如第一章所示)
// DJI::OSDK::ACK::ErrorCode activateAck = vehicle->activate(...);
// ... 错误检查 ...int functionTimeout = 1; // SDK函数的通用超时时间

第一步:获取摇杆控制权限

在你的代码可以控制无人机飞行之前,必须明确获取控制权限

这是一个关键的安全特性。它告诉无人机:“我的程序现在负责飞行,而不是物理遥控器。”

// ... 飞行器初始化和激活后 ...std::cout << "尝试获取摇杆控制权限...\n";
DJI::OSDK::ErrorCode::ErrorCodeType ret =vehicle->flightController->obtainJoystickCtrlAuthoritySync(functionTimeout);if (ret != DJI::OSDK::ErrorCode::SysCommonErr::Success) 
{std::cout << "获取摇杆控制权限失败!错误: " << std::hex << ret << std::endl;return -1;
}
std::cout << "成功获取摇杆控制权限!\n";

说明:我们flightController对象上调用obtainJoystickCtrlAuthoritySync()

Sync(同步)意味着程序将等待无人机响应后再继续。我们检查ret代码以确保成功。

第二步:起飞

有了控制权限,我们现在可以命令无人机起飞。

// ... 获取控制权限后 ...std::cout << "尝试启动起飞...\n";
DJI::OSDK::ErrorCode::ErrorCodeType takeoffRet =vehicle->flightController->startTakeoffSync(functionTimeout);if (takeoffRet != DJI::OSDK::ErrorCode::SysCommonErr::Success) {std::cout << "起飞启动失败!错误: " << std::hex << takeoffRet << std::endl;// 如果起飞失败或在结束时,记得释放控制权限(cpp是这样的说)vehicle->flightController->releaseJoystickCtrlAuthoritySync(functionTimeout);return -1;
}std::cout << "起飞指令已发送。无人机应正在上升!\n";// 让无人机悬停几秒
sleep(8); // 等待8秒

说明startTakeoffSync()方法发送起飞指令

无人机会自动上升到安全高度(通常1.2米)并悬停。我们添加sleep()调用,让无人机完成起飞并悬停片刻。

第三步:降落

悬停后,是时候让无人机安全降落了。

// ... 悬停后 ...std::cout << "尝试启动降落...\n";
DJI::OSDK::ErrorCode::ErrorCodeType landRet =vehicle->flightController->startLandingSync(functionTimeout);if (landRet != DJI::OSDK::ErrorCode::SysCommonErr::Success) {std::cout << "降落启动失败!错误: " << std::hex << landRet << std::endl;vehicle->flightController->releaseJoystickCtrlAuthoritySync(functionTimeout);return -1;
}
std::cout << "降落指令已发送。无人机应正在下降!\n";// 等待无人机降落
sleep(10); // 给它一些时间降落

说明startLandingSync()启动降落序列。

无人机将下降并在接触地面时自动关闭电机。

第四步:释放控制权限

飞行操作完成后,必须释放控制权限。这允许物理遥控器重新接管或另一个授权应用程序控制无人机

// ... 降落后 ...std::cout << "尝试释放摇杆控制权限...\n";
DJI::OSDK::ErrorCode::ErrorCodeType releaseRet =vehicle->flightController->releaseJoystickCtrlAuthoritySync(functionTimeout);if (releaseRet != DJI::OSDK::ErrorCode::SysCommonErr::Success) {std::cout << "释放摇杆控制权限失败!错误: " << std::hex << releaseRet << std::endl;return -1;
}std::cout << "摇杆控制权限已成功释放!飞行完成。\n";

说明:调用releaseJoystickCtrlAuthoritySync()将无人机的飞行控制权返回给默认系统。

内部机制:FlightController如何工作

FlightController不仅仅是一个简单的指令发送器;它是一个复杂的协调器。

当要求它执行一个动作时,它会将任务委托给其专门的内部组件,并管理与无人机的通信。

FlightController初始化流程

从第一章:飞行器中记得,Vehicle对象初始化了许多子模块。FlightController是这些关键模块之一。当调用Vehicle::init()时,它专门设置了FlightController及其内部部分。

在这里插入图片描述
在这里插入图片描述

说明:此图展示了"起飞"等指令的旅程。

  • 应用程序调用FlightController方法。
  • FlightController随后将其委托给适当的内部模块(如FlightActionsFlightJoystick)。
  • 该模块又使用FlightLink与低层连接器(Linker)通信
  • 后者通过物理连接(USB/UART)向无人机的飞行控制器发送实际数据包。

一旦无人机响应,确认(ACK)会沿链返回

代码:构建自动驾驶管理器

在这里插入图片描述

让我们看一些简化的代码片段,揭示FlightController的结构及其与内部模块的交互方式

FlightController构造函数(简化自osdk-core/api/src/dji_flight_controller.cpp

FlightController的构造函数清楚地表明,它立即创建了其子模块的实例:FlightAssistantFlightActionsFlightJoystick

每个子模块都接收Vehicle指针,允许它们访问无人机的通信通道。

// osdk-core/api/src/dji_flight_controller.cpp
FlightController::FlightController(Vehicle* vehicle) 
{flightAssistant = new FlightAssistant(vehicle); // 管理飞行辅助flightActions = new FlightActions(vehicle);     // 处理基本飞行动作flightJoystick = new FlightJoystick(vehicle);   // 管理摇杆控制
}FlightController::~FlightController() 
{delete this->flightAssistant;delete this->flightActions;delete this->flightJoystick;
}

说明:这表明FlightController像一个管理者,持有其专业工作者的指针

它本身不做繁重的工作,但知道每个任务该找谁

(实现解耦分发的架构)

FlightController::startTakeoffSync()(简化自osdk-core/api/src/dji_flight_controller.cpp

当调用FlightController上的startTakeoffSync()时,它并不直接执行起飞。相反,它将此指令委托给其flightActions模块

// osdk-core/api/src/dji_flight_controller.cpp
ErrorCode::ErrorCodeType FlightController::startTakeoffSync(int timeout) {if (flightActions) { // 检查FlightActions模块是否存在return flightActions->actionSync(FlightActions::FlightCommand::TAKE_OFF,timeout);} else return ErrorCode::SysCommonErr::AllocMemoryFailed;
}

说明:此方法充当简单的传递。它在flightActions对象上调用actionSync(),提供TAKE_OFF指令和超时。

这种模块化设计保持了代码的组织性。(包装一层又一层 &传递)

FlightActions::actionSync()(简化自osdk-core/modules/src/flight/dji_flight_actions_module.cpp

FlightActions模块随后获取TAKE_OFF指令,并使用FlightLink通过线路发送它

// osdk-core/modules/src/flight/dji_flight_actions_module.cpp
ErrorCode::ErrorCodeType FlightActions::actionSync(uint8_t req, int timeout) 
{if (flightLink) { // 检查FlightLink模块是否存在// 通过FlightLink向无人机的飞行控制器发送指令ACK::ErrorCode* rsp = (ACK::ErrorCode*)flightLink->sendSync(OpenProtocolCMD::CMDSet::Control::task, // 控制任务的指令集(void*)&req,                          // 实际的起飞请求sizeof(req),                          // 请求的大小timeout);                             // 响应的超时时间// ... 进一步处理响应 ...} else return ErrorCode::SysCommonErr::AllocMemoryFailed;
}

说明:这是指令实际开始向无人机传输的地方

flightLink->sendSync()处理低层通信,打包TAKE_OFF请求(由req表示)并将其发送到无人机的飞行控制器

结论

FlightController对象是强大的副驾驶,通过提供高级API简化无人机飞行控制,用于复杂动作如起飞、降落和动态机动。

  • 通过将任务委托给专门模块并通过连接器(Linker)管理通信,它抽象了底层复杂性,让你专注于应用程序的逻辑

现在我们知道如何让无人机飞行,让我们探索如何让它执行更复杂的自动化任务并遵循预定义路径


下一章:任务管理器 & 航点任务/热点任务

http://www.dtcms.com/a/535955.html

相关文章:

  • [linux仓库]线程与进程的较量:资源划分与内核实现的全景解析[线程·贰]
  • Flutter开发HarmonyOS鸿蒙App商业项目实战已出炉
  • 宁波网站建设制作公司排名网站优化外链怎么做
  • 开发做网站公司国内网站空间推荐
  • 罗克韦尔PLC通过Modbus TCP转EtherNet/IP智能网关与港口中央监控云平台的互通方案解析
  • 学习threejs,打造交互式泡泡、粒子特效与科幻氛围​​
  • Linux小课堂: Apache虚拟主机配置之基于IP与域名的服务器部署指南
  • MCU的时钟系统
  • OpenCV 4.1.2 SDK 静态库作用与功能详解
  • Hive数据仓库:架构原理与现代化实践指南
  • 当选择中药饮片时,如何确保性价比高的优质选择?
  • FFmpeg 基本数据结构 URLProtocol分析
  • Socket和Websocket编程的区别
  • 龙岗区住房和建设局官方网站巩义做网站优化
  • 网站建设的扁平化设计微信公众平台官网登录入口网页版
  • 《国家哲学社会科学文献中心:类似网站列表》
  • DC-DC降压芯片120V转12V5V3.3V4A大电流大功率H6253L 150V高耐压内置MOS管 电动车电源芯片
  • 学习和掌握RabbitMQ及其与springboot的整合实践(篇一)
  • 【数据集】【YOLO】目标检测游泳数据集 4481 张,溺水数据集,YOLO河道、海滩游泳识别算法实战训练教程。
  • 从“十五五”规划看中国视频基础设施的下一个五年:SmartMediaKit 的战略跃迁与时代机遇
  • ionic 列表:详解移动端UI设计中的列表组件
  • 做网站销售电话术语住房和城乡建设部网站评估
  • C#数据类型:List
  • 帝国网站地图模板酒类网站建设
  • [nanoGPT] 检查点 | `ckpt.pt`记忆 | 预训练模型加载`from_pretrained`
  • Spring事务管理:从原理到实战
  • 彩票类网站开发哪些网站可以做免费推广
  • AOI设置在光伏制造领域的核心应用
  • win7 VSCode 1.70设置R语言的版本,电脑上有两个版本
  • 大疆/地平线招聘要求参考:未来学习方向