节点和软件包
节点Node和软件包Package是ROS2程序的组织形式,其中节点相当于是ROS2的程序文件,当运行一个ROS2程序时,实际上运行的是一个或多个节点文件,软件包是节点文件的容器,通常是一个包含了一系列配置文件的目录。
创建软件包
cd ~/ros2_ws/src
ros2 pkg create my_pkg
编写节点
创建my_node.cpp在src下
#include "rclcpp/rclcpp.hpp"
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<rclcpp::Node>("my_node");
RCLCPP_INFO(node->get_logger(), "Hello world!");
while (rclcpp::ok())
{
;
}
rclcpp::shutdown();
return 0;
}
设置编译规则,修改CMakeLists.txt
find_package(rclcpp REQUIRED
add_executable(my_node src/my_node.cpp)
ament_target_dependencies(my_node "rclcpp")
install(TARGETS
my_node
DESTINATION lib/${PROJECT_NAME}
)
修改软件包信息,修改package.xml,增加下句:
<depend>rclcpp</depend>
完成上述步骤后cd ~/ros2_ws编译:colcon build
运行节点
source install/setup.bash
ros2 run my_pkg my_node
#终端输出hello world
话题和消息
在ROS2中,节点之间的通信最常用的方式是话题Topic和消息Message,话题可以理解为聊天室,参与话题聊天室的节点可以被分为发言的发布者publisher,看到发言的节点订阅者subscriber
发布者和订阅者所使用的消息格式必须一致,否则无法完成通信。
编写话题发布者
cd ~/ros2_ws/src
ros2 pkg create topic_pkg
新建节点文件publisher_node.cpp在src文件夹下
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<rclcpp::Node>("publisher_node");
auto publisher = node->create_publisher<std_msgs::msg::String>("/my_topic", 10);
std_msgs::msg::String message;
message.data = "Hello World!";
rclcpp::Rate loop_rate(1);
while (rclcpp::ok())
{
publisher->publish(message);
loop_rate.sleep();
}
rclcpp::shutdown();
return 0;
}
设置编译规则,修改CmakeLists.txt
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
add_executable(publisher_node src/publisher_node.cpp)
ament_target_dependencies(publisher_node "rclcpp" "std_msgs")
install(TARGETS
publisher_node
DESTINATION lib/${PROJECT_NAME}
)
修改packages.xml
<depend>rclcpp</depend>
<depend>std_msgs</depend>
跳回~/ros_ws编译节点colcon build
运行话题发布节点
source install/setup.bash
ros2 run topic_pkh publisher_node
之前安装过terminator,可以找到这个应用,打开后ctrl+shift+o可以实现分窗口,比普通终端更方便
新终端ros2 topic list可以找到发布的话题,使用ros2 topic echo /my_topic可以查看话题发布的消息内容
编写话题订阅者
//subscriber_node.cpp
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
std::shared_ptr<rclcpp::Node> node;
void Callback(const std_msgs::msg::String::SharedPtr msg)
{
RCLCPP_INFO(node->get_logger(),"Receive : %s", msg->data.c_str());
}
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
node = std::make_shared<rclcpp::Node>("subscriber_node");
auto subscriber= node->create_subscription<std_msgs::msg::String>("/my_topic", 10, &Callback);
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
后面的操作基本与之前一致,修改编译文件巴拉巴拉的