ardupilot开发 --- Jetson Orin Nano 后篇

在这里插入图片描述

我拼命加速,但贫穷始终快我一步

  • 0~19
  • 20. visp-d455:基于IBVS的Pixhawk无人机视觉伺服
    • 20.1 基础
      • 关于连接、通讯、UDP forward服务:
      • 一些相关的、有用的例程
      • Linux C++程序的gdb断点调试
      • 搭建仿真
      • 解决【testPixhawkDroneTakeoff.cpp例程能解锁但起飞命令无响应,断点模式下却有响应】问题
      • 解决【使用最新的mavsdk版本导致visp编译报错】问题
      • visp中的异步编程:std::promise和std::future
    • 20.2 视觉伺服
      • 知识储备
      • 分析与实践

0~19

请参考前篇。

20. visp-d455:基于IBVS的Pixhawk无人机视觉伺服

20.1 基础

在这里插入图片描述
参考:Tutorial: Image-based visual-servoing on a drone equipped with a Pixhawk
第三方库: MavSDK,librealsense
一些概念:

  • onboard computer:板载计算机、机载计算机

软件:

  • QGC 或 Mission Planner,安装在地面站PC上,windows系统或Ubuntu系统。
  • MavProxy ,安装在板载计算机上。

关于连接、通讯、UDP forward服务:

  • 板载计算机与飞控用USB连接。
  • 板载计算机与地面站PC:通过局域网连接,进行SSH。例如使用思翼科技的链路产品MK32实现局域网连接,使用MobaXterm实现SSH。
  • MavProxy
    运行在:板载计算机上,Ubuntu20.04,安装教程。
    与飞控的连接:USB,即--master=/dev/ttyACM0
    创建3个UDP forward服务,使得其他应用或程序能过通过UDP连接到飞控(与飞控通讯)!
    启动命令如:
    mavproxy.py --master=/dev/ttyACM0 --out=udpout:192.168.30.111:14550 --out=udpout:192.168.30.111:14551 --out=udpout:127.0.0.1:14552
    
  • Mission Planner 或 QGC
    运行在:地面站PC,windows系统或Ubuntu系统都可。
    与飞控的连接:通过mavproxy创建的UDP forward服务:192.168.30.111:14550,其中192.168.30.111是地面站PC的IP地址。
  • keyboard Control app:
    运行在:地面站PC,windows系统或Ubuntu系统都可。
    与飞控的连接:通过mavproxy创建的UDP forward服务:192.168.30.111:14551,其中192.168.30.111是app所在系统的IP地址。通讯使用MavSDK。
  • IBVS app
    视觉伺服程序,visp程序。
    运行在:板载计算机上,Ubuntu20.04.
    与飞控的连接:通过mavproxy创建的UDP forward服务127.0.0.1:14552,其中127.0.0.1是app所在系统的IP地址。通讯使用MavSDK。

一些相关的、有用的例程

  • testPixhawkDroneTakeoff.cpp
    简单的起飞然后降落。
  • testPixhawkDronePositionAbsoluteControl.cpp
    起飞,方形轨迹飞行
  • testPixhawkDronePositionRelativeControl.cpp
    起飞,以起飞点为中心进行方形轨迹飞行
  • testPixhawkDroneVelocityControl.cpp
    起飞之后是一个简单的轨迹,使用速度控制测试一些不同的动作。
  • autopilot_server.cpp

Linux C++程序的gdb断点调试

  • 1)用VSCode打开代码
  • 2)开始调试 在这里插入图片描述
    注意:
    【1】"program": "/home/jetson/shd/visp-ws/visp-build/modules/robot/testPixhawkDroneTakeoff"中不要使用~来表示用户目录,因为VSCode无法识别!!
    【2】编译时:cmake -DCMAKE_BUILD_TYPE=debug否则无法识别断点!

