ROS中的Node和Package
Node节点和Package包
在 ROS中,Node(节点)是一个运行中的进程,它是 ROS 应用程序的基本组成单位。每个节点都执行特定的任务,例如控制机器人的一个部件、处理数据或与其他节点通信。节点之间通过 ROS 的通信系统交换信息,这包括话题(Topics)、服务(Services)和动作(Actions)。
在 ROS中,Package(包)是组织软件的基本单位。一个 ROS 包包含了实现特定功能或任务的代码、数据和资源。ROS 包是模块化的,使得复用和共享代码变得容易。
一个完整功能的机器人包含着各种各样的功能程序,节点的作用就是将各个功能包装实现。节点不可单独安装,需要以包为单位下载。利用Cmake和catkin编译工具,将各个节点以包的身份规整起来,不需要一个一个节点下载。包是节点的容器。
工作空间 workspace
工作空间是一个存放工程开发相关文件的文件夹。就像用IDE创建工程的工程目录一样
有4个主要文件夹:
-
src:代码空间(Source Space)
-
build:编译空间(Build Space)
-
devel:开发空间(Development Space)
-
install:安装空间(Install Space)
创建工作空间(如果尚未创建)
在创建软件包之前,你需要有一个 catkin 工作空间。如果还没有,可以按照以下步骤创建:
在终端中,创建一个新的工作空间目录:
mkdir -p ~/catkin_ws/src
切换到工作空间的根目录:
cd ~/catkin_ws
初始化工作空间:
catkin_make
这将创建一个名为 catkin_ws
的新工作空间。
可以看到多了devel和build目录
但是并没有产生install这个空间
catkin_make install
可以看到此时build、devel、install目录中都有不少文件了
install是安装空间,最终编译生成的可执行文件都会放在这 devel是开发空间,放置开发过程中的可执行文件和库 build是开发过程中的一些中间文件,二进制文件,我们基本上是用不到的
创建Package包
命令:
catkin_create_pkg <包名> <依赖项列表>
依赖项一般是被经常使用的节点,如roscpp
、rospy
、std_msgs
根据教程,我们输入下列指令:
catkin_create_pkg ssr_pkg roscpp rospy std_msgs
在新建以后,我们可以获得这样的CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(ssr_pkg)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
)
####后续省略
第一行为最低cmake版本,第二行为工程名字,第10-14行是寻找依赖包
注释里面,双井号是文字注释和描述,单井号是对应的命令
同时,我们新建包下还多了一个package.xml
文件,同样地,它包含了各种关于这个包的说明,此处省略。
回访依赖项
刚刚我们创建包的时候,使用了roscpp
、rospy
、std_msgs
三个依赖项,由于我们不清楚具体包的路径,所以我们可以用roscd
命令访问其位置
roscd roscpp
可以看到我们进入了opt/ros/noetic/share/roscpp
目录,ls
后发现package.xml
文件,说明这也是一个包
我们用VSCode打开
code package.xml
在opt/ros/noetic/share/
下都是package包,来源有两个:
-
sudo apt-get install ros-<ROS版本>-desktop-full 基础包
-
sudo apt-get install ros-<ROS版本>-xxx 独立扩展包
这里的包都是可执行文件,可直接运行,而catkin工作空间里的都是源码文件,需要编译后才能运行。
在*.bashrc
添加的两行命令:
source opt/ros/noetic/setup.bash
source ~/catkin_ws/devel/setup.bush
分别对应share下的软件包地址和catkin工作空间里的软件包地址
创建Node节点
在src目录下创建cpp文件(假设为chao_node.cpp):
#include <ros/ros.h>
int main(int argc, char const *argv[])
{
printf("Hello,world!\n");
return 0;
}
我们需要使用CMake进行编译,选中ssr_pkg
包下的CMakeLists.txt
,找到:
###########
## Build ##
###########
#........
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/ssr_pkg_node.cpp)
此时还是注释状态,我们将其复制到最后一行,改为:
add_executable(chao_node src/chao_node.cpp)
我们可以使用快捷键Shift + Ctrl + B
快捷键编译,或者手动打开新terminal,输入:
cd catkin_ws
catkin_make
运行Node节点
使用Terminators,使用多个终端进行,下面不同代码块代表不同终端
roscore
#ROS核心运行指令
rosrun ssr_pkg chao_node
#################################
#如果报错,说明没有运行source指令,可以修改bashrc文件
vim ~/.bashrc
#在文件里添加命令
source ~/catkin_ws/devel/setup.bash
Node节点的完善
将chao_node.cpp
文件改为:
#include <ros/ros.h>
int main(int argc, char *argv[])
{
ros::init(argc, argv, "chao_node");//初始化ros
printf("Hello,ROS!\n");
return 0;
}
发生报错:
undefined reference to `ros::init(int&, char**, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)'
编译器找不到这个函数的实现,我们需要把这个函数所在的库文件链接起来,一起编译。
修改CMakeLists.txt
,找到Build
下:
## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
如果我们写了一个一直循环的while()
,最好写成下面的样子,来确保使用Crtl + C
能正常推出:
while(ros::ok()){
/* code */
}
ros::ok():
1、按下Ctrl-C时。
2、我们被一个同名同姓的节点从网络中踢出。
3、ros::shutdown()被应用程序的另一部分调用。
4、所有的ros::NodeHandles都被销毁了。
5、一旦ros::ok()返回false,所有的ROS调用都会失败
进入节点的主循环,如果下列条件之一发生,ros::ok() 返回false,跳出循环:
-
SIGINT 被触发 (Ctrl+C):roscpp 会默认生成一个 SIGINT 句柄,它负责·处理 Ctrl+C 键盘操作使ros::ok() 返回 false
-
被另一同名节点踢出 ROS 网络
-
关闭函数ros::shutdown() 被程序的另一部分调用
-
节点中的所有 ros::NodeHandles 都已经被销毁
一旦 ros::ok() 返回 false, 所有的 ROS 调用都会失效。
其他
1、遇到VSCode报错:标红检测到 #include 错误。
方案一,在c_cpp_properties.json
中添加下列include项:
"includePath": [
"/opt/ros/noetic/include/**",
"/home/eigh18n/catkin_ws/src/wpr_simulation/include/**",
"/usr/include/**",
"/opt/ros/noetic/include"
],
方案二,直接删掉c_cpp_properties.json
,关闭VSCode,再重新打开,让其自动配置c_cpp_properties.json
即可。
2、VSCode不自动补全ROS
以下几种办法:
第一种是添加compile_commands.json
办法:
https://blog.csdn.net/Kingzhy666/article/details/142427112
第二种是修改includePath
https://blog.csdn.net/m0_61819121/article/details/141104198
在评论区遇见了最后的解决方案:
终于解决了,我是把"/usr/include/**",改成"/usr/local/include/**"****,解决的
神!!!!!
3、不重新编译
直接删掉工作空间的build
文件夹然后重新编译
4、python方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!