【ROS实现简单的节点和包】

提示:环境配置为Ubuntu20.04&ROS Noetic


前言

本期展示如何实现一个简单的节点和包


传感器在ROS中通常有一个对应的节点。
假设要实现一个超声波节点,由于节点不能脱离包而存在,所以要创建这个节点需要先创建一个包。

1.创建一个包

创建一个包,名称取为ssr_pkg,超声波节点就存放在这个包里面
ssr是sensor的缩写,pkg是package的缩写;

2.工作空间设置

VSCOD的开发环境设置(代码提示、编译快捷键)都是以配置文件的形式保存在之前创建的工作空间catkin_ws文件夹中;

3.创建Package包

1.唤出终端
CTRL+SHIFT+T

2.进入到工作空间的src目录下
cd catkin_ws/src

3.输入catkin_create_pkg ssr_pkg rospy roscpp std_msgs
解释:catkin_create_pkg 表示用catkin工具创建一个package软件包;
ssr_pkg表示包的名字;
rospy roscpp std_msgs表示依赖项;
rospy类似Ros结合Python的产物;
roscpp类似Ros结合C++的产物;
std_msgs表示标准消息;
上述指令创建了四个项:前两个是文件,后两个是目录
在这里插入图片描述
可以看到在工作空间catkin_ws=>src目录下创建了一个ssr_pkg文件目录
在这里插入图片描述前面已经配置好了VSCODE,打开这个软件能看到包的结构
在这里插入图片描述

4.rospy、roscpp 、std_msgs依赖项的解释

rospy、roscpp 、std_msgs这些也是包;
如何证明它们都是包?
每个包里都有必要的描述文件package.xml;
利用roscd,可以将当前路径跳转到对应的软件包地址;
roscd roscpp
ls

利用vscode打开package.xml (里面的文件是对包的描述)
code package.xml
在这里插入图片描述

5.各种包的分布与作用解释

/opt/ros/noetic/share/目录下存放的全是ROS的Package包;
这些包的来源有两个:1.安装ROS的时候使用apt安装了ros-noetic-desktop-full附带的一些基础包2.安装好ros后使用apt安装的额外软件包(例如turtlesim、rqt_robot_steering)

这些包和catkin_ws工作空间文件目录下的包有什么区别?
通过apt下载的软件包都是现成的可执行文件,可以直接运行;
catkin_ws工作空间里的软件包都是源码文件,需要编译成可执行程序才能运行;

联想一下.bashrc文件里的source指令
gedit ~/.bashrc #可打开.bashrc文件进行编辑,之前添加的如下指令:
source /opt/ros/noetic/setup.bash
#加载的即是/opt/ros/noetic/share/目录下存放的ROS的Package软件包地址
source ~/catkin_ws/devel/setup.bash
#加载的即是catkin_ws工作空间下的软件包地址
创建的软件包所设置的依赖项就是上述两个地址下的一些软件包,当所需依赖项在这两个包地址中都不存在,新创建的包在编译运行的时候就会报错;

6.添加节点

打开vscode,找到前面创建的ssr_pkg文件目录;
选择上述目录的src子目录,右键选择新建文件夹,输入Ultrasound_node.cpp;
在这里插入图片描述
编写基础节点代码,CTRL+S保存;
编写功能,CTRL+S保存;

#include <ros/ros.h>

int main(int argc,char const *argv[])
{
    
    
    printf("Hello world!\n");
    return 0;
}

源码编译
在CMakeLists.txt为新建节点添加编译规则;
在CMakeLists.txt找到Build章节;
在这里插入图片描述
找到## Declare a C++ executable章节
在这里插入图片描述
将# add_executable(KaTeX parse error: Expected 'EOF', got '#' at position 44: …pkg_node.cpp)去掉#̲号注释放到该文件末尾,作用是为…{PROJECT_NAME}_node是这个可执行文件的名称,这里需要替换成上述新建的节点名称Ultrasound_node,使得文件和包名称一致(后面不容易认错);

src/ssr_pkg_node.cpp表示指定从哪个代码文件进行编译,指定为src目录下的Ultrasound_node.cpp文件;

add_executable(Ultrasound_node src/Ultrasound_node.cpp)
CTRL+S保存;
CTRL+SHIFT+B编译;
编译结束后在调试栏输入任意按键;

如果想在ubuntu的终端进行编译也是可以的:
打开终端CTRL+ALT+T
cd catkin_ws
catkin_make

7.运行节点

