QGC地面站二次开发(三)Qt 简洁地面站

2023-05-16

目录

多机控制原理

多机控制实现

简洁地面站优化 

1. 飞机的飞行轨迹以不同的颜色区分

2. 控制所有的飞机

3. 将设定航线送给特定的飞机


多机控制原理

多机地面站支持 TCP、 UDP 和串口等三种连接方式,首先我们需要对这两种连接方式抽象出一个基类 LinkInterface,提供两个虚函数分别对应于数据接受和发送处理, 针对不同的连接方式实现 TCP、 UDP 和串口连接相对应的子类TCPLink、 UDPLink 和 SerialLink 并在该类中完成将输入写入 socket 和串口的操作。再实现一个 MAVLinkProtocol 类,它实现将所有接受到的数据统一汇总到MAVlink 的消息解析的接口中,实现消息的解包,每个飞机对应于唯一的system id,当出现不同的 system id 时,构造一个飞机类。该飞机 Vehicle 类实现对飞机的控制(如解锁、起飞、航点等操作)以及数据接受显示(如飞行轨迹绘制等等)。 这些多机通过 MultiVehicleManager 来多机的管理,其中多机管理中通过 activeVehicle 接口来选中当前活跃的飞机,进而实现对该飞机的单机控制。同样的,我们可以可以遍历连接的所有的飞机进而实现对所有飞机的控制
 

连接到多机构造的原理图
 

多机控制原理

多机控制实现

多机控制首先需要实现的是建立地面站和飞机之间的连接,将 TCP、 UDP 和串口通信抽象出一个LinkInterface 基类,实现父类 TCPLink、 UDPLink 和SerialLink 分别对应于 TCP、 UDP、 串口的数读入和写入操作。

接口void _writeBytes(const QByteArray)
意义将数据写入 TCP、 UDP 和串口等。
输入const QByteArray写入的字节流
输出
接口void bytesReceived(LinkInterface* link, QByteArray data);
意义将接受到的字节流通过信号发射出去
输入
LinkInterface* link 接受到数据的链接
QByteArray data接受到的字节流

输出

将接受到的所有数据汇聚到 MAVLinkProtocol 的 receiveBytes 接口中进行通过MAVLink 的解析接口进行消息的解析。

接口void receiveBytes(LinkInterface* link, QByteArray b)
意义将地面站接受到的字节解析为 MAVlink 消息包,并通过信号
messageReceived(LinkInterface* link, mavlink_message_t
message)将解析出的 MAVLink 结构体发射出去。
输入
LinkInterface* link 接受到数据的链接
QByteArray data接受到的字节流

输出

同时再 MAVLinkProtocol 解析到心跳包还会发射 vehicleHeartbeatInfo 信号,在MultiVehicleManager 类的的_vehicleHeartbeatInfo 中进行处理, 判断心跳中出现新的 system id 时构造一个 Vehicle 类。

当前选中的飞机
所在类MultiVehicleManager
接口Vehicle* activeVehicle()
属性activeVehicle
WRITEsetActiveVehicle
NOTIFYactiveVehicleChanged
多机链表
所在类MultiVehicleManager
接口QmlObjectListModel* vehicles(void)
属性vehicles


多机实现关系图

简洁地面站优化 

1. 飞机的飞行轨迹以不同的颜色区分

主要的思想时预选一系列的颜色,将飞机的 ID 和轨迹颜色的相应序列号建立一一的对应关系,并在 Vehicle 中提供一个轨迹颜色的属性提供给 qml 进行访问。首先再 Vehicle 中添加三个静态变量和轨迹颜色属性: 

public:
//连接的飞机的数,每多连接一台飞机该值加 1 ,即在
Vehicle::Vehicle(LinkInterface* link,……)构造函数中加一
static quint16 connectedVehicleCount;
//提供一组轨迹颜色
static QList<QColor> trajectoryColors;
//建立飞机 ID 和轨迹颜色序列号的对应
static QMap<int, int> vehicleIdAndConnectedSeq;
Q_PROPERTY(QColor trajectoryColor READ trajectoryColor
CONSTANT)

对 connectedVehicleCount 和 trajectoryColors 进行初始化

