X3派 大疆无人机-SLAM单目建图.上 上篇文章在此,猝不及防的小小的火了一下,让我清汤寡水的生活有了一丝慰藉。
好活
无所谓了,彻底放飞自我:
摇晃鸭送给大家
目前你要知道的一点是,ROS说到底就是一个接收和发送的过程,这里就先对发送的信息来一个打包了。
这里需要看一下无人机的SDK来构建这个东西。
代码语言:javascript复制https://dl.djicdn.com/downloads/RoboMaster TT/Tello_SDK_3.0_User_Guide_cn.pdf
官网有,自取
目前先了解这个就行
视频流也是需要的
我们先建立一个这样的文件夹
把我们需要得信息来封装一下,ROS得Msg是固定的几种
WIFI的配置也有
在Cmake里面写好我们要编译的信息
ROS终归就是个软件的框架,最终的还是需要一个语言去落实,这里就编译成C 的。
XML文件呢,就是这个包的身份证,编译的时候依赖谁,包的作用等等
对一个机器人来说,我们需要控制的对吧?
少废话,整快点
显示无人机图像并提供键盘控制。
T 用于起飞,L 用于降落无人机,F 用于向前翻转,E 用于紧急停止,WASD 和箭头用于控制无人机运动。
SDK中获得我们的控制命令
在具体的写以前,我想让大家这里这个控制文件的一个宏观的设计
头写上
我们需要C 的ROS2控制库
附有完整的API,使用的时候记得多查
假如你不查,我觉得就是欠揍,你咋个那么厉害哟~
捏爆你的双黄蛋
关ROS中常用的消息。包括动作消息 (actionlib_msgs)、诊断 (diagnostic_msgs)、几何图元 (geometry_msgs)、机器人导航 (nav_msgs) 和常见传感器 (sensor_msgs),例如激光测距仪、相机、点云。
这里有用这个
这表示自由空间中的速度,分为线性部分和角度部分。你等我写完这些就阅读ROS的源码。
这个消息包的作用是:隔离消息以在共享依赖关系中的堆栈之间进行通信允许依赖堆栈中的节点进行通信,而无需相互依赖。该堆栈被设计为包含多个堆栈之间使用的最常见消息,以提供共享依赖关系,从而消除有问题的循环依赖关系。
下面的代码是:ROS 主题发布,你别问为什么这么写,因为别人也是这样写的。
这里是ROS2的写法
代码语言:javascript复制ROS1到ROS2的很多消息定义类似,大部分一样只是多了一个msg域 我自己说的(夸我)
#include <ros/ros.h>----> #include <rclcpp/rclcpp.hpp>
这也是变化
才学两天模板就出来搞这了
这里推荐一本书
ROS1的定时器使用的是while,二代就牛逼了一些。
每个节点都有一个句柄列表(与计时器、订阅者、客户端、服务、等待对象相关),这些句柄被放入等待集中。每当节点旋转(执行周期)时,都会检查此等待集以查看是否准备好执行任何操作。
对于计时器,这仅仅意味着检查计时器是否“过期”-> 如果是,则执行回调。
对于订阅,可以将其想象成 rcl 层询问 rmw 是否在 DDS 级别发生了任何事情,例如接收消息。
但基本上,节点只是检查是否为正确类型的回调触发了正确的事件。回调中的内容无关紧要。你可以在里面放任何东西。
这个函数的原型
看参数就行
接着我们就可以写出这样的代码,妈的,这就好像我教你1 1,但是留作业是微积分的样子,但是写程序就是这样。事实上还有一段回调没有写,开始~
还是先解释一下这个东西,我们设计了一个节点,这个节点不停的发送SDK里面的指令。里面的命令在外部被订阅,收到就会执行任务。
之后里面搞了一个定时器。1ms看看有没有东西发生,或者这样说吧,1ms就看看回调函数有没有活干,我想回调函数是骂骂咧咧的。
回调函数摸头,定时器你礼貌吗?
我之前是个土狗,没有用过回调函数,曾经看过很多的文章,正经的不正经的都有,但是抛开一切。回调函数无非就是个等候调用的小老弟。说大白话有点不装逼,来一段拽一些的:顾名思义,回调函数就是回头再调用它。回调函数其实就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。
这里我也决定把我的笔记分享给大家:
看懂了吗?
快说看懂了啊,我这截图不浪费功夫咩???
在你假装看懂的基础上继续看这个回调函数:
先看个大的
这些是OpenCV的东西,就是先搞个控制的照片,填充窗口,然后就是创建,显示啥的。15ms看看有没有按键按下,还记得我前面的东西吗?
就看一个,如果按键按下
就把信息发出去
如果都没有就调用手动的函数,妈的,老母猪戴胸罩,一套又一套,再写个函数。
好烦
没啥好说的,把来自键盘的信息发出去
发给这个
最后这个信息发的时候注意组装
最后收尾,漂亮~
添加的编译文件
在上面写一下关于OpenCV的依赖项
内容准备的有点多的了。。。接下来一个Node,用于控制DJI Tello无人机的软件包,根据DJI提供的官方SDK提供数据和对无人机的控制。
还是先看看组织的样子
这个东西有点复杂,我怕我写不下去。
先导入库
代码有点长,倒着看,就是一个节点的启动
四元到欧拉
欧拉到四元
我不讲这个,因为我们是APP不是算法文章,下次讲,而且这两个函数是可以复用的。
节点里面有这些函数
这么努力的写不知道有没有人在看,太伤心了
节点一开始内置的参数,不要改动。主要是连接的信息
把内部的参数获取,进行类型的转换
这里看这个,因为主题是单目的SLAM,所以镜头的参数就很重要了
相机的参数是可以从外部获取的
这些参数是哪里来的额?是使用关于标定的ROS包搞来的
这里就会把外部标定的数据传给变量。
这个是外部的Tello控制包,下次我给你解读
和日志功能连用,来告诉操作者(就是我,连接情况)
一个节点的收发功能也启动到位
三大线程也启动
无人机准备起飞!
发布的节点是这样的,应该可以看的明白把。有图像,镜头标定信息,Tello的状态,ID,IMU的数据,电池,温度,里程计等,后面还有坐标的广播。
订阅的是外部的信息,起飞?迫降,控制啥的,翻跟头
就是ROS之间,信息的传输都是标准的信息,所以这里需要进行一个信息的转换,对于CV来说,思路就是按照顺序,追踪着视频流走就好,这里就是一个信息的捕获,转换,发送,而且是作为线程处理的一个函数。
另外一个是无人机的信息线程
死锁发送
一个电源的节点,其实有很多的信息,有不变的,有变的,大家都会发出来,但是你具体的使用,都要去选择的订阅, 不然我怎么知道你要啥信息,信息是从tello搞来的
tello的状态是这样的,注意看我选择的关键词,tello都是外部获得的。感兴趣的姿态信息都有了,
相机的信息是yaml里面存的,就像外挂一样,也一起发送了。
这键盘灯就是帮我找到在哪里,上面的字一个也看不清
剩下就是里程计的发送线程了
里程计说到底就是距离和角度,自己看要啥
这个相当于Util函数,写几个和机器本身相关的函数
可以通过这样的信息,搭配RC指令来精确的控制俺们的小机机
写完了!!!
本来应该上机给大家展示一下编译过程的,但是我好累,明天文章的开头展示,这里放上编译的脚本:
代码语言:javascript复制#!/bin/bash
cd ../workspace
rm -rf build install log
rosdep install -i --from-path src
colcon build --symlink-install --packages-select tello tello_control tello_msg
# 表示编译时如果 install 中文件已经存在于 src 或者 build 文件夹中,
# 就用超链接指向该文件,避免浪费空间,也可以实现同步更新
昨天因为一个JK引男女老少都进来看看有啥好东西,所以今天也得搞点不一样的,这就去找。
老夫压箱底图片一张
代码语言:javascript复制https://www.jianshu.com/p/8c7516fc3b1a
代码语言:javascript复制https://wenku.baidu.com/view/3cc58005bfd126fff705cc1755270722192e5920.html
代码语言:javascript复制https://github.com/ros/common_msgs
代码语言:javascript复制https://www.pianshen.com/article/9755969759/
代码语言:javascript复制http://docs.ros.org/en/rolling/Concepts/About-ROS-Interfaces.html?highlight=geometry_msgs
代码语言:javascript复制https://github.com/ament/ament_lint/blob/master/ament_cmake_lint_cmake/doc/index.rst
代码语言:javascript复制https://docs.ros2.org/latest/api/rclcpp/