Beginner:Client libraries-6创建自定义的msg和srv文件
目标:定义自定义接口文件(.msg和.srv),在c++节点和Python中使用他们。
背景
有时候需要定义自己的消息和服务。之前教程都是已经定义好的系统的消息类型,本教程介绍最简单的自定义接口定义的方法。
任务
1、创建一个包
ros2 pkg create --build-type ament_cmake tutorial_interfaces
2、创建自定义消息
2.1 msg定义
创建了两个文件Num.msg以及Sphere.msg
2.2 srv定义
创建文件AddThreeInts.srv
3. CMakeLists.txt
将自定义的类型转换为具体语言可识别的消息,在CMakeLists.txt中添加如下
find_package(geometry_msgs REQUIRED) find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} "msg/Num.msg" "msg/Sphere.msg" "srv/AddThreeInts.srv" DEPENDENCIES geometry_msgs # Add packages that above messages depend on, in this case geometry_msgs for Sphere.msg )
cmake_minimum_required(VERSION 3.8)
project(tutorial_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(geometry_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/Num.msg"
"msg/Sphere.msg"
"srv/AddThreeInts.srv"
DEPENDENCIES geometry_msgs)
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()
注意:在rosidl_generate_interfaces中的第一个参数必须是${PROJECT_NAME}
4、package.xml
因为定义的信息依赖于rosidl_default_generators用于生成制定的语言代码,需要声明编译工具依赖它。rosidl_default_runtime是运行时或者执行阶段的依赖,在之后使用消息时被需要。rosidl_interface_packages是你包的依赖组的名字。tutorial_interfaces应与关联,并使用<member_of_group>标记声明。
<?xml version="1.0"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <package format="3"> <name>tutorial_interfaces</name> <version>0.0.0</version> <description>TODO: Package description</description> <maintainer email="stardust@todo.todo">stardust</maintainer> <license>TODO: License declaration</license> <buildtool_depend>ament_cmake</buildtool_depend> <depend>geometry_msgs</depend> <buildtool_depend>rosidl_default_generator</buildtool_depend> <exec_depend>rosidl_default_runtime</exec_depend> <test_depend>ament_lint_auto</test_depend> <test_depend>ament_lint_common</test_depend> <member_of_group>rosidl_interface_packages</member_of_group> <export> <build_type>ament_cmake</build_type> </export> </package>
5、编译并运行
colcon build --packages-select tutorial_interfaces
检查是否有消息
ros2 interface show tutorial_interfaces/msg/Num ros2 interface show tutorial_interfaces/msg/Sphere ros2 interface show tutorial_interfaces/srv/AddThreeInts
6、测试自定义消息
6.1 用发布器和订阅器来测试Num.msg
发布者
#include <chrono> #include <memory> #include "rclcpp/rclcpp.hpp" #include "tutorial_interfaces/msg/num.hpp" // CHANGE using namespace std::chrono_literals; class MinimalPublisher : public rclcpp::Node { public: MinimalPublisher() : Node("minimal_publisher"), count_(0) { publisher_ = this->create_publisher<tutorial_interfaces::msg::Num>("topic", 10); // CHANGE timer_ = this->create_wall_timer( 500ms, std::bind(&MinimalPublisher::timer_callback, this)); } private: void timer_callback() { auto message = tutorial_interfaces::msg::Num(); // CHANGE message.num = this->count_++; // CHANGE RCLCPP_INFO_STREAM(this->get_logger(), "Publishing: '" << message.num << "'"); // CHANGE publisher_->publish(message); } rclcpp::TimerBase::SharedPtr timer_; rclcpp::Publisher<tutorial_interfaces::msg::Num>::SharedPtr publisher_; // CHANGE size_t count_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MinimalPublisher>()); rclcpp::shutdown(); return 0; }
订阅者
#include <functional> #include <memory> #include "rclcpp/rclcpp.hpp" #include "tutorial_interfaces/msg/num.hpp" // CHANGE using std::placeholders::_1; class MinimalSubscriber : public rclcpp::Node { public: MinimalSubscriber() : Node("minimal_subscriber") { subscription_ = this->create_subscription<tutorial_interfaces::msg::Num>( // CHANGE "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1)); } private: void topic_callback(const tutorial_interfaces::msg::Num & msg) const // CHANGE { RCLCPP_INFO_STREAM(this->get_logger(), "I heard: '" << msg.num << "'"); // CHANGE } rclcpp::Subscription<tutorial_interfaces::msg::Num>::SharedPtr subscription_; // CHANGE }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MinimalSubscriber>()); rclcpp::shutdown(); return 0; }
CMakeLists.txt
#... find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(tutorial_interfaces REQUIRED) # CHANGE add_executable(talker src/publisher_member_function.cpp) ament_target_dependencies(talker rclcpp tutorial_interfaces) # CHANGE add_executable(listener src/subscriber_member_function.cpp) ament_target_dependencies(listener rclcpp tutorial_interfaces) # CHANGE install(TARGETS talker listener DESTINATION lib/${PROJECT_NAME}) ament_package()
package.xml
<?xml version="1.0"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <package format="3"> <name>cpp_pubsub</name> <version>0.0.0</version> <description>TODO: Package description</description> <maintainer email="stardust@todo.todo">stardust</maintainer> <license>TODO: License declaration</license> <buildtool_depend>ament_cmake</buildtool_depend> <test_depend>ament_lint_auto</test_depend> <test_depend>ament_lint_common</test_depend> <depend>rclcpp</depend> <depend>std_msgs</depend> <depend>tutorial_interfaces</depend> <export> <build_type>ament_cmake</build_type> </export> </package>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2016-06-02 移动文件读/写指针----lseek
2016-06-02 向文件写入一个数据块---write
2016-06-02 由已打开的文件读取数据---read
2016-06-02 关闭文件描述符-close
2016-06-02 系统调用方式文件编程-open
2016-06-02 动态函数库设计
2016-06-02 静态函数库设计