quint16 Vehicle::connectedVehicleCount = 0;
//http://www.sioe.cn/yingyong/yanse-rgb-16/
QList<QColor> Vehicle::trajectoryColors = {
QColor(0x00, 0x00, 0x00), //black unused
QColor(0xFF, 0xFF, 0x00), //Yellow
QColor(0xFF, 0x00, 0x00), //red
QColor(0xFF, 0x8C, 0x00), //DarkOrange
QColor(0xFF, 0x45, 0x00), //OrangeRed
QColor(0xD2, 0x69, 0x1E), //Chocolate
QColor(0xFA, 0x80, 0x72), //Salmon
QColor(0x8B, 0x00, 0x00), //DarkRed
QColor(0xDA, 0xA5, 0x20), //GoldEnrod
QColor(0xFF, 0x00, 0xFF), //Magenta
QColor(0x94, 0x00, 0xD3), //DarkVoilet
};
QMap<int, int> Vehicle::vehicleIdAndConnectedSeq;

在构造函数中添加对颜色的处理

//连接飞机数量加 1
Vehicle::connectedVehicleCount++;
//如果存储飞机 ID 和轨迹颜色序列号的对应的列表为空,则直接添加映射关系,
如果不为空的情况下需要考虑断开连接之后轨迹颜色资源的回收问题,可以通过遍历存
储的 ID 和颜色序列号映射表,直接该轨迹颜色;而如果没有直接在尾部追加即可。
if(Vehicle::vehicleIdAndConnectedSeq.isEmpty()){
Vehicle::vehicleIdAndConnectedSeq.insert(_id,
Vehicle::connectedVehicleCount);
}else{
QMap<int, int>::iterator tmp;
int querySeq = 1;
bool found = false;
for(tmp=Vehicle::vehicleIdAndConnectedSeq.begin();tmp !=
Vehicle::vehicleIdAndConnectedSeq.end();tmp++){
if(tmp.value() != querySeq){
found = true;
Vehicle::vehicleIdAndConnectedSeq.insert(_id, querySeq);
break;
}
querySeq++;
}
if(!found)
Vehicle::vehicleIdAndConnectedSeq.insert(_id,
Vehicle::connectedVehicleCount);
}

同时,断开连接之后,析构函数中将连接的飞机数减 1,同时删除飞机编号和飞机轨迹颜色的映射关系的映射辨析。
 

Vehicle::connectedVehicleCount--;
Vehicle::vehicleIdAndConnectedSeq.take(_id);

之后给 trajectoryColor 添加相关实现:

QColor Vehicle::trajectoryColor()
{
if(Vehicle::connectedVehicleCount < Vehicle::trajectoryColors.count()){
return
Vehicle::trajectoryColors.at(Vehicle::vehicleIdAndConnectedSeq.find(_id).val
ue());
}else{
//generate a color you can make it better
return QColor(0xFF,Vehicle::connectedVehicleCount * 0xF,
Vehicle::connectedVehicleCount * 8);
} }

之后在 FlightDisplayViewMap.qml 中绘制轨迹颜色取 Vehicle 中 trajectoryColor 即可。
 

// Add trajectory points to the map
MapItemView {
model: _mainIsMap ? _activeVehicle ? _activeVehicle.trajectoryPoints :
0 : 0
delegate: MapPolyline {
line.width: 3
line.color: _activeVehicle?_activeVehicle.trajectoryColor:"red"
z: QGroundControl.zOrderTrajectoryLines
path: [
object.coordinate1,
object.coordinate2,
]
}
}

2. 控制所有的飞机

GuidedActionsController 中通过 actionID 进行不同状态切换和指令的实现,实现控制所有的飞机解锁、上锁、返航、起飞、降落、紧急停机等,首先新建如下的 id,遍历 MultiVehicleManager 中的 Vehicles 调用相关的控制接口可以实现相关的操作。

readonly property int actionMVArm: 22
readonly property int actionMVDisarm: 23
readonly property int actionMVRTL: 24
readonly property int actionMVTakeoff: 25
readonly property int actionMVLand: 26
readonly property int actionMVEmergencyStop: 27

之后在 confirmAction(actionCode, actionData)中追加一系列消息提醒的。