打开终端CTRL+ALT+T
1.启动ros
打开新的终端,输入roscore
2.快捷键CTRL+SHIFT+O分出新的终端(前提是已经安装了终端软件sudo apt install terminator)
3.运行Node节点,
确保ros核心处于运行状态;
终端执行rosrun <包名称> <节点的名称>
rosrun ssr_pkg Ultrasound_node
在这里插入图片描述

如果发生报错,需要
gedit ~/.bashrc
在文件末尾写入如下指令并保存,原因前文已经阐明了:
source /opt/ros/noetic/setup.bash
source ~/catkin_ws/devel/setup.bash
在这里插入图片描述

在终端程序里可以使用键盘的上、下键复现过去执行的指令;

ROS的节点相当于一个应用程序,类似常规的C++程序;

8.完善Node节点

上述编写的简单应用程序还不是一个完整的节点,还不能和ROS系统产生互动,需要对其进行完善。

1.初始化该节点
只有初始化后的节点才算是根ROS系统产生了连接并调用ROS核心的各项功能;
这样写会因为参数不批评报错;

int main(int argc,char const *argv[])
{
    
    
    ros::init(argc,argv,"Ultrasound_node");
    printf("Hello world!\n");
    return 0;
}

在这里插入图片描述

需要将上述的main函数的参数的char const *argv[]改写为char *argv[],即去掉const;

此外还有个报错:(编译器找不到这个函数的实现)
undefined reference to `ros::init(int&, char**, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, unsigned int)’
collect2: error: ld returned 1 exit status
解决方案:
将函数所在的库文件链接进来一同编译;
在CMakeLists.txt里找到Build–## Specify libraries to link a library or executable target against选项:
这里详细说明了要链接的库;
在这里插入图片描述复制单#号的代码到文件末尾:

## Specify libraries to link a library or executable target against
# target_link_libraries(${
      
      PROJECT_NAME}_node
#   ${
    
    catkin_LIBRARIES}
# )

按CTRL+/可以通过选中的方式去除或者添加注释

上述指令需要作出微小的改动;

target_link_libraries(Ultrasound_node
  ${
    
    catkin_LIBRARIES}
)

CTRL+SHIFT+B编译
编译通过:
在这里插入图片描述终端里执行rosrun ssr_pkg Ultrasound_node可以运行上述节点

上述程序return 0;产生的问题:
每次运行节点后节点就退出了,如何才能让节点保持运行状态呢?
类似单片机的主程序,加入死循环,让程序一直运行

#include <ros/ros.h>

int main(int argc,char *argv[])
{
    
    
    ros::init(argc,argv,"Ultrasound_node");
    printf("Hello world!\n");
    while(true)
    {
    
    
        printf("Ultrasound_node is working!\n");
    }
    return 0;
}

CTRL+S保存
CTRL+SHIFT+B编译
CTRL+ALT+T打开终端
输入rosrun ssr_pkg Ultrasound_node
现象:打印字符刷屏
在这里插入图片描述如果要关闭上述节点:
CTRL+C
或者
CTRL+SHIFT+W

此外while循环体中的true的条件可以改写成ros::ok()


总结

ROS实现简单的节点和包的步骤总结如下:
1.使用catkin_create_pkg ssr_pkg rospy roscpp std_msgs 创建一个软件包,其中黄色字体是包的名称;
2.在软件包的src文件夹下创建一个节点的cpp源码文件;
3.在节点的源码文件中include包含ROS头文件(#include <ros/ros.h>);
4.构建一个main函数,在函数开头执行ros::init() (即ros::init(argc,argv,“Ultrasound_node”);注意要将main函数参数的const修饰符去掉)
5.构建while死循环,条件中的true可以改写为ros::ok()
6.在CMakeLists.txt中设置节点源码文件的编译规则:
add_executable(Ultrasound_node src/Ultrasound_node.cpp)

target_link_libraries(Ultrasound_node
${catkin_LIBRARIES}
)
注意指令的格式以及上述需要修改的地方
7.编译运行,rosrun ssr_pkg Utrasound_node

常用快捷键汇总:

关闭终端程序窗口
CTRL+C
CTRL+SHIFT+W

开启终端程序窗口
CTRL+ALT+T

vscode的常用快捷键
CTRL+S保存
CTRL+SHIFT+B编译
CTRL+ALT+T打开终端

本期ros的学习分享就到这里了

猜你喜欢

转载自blog.csdn.net/weixin_46187287/article/details/143194332