#### Topic Demo程序
1,创建程序包(在工作空间的src目录下):
cd catkin_ws/src/ catkin_create_pkg topic_demo roscpp std_msgs
2,修改package.xml作者邮箱:
cd topic_demo;gedit package.xml
3,编译测试(在工作空间目录下:cd ../.. 或者 cd ~/catkin_ws):
catkin_make
4,定义新的消息:
cd ~/catkin_ws/src/topic_demo mkdir msg cd msg;gedit gps.msg
输入以下代码并保存:
string state #工作状态
float32 x #x坐标
float32 y #y坐标
5,通过rosmsg show命令,检查ROS是否能够识消息:
rosmsg show topic_demo/gps
将会看到:
float32 x
float32 y
string state
6,查看package.xml, 确保它包含一下两条语句(接近末尾处),如果没有,添加进去:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
7,修改修改CMakeLists.txt文件:
1)在find_packag函数的COMPONENTS的列表里增加message_generation,就像这样:
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation #需要添加的地方
)
2)设置运行依赖:
# 用于配置ROS和packge配置文件和Cmake文件
catkin_package(
...
CATKIN_DEPENDS message_runtime
...
)
3)用你的.msg文件替代Message*.msg:
add_message_files(FILES gps.msg) #指定从哪个消息文件生成
4)取消generate_messages()的注释:
generate_messages(DEPENDENCIES std_msgs) #用于生成消息 #DEPENDENCIES后面指定生成msg需要依赖其他什么消息,由于gps.msg用到了flaot32这种ROS标准消息,因此需要再把std_msgs作为依赖
8,编译生成gps.msg对应的头文件:
cd ~/catkin_ws catkin_make
9,编写源代码
1)创建消息发布节点:
roscd topic_demo/src/ gedit talker.cpp
输入以下代码:
#include <ros/ros.h>
#include <topic_demo/gps.h> //自定义msg产生的头文件
int main(int argc, char **argv)
{
ros::init(argc, argv,"talker"); //用于解析ROS参数,第三个参数为本节点名
ros::NodeHandle n; //实例化句柄,初始化node
topic_demo::gps msg; //自定义gps消息并初始化
msg.x = 1.0;
msg.y = 1.0;
msg.state = "working";
ros::Publisher pub = n.advertise<topic_demo::gps>("gps_info",1); //创建publisher,往"gps_info"话题上发布消息
ros::Rate loop_rate(1.0); //定义发布的频率,1HZ
while(ros::ok()) //循环发布msg
{
msg.x = 1.03 * msg.x;
msg.y = 1.01 * msg.y;
ROS_INFO("Talker: GPS: x = %f, y = %f",msg.x,msg.y);
pub.publish(msg); //发布m消息
loop_rate.sleep(); //根据前面的定义的loop_rate,设置1s的暂停
}
return 0;
}
2)创建消息接收节点:
gedit listener.cpp
输入以下代码:
#include <ros/ros.h>
#include <topic_demo/gps.h>
#include <std_msgs/Float32.h>
void gpsCallback(const topic_demo::gps::ConstPtr &msg)
{
std_msgs::Float32 distance; //计算离原点(0,0)的距离
distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2));
ROS_INFO("Listener: Distance to origin = %f, state: %s",distance.data,msg->state.c_str()); //输出
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("gps_info", 1, gpsCallback); //设置回调函数gpsCallback
ros::spin(); //ros::spin()用于调用所有可触发的回调函数,将进入循环,不会返回,类似于在循环里反复调用spinOnce()
//而ros::spinOnce()只会去触发一次
return 0;
}
10,CMakeLists.txt文件修改
在 CMakeLists.txt 添加以下内容,生成可执行文件
add_executable(talker src/talker.cpp) #生成可执行文件talker
add_dependencies(talker topic_demo_generate_messages_cpp)
#表明在编译talker前,必须先生编译完成自定义消息
#必须添加add_dependencies,否则找不到自定义的msg产生的头文件
#表明在编译talker前,必须先生编译完成自定义消息
target_link_libraries(talker ${catkin_LIBRARIES}) #链接
add_executable(listener src/listener.cpp) #声称可执行文件listener
add_dependencies(listener topic_demo_generate_messages_cpp)
target_link_libraries(listener ${catkin_LIBRARIES})#链接
11,编译
cd ~/catkin_ws catkin_make
注:如果只想编译工作空间某一个包:catkin_make -DCATKIN_WHITELIST_PACKAGES="包名"
例如:
catkin_make -DCATKIN_WHITELIST_PACKAGES="topic_demo"
12,运行
打开新终端输入命令
roscore #启动master节点
启动talker节点:
rosrun topic_demo talker
启动talker节点:
rosrun topic_demo listener