case actionMVArm:
confirmDialog.title = qsTr("All arm")
confirmDialog.message = qsTr("Command all vehicles to arm")
confirmDialog.hideTrigger = true;
break;
case actionMVDisarm:
confirmDialog.title = qsTr("All disarm")
confirmDialog.message = qsTr("Command all vehicles to disarm")
confirmDialog.hideTrigger = true;
break;
case actionMVTakeoff:
confirmDialog.title = qsTr("All takeoff")
confirmDialog.message = qsTr("Command all vehicles to takeoff")
confirmDialog.hideTrigger = true;
break;
case actionMVRTL:
confirmDialog.title = qsTr("All RTL")
confirmDialog.message = qsTr("Command all vehicles to RTL")
confirmDialog.hideTrigger = true;
break;
case actionMVLand:
confirmDialog.title = qsTr("All Land")
confirmDialog.message = qsTr("Command all vehicles to Land")
confirmDialog.hideTrigger = true;
break;
case actionMVEmergencyStop:
confirmDialog.title = qsTr("All Emergency Stop")
confirmDialog.message = qsTr("Command all vehicles to Emergency
Stop")
confirmDialog.hideTrigger = true;
break;

executeAction 中追加代码实现当我们触发了确认操作需要执行的一系列动作。

case actionMVArm:
rgVehicle = QGroundControl.multiVehicleManager.vehicles
for (i = 0; i < rgVehicle.count; i++) {
rgVehicle.get(i).armed = true
}
break
case actionMVDisarm:
rgVehicle = QGroundControl.multiVehicleManager.vehicles
for (i = 0; i < rgVehicle.count; i++) {
rgVehicle.get(i).armed = false
}
break
case actionMVLand:
rgVehicle = QGroundControl.multiVehicleManager.vehicles
for (i = 0; i < rgVehicle.count; i++) {
rgVehicle.get(i).guidedModeLand()
}
break
case actionMVRTL:
rgVehicle = QGroundControl.multiVehicleManager.vehicles
for (i = 0; i < rgVehicle.count; i++) {
rgVehicle.get(i).guidedModeRTL()
}
break
case actionMVTakeoff:
rgVehicle = QGroundControl.multiVehicleManager.vehicles
for (i = 0; i < rgVehicle.count; i++) {
rgVehicle.get(i).guidedModeTakeoff(actionAltitudeChange)
}
break;
case actionMVEmergencyStop:
rgVehicle = QGroundControl.multiVehicleManager.vehicles
for (i = 0; i < rgVehicle.count; i++) {
rgVehicle.get(i).emergencyStop()
}
break

接下来我们在页面上添加出发动作的按钮,在 MultiVehicleList.qml 中添加:

Column {
id: mvCommandsColumn
anchors.margins: _margin
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("The following commands will be applied
to all vehicles")
color: _textColor
wrapMode: Text.WordWrap
font.pointSize: ScreenTools.smallFontPointSize
}
Row{
spacing: _margin
QGCButton {
text: qsTr("arm")
onClicked:
guidedActionsController.confirmAction(guidedActionsController.actionMVArm)
}
QGCButton {
text: qsTr("disarm")
onClicked:
guidedActionsController.confirmAction(guidedActionsController.actionMVDisarm
)
}
QGCButton {
text: qsTr("EmergencyStop")
onClicked:
guidedActionsController.confirmAction(guidedActionsController.actionMVEmerge
ncyStop)
}
}
Row{
spacing: _margin
QGCButton {
text: qsTr("Takeoff")
onClicked:
guidedActionsController.confirmAction(guidedActionsController.actionMVTakeof
f)
}
QGCButton {
text: qsTr("Land")
onClicked:
guidedActionsController.confirmAction(guidedActionsController.actionMVLand)
}
QGCButton {
text: qsTr("RTL")
onClicked:
guidedActionsController.confirmAction(guidedActionsController.actionMVRTL)
}
}
Row {
spacing: _margin
QGCButton {
text: qsTr("Pause")
onClicked:
guidedActionsController.confirmAction(guidedActionsController.actionMVPause)
}
QGCButton {
text: qsTr("Start Mission")
onClicked:
guidedActionsController.confirmAction(guidedActionsController.actionMVStartM
ission)
}
}
}
}

在 FlightDisplayView.qml 给 MultiVehicleList 传 guidedActionsController属性值,实现鼠标点击触发操作动作。

MultiVehicleList {
anchors.margins: _margins
anchors.top: singleMultiSelector.bottom
anchors.right: parent.right
anchors.bottom: parent.bottom
width: ScreenTools.defaultFontPixelWidth * 30
visible: !singleVehicleView.checked
&& !QGroundControl.videoManager.fullScreen
z: _panel.z + 4
guidedActionsController:guidedActionsController
}

3. 将设定航线送给特定的飞机

该实现的主要的思想是当前活跃的飞机切换时,擦出之前规划的航线,同时后续发送航线时,将当前的航线信息通过当前活跃的飞机发射出去。PlanMasterController 的 start 函数将MultiVehicleManager 的activeVehicleChanged 信号和它自身的_activeVehicleChanged 槽函数绑定,来实现对当当前飞机更改时的相关操作。
 

