自动驾驶(六十七)---------ROS学习笔记(3)

       前面介绍了ROS的原理,简单的编译,如何创建一个节点,和其他节点收发信息呢?本篇主要介绍这部分内容.

1. 编写发布器节点

       在catkin_ws中新建的功能包取名为topic_example, 在这个功能包中分别编写两个节点程序publish_node.cpp和subscribe_node.cpp,发布节点(publish_node)向话题(chatter)发布std_msgs::String类型的消息,订阅节点(subscribe_node)从话题(chatter)订阅std_msgs::String类型的消息.
       a. 在catkin_ws/src/目录下新建功能包topic_example,并在创建时显式的指明依赖roscpp和std_msgs。打开命令行终端,输入命令:
         $ cd ~/catkin_ws/src/      
         $ catkin_create_pkg topic_example roscpp std_msgs      
           ###创建时显式的指明依赖roscpp和std_msgs。依赖会被默认写到功能包的CMakeLists.txt和package.xml中

       b. 源代码编写, 在新建的功能包topic_example/src/目录下新建两个文件publish_node.cpp和subscribe_node.cpp,并将下面的代码分别填入。  

///////publish_node.cpp

#include "ros/ros.h" 
#include "std_msgs/String.h" 
#include <sstream>

int main(int argc, char **argv) {
  ros::init(argc, argv, "publish_node");//初始化,节点取名为publish_node
  ros::NodeHandle nh;//创建节点句柄
  ros::Publisher chatter_pub = nh.advertise<std_msgs::String>("chatter", 1000);
  ////这句话告诉ros节点管理器我们将会在chatter这个话题上发布std_msgs::String类型的消息。
  ros::Rate loop_rate(10);//自循环的频率,10Hz频率
  int count = 0;
  while (ros::ok()) {
    std_msgs::String msg;
    std::stringstream ss; 
    ss << "how are you " << count; 
    msg.data = ss.str();
    ROS_INFO("%s", msg.data.c_str());
    chatter_pub.publish(msg);//广播信息
    ros::spinOnce();
    loop_rate.sleep();//通过休眠来控制自循环的频率
    ++count;
  }
  return 0;
}
////subscribe_node.cpp

#include "ros/ros.h" 
#include "std_msgs/String.h" 

///这是一个回调函数,当有消息到达chatter话题时会自动被调用一次,用来打印从话题中订阅的消息数据。
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, "subscribe_node");
  ros::NodeHandle nh;
  ros::Subscriber chatter_sub = nh.subscribe("chatter", 1000,chatterCallback);
  //告诉ros节点管理器我们将会从chatter这个话题中订阅消息,当有消息到达时会自动调用这里指定的chatterCallback回调函数。这里的参数1000是表示订阅序列的大小,如果消息处理的速度不够快,缓冲区中的消息大于1000个的话就会开始丢弃先前接收的消息。
  ros::spin();//这一句话让程序进入自循环的挂起状态,从而让程序以最好的效率接收消息并调用回调函数。
  return 0;
}

2. 编译配置及编译      
      创建功能包topic_example时,显式的指明依赖roscpp和std_msgs,依赖会被默认写到功能包的CMakeLists.txt和package.xml中,所以只需要在CMakeLists.txt文件的末尾行加入以下几句用于声明可执行文件就可以了:

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})

       就可以用下面的命令对功能包进行编译了:

cd ~/catkin_ws/
catkin_make -DCATKIN_WHITELIST_PACKAGES="topic_example"

3. 功能包的启动运行

       需要用roscore命令来启动ROS节点管理器,ROS节点管理器是所有节点运行的基础.
       重起一个终端,用source devel/setup.bash激活catkin_ws工作空间, zsh:source devel/setup.zsh ,用rosrun <package_name> <node_name>启动功能包中的发布节点.并且看到一直在发送信息: 

$ roscore
$ cd ~/catkin_ws/
$ source devel/setup.bash
$ rosrun topic_example publish_node 

                                    

        特别的,如果出现:

        在CMakeList.txt 里 只需在find_package() 后面加上  catkin_package()  重新编译即可.      

        重启一个终端,用source devel/setup.bash激活catkin_ws工作空间,zsh:source devel/setup.zsh ,用rosrun <package_name> <node_name>启动功能包中的订阅节点。至此 我们编写的消息发布器和订阅器就大功告成了.

$ cd ~/catkin_ws/
$ source devel/setup.bash
$ rosrun topic_example subscribe_node 

                           
      
      

发布了68 篇原创文章 · 获赞 115 · 访问量 83万+

猜你喜欢

转载自blog.csdn.net/zhouyy858/article/details/104549991