搭建仿真

  • 前提:
    Ardupilot仿真运行在WSL上,visp程序和mavproxy运行在Jetson Orin Nano上!
    WSL和Jetson Orin Nano在同一个局域网!
  • 1)在Jetson Orin Nano上安装mavproxy:
    sudo apt-get install python3-dev python3-pip python3-matplotlib python3-lxml python3-pygame
    pip3 install PyYAML mavproxy --user
    echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
    . ~/.bashrc
    
  • 2)已知Jetson Orin Nano的IP地址为:192.168.100.197
  • 3)在WSL上运行SITL仿真:
    sim_vehicle.py -v ArduCopter --console --out "192.168.100.197:14550" --out "127.0.0.1:14550" -w
    
    其中127.0.0.1:14550可用连接windows端的mission planner,便于查看飞行状态。
  • 4)在Jetson Orin Nano上启动MavProxy
    mavproxy.py --master=udp:192.168.100.197:14550 --out=udpout:127.0.0.1:14552
    
    注意:MavProxy生成的缓存文件mav.parm, mav.tlog ,mav.tlog.raw 要定时清理,这些文件保存在运行命令时的所在目录!不然会占用机载计算机的内存空间!
  • 5)testPixhawkDroneTakeoff.cpp例程调试和分析
    • /home/jetson/shd/visp-ws/visp/modules/robot/test/servo-pixhawk/testPixhawkDroneTakeoff.cpp
    • 构造一个mavsdk 对象;
    • 飞控已启动后,局域网已正常连接;
    • 建立一个TCP、UDP、串口连接,不成功会抛出异常并终止程序。
    • 发送指令之前先调用isRunning()函数,查看飞机是否在运行。
    • mavsdk的析构函数会导致飞机降落??
    • 使用类vpRobotMavsdk控制飞机飞行的方式:
      • 1)先使用setPositioningIncertitude()设置定位和偏航的不确定性参数,如:
        drone.setPositioningIncertitude(0.10, vpMath::rad(5.));
        位置和偏航不确定范围为0.1m和5deg。
        这些参数用于你判断飞机是否到设定的期望位置或偏航角期望值,可以用
      • 2)调用takeControl()让飞机进入guided(ardupilot)或off-board(PX4)模式。
      • 3)使用 setPosition() 或 setVelocity() 去控制飞机移动 。
      • 其他
        设置起飞高度:drone.setTakeOffAlt(5.);
        是否打印详细信息:drone.setVerbose(true);

解决【testPixhawkDroneTakeoff.cpp例程能解锁但起飞命令无响应,断点模式下却有响应】问题

在这里插入图片描述
解决:先用地面站将飞控设置为guided,再运行testPixhawkDroneTakeoff.cpp例程。

解决【使用最新的mavsdk版本导致visp编译报错】问题

背景:visp中的视觉伺服例程使用的固件是px4,跟本人正在使用Ardupilot有较大区别,例如px4中的off-board而Ardupilot中是guided模式,等等。
通过查阅mavsdk源码可知:mavsdk中对guided模式的一些定义和使用在src\mavsdk\core\ardupilot_custom_mode.h中,并且必须是最新的mavsdk源码版本即main分支。
使用最新的mavsdk代码,编译visp时报错,分析和解决如下:
在这里插入图片描述
解决方式:使用合适的构造函数代替:
cpp //mavsdk::Mavsdk m_mavsdk {}; mavsdk::Mavsdk m_mavsdk{mavsdk::Mavsdk::Configuration{mavsdk::Mavsdk::ComponentType::GroundStation}};
在这里插入图片描述
解决方式:
cpp #if (VISP_HAVE_MAVSDK_VERSION > 0x010412) passthrough.unsubscribe_message(MAVLINK_MSG_ID_HEARTBEAT,handle); #else passthrough.subscribe_message_async(MAVLINK_MSG_ID_HEARTBEAT, nullptr); #endif
一些条件编译中的报错处理方法大同小异:
大部分都是#if (VISP_HAVE_MAVSDK_VERSION > 0x010412)下面的代码报错,因为visp作者使用的是mavsdk1.4版本,在例程中执行的是else下面的代码if下的代码则不会被执行所以不会被发现,更新mavsdk到最新版本后再编译visp就会出现编译报错!!
解决方式:
在这里插入图片描述

visp中的异步编程:std::promise和std::future

std::promise和 std::future 是怎么配合工作的?以及它们在异步编程中扮演的角色是什么?参考百度。

20.2 视觉伺服

