调用使用Protobuf定义号的ROS消息[C++/Python]

接上篇,我们这里来调用定义好的protobuf消息,这里依然参考apollo的代码,https://github.com/ApolloAuto/apollo-platform仓库里面的ros下面的pb_msgs_example里面的代码
下面的内容也都是里面的代码粘贴复制,感兴趣的直接看源代码就可以

2.调用自定义的proto_msg

https://github.com/ApolloAuto/apollo-platform/blob/master/ros/pb_msgs_example

2.1 代码结构

代码结构

2.2 代码
2.2.1 proto
chatter.proto
syntax = "proto2";

package pb_msgs;

import "time.proto";

message ShortMessage {
    required Time stamp = 1;
    required string content = 2;
}

message Counter {
    required uint64 count = 1 [default = 0];
}
2.2.1 scripts
listener.py
#!/usr/bin/env python

import rospy
import pb_msgs.msg

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.content)

def listener():
    rospy.init_node("listener", anonymous = True)
    
    rospy.Subscriber("pb_chatter", pb_msgs.msg.ShortMessage, callback)

    rospy.spin()

if __name__ == "__main__":
    listener()
talker.py
#!/usr/bin/env python

import rospy
import pb_msgs.msg

def talker():
    pub = rospy.Publisher('pb_chatter', pb_msgs.msg.ShortMessage, queue_size = 10)
    rospy.init_node('talker', anonymous = True)
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        msg = pb_msgs.msg.ShortMessage()
        now = rospy.get_rostime()
        msg.stamp.sec = now.secs
        msg.stamp.nsec = now.nsecs
        msg.content = "Hello world!"
        pub.publish(msg)
        rate.sleep()
        
if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass
2.2.1 src
listener.cpp
#include "ros/ros.h"
#include "chatter.pb.h"

void pbChatterCallback(const boost::shared_ptr<pb_msgs::ShortMessage>& msg)
{
  ROS_INFO_STREAM("Time: " << msg->stamp().sec() << "." << msg->stamp().nsec());
  ROS_INFO("I heard pb short message: [%s]", msg->content().c_str());
}

void counterCallback(const boost::shared_ptr<pb_msgs::Counter>& msg)
{
  ROS_INFO("I get counter message: [%d]", (int)msg->count());
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "listener");
  ros::NodeHandle n;
  ros::Subscriber pb_sub = n.subscribe("pb_chatter", 1000, pbChatterCallback);
  ros::Subscriber sub = n.subscribe("counter", 1000, counterCallback);
  ros::spin();

  return 0;
}
talker.cpp
#include "ros/ros.h"
#include "chatter.pb.h"

#include <sstream>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "talker");
  ros::NodeHandle n;
  ros::Publisher pb_chatter_pub = n.advertise<pb_msgs::ShortMessage>("pb_chatter", 1000);
  ros::Publisher counter_pub = n.advertise<pb_msgs::Counter>("counter", 1000);
  
  ros::Rate loop_rate(10);

  int count = 0;
  while (ros::ok())
  {
    pb_msgs::ShortMessage pb_msg;
    ros::Time now = ros::Time::now();
    pb_msg.mutable_stamp()->set_sec(now.sec);
    pb_msg.mutable_stamp()->set_nsec(now.nsec);
    std::stringstream ss;
    ss << "Hello world " << count;
    pb_msg.set_content(ss.str());

    ROS_INFO("%s", pb_msg.content().c_str());
    pb_chatter_pub.publish(pb_msg);

    pb_msgs::Counter counter;
    counter.set_count(count);
    counter_pub.publish(counter);

    ros::spinOnce();

    loop_rate.sleep();
    ++count;
  }

  return 0;
}
2.2.1 CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(pb_msgs_example)

## Add support for C++11, supported in ROS Kinetic and newer
# add_definitions(-std=c++11)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS roscpp genmsg std_msgs pb_msgs)

## Generate messages in the 'msg' folder
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

