节点是通过ROS图通信的可执行进程。在本教程中,节点将通过主题以字符串消息的形式相互传递信息。这里使用的例子是一个简单的“说话者”和“倾听者”系统;一个节点发布数据,而另一个节点订阅该主题,以便它可以接收该数据。
创建对应功能包
打开一个新的终端并获取ROS 2安装的源代码,这样ros 2命令就可以工作了.
导航到上一教程中创建的ros2_ws目录。
回想一下,应该在src目录中创建包,而不是在工作区的根目录中。因此,导航到ros2_ws/src,并运行包创建命令:
ros2 pkg create --build-type ament_cmake cpp_pubsub
您的终端将返回一条消息,验证您的包cpp_pubsub及其所有必要文件和文件夹的创建。
导航到ros2_ws/源代码/cpp_pubsub/源代码。回想一下,这是任何CMake包中包含可执行文件的源文件所属的目录。
话题节点的创建
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using namespace std;
using namespace rclcpp;
using namespace std_msgs;
using namespace std::chrono_literals;
class MinimalPublisher : public Node{
public:
MinimalPublisher():Node("minimal_publisher"),count_(0){
publisher_ = this->create_publisher<std_msgs::msg::String>("topic",10);
timer_ = this->create_wall_timer(500ms,std::bind(&MinimalPublisher::timer_callback,this));
}
private:
void timer_callback(){
auto message = std_msgs::msg::String();
message.data = "hello world" + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(),"publishing:%s",message.data.c_str());
publisher_->publish(message);
}
size_t count_;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
rclcpp::TimerBase::SharedPtr timer_;
};
int main(int argc, const char** argv) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalPublisher>());
rclcpp::shutdown();
return 0;
}
订阅者节点创建
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using std::placeholders::_1;
using namespace std;
using namespace rclcpp;
using namespace std_msgs;
class MinimalSubscriber : public Node{
public:
MinimalSubscriber():Node("MinimalSubscriber"){
subscription_ = this->create_subscription<std_msgs::msg::String>("topic",10,std::bind(&MinimalSubscriber::topic_callback,this,_1));
}
private:
void topic_callback(const std_msgs::msg::String::SharedPtr msg){
RCLCPP_INFO(this->get_logger(),"I heard %s",msg->data.c_str());
}
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalSubscriber>());
rclcpp::shutdown();
return 0;
}
修改XML文件
在ament_cmake buildtool依赖项后面添加一个新行,并粘贴与节点的include语句对应的以下依赖项:
<!-- 设置对应的依赖 -->
<depend>rclcpp</depend>
<depend>std_msgs</depend>
修改CMakeLsits.txt
现在打开CMakeLists.txt文件。在现有依赖项find_package(ament_cmake REQUIRED)下面添加以下行:
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
之后,添加可执行文件并将其命名为talker,以便可以使用ros2 run运行节点:
add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)
add_executable(listen src/subscriber_member_function.cpp)
ament_target_dependencies(listen rclcpp std_msgs)
最后,添加install(TARGETS...)部分,以便ros2 run可以找到您的可执行文件:
install(TARGETS
talker
listen
DESTINATION lib/${PROJECT_NAME})
进行编译
您可能已经将rclcpp和std_msgs包作为ROS 2系统的一部分进行了安装。最好在工作区的根目录(ros2_ws)下运行rosdep,以便在构建之前检查缺少的依赖项:
colcon build --packages-select cpp_pubsub