分为以下三种:
1,话题编程
2,服务编程
3,动作编程
在功能包learn_communication/src/
目录下添加talker.cpp
文件:
1,添加头文件
//添加ROS包
#include "ros/ros.h"
//添加ROS string变量
#include "std_msgs/String.h"
2 Ros结点初始化,定义结点名称
ros::init(argc,argv,"talker");
3创建结点句柄
通过创建结点句柄,方便我们对结点资源进行管理(包括发布者,订阅者等等的管理)
//创建结点句柄
ros::NodeHandle n;
4创建发布者
创建一个Publisher的对象,发布名为chatter的话题,消息类型为std_msg::String,发布者队列长度为1000(将数据放入队列,避免发布过快,接受者接收不到)
ros::Publisher chatter_pub = n.advertise("chatter",1000);
5发布消息
//发布消息
chatter_pub.publish(msg);
6完整代码
//添加ROS包
#include "ros/ros.h"
//添加ROS string变量
#include "std_msgs/String.h"
int main(int argc, char **argv)
{
//ROS结点初始化
//创建talker结点
ros::init(argc,argv,"talker");
//创建结点句柄
ros::NodeHandle n;
//创建一个Publisher,发布名为chatter的话题,消息类型为std_msgs::String
ros::Publisher chatter_pub = n.advertise("chatter",1000);
//设置循环的频率 10HZ
ros::Rate loop_rate(10);
int count = 0;
while(ros::ok())
{
//初始化std_msgs::String 类型的消息
std_msgs::String msg;
std::stringstream ss;
ss<<"hello world"<
1,初始化ROS结点
//初始化ROS结点
ros::init(argc,char **argv,"listrner");
2,创建结点句柄
//创建结点句柄
ros::NodeHandle n;
3,创建一个订阅者
并且绑定订阅的话题,收到消息的回调函数
//创建一个接受者,订阅名为chatter的话题,注册回调函数chatterCallback
ros::Subscriber sub = n.subscribe("chatter",1000,chatterCallback);
4,创建回调函数
//接收消息的回调函数
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard :{%s}",msg->data.c_str());
}
5,循环等待回调函数
//循环等待回调函数
ros::spin();
6,完整代码
#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结点
ros::init(argc,argv,"listrner");
//创建结点句柄
ros::NodeHandle n;
//创建一个接受者,订阅名为chatter的话题,注册回调函数chatterCallback 1000代表消息队列的大小
ros::Subscriber sub = n.subscribe("chatter",1000,chatterCallback);
//循环等待回调函数
ros::spin();
return 0;
}
当我们用c++写完这两个结点的功能后,需要将代码编译为可执行文件(用python写就不用编译,Python本身就是可执行文件)
1,更改编译配置文件
更改功能包目录下的cmaklists.txt文件:
将add_executable(${PROJECT_NAME}_node src/learing_communication_node.cpp)
取消注释,并更改内容
更改为:
意思是将src目录下的talker.cpp编译为talker可执行文件
add_executable(talker src/talker.cpp)
链接第三方库:
因为这里没用到其他库,只有ROS默认的库,所以我们链接catkin_LIBRARIES
target_link_libraries(talker ${catkin_LIBRARIES})
更改后的完整内容为:
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
2,编译
在工作空间目录catkin_ws
下打开终端;
命令:
catkin_make
编译完成:
可以在devl目录下看见我们编译完成的可执行程序:
devel/lib/learing_communication/
1,启动rosMaster
新建终端
roscore
2,启动listener
用rosrun
命令
rosrun 功能包名 结点名
rosrun learing_communication talker
rosrun learing_communication listener
前面的话题我们都是发送一个string类型的数据,但是我们想要发送一组有类型的数据怎么办呢?
通过自定义话题来解决
1,定义msg文件
在功能包目录下创建msg文件夹(存放msg文件):
在文件夹下创建person.msg文件:
定义person相关信息,并且可以定义常量(unknown,male,female):
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
2,在package.xml中添加功能包依赖
打开功能包目录下的package.xml添加以下:
message_generation
message_runtime
注意:
3,在cmakelist.txt添加编译选项
打开功能包目录下的cmakelist.txt做以下更改:
• find_package( …… message_generation)
• catkin_package(CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime)
• add_message_files(FILES Person.msg) generate_messages(DEPENDENCIES std_msgs)
添加功能包:
find_package( …… message_generation)
catkin_package(CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime)
add_message_files(FILES Person.msg) generate_messages(DEPENDENCIES std_msgs)
4,编译
将msg文件编译成对应语言的头文件:
在工作空间根目录进行编译:
catkin_make
可以看见他被编译成不同语言接口供我们使用
5,查看自定义的消息
rosmsg show person