小白先熟悉ROS和M300的操作:
ubuntu18.04下安装好ROS 的Melodic版本。
Nano板子电源是5V。
开机关机飞机,短按然后长按3s
飞机线怎么接:
osdk口接电源(裂痕要往外),这根线串到低配版GPU运算平台的Jetson Nano(这个传的数据带宽很少),这个板载计算机nano有一个usb接口接到M300组件的串口,这样就可以传输高数据的图像了,虽然搞多一条线去高速传输也依然会出现数据丢失的现象,但总比原来的那条低带宽数据传输效果好很多。M300RTK飞机模拟器助手官网下载
新建ROS工作空间,先编译ubuntu下的onboard SDK-master,再编译ros:Onboard-SDK-ROS,了解编译过程,两个都放在src直接编译就好了。
如果要使用视觉功能就要cmake … -DADVANCED_SENSING=ON获取ROS版本:
首先 在终端输入
roscore
再打开新终端 输入
rosparam list
再输入
rosparam get /rosdistro因为我们用roslaunch命令(比rosrun方便一点,因为每次配置当前目录都可能不一样)运行ROS 的主节点,UserConfig.txt 要放在.ros文件夹里面,每次连那台飞机都要在这里改,
也因为我们用的是OSDK 4.0.1,所以用
roslaunch dji_osdk_ros dji_vehicle_node.launch(待会再运行)
如果是用OSDK ROS 3.8
roslaunch dji_osdk_ros dji_sdk_node.launch执行catkin_make命令后,catkin文件夹下有三个文件夹:build、devel和src。build文件为编译空间(The Build Space),其中的
CMake*和catkin文件为工作包和项目保存缓存信息、配置和其他中间文件;
devel文件为开发空间(The Development Space),该文件夹保存编译后的程序,这些程序不需要安装就可以进行测试运行。编译完后,记得运行ROS节点或者roscore时先source devel/setup.bash来配置当前工作空间(所以最好在.bashrc里面添加 source /home/xxx/catkin_Drone/devel/setup.bash)
然后去catkin_test/src/Onboard-SDK-ROS 改dji_verhicle_node.launch
改acm_name 默认是0,想确定是哪一个就要终端输入 ls /dev/tty*去看acm名字是多少,正常是0,不是0的话要么dji_verhicle_node.launch 改为其他名字要么就重新拔插一下飞机那一条线的串口改serial_name 默认是ttyUSB0。
改好之后sudo chmod 777 /dev/tty*
改baud_rate为1000000
改app_id为1098852(每台飞机对应一个,在OSDK_ID_key.txtl里面)
改enc_key为XXXX(每台飞机对应一个,在OSDK_ID_key.txtl里面)一个终端roscore
另一个终端rostopic list查看话题列表
比如用rostopic echo /dji_osdk_ros/gps_position来看飞机位置roslaunch dji_osdk_ros dji_vehicle_node.launch启动dji_vehicle_node,如果有failed to initialize ACM Linker channel! 那么是串口名字不对你要么重新拔插要么改文件中串口acm名字
ack dji_vehicle_node 相当于IDE里面的全局搜素这个变量,然后发现这个有指向cpp文件,发现这个cpp在dji_osdk_ros里面,所以这个就是源文件了
dji_sdk_node.cpp–》该节点为dji_sdk包的核心,成员变量包括无人机的状态信息,服务信息,控制信息,话题发布和订阅信息。win下面下一个ros飞机模拟器,不用登录,直接连接到电脑。然后就会找到M300,然后在Onboard SDK里面勾选启动api和遥控时空不切SDK(这个是为了飞机失控时候可以用ax1里面进行控制)
此时修改后要关飞机重新连接,长按关机,短按再长按就开机,注意此时是否所有线都接好并且飞行遥控器从视觉定位转到GPS定位(视觉定位是可以在室内看的清情况下起飞,而在室内却转到GPS模式证明是
在模拟器下面用),每当修改了启动节点或者其他东西,模拟器里面飞机不动了那么关闭软件再打开或者rosservice list 查看ros服务
rosservice call /camera_task_zoom_ctrl (call是rosservice的命令,它可以改变飞机的IOS,摄像头啊,变焦那些数据并且同步修改飞机遥控器的操作和显示)查看ROS软件包依赖:
rospack depends1查看直接依赖,rospack depends查看间接依赖。
直接开始学习
- ROS的几个重要概念:节点、消息、主题、服务(转载)
ROS是机器人操作系统(Robot Operating System)的简称,用于编写机器人的软件程序。
ROS是一种具有高度灵活性的软件架构,能够帮助软件开发者快速创建机器人应用软件。
ROS提供了一系列程序库和工具,包括:硬件抽象、设备驱动、库函数、可视化、进程间消息传递和软件包管理等。ROS是一个分布式的进程(也就是“节点”)框架,这些进程被封装在不同的程序包或功能包中。
ROS可以分成两层,底层是操作系统层(通常不需要用户关心),上层则是实现不同功能的软件包,如感知、定位、规划、控制等。
了解了ROS的目录文件结构之后:
本文主要介绍几个ROS的重要概念:节点(node)、消息(message)、主题(topic)、服务(service),ROS控制器(ROS
master),帮助初学者快速了解ROS。
1、节点(node)
节点是进行运算任务的进程。一个系统可以由很多节点组成,节点也可以称为软件模块。
ROS是以节点的形式开发的,节点是根据其目的,可以细分的可执行程序的最小单位。
节点使基于ROS的系统在运行时更加形象化,当许多节点同时进行时,可以将不同节点的通讯绘制成下图。
2、消息(message)
节点之间通过传送消息进行通讯。每一个消息都是一种数据结构。
ROS的消息支持标准的数据类型(整型、浮点型、布尔型等),还包括数组、结构体、自定义的数据类型等等。
3、主题(topic)
消息以一种 发布/订阅 的方式传递,一个或多个节点可以在一个给定的主题中发布消息,多个节点可以订阅同一个主题。
发布者和订阅者不了解彼此的存在。
4、服务(service)
基于主题 发布/订阅 的通信方法是一种异步方法,该 发布/订阅 模型是一种很灵活的通讯模式。但在某些情况下,需要一种同时使用请求和响应的同步消息交换方案,ROS提供了叫做服务的消息同步方法,是一种一对一的机制。
一个服务被分成服务服务器和服务客户端,其中服务服务器只在有请求(request)的时候才响应(response),而服务客户端会在发送请求后接收响应。与话题不同,服务是一次性消息通信。
因此,当服务的请求和响应完成时,两个连接的节点将被断开。
服务通常被用作请求机器人执行特定操作时使用的命令,或者用于根据特定条件需要产生事件的节点。
由于它是一次性的通信方式,在网络上的负载很小,所以它也被用作代替 基于主题 发布/订阅 的通信手段。
5、ROS控制器(ROS master)
在上面概念的基础上,需要有一个控制器,可以使所有节点有条不紊地执行,这就是ROS的控制器(ROS master)。
ROS master 通过RPC(Remote Procedure Call Protocol,远程过程调用)提供登记列表和对其他节点/主题的查找。
总结为一句话就是:ROS中最小的进程单元就是节点(node),节点之间通过主题(topic)传递消息数据(message)。
消息记录包(bag)是一种用于保存和回放ROS消息数据的文件格式。ROS提供了可以将bag文件可视化的图形工具,详见这个文章:
ROS文件目录结构(转载)

