目标:在ROS2中学习更多的实现自定义接口
背景
在指定的接口包中声明接口,有时在一个包中声明、创建、使用所有接口很方便。
本教程关注msg接口类型,但是步骤对于其他所有接口类型适用。
任务
1、创建一个包
ros2 pkg create --build-type ament_cmake more_interfaces mkdir more_interfaces/msg
2、创建一个msg文件
AddressBook.msg uint8 PHONE_TYPE_HOME=0 uint8 PHONE_TYPE_WORK=1 uint8 PHONE_TYPE_MOBILE=2 string first_name string last_name string phone_number uint8 phone_type
See About ROS 2 interfaces for more ways you can customize interfaces.
2.1 编译msg文件
package.xml <buildtool_depend>rosidl_default_generators</buildtool_depend> <exec_depend>rosidl_default_runtime</exec_depend> <member_of_group>rosidl_interface_packages</member_of_group>
CMakeLists.txt
cmake_minimum_required(VERSION 3.8) project(more_interfaces) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() # find dependencies find_package(ament_cmake REQUIRED) find_package(rosidl_default_generators REQUIRED) # uncomment the following section in order to fill in # further dependencies manually. # find_package(<dependency> REQUIRED) set(msg_files "msg/AddressBook.msg" ) rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files} ) ament_export_dependencies(rosidl_default_runtime) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) # the following line skips the linter which checks for copyrights # comment the line when a copyright and license is added to all source files set(ament_cmake_copyright_FOUND TRUE) # the following line skips cpplint (only works in a git repo) # comment the line when this package is in a git repo and when # a copyright and license is added to all source files set(ament_cmake_cpplint_FOUND TRUE) ament_lint_auto_find_test_dependencies() endif() ament_package()
2.2 设置更多的接口
在CMakeLists.txt中设置
set(msg_files "msg/Message1.msg" "msg/Message2.msg" # etc ) set(srv_files "srv/Service1.srv" "srv/Service2.srv" # etc )
生成所有的消息
rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files} ${srv_files} )
3、使用来自相同包的接口
在more_interfaces/src下创建publish_address_book.cpp
#include <chrono> #include <memory> #include "rclcpp/rclcpp.hpp" #include "more_interfaces/msg/address_book.hpp" using namespace std::chrono_literals; class AddressBookPublisher : public rclcpp::Node { public: AddressBookPublisher() : Node("address_book_publisher") { address_book_publisher_ = this->create_publisher<more_interfaces::msg::AddressBook>("address_book", 10); auto publish_msg = [this]() -> void { auto message = more_interfaces::msg::AddressBook(); message.first_name = "John"; message.last_name = "Doe"; message.phone_number = "1234567890"; message.phone_type = message.PHONE_TYPE_MOBILE; std::cout << "Publishing Contact\nFirst:" << message.first_name << " Last:" << message.last_name << std::endl; this->address_book_publisher_->publish(message); }; timer_ = this->create_wall_timer(1s, publish_msg); } private: rclcpp::Publisher<more_interfaces::msg::AddressBook>::SharedPtr address_book_publisher_; rclcpp::TimerBase::SharedPtr timer_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<AddressBookPublisher>()); rclcpp::shutdown(); return 0; }
在CMakeLists.txt中添加如下
find_package(rclcpp REQUIRED) add_executable(publish_address_book src/publish_address_book.cpp) ament_target_dependencies(publish_address_book rclcpp) install(TARGETS publish_address_book DESTINATION lib/${PROJECT_NAME})
3.1与自定义接口类型链接
为了使用本包生成的消息,需要再CMakeLists.txt中添加如下
rosidl_get_typesupport_target(cpp_typesupport_target ${PROJECT_NAME} rosidl_typesupport_cpp) target_link_libraries(publish_address_book "${cpp_typesupport_target}")
您可能已经注意到,当使用的接口来自独立构建的不同包时,没有必要执行此步骤。只有当您希望在与定义接口的包相同的包中使用接口时,才需要此CMake代码。
4、编译并运行
colcon build --packages-up-to more_interfaces source install/local_setup.bash ros2 run more_interfaces publish_address_book 查看消息内容 source install/setup.bash ros2 topic echo /address_book
5、使用已经存在的接口定义
注意
可以在一个新的接口定义中使用已经存在的接口定义。例如,有一个消息的名字叫做Contact.msg,其属于包rosidl_tutorials_msgs。可以在自己的包中定义如下的数组
rosidl_tutorial_msgs/Contact[] address_book
为了生成依赖的消息Contack.msg,需要再package.xml中添加对应的包rosidl_tutorial_msgs
如下
<build_depend>rosidl_tutorials_msgs</build_depend> <exec_depend>rosidl_tutorials_msgs</exec_depend>
在CMakeLists.txt中添加如下
find_package(rosidl_tutorials_msgs REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files} DEPENDENCIES rosidl_tutorials_msgs )
在cpp文件中需要添加头文件#include "rosidl_tutorials_msgs/msg/contact.hpp"
以及如下的修改
auto publish_msg = [this]() -> void { auto msg = std::make_shared<more_interfaces::msg::AddressBook>(); { rosidl_tutorials_msgs::msg::Contact contact; contact.first_name = "John"; contact.last_name = "Doe"; contact.phone_number = "1234567890"; contact.phone_type = message.PHONE_TYPE_MOBILE; msg->address_book.push_back(contact); } { rosidl_tutorials_msgs::msg::Contact contact; contact.first_name = "Jane"; contact.last_name = "Doe"; contact.phone_number = "4254242424"; contact.phone_type = message.PHONE_TYPE_HOME; msg->address_book.push_back(contact); } std::cout << "Publishing address book:" << std::endl; for (auto contact : msg->address_book) { std::cout << "First:" << contact.first_name << " Last:" << contact.last_name << std::endl; } address_book_publisher_->publish(*msg); };
总结
在本教程中,您尝试了不同的字段类型来定义接口,然后在使用接口的同一个包中构建了一个接口。您还学习了如何使用其他接口作为字段类型,以及使用该功能所需的package.xml、CMakeLists.txt和#include语句。
标签:自定义,Beginner,interfaces,contact,libraries,book,address,msg,rosidl From: https://www.cnblogs.com/gary-guo/p/17452334.html