ROS2自定义消息并在同一功能包与其他功能包中使用

1创建自定义消息

1.1. 创建工作空间

mkdir -p ros2_ws/src

1.2.创建功能包

cd ros2_ws/src
ros2 pkg create msg_pkg --build-type ament_cmake --dependencies rclcpp std_msgs

1.3.创建消息

在功能包msg_pkg中创建msg文件夹,并在msg目录中创建消息文件.类型.msg. 如Student.msg和Class.msg(切记消息类型首字母大写)

cd msg_pkg
mkdir msg

Student.msg中内容如下:

string name
int16 age

Class.msg中内容如下:

int16 id
Student[] students #当引用同一包中的消息时不需要加包名.如果在其他中中引用需要加上包名msg_pkg/Student[] students

1.4.修改CMakeLists.txt

添加如下代码段

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
#========================================
# 自定义消息
find_package(geometry_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)
set(msg_files
"msg/Student.msg"
"msg/Class.msg"
)
rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files}
  DEPENDENCIES std_msgs geometry_msgs
 )
 ament_export_dependencies(rosidl_default_runtime)

#========================================

1. 5.修改package.xml

添加如下代码段

  <!--添加自定义消息-->
  rosidl_default_generators</buildtool_depend>
  rosidl_default_runtime</exec_depend>
  rosidl_interface_packages</member_of_group>
  <!--添加自定义消息-->

1.6.编译并查看

1.6.1.编译

返回到工作空间目录下.这里是ros2_ws目录下,执行如下命令进行编译

colcon build --packages-up-to objectsDetection

1.6.2.查看

. install/local_setup.bash
ros2 interface package msg_pkg

出现如下消息类型,则成功
在这里插入图片描述

2.同一个包下使用自定义消息(简单的发布者和订阅者)

注意点:在同一个包中使用自定义消息在CMakeLists.txt中必须添加如下代码段,不然找不的自定义消息的头文件

rosidl_target_interfaces(classPlush
  ${PROJECT_NAME} "rosidl_typesupport_cpp")

2.1 发布者(在msg_pkg功能包的src中添加push.cpp)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
static volatile int keepRunning = 1;
void signal_handler(int signum) {
  printf("signal_handler: caught signal %d\n", signum);
  if (signum == SIGINT) {
    keepRunning = 0;
    // SLAM.Shutdown();
  }
}
int main(int argc, char const *argv[]) {
  if (signal(SIGINT, signal_handler) == SIG_ERR) {
    printf("Failed to caught signal\n");
  } else {
    std::cout << "signal_handler ok" << std::endl;
  }
  /* 初始化rclcpp  */
  rclcpp::init(argc, argv);
  /*产生一个节点*/
  auto node = std::make_shared("classPlus");
  RCLCPP_INFO(node->get_logger(), "RosNode_1节点已经启动.");
  rclcpp::PublisherClass>::SharedPtr clss_pub =
      node->create_publisherClass>("classMesag", 1);
  int i = 0;
  msg_pkg::msg::Class cl;
  while (keepRunning) {
    msg_pkg::msg::Student stu;
    stu.age = i * 10 + 1;
    stu.name = "stu" + std::to_string(i);
    cl.students.push_back(stu);
    if (i % 5 == 0) {
      cl.id = i;
      clss_pub->publish(cl);
      std::cout << "publish end" << std::endl;
    }
    i++;
  }
  rclcpp::shutdown();
  return 0;
}

2.1.1 修改CMakeLists.txt

添加如下代码段

#=========================================
#发布者
add_executable(classPlush src/push.cpp)
target_link_libraries(classPlush rclcpp::rclcpp )

rosidl_target_interfaces(classPlush
  ${PROJECT_NAME} "rosidl_typesupport_cpp")
 #注册可执行文件
install(TARGETS classPlush
DESTINATION lib/${PROJECT_NAME}
)
#=========================================

2.1.2 编译并查看可执行文件

2.1.2.1 编译(同上)

colcon build --packages-up-to objectsDetection

2.1.2.2 查看可执行文件

 ros2 pkg executables msg_pkg

若没有对应可执行文件classPlush出现或者运行报出如下错误,那是因为在CMakeLists.txt中没有加入install(TARGETS classPlush DESTINATION lib/${PROJECT_NAME} )进行注册.

No executable found

2.1.3 执行并订阅查看

2.1.3.1 执行

ros2 run msg_pkg classPlush

2.1.3.2 查看

ROS2自定义消息并在同一功能包与其他功能包中使用_第1张图片

2.2 订阅者(编译修改同上)

#include 
#include 
#include 

#include "rclcpp/rclcpp.hpp"
using std::placeholders::_1;

class MinimalSubscriber : public rclcpp::Node {
 public:
  MinimalSubscriber() : Node("classSub") {
    subscription_ = this->create_subscriptionClass>(
        "classMesag", 10,
        std::bind(&MinimalSubscriber::topic_callback, this, _1));
  }

 private:
  void topic_callback(const msg_pkg::msg::Class::SharedPtr msg) const {
    std::cout << "clssid: " << msg->id << std::endl;
    for (int i = 0; i < msg->students.size(); i++) {
      msg_pkg::msg::Student std = msg->students[i];
      std::cout << "age: " << std.age << std::endl;
    }
  }
  rclcpp::SubscriptionClass>::SharedPtr subscription_;
};

int main(int argc, char* argv[]) {
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared());
  rclcpp::shutdown();
  return 0;
}

你可能感兴趣的:(机器人ROS,java,服务器,前端)