知识储备

  • 坐标变换矩阵 = 坐标旋转矩阵+坐标平移矩阵
    Rotation Matrix
    本质:坐标变换本质上是一种投影变换,是一种投影关系!从系a转换到系b即把系a中的坐标投影到系b.
    应用:2维,3维,n维
    举例:Xb = Tr * Xa + Tt * Xa
    旋转译自rotation平移译自translations转换译自transformation
    坐标旋转的表示方式有多种:方向余弦矩阵、欧拉角、四元素等等,可参考坐标旋转篇。
    在这里插入图片描述
  • 单应性矩阵(单应矩阵、齐次矩阵、投影变换矩阵)
    Homogeneous Matrix
    本质:是一种坐标转换关系,是两个图像坐标系之间的转换关系矩阵。
    应用:图像投影。
    什么是图像投影?有什么作用?
    对于3D空间的一系列点(某个场景),在不同视觉角度拍摄得到的图像分别记作P1、P2,P1P2中的同一个点p在P1P2的图像坐标系(2D的)的坐标记作【x1,y1】、【x2,y2】,那么它们之间的转换关系可以用单应矩阵表示:【x2,y2】= H * 【x1,y1】
    应用场景:交通场景中,例如需要获得俯视视角下的街道平面各智能体的坐标。而摄像机的位置可能无法做到完全俯视。此时可以标注一些地标,例如地板正方形瓷砖的角作为对应点,之后通过确定的H矩阵来将摄像机的影像转换为俯视视角的坐标。
    参考:Homography matrix(单应矩阵)简介
    计算方式:
    在visp中单应矩阵可以通过3D空间坐标旋转矩阵得到,如:
    vpRxyzVector c1_rxyz_c(vpMath::rad(-10.0), vpMath::rad(0), 0);
    vpRotationMatrix c1Rc(c1_rxyz_c); // Rotation between (c1) and (c)  //c1->c的3d空间坐标旋转矩阵
    vpHomogeneousMatrix c1Mc(vpTranslationVector(), c1Rc); // Homogeneous matrix between (c1) and (c) //c1->c的2d图像(平面)坐标旋转矩阵,即单应矩阵
    
    对于单应矩阵的估计请参考:这里或Tutorial: Homography estimation from points
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 图像矩(Image Moments)
    • 源自:数学学科中随机变量的矩

    • 领域:数字图像处理、计算机视觉、深度学习

    • 对象:二值图像、灰度图像

    • 概念:图像的矩可以概括为图像的某些像素点的灰度值(像素值,在灰度图中像素值即灰度值)的加权平均值,或者是图像具有类似功能或意义的属性的加权平均值。
      意义:可以通过图像的矩来获得图像的一些有用的性质,包括面积、轮廓、几何中心(重心、质心)、方向(特征向量、主轴)等信息 ,这些信息对于图像识别、形状匹配和目标跟踪等应用非常有用。

    • 分类:

      • 原点矩
        (p+q)阶原点矩:
        在这里插入图片描述
      • 中心距
        (p+q)阶原点矩:
        在这里插入图片描述
      • 中心归一化距
        (p+q)阶中心归一化距:
        在这里插入图片描述
    • 矩的应用:

      • 目标区域的面积 = 目标区域的像素个数 = m00
        与零阶混合原点矩有关!
      • 目标区域的质心坐标 =【m01/m00, m10/00】
        与 一阶混合原点矩有关!
      • 目标区域的方向
        与二阶混合中心距有关!
        主轴斜率 = mu20/mu11
        副轴斜率 = mu11/mu20
        在这里插入图片描述
    • opencv中的图像矩介绍
      空间矩:double m00,m10,m01,m20,m11,m02,m30,m21,m12,m03
      中心矩:double mu20,mu11,mu02,mu30,mu21,mu12,mu03
      中心归一化矩:double nu20,nu11,nu02,nu30,nu21,nu12,nu03

    • 参考文献
      https://zh.wikipedia.org/wiki//wiki/矩_(图像)
      https://zhuanlan.zhihu.com/p/519713049
      https://blog.csdn.net/weixin_43212588/article/details/132674015
      https://blog.csdn.net/shuiyixin/article/details/104646531/

分析与实践

  • 代码:servoPixhawkDroneIBVS.cpp
    根据相机的位置来调整位置转换矩阵,例如:
    FLU body frame 和 相机坐标系之间的转换矩阵:
    在这里插入图片描述
    飞机机体坐标系,记作e,即终端坐标系:FLU
    最终的控制量:机体速度,也是要转换到FLU坐标系下。
    相机坐标,记作c
    中间坐标系:原点与c重合,轴与e同向,记作c1
    那么,c1与c的转换矩阵是由自己的安装位置决定的,是已知的。
    e跟c1的转换矩阵:只有位移关系,也是已知的。
    上面的转换矩阵最终求得e到c的转换关系矩阵:cVe
    在这里插入图片描述
    Xn:重心矩视觉特征的x分量误差!!!!!
    Yn:重心矩视觉特征的y分量误差!!!!!
    an:目标区域面积视觉特征误差!!!!!
    atan(1/rho)"):灭点视觉特征误差!!!!!
    在这里插入图片描述
    待续…