void PlanMasterController::_activeVehicleChanged(Vehicle* activeVehicle)
{
if (_managerVehicle == activeVehicle) {
// We are already setup for this vehicle
return;
}
if (_managerVehicle) {
// Disconnect old vehicle
………
//删除地面站上的航点信息,未删除飞机中的航点信息
_missionController.removeAll();
_missionController.setDirty(false);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QGC地面站二次开发(三)Qt 简洁地面站 的相关文章

  • ubuntu 修改pip指定路径

    参考这篇文章 还有 这篇文章 第二篇更好一点 xff0c 亲测成功
  • CrowdHuman数据集介绍

    CrowdHuman数据集是旷世发布的用于行人检测的数据集 xff0c 图片数据大多来自于google搜索 CrowdHuman 数据集数据量比较大 xff0c 训练集15000张 xff0c 测试集5000张 xff0c 验证集4370张
  • CityPersons数据集介绍

    CityPersons数据集是cityscape的一个子集 xff0c 它只包含个人注释 有2975张图片用于培训 xff0c 500张和1575张图片用于验证和测试 一幅图像中行人的平均数量为7人 xff0c 提供了可视区域和全身标注 C
  • CUHK-SYSU数据集介绍

    该数据集是一个大规模的人员搜索基准 xff0c 包含18184张图像和8432个身份 根据图像来源 xff0c 数据集可以分为两部分 xff1a 街道捕捉和电影 xff1a 在街拍中 xff0c 图像通过手持摄像机收集 xff0c 跨越数百
  • ETHZ数据集介绍

    Ess等构建了基于双目视觉的行人数据库用于多人的行人检测与跟踪研究 该数据库采用一对车载的AVT Marlins F033C摄像头进行拍摄 xff0c 分辨率为640 480 xff0c 帧率13 14fps xff0c 给出标定信息和行人
  • Swin Transformer V2

    Swin Transformer V2 论文链接 xff1a https arxiv org pdf 2111 09833 pdf 代码链接 xff1a https github com microsoft Swin Transformer
  • Jetson_Xavier_NX使用教程1(刷机)

    刷机教程 一 xff1a 准备 1 xff1a 准备需要一个tf卡 xff0c 容量最好大点 xff0c 我买的128G的 2 xff1a 还有两个软件一个是格式化卡的软件 xff0c 一个是将镜像文件写入的卡的软件 格式化卡的软件 写入镜
  • Jetson_Xavier_NX使用教程2(简单实用)

    本文会介绍一些刷机后的基本操作 1 风扇控制 刚开始插入电源风扇不转我以外坏了 xff0c 后来才发现并没有 Xavier NX的风扇在系统内核中有一套自动控制温度和转速的算法 xff0c 经过我观察大约在40度左右的时候会自动开启风扇进行
  • NVIDIA Jetson NX使用教程3配置pytorch环境

    本节主要记录 xff0c 安装pytorch及torch vision 1 下载Pytorch 因为jetson属于arm架构的机器 xff0c 所以需要去nvidia的官网下载对应的安装包而不是pytroch的官网 官网链接 xff0c
  • Java 基于 IETF RFC 2617 身份认证

    IETF RFC 2617 身份认证 是基于 HTTP 协议进行验证的 xff0c 认证过程中需要发送两次 HTTP 请求 xff0c 第一次请求服务器返回 401 和 认证标识 xff08 nonce xff09 xff0c 第二次访问H
  • 判断一台机器是大端序还是小端序

    在几乎所有的机器上 xff0c 多字节对象都被存储为连续的字节序列 例如在C语言中 xff0c 一个类型为int的变量x地址为0x100 xff0c 那么其对应地址表达式 amp x的值为0x100 且x的四个字节将被存储在存储器的0x10
  • STL容器保存智能指针并将this指针通过emplace传入STL容器所造成的致命问题(【double free or corruption (out)】和【bad_weak_ptr】)

    我用std queue保存了一个Message类型的智能指针 queue lt shared ptr lt MessageA gt xff0c 然后在Message类型中来将this指针插入队列 xff0c 使用std queue push
  • 实时动态定位(RTK)

    内容来着网络 实时动态定位 xff1a Real Time Kinematic RTK技术的关键在于使用了GPS的载波相位观测量 xff0c 并利用了参考站和移动站之间观测误差的空间相关性 xff0c 通过差分的方式除去移动站观测数据中的大
  • 几个实用的 Bat 脚本命令

    文章目录 1 截图2 息屏后锁屏3 查看当前的路径4 倒计时5 密码输入6 比较两个文本的差异 1 截图 start snippingtool 2 息屏后锁屏 powershell Add Type 39 DllImport 34 user
  • 学习cmake的使用和CMakeLists.txt

    1 学习cmake的使用和CMakeLists txt 文章目录 1 学习cmake的使用和CMakeLists txt1 1 cmake外部构建基础1 2 让每个源文件目录都包含一个CMakeLists txt1 3 安装 1 4 构建静
  • ROS系统基础知识梳理(四) 串口通信

    ROS系统基础知识梳理 四 串口通信 学习ROS系统 xff0c 初步接触到ROS系统外接传感器 xff0c 传感器通过Uart通信向台式机发送数据 xff0c 内容涉及到ROS调用串口数据 串口数据校验 以及欧拉角转换四元数 任务系统 x
  • Keil5中添加新的.c和.h文件

    目录 在Project的文件夹中添加添加路径使用include 在Project的文件夹中添加 如图1所示 xff0c 在User的文件夹上右键 xff0c 添加已有文件 图1 添加路径 然后需要在options for Target xf
  • 学习c语言的总结

    学习时间 xff1a 早上9点 晚上9点 学习内容 xff1a 利用c语言对 的代码学习 xff0c 并根据自己的理解编写代码 xff0c 最后整合学习的代码和自己理解的代码 xff0c 编写出更优的代码 学习体会 xff1a 对一个问题举
  • C/C++程序编译成可执行程序步骤图文源码详解

    一个C 43 43 程序被编译为目标程序的过程中经历了四个部分 xff0c 分别是预处理 编译 汇编 链接 下面将通过一个简单的C 43 43 代码分别执行预处理 编译 汇编 链接四个步骤后的结果和基本原理讲解 注意 xff1a 博主是在u
  • 【linux】程序找不到动态库.so的解决办法|查看.so动态库信息|.so动态库加载顺序

    目录 找不到 so解决方法 方法一 xff1a 添加环境变量 方法二 xff1a 复制so文件到lib路径 方法三 xff1a xff08 推荐 xff09 添加ldconfig寻找路径 方法四 xff1a 在编译目标代码时指定该程序的动态

随机推荐

  • 使用Arduino开发ESP32(08):TCP Client与TCP Server使用

    文章目录 目的TCP Client使用说明常用方法基础使用演示作为WEB Client使用 TCP Server使用说明常用方法基础使用演示作为WEB Server使用 总结 目的 TCP是网络应用中常用的功能 xff0c 很多高级功能也是
  • ModBus学习笔记

    一 什么是ModBus xff1f 1 预备知识 xff08 1 xff09 什么是通讯协议 xff1f 通信协议是指双方实体完成通信或服务所必须遵循的规则和约定 通过通信信道和设备互连起来的多个不同地理位置的数据通信系统 xff0c 要使
  • Jetson TX2 将系统迁移到SD卡,系统文件修改方式

    系统迁移步骤 xff1a 格式化SD卡 复制系统到SD卡 修改系统文件 1 在原系统盘内 cd boot extlinux sudo vim extlinux conf 该文件初始内容如下 xff1a TIMEOUT 30 DEFAULT
  • svn中打标签的一种方法

    SVN创建标签的方法 方法一 xff1a TortoiseSVN客户端浏览创建 选中需要创建标签的目录 xff0c 右键 gt copy to 在弹出框中输入新建标签所在的URL地址 xff0c 填写log信息 xff0c 确定 方法二 x
  • (图解 HTTP)一篇文章带你深入了解 HTTP 协议

    文章目录 一 了解客户端和服务器通讯的过程二 HTTP 是不保存状态的协议三 请求 URI 定位资源四 告知服务器意图的 HTTP 方法1 GET xff1a 获取资源2 POST xff1a 传输实体主体3 PUT xff1a 传输文件4
  • VC编译选项

    C 在预处理输出中保留注释语句 c 只编译 xff0c 不连接 xff0c 相当于在 34 Build 34 菜单下选择了 34 Compile 34 D 定义常量和宏 xff0c 与源程序里的 define 有相同效果 E 预处理C C
  • C语言中String库函数

    为了以后学习以及查阅方便 xff0c 转贴在此 xff0c 若有雷同 xff0c 敬请包含 文中内容摘自 C程序设计教程 xff08 美 xff09 H M Deitel P J Deitel著 xff0c 薛万鹏等译 xff0c 机械工业
  • JAVA与海康威视人脸机对接,使用ISUP方式

    1下载DEMO包 下载地址 JAVA海康威视人脸机isup方式对接demo包 Java文档类资源 CSDN下载 2设置依赖 需要把examples jar和jna jar引入项目 3配置本地 config properties 把ip地址设
  • Keil工程

    文章目录 1 Keil工程添加源文件和头文件 xff08 c和 h xff09 的方法1 方式一2 方式二 2 keil工程生成的MAP文件取消优化 1 Keil工程添加源文件和头文件 xff08 c和 h xff09 的方法 1 方式一
  • 2020-09-28

    通用异步收发器 xff08 Universal Asynchronous Receiver Transmitter xff0c 通常称作UART xff0c 是一种串行 异步 全双工的通信协议 xff0c 在嵌入式领域应用的非常广泛 UAR
  • 【cmake】CMakeList添加库|添加头文件|添加路径|add_executable、add_library、target_link_libraries|添加编译选项|宏开关

    目录 官网查阅 开胃菜例子 CMakeLists生成和添加依赖库 CMakeLists更多小例子 生成 so共享库文件 调用 so共享库文件 生成一个可执行程序的 CMakeList 生成一个 so动态库的 CMakeList add li
  • TCP连接的建立

    前言 xff1a TCP的问题已然困惑我很久了 xff0c 一直是一知半解 xff0c 靠记忆来记住TCP连接的过程 xff0c 不能根本上理解 xff0c 漏洞百出 xff0c 最近抽时间把TCP经典书籍 TCP IP详解 阅读了一下 废
  • 【Nokov】动作捕捉系统培训笔记

    Nokov度量科技 简介 xff1a Nokov是一种光学三维动作捕捉系统 xff0c 采用红外镜头捕捉被动发光标记点 xff0c 构建三维数据的动作采集与分析系统 xff0c 运用于运动分析 步态康复 模拟训练 机械仿生 机器人 无人机
  • 【Nokov】动作捕捉系统标定与机械臂各坐标系的说明

    导语 xff1a 这一周的工作先是完成了度量系统Nokov的标定 xff0c 然后对机械臂自身的编码器得到的坐标值与动作捕捉系统Nokov测得的坐标值进行了比较 xff0c 来观察二者之间的误差 在这个过程中我对Nokov软件Seeker的
  • 【Nokov】关于动捕系统获取刚体姿态的说明

    动作捕捉系统Nokov获取刚体的姿态信息 前言 xff1a 对于动捕系统软件Seeker的基本使用以及获取单个Marker的位置操作已经比较熟悉了 xff0c 对于机械臂而言 xff0c 接下来就是获取它的姿态信息 xff0c 经过昨天下午
  • 【机器人】机械臂与动捕Nokov的深入了解

    导语 xff1a 每次的实践操作后 xff0c 总能刷新我对机械臂以及Nokov的认识 xff0c 既让我惊喜不已 xff0c 同时也让我知道我掌握的还远远不够 xff0c 需要不断的学习 关于机械臂 示教器上NOA姿态表示方式 xff1a
  • Ubuntu18.04+ROS+kalibr标定工具箱安装编译

    目录 前言 一 安装ROS 1 设置镜像源 2 更新软件包索引 3 安装ROS 4 测试ROS是否安装成功 二 安装kalibr melodic 1 kalibr简介 2 安装kalibr 3 测试kalibr 参考文献 xff1a 前言
  • okhttp源码分析,Builder.ParseResult.parse(null, url) HttpUrl.parse(url) 方法详细分析

    在使用okhttp3时 以下方式具体对url进行了怎样的处理 查了许多资料没有发现有关介绍查询源码进行分析添加相关方法介绍 Request request 61 new Request Builder url 34 https www be
  • MP地面站二次开发教程(二)MP的框架与修改

    目录 MP高级功能 主界面基本修改 1 菜单名称背景修改 2 主窗体语言修改 3 主要窗体目录位置 4 菜单栏删除 5 入口函数 6 参数配置函数 定制修改步骤 1 主题环境修改 2 菜单精简 去掉冗余菜单按键 3 功能按键添加 新建按钮实
  • QGC地面站二次开发(三)Qt 简洁地面站

    目录 多机控制原理 多机控制实现 简洁地面站优化 1 飞机的飞行轨迹以不同的颜色区分 2 控制所有的飞机 3 将设定航线送给特定的飞机 多机控制原理 多机地面站支持 TCP UDP 和串口等三种连接方式 xff0c 首先我们需要对这两种连接