在前面小节已经实现了ROS工作空间的创建,这里开始功能包的开发实战了。
首先创建功能包:
cd ~/ROS/src
#创建功能包topic,指定依赖roscpp和std_msgs包
catkin_create_pkg topic roscpp std_msgs
执行完上述步奏,会在topic功能包里面生成一下文件和文件夹
其中include存放头文件,src存放源文件,接下来开始撸代码:
进入src目录,创建发布话题的节点源码
#进入src目录
cd topic/src
#创建publisher_node.cpp、subscriber_node.cpp文件
touch publisher_node.cpp subscriber_node.cpp
编辑publisher_node.cpp代码如下
//开发ROS节点必须包含的头文件
#include "ros/ros.h"
//包含ROS提供的标准消息类型
#include "std_msgs/String.h"
//C++标准库
#include <sstream>
//进入main函数
int main (int argc, char **argv)
{
//初始化一个叫“publish_node”的节点
ros::init(argc,argv,"publish_node");
//实例化节点句柄
ros::NodeHandle nh;
//创建一个Publisher,发布名为ssj_chatter的topic,消息类型为 chatter_example::Persion,队列长度为100
ros::Publisher ssj_pub = nh.advertise<chatter_example::Person>("ssj_chatter",1000);
//设置自循环频率,需要搭配该类的sleep方法使用,100代表频率(100HZ)
ros::Rate loop_rate(100);
int count = 0;
while(ros::ok())
{
//实例化String,取名为msg
std_msgs::String msg;
//实例化标准字符串流
std::stringstream ss;
//初始化字符串流
ss << "hello" << count;
msg.data = ss.str();
//ROS_INFO打印信息到终端
ROS_INFO("%s",msg.data.c_str());
//发布消息
ssj_pub.publish(msg);
//让回调函数有机会被执行的声明
ros::spinOnce();
//休眠实现延时
loop_rate.sleep();
++count;
}
return 0;
}
编辑subscribe_node.cpp代码如下:
#include "ros/ros.h"
#include "std_msgs/String.h"
//回调函数
void topicCallback(const std_msg::String::ConstPtr& msg)
{
//将接收到的信息打印到终端
ROS_INFO(" [%s] ", msg->data.c_str());
}
int main(int argc,char **argv)
{
//初始化节点
ros::init(argc,argv,"subscribe_node");
//实例化一个节点句柄
ros::NodeHandle nh;
//订阅话题ssj_chatter中的消息
ros::Subscriber ssj_sub = nh.subscribe("ssj_chatter",1000,topicCallback);
//程序进入自循环挂起状态
ros::spin();
return 0;
}
修改CMakeLists.txt,至于CMakeLists.txt是什么在此不再解释,可以另行学习cmake的知识。
打开topic目录下的CMakeLists.txt,作如下修改
#指定编译该功能包所需要依赖的包
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation
)
#要编译的文件,和可执行文件名
add_executable(publish_node src/publish_node.cpp)
#指定要链接的库
target_link_libraries(publish_node ${catkin_LIBRARIES})
add_executable(subscribe_node src/subscribe_node.cpp)
target_link_libraries(subscribe_node ${catkin_LIBRARIES})
打开topic目录下的package.xml 文件,添加下列内容:
#编译依赖的工具,是catkin 必不可少的
<buildtool_depend>catkin</buildtool_depend>
#编译依赖项
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>gometry_msgs</build_depend>
<build_depend>message_generation</build_depend>
#编译导出依赖项
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<build_export_depend>gometry_msgs</build_export_depend>
#执行依赖项
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<exec_depend>message_runtime</exec_depend>
<exec_depend>gometry_msgs</exec_depend>
修改CMakeLists.txt 和 package.xml之后进入,工作空间执行编译指令
catkin_make
待编译完成之后:
#运行ros的核心服务
roscore
#运行topic功能包的publish_node节点
rosrun topic publish_node
#运行topic功能包的subscribe_node节点
rosrun topic subscribe_node
扩展内容: package.xml与CMakeList的关系
CMakeList.txt文件并不知道package.xml文件的存在。