如上图所示,首先是最顶层的catkin工作空间,它是整个ROS工程中层次最高的概念。
工作空间也就是管理和组织ROS工程项目文件的地方。其下主要的一级目录有四个:
src:源空间
build:编译空间
devel:开发空间
install:安装空间
其中,
最顶层的工作空间(可以任意命名)和 src (必须为src)文件夹是需要自己创建;
build 和 devel 文件夹由 catkin_make 命令自动创建;
install 文件夹由 catkin_make install 命令自动创建。
catkin 是 ROS 定制的编译构建系统,是对CMake的扩展,对ROS这样大体量的工程有更好的支持,同时也简化了操作。
注意:使用 catkin_make 编译之前一定要回到最顶层的工作空间。

1、src:源空间
存放功能包(package)。
功能包是ROS文件系统中组织程序文件的基本单元,也就是catkin编译的基本单元。一个 package 下必须包含 CMakeLists.txt 和 package.xml 两个文件:
CMakeLists.txt 文件中规定了功能包的编译规则,包括指定功能包名称,指定编译依赖项,指定要编译的源文件,指定要添加的消息格式文件/服务格式文件/动作格式文件,指定生成的消息/服务/动作,指定头文件搜索目录,指定链接库搜索目录,指定生成的静态链接库文件,指定需要链接的库文件,指定编译生成的可执行文件以及路径等等。
package.xml 文件定义了功能包的属性信息,包括包名,版本号,作者,编译依赖和运行依赖等。
另外,
include 和 src 分别存放头文件(.h)和源程序文件(.c/.cpp等);
scripts 存放脚本文件(比如Python文件 .py,shell文件 .sh);
launch 存放 launch文件(.launch),用于批量运行多个可执行文件;
config 存放配置文件(.yaml等);
此外,还有自定义的通信格式文件,包括消息(.msg)、服务(.srv)以及动作(.action)。
2、build:编译空间
存放CMake和catkin的缓存信息、配置信息和其他中间文件。
3、devel:开发空间
存放编译后生成的目标文件,包括头文件、动态&静态链接库、可执行文件等。
4、install:安装空间
即开发完成后的安装包。
将这个博主文章复现一遍再说
期间会遇到名字不一样或者各种编译的问题,稳住。ROS节点订阅与发布学习也可以看下面这两个:
看这个测试就好
也可以参考这个
ROS 服务(service)编程学习也可以看这个:
ROS 服务编程可以在Home文件下的.bashrc文件最后加入
~/catkin_test/devel/setup.bash
这样就可以避免每次启动ROS节点或者roscorer核心时候都输入一次(因为Linux是多用户操作系统,每个重新建立一个shell其环境变量都是新的,所以新的终端也要在这样运行一次)
常用操作:启动测试和订阅服务和话题
###启动测试
roscore//启动ros核心- 新终端:
./Dji_osdk_lanuch.sh//里面是roslanuch dji_osdk_ros_vehicled.sh,启动dj的ros里面的相关文件 rosrun flight_control my_test//启动节点
###订阅服务
rosservice listrosservice call/get_camera_version双击tab 出现"playoad_index:0"//你可以修改0为其他数字(这个是直接测试)- ack 服务->ack 回调函数 ->找到srv文件->知道输入输出类型
- 主程序main() land_control.cpp 加入订阅语句(主程序记得在功能包/src/CMakeLists.txt里面添加add_executeable等依赖)
- osdk_data.cpp 写构造函数输入和输出
- osdk_data.h 写定义的构造函数
- 主程序get_camera_version(0)去验证
- 可以在osdk_common.cpp 这个方法类里面写个函数对输入的数据“0”处理。//只是举个例子,测试时候可以不这样做
- 这程序main()里对osdk_common.cpp计算后返回的string数据做逻辑处理或者输出结果。
catkin_make后rosrun flight_controll my_test- 提示:src服务要添加到cmakelist里面。如果想知道发布者的输入输出,那么ack 这个服务的发布者就知道在dji_vechicle_node.cpp里面调用,也知道在dji_vechicl_noce_publisher.cpp里有输入是什么值。
###订阅话题
rostopic list//查看想要的话题acktopic //在dji_osdk_ros_vehicle.node或者sample函数里面找出并确定该topic是在DJ的ROS包还是原来ROS包里。并且确定消息载体和载体类型rostopic echo /Dji-osdk-ros/Vo_position//eg:输出Vo_position数据看看是否我们想要的东西。(可跳过)rostopic type /dji-osdk-ros/Vo_position//查看这个Vo_positino的类型(可跳过)ack载体 //找出回调函数,这个回调函数你可以自己重新改名字。- 在mian里面去订阅该话题
- 在osdk_data.cpp 里去定义载体
- 在osdk_data.h 里添加函数声明
学习过程中遇到的问题:
理解清楚:OSDK-ROS,OSDK英文全拼就是Onboard Software Development kit(板载软件开发包),ROS就是Robot Operating System(机器人操作系统)。大疆的软件开发包有两种,带ROS和不带ROS的,带ROS就是这个软件开发包是基于机器人操作系统这个平台上运行的,而不带ROS的就相当于在“裸板”上运行的,所以区别在于(带ROS需要创建ROS工作空间,并将SDK源码放入catkin_ws工作空间进行编译执行,而且DJI-Onboard-SDK 是底层的ROS(即osdk-ubuntu),DJI-Onboard-SDK-ROS是大疆的上层ROS,上层会调用底层的东西,我们平时开发一般只会通过上层调用,除非要修改底层调用GPU进行视频流解码之类的)。所以编译时候先下载osdk编译,然后下载osdk-ros,然后有自己的功能包的话直接catkin_make即可。
如果更新ROS版本到4.1.0的话,需要先编译osdk-ubuntu,然后再编译osdk-ros,期间可以会遇到一些库丢失或者是Userconfig出错,解决一下就好了。
ls /dev/tty*看接口名字是否:ttyACM0,不是则拔一下USB接口。还有记得下面第二张图的接口一定要接上,否则找不到这个ttyACM0接口。