add_proto_files(
  DIRECTORY proto
  FILES chatter.proto
)

## Generate added messages and services with any dependencies listed here
generate_messages(DEPENDENCIES pb_msgs std_msgs)

###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
  # INCLUDE_DIRS include
  LIBRARIES pb_msgs_example_proto
  CATKIN_DEPENDS roscpp
  DEPENDS roscpp genmsg gencpp genpy pb_msgs std_msgs
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
# include_directories(include)
# TODO: Check names of system library include directories (genmsg, gencpp, genpy)
include_directories(${CATKIN_INCLUDE_DIRS})

## Declare a C++ library
# add_library(${PROJECT_NAME}
#   src/${PROJECT_NAME}/pb_msgs_example.cpp
# )

## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(pb_talker src/talker.cpp)
target_link_libraries(pb_talker ${catkin_LIBRARIES}  pb_msgs_example_proto)
add_executable(pb_listener src/listener.cpp)
target_link_libraries(pb_listener ${catkin_LIBRARIES}  pb_msgs_example_proto)

## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")

## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
#   ${catkin_LIBRARIES}
#   ${genmsg_LIBRARIES}
#   ${gencpp_LIBRARIES}
#   ${genpy_LIBRARIES}
# )

#############
## Install ##
#############

# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html

## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# install(PROGRAMS
#   scripts/my_python_script
#   DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

catkin_install_python(PROGRAMS
  scripts/talker.py
  scripts/listener.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

## Mark executables and/or libraries for installation
install(TARGETS pb_talker pb_listener
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
#   DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
#   FILES_MATCHING PATTERN "*.h"
#   PATTERN ".svn" EXCLUDE
# )

#############
## Testing ##
#############

## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_pb_msgs_example.cpp)
# if(TARGET ${PROJECT_NAME}-test)
#   target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()

## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
2.2.1 package.xml
<package>
  <name>pb_msgs_example</name>
  <version>1.0.0</version>
  <description>The pb_msgs_example package</description>
  <maintainer email="info@apollo.auto">Apollo Authors</maintainer>
  <license>BSD</license>
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>gencpp</build_depend>
  <build_depend>genmsg</build_depend>
  <build_depend>genpy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>pb_msgs</build_depend>
  <run_depend>roscpp</run_depend>
  <run_depend>gencpp</run_depend>
  <run_depend>genmsg</run_depend>
  <run_depend>genpy</run_depend>
  <run_depend>std_msgs</run_depend>
  <run_depend>pb_msgs</run_depend>
</package>
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
protobufProtocol Buffers)是一种用于序列化结构化数据的语言无关、平台无关、可扩展的机制。它可以用于网络消息协议的设计。下面将介绍protobuf作为网络消息协议的优点。 首先,protobuf具有良好的性能。相比于其他序列化机制,protobuf具有更高的效率和更小的数据体积。因为protobuf使用二进制编码,并且采用紧凑的数据格式,所以在网络传输过程中能够更快地进行数据传输,减少带宽占用和网络资源消耗。 其次,protobuf具有良好的跨语言支持。因为protobuf使用IDL(Interface Definition Language)来定义消息结构,它能够生成多种语言的代码,包括C++, Java, Python等。这样,不同语言的服务端和客户端可以通过protobuf定义消息结构进行通信,实现跨平台、跨语言的消息传递。 此外,protobuf还具有可扩展性。当需求变化时,可以很方便地通过更新消息结构来支持新的数据类型或字段,而无需改变底层的网络通信协议。 protobuf支持向后和向前兼容,可以确保客户端和服务端的平滑升级。 另外,protobuf还支持消息的压缩和加密,以提高数据传输的安全性和效率。通过使用压缩算法和加密算法,可以减少消息的大小,并保护数据的机密性。 综上所述,protobuf作为网络消息协议具有较高的性能、良好的跨语言支持、可扩展性和安全性等优点。因此,使用protobuf作为网络消息协议可以提高数据传输的效率和安全性,并实现跨平台、跨语言的消息通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值