运行

cd ~/shd/visp-ws/visp-build/example/servo-pixhawk
./servoPixhawkDroneIBVS --tag-size 0.12 --co udp://:14550

在代码中引用外部库xxxx.h xxxx.so
CMakeLists.txt中:
在这里插入图片描述
pkg-config --cflags --libs gstreamer-1.0

等待解决的问题:

  • cVe坐标系的问题,为什么是相机系到FLU的而不是飞机机体系FRD?为什么视觉伺服计算得到的ve是FRD下表示的?
  • 推流如显示检测结果和误差曲线?
  • 二维码颠倒之后伺服控制量是否正常???
    与摆放位置无关!伺服控制量都是正常的!以第一次识别到二维码时的二维码姿态来计算初始灭点水平线!!!!!
  • 相机坐标系,图像坐标系的轴向?视觉伺服控制量坐标系的轴向??关系???
  • 由guided模式切换到其他模式如loiter和atlHold为什么会自动下降高度直到降落????
  • 如何将鼠标点击事件转换成命令行输入的形式?左击开始,再左击停止,右击停止并降落!!
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/31453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

物联网LORA技术-SX1276/SX1277/SX1278-137MHz至1020MHz低功耗远距离收发器

概述: SX1276/SX1277/SX1278 收发器主要采用LORATM 远程调制解调器,用于超长距离扩频通信,抗干扰性强,能够最大限度降低电流消耗。借助升特的LoRaTM 专利调制技术,SX1276/SX1277/SX1278 采用低成本的晶体和物料即可获得…

SHELL脚本学习(十)初识 sed编辑器

一、sed 编辑器 sed 编辑器被称作流编辑器,根据命令来处理数据流中的数据。 这些数据要么从命令行输入,要么保存在命令文本文件中。 sed编辑器可以执行下列操作: 从输入中读取一行数据根据所提供的命令匹配数据按照命令修改数据流中的数据将…

WIFI6E中的MESH组网功能

什么是WIFI6E和MESH组网? WIFI 6E 是扩展到6GHz 频段的WIFI 6无线通信技术,而“WIFI 6E”中的“6”是指WIFI技术的“第6代”,“E”则是指使用新频段的标准的最新扩展。WIFI 6E通过增加6GHz频段,提供更高的带宽、更低的延迟和更大…

VMware虚拟机下载安装Windows Server 2016

「作者简介」:2022年北京冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础对安全知识体系进行总结与归纳,著作适用于快速入门的 《网络安全自学教程》,内容涵盖系统安全、信息收集等…

从新手小白到红酒大咖:解锁红酒品鉴的终极秘籍,升级之路全攻略

在五彩斑斓的饮品世界中,红酒以其深邃的色泽、丰富的口感和悠久的历史,吸引了无数人的目光。对于红酒的初学者来说,从小白到品鉴师的道路或许充满了未知与挑战,但只要掌握了正确的知识和方法,就能够轻松踏入这个美妙的…

用群辉NAS打造影视墙(Jellyfin篇)

目录 1、安装Jellyfin媒体服务器 2、配置 (1)语言 (2)管理员账户 (3)添加媒体库 (4)指定元数据语言 (5)远程访问设置 (6)修改文件夹权限 (7)刷新电影 (8)启用硬件加速 3、PC浏览器访问 4、手机客户端 5、智能TV客户端 6、解决演员不能显示中文的问…

Android SurfaceFlinger——注册监听调用流程(七)

这一篇我们介绍一下 IComposer 中的另一个比较重要的方法,通过注册监听 Hal 层实现监听驱动的关键动作。 一、注册监听 在前面文章 SurfaceFlinger 的 init() 方法中,我们注册了一个 Callback 到 Hal 层中。最终通过 HIDL 调用到 Hal 层。 1、SurfaceF…

Java从小白到入职 视频教程 下载 因为太大存百度云盘4.zip