catkin_make时候找不到SDL2Config.cmake:看这位up主
小海龟动不了:要把鼠标放在第三个控制小乌龟的终端上
创建cpp文件
touch main.cpp
- 不用每次启动节点都要source一次->bashrc文件里面输入source命令
- 按照ROS教程中的命令:$ rosmsg show beginner_tutorials/Num执行产生错误
- ROS(C++)中的subscribe的参数介绍
- 在code oss编辑器里如果时间错误之后编译,你需要随便在代码加个空格,编译才会生效。这是因为时间的问题导致的。
- 控制命令是:通过串口协议<-ubuntu<-调用API<-ROS<-flight_control这样来发送数据的。DJ的dji-osdk-ros是对原来的ros系统进行改造添加,所以要看清楚调用的是ROS包还是dji-osdk-ros包里面的话题和服务(有Dji-osdk-ros::才是Dj里面的ROS包的内容,没有说明就是原来ros里面的)。
- ROS Nodehandle句柄的理解
- 查看消息类型:
rosmsg show std_msg/Bool
- 想显示云台的视频流::
方法一:通过python脚本直接订阅并用cv2显示

方法二:通过运行roscore->roslaunch dji_vehicle_node->rostopic echo /dji_osdk_ros/camera_h264_stream(验证数据是否接收到了)->./camera_service.sh->rosrun rviz rrviz->(rviz里面去Add->By topic-> /main_camera_images中的image就可以实时显示视频流了)

