从0到1手把手教你学会编写ROS基础程序包(C++版):让ROS说Hello World

目的:学会如何用C++编写一个ROS节点,并创建launch文件
最终效果:创建出一个hello_world的基础程序包,以及一个发送节点,一个接收节点,用于传递“Hello World”字符串消息,并创建启动文件
1、新建一个名为catkin_ws的工作空间

//创建一个名称为catkin_ws的文件夹
mkdir -p ~/catkin_ws/src
//切换到src文件夹
cd catkin_ws/src
//初始化工作空间
catkin_init_workspace
//回到工作空间根目录
cd ..
//编译工作空间
catkin_make

2、配置环境变量

//home文件夹下打开.bashrc文件
gedit ~/.bashrc
//添加如下两行命令并保存
source ~/catkin_ws/devel/setup.bash
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:~/catkin_ws/

3、创建ROS程序包

//切换到src文件夹下
cd catkin/src
//创建名为hello_world的ROS程序包,以后创建其他的包也是此方法,只需修改包的名称即可
catkin_create_pkg hello_world roscpp rospy std_msgs

4、创建发布消息的节点
这是一个发布“Hello World”字符串消息的节点,将其保存在src/talker.cpp文件中,以此为例,告诉你以后自己写其他发布消息的节点哪些要修改,哪些只需照抄。

#include "ros/ros.h"//创建ROS节点必须包含的头文件,固定格式
#include "std_msgs/String.h"//如果要在节点中使用某种特定的消息类型,一定要包含的消息头文件,此处根据实际情况决定
#include <sstream>//C++中用来处理面向流的输入和输出的标准库,此处根据实际情况决定
int main(int argc,char **argv)//初始化节点必须要的玩意,固定格式
{
	ros::init(argc,argv,"talker");//初始化一个名为talker的节点,以后写其他的节点只要修改talker就行
	ros::NodeHandle n;//创建名为n的节点句柄,自己写程序只要改n这个地方就行
	ros::Pulisher chatter_pub=n.advertise<std_msgs::String>("chatter",1000);//ROS节点中发布话题的方式,chatter_pub是发布者实例,发布消息的类型是std_msgs/String的话题,话题名称为chatter,队列大小为1000,n为访问实例,要修改的话就改提到的这几个地方
	ros::Rate_loop_rate(10);//制定循环的频率,此处为10HZ,固定格式
	int count=0;//进入节点的主循环,在节点未发生异常的情况下将一直在循环,固定格式
	while(ros::ok())//当Ctrl+C按下时,ros::ok()将会返回false,固定格式
	{
		//初始化std_msgs::String类型的消息
		std_msgs::String msg;
		std::stringstream ss;
		ss<<"hello world"<<count;
		msg.data=ss.str();//用data来存储字符串
		//发布消息
		ROS_INFO("%s",msg.data.c_str())//ROS_INFO类似于cout和printf
		chatter_pub.publish(msg);//发布封装完毕的消息msg
		//循环等待回调函数
		ros::SpinOnce();//用来处理节点订阅话题的所有回调函数
		//按照循环频率延时,固定格式
		loop_rate.sleep();
		++count;
	}
	return 0}

5、创建接收消息的节点

#include "ros/ros.h"//固定格式
#include "std_msgs/String.h"//如果要在节点中使用某种特定的消息类型,一定要包含的消息头文件,此处根据实际情况决定
//接收到订阅的消息,进入回调函数
void chatterCallback(const std_msgs::String::ConstPtr & msg)
{
	ROS_INFO("I heard: [%s]", msg->data.c_str());//将接收的消息打印出来
}
int main(int argc,char **argv)//固定格式
{
	ros::init(argc,argv,"listener");//初始化一个名为listener的节点
	ros::NodeHandle n;//创建名为n的节点句柄
	ros::Subscriber sub=n.subscribe("chatter",1000,chatterCallback);//创建一个Subscriber的话题,注册回调函数chatterCallback
	//循环等待回调函数
	ros::Spin();
	return 0

6、编辑CMakeLists.txt文件
在hello_world/src文件夹中,修改CMakeLists.txt文件,加入如下两段

add_executable(talker src/talker.cpp)  
target_link_libraries(talker ${catkin_LIBRARIES})  
add_dependencies(talker beginner_tutorials_generate_messages_cpp)  
  
add_executable(listener src/listener.cpp)  
target_link_libraries(listener ${catkin_LIBRARIES})  
add_dependencies(listener beginner_tutorials_generate_messages_cpp) 

7、编译C++节点

cd ~/catkin_ws
catkin_make

8、执行C++节点
打开三个终端,分别运行如下三条命令

roscore
rosrun hello_world talker
rosrun hello_world listener

9、创建启动文件
ROS启动文件的优势在于可以在一条指令中运行任意数量的节点,launch保存在包目录中的launch文件夹下面,此处命名为talker_listener

<launch>
	<node name="listener_node" pkg="hello_world" type="listener" output="screen"/>
	<node name="talker_node" pkg="hello_world" type="talkerer" output="screen"/>
</launch>

node name: 该节点的名字,相当于代码中 ros::init() 中设置的信息,有了它代码中的名称会被覆盖;
pkg: 表示该节点的package,相当于 rosrun 命令后面的第一个参数;
type: 可执行文件的名字,rosrun 命令的第二个参数;是否可以理解为要执行的节点;
output=“screen”: 将标准输出显示在屏幕上而不是记录在日志中
类似的还有:
respawn=“true” :请求复位,roslaunch 会在该节点崩溃时重新启动该节点;
required=“true” :必要节点,roslaunch 会在该节点终止时终止其他活跃节点;
ns=“namespace”: 命名空间,为节点内的相对名称添加命名空间前缀
arg name=“arguments”:节点需要的输入参数

10、更改文件可执行权限

cd catkin_ws/src/hello_world/launch
sudo chmod +x talker_listener.launch 

11、执行launch文件

launch hello_world talker_listener.launch

12、查看计算图

rqt_graph

13、查看话题列表

rostopic list
  • 1
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落体偏东

原创动力来自大佬们的鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值