Java从小白到入职 视频教程 下载 1---战前准备_00-课程介绍&个人简介.mp4 2---战前准备_00-02-学习方法.mp4 3---战前准备_00-03-你的角色.mp4 4---战前准备_00-04-学习工具.mp4 5---战前准备_00-05-技术岗位概述-Web前端.mp4 6---战前准备_00-06-技术岗位概述-Java语…

Jenkins+gitee流水线部署springboot项目

目录 前言 一、软件版本/仓库 二、准备工作 2.1 安装jdk 11 2.2 安装maven3.9.7 2.3 安装docker 2.4 docker部署jenkins容器 三、jenkins入门使用 3.1 新手入门 3.2 jenkins设置环境变量JDK、MAVEN、全局变量 3.2.1 jenkins页面 3.2.2 jenkins容器内部终端 3.2.3 全…

购物返利系统中的数据处理与优化策略

购物返利系统中的数据处理与优化策略 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 随着电商行业的不断发展,购物返利系统作为一种常见的营销手段…

python-赏月

[题目描述] 在某个星球上看到的月亮大小有一个规律,月亮为每30天一个周期,在这30天的周期里,月亮的大小分别为 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1。 虽然天气很冷,但这个星球上的某个居民今…

MyBatis 源码分析--SqlSessionFactory

前言: 前文我们简单的回顾了 MyBatis 的基本概念,有聊到核心组件,工作流程等,本篇我们开始深入剖析 MyBatis 的核心源码,欢迎大家持续关注。 Mybatis 知识传送门 初识 MyBatis 【MyBatis 核心概念】 MyBatis 源码解…

钒能新材料综合回收利用,钒溶液净化富集工艺之离子交换法

钒电池储能产业作为典型的绿色低碳优势产业,是新型储能领域重要发展方向。钒电池储能具备大规模、长周期等优势,是储能领域的重要组成部分,将成为拓展电能利用、应对可再生能源随机波动、支撑可再生能源高占比电力系统的最佳技术途径之一。 …

力扣1019.链表中的下一个更大节点

力扣1019.链表中的下一个更大节点 从左到右 每个数确定下一个更大节点后 弹出栈中存下标 即res.size() class Solution {public:vector<int> nextLargerNodes(ListNode* head) {vector<int> res;stack<int> st;for(auto ihead;i;ii->next){while(!st.e…

openEuler 24.03 LTS - 华为欧拉开源版(华为 RHEL 兼容发行版)

openEuler 24.03 LTS - 华为欧拉开源版&#xff08;华为 RHEL 兼容发行版&#xff09; 华为红帽企业 Linux 兼容发行版 请访问原文链接&#xff1a;https://sysin.org/blog/openeuler/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sy…

Haproxy部署Web群集

HAProxy是一款开源的、高性能的TCP/HTTP负载均衡器和代理服务器&#xff0c;广泛应用于提高网站和应用的可用性和性能。本篇博客将介绍如何使用HAProxy部署一个高可用的Web集群。 目录 环境准备 安装HAProxy 配置HAProxy 配置解析 配置Web服务器 环境准备 假设我们有以下服…

【C++题解】1026 - 求商数和余数

问题&#xff1a;1026 - 求商数和余数 类型&#xff1a;基础问题 题目描述&#xff1a; 输入 a,b 两个整数&#xff0c;编程求出 a 除以 b 得到的商和余数。 输入&#xff1a; 输入一行&#xff0c;只有两个整数(中间有空格)。 输出&#xff1a; 输出只有一行&#xff0c…

【数学】Leetcode 69. x 的平方根【简单】

x 的平方根 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 注意&#xff1a; 不允许使用任何内置指数函数和算符&#xff0c;例如 pow(x, 0.5) 或者 x ** 0.5 。 示…

nginx升级漏洞补丁

nginx漏洞补丁升级 1、安装patch patch未找到命令&#xff0c;请先下载patch-2.7.6.tar.gz。下载路径&#xff1a;https://mirrors.aliyun.com/gnu/patch/ # 解压 tar -zxf patch-2.7.6.tar.gz # 编译、检查并安装 Patch time { ./configure --prefix/usr && make &am…

优思学院|质量管理中如何应用5W1H或5W2H方法?

5W1H或者5W2H其实是一种"工作方式"&#xff0c;它不是"思考方法"&#xff0c;这种工作方式是通过回答“什么&#xff08;What&#xff09;&#xff1f;为什么&#xff08;Why&#xff09;&#xff1f;谁&#xff08;Who&#xff09;&#xff1f;何时&#…