- 想发送string类型json格式的数据到MQTT服务器,然后服务器再web端去接收这个数据并呈现:
用mqtt_bridge实现,直接将这个功能包放在工作空间里面就可以直接调用,非常方便!!!
安装步骤看我的另外一个博客文章。
原理是:msg消息->发布到/echo主题->mqtt_bridge里面的echo->mqtt_bridged里面的back->mqtt_bridge的返回的/back
demo_params.yaml文件修改如下:
主程序调用时候就直接订阅就可以了,如下图所示:

期间会遇到ROS to mqtt时,mqtt上接收到的数据为��data�hello,(具体看这位博主如何解决)这个的话改bridge.py就好了。具体修改如下:


而且我也遇到了将string类型的json格式(去掉\n\t这些字符)发过去之后,订阅这个回调函数显示我发送的字符串数据是正常的,但通过rostopic echo /back输出的字符串是有’\’ 这个字符 的,这个应该是mqtt_bridge里面的/back 返回显示是那样定义的,但不影响我做判断就不管它了,如下图所示:
12. 疑惑
我想问一下,在一个ros进程里面用4个异步AsyncSpinner线程 ,然后用10个不同频率的定时器createTimer。那请问这10个定时器是如何分配到异步线程里的?我的理解是这10个定时器都是分配到这个进程里面的主线程里面了,当有回调的时候会查看4个子线程哪个处于空闲,然后就会去调用,如果定时器过多,创建的多线程过少,那么依然会导致部分定时器的回调函数处于阻塞状态,不知理解是否正确,求解答。
13. catkin_make 、catkin_make_isolated、catkin build区别
catkin系列工具的产生是为了更好的build使用cmake构建的pkg,catkin_make是cmake的升级版,可以认为是对cmake进一步封装的高级命令。然后是catkin_make_isolated,相比catkin_make的一个改进是将工作空间下的所有的pkg进行独立编译,缺点就是编译时间比catkin_make更长。最后就是catkin build,改进了catkin_make_isolated和catkin_make,能够对工作空间下每个pkg独立编译,并且使用更方便,对用户来讲命令更友好