系列目录

  • ROS2与C++入门教程-目录

  • ROS2与C++入门教程-新建ros2工作空间

  • ROS2与C++入门教程-新建ros2包

  • ROS2与C++入门教程-编写订阅和发布

  • ROS2与C++入门教程-编写服务端和客户端

  • ROS2与C++入门教程-创建消息(msg)文件

  • ROS2与C++入门教程-创建服务(srv)文件

  • ROS2与C++入门教程-创建ros2接口

  • ROS2与C++入门教程-使用参数

  • ROS2与C++入门教程-创建和使用插件

  • ROS2与C++入门教程-编写动作服务器

  • ROS2与C++入门教程-编写动作客户端

  • ROS2与C++入门教程-Topic Statistics查看话题

  • ROS2与C++入门教程-增加头文件

  • ROS2与C++入门教程-在C++包里增加python支持

  • ROS2与C++入门教程-增加命名空间

  • ROS2与C++入门教程-多线程演示

  • ROS2与C++入门教程-单线程演示

  • ROS2与C++入门教程-话题组件演示

  • ROS2与C++入门教程-话题组件增加launch启动演示

  • ROS2与C++入门教程-服务组件演示

  • ROS2与C++入门教程-服务组件增加launch启动演示

  • ROS2与C++入门教程-进程内(intra_process)话题发布和订阅演示

  • ROS2与C++入门教程-进程内(intra_process)话题发布和订阅演示2

  • ROS2与C++入门教程-进程内(intra_process)图像处理演示

  • ROS2与C++入门教程-生命周期节点演示

说明:

  • 介绍如何在C++包增加Python支持,实现通过C++节点发布话题信息,通过Python节点接受话题信息
  • 一般情况下都是C++或Python都独立的包,这样对于各自管理的节点也很方便。
  • 但是有些情况也例外,如果C++包里想同时增加Python也是支持的。步骤也多一些

步骤:

  • 新建包my_cpp_py_pkg
cd ~/dev_ws/src
ros2 pkg create my_cpp_py_pkg --build-type ament_cmake
  • 内容如下:
my_cpp_py_pkg/
├── CMakeLists.txt
├── include
│   └── my_cpp_py_pkg
├── package.xml
└── src
  • 增加cpp节点和头文件
cd my_cpp_py_pkg/
touch src/cpp_node.cpp
touch include/my_cpp_py_pkg/cpp_talker.hpp
  • cpp_talker.hpp内容如下:
#include <chrono>
#include <memory>#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
  • cpp_node.cpp需要增加引入头文件,增加如下内容cpp_talker.cpp
#include "my_cpp_py_pkg/cpp_talker.hpp"using namespace std::chrono_literals;/* This example creates a subclass of Node and uses std::bind() to register a* member function as a callback from the timer. */class MinimalPublisher : public rclcpp::Node
{
public:MinimalPublisher(): Node("minimal_publisher"), count_(0){publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);timer_ = this->create_wall_timer(500ms, std::bind(&MinimalPublisher::timer_callback, this));}private:void timer_callback(){auto message = std_msgs::msg::String();message.data = "Hello, world! " + std::to_string(count_++);RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());publisher_->publish(message);}rclcpp::TimerBase::SharedPtr timer_;rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;size_t count_;
};int main(int argc, char * argv[])
{rclcpp::init(argc, argv);rclcpp::spin(std::make_shared<MinimalPublisher>());rclcpp::shutdown();return 0;
}
  • 增加python节点和模块导入
  • 新建pyton目录
mkdir my_cpp_py_pkg
touch my_cpp_py_pkg/__init__.py
mkdir scripts
  • 新建python文件
touch my_cpp_py_pkg/module_to_import.py
touch scripts/py_listener.py
  • module_to_import.py内容如下:
def listener_write(data) : my_open = open("/tmp/my_write.txt", 'w')#打开/tmp路径下的my_write.txt文件,采用写入模式#若文件不存在,创建,若存在,清空并写入my_open.write(data)#在文件中写入一个字符串my_open.write('\n')my_open.close()
  • py_listener.py内容如下:
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
from my_cpp_py_pkg.module_to_import import listener_writeclass MinimalSubscriber(Node):def __init__(self):super().__init__('minimal_subscriber')self.subscription = self.create_subscription(String,'topic',self.listener_callback,10)self.subscription #def listener_callback(self, msg):self.get_logger().info('I heard: "%s"' % msg.data)listener_write(msg.data)def main(args=None):rclpy.init(args=args)minimal_subscriber = MinimalSubscriber()rclpy.spin(minimal_subscriber)minimal_subscriber.destroy_node()rclpy.shutdown()if __name__ == '__main__':main()
  • 重要提示:您必须首先在 py_listener.py 文件中添加一个行:
#!/usr/bin/env python3
  • 你不增加这一行,用ros2 run运用就会出错。
  • 同时要增加执行权限
chmod +x scripts/py_listener.py
  • 如果要导入模块,可以在py_listener.py增加如下行。
from my_cpp_py_pkg.module_to_import import  listener_write
  • 最终的结构如下:
my_cpp_py_pkg/
# --> package info, configuration, and compilation
├── CMakeLists.txt
├── package.xml
# --> Python stuff
├── my_cpp_py_pkg
│   ├── __init__.py
│   └── module_to_import.py
├── scripts
│   └── py_listener.py
# --> Cpp stuff
├── include
│   └── my_cpp_py_pkg
│       └── cpp_talker.hpp
└── src└── cpp_talker.cpp
  • 配置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>my_cpp_py_pkg</name><version>0.0.0</version><description>TODO: Package description</description><maintainer email="your@email.com">Name</maintainer><license>TODO: License declaration</license><buildtool_depend>ament_cmake</buildtool_depend><buildtool_depend>ament_cmake_python</buildtool_depend><depend>rclcpp</depend><depend>rclpy</depend><depend>std_msgs</depend><test_depend>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend><export><build_type>ament_cmake</build_type></export>
</package>
  • 增加<buildtool_depend>ament_cmake_python</buildtool_depend>行和rclpy,支持python使用。
  • 注意:在标准的 Python 包中,你应该有 ament_python,而不是 ament_cmake_python。 确保不要混合使用这 2 个。
  • 使用 ament_cmake_python 意味着我们将能够使用 cmake 设置我们的 Python 内容。
  • 配置CMakeLists.txt
  • 内容如下:
cmake_minimum_required(VERSION 3.5)
project(my_cpp_py_pkg)# Default to C++14
if(NOT CMAKE_CXX_STANDARD)set(CMAKE_CXX_STANDARD 14)
endif()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(ament_cmake_python REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclpy REQUIRED)
find_package(std_msgs REQUIRED)# Include Cpp "include" directory
include_directories(include)# Create Cpp executable
add_executable(cpp_talker src/cpp_talker.cpp)
ament_target_dependencies(cpp_executable rclcpp)# Install Cpp executables
install(TARGETScpp_talkerDESTINATION lib/${PROJECT_NAME}
)# Install Python modules
ament_python_install_package(${PROJECT_NAME})# Install Python executables
install(PROGRAMSscripts/py_listener.pyDESTINATION lib/${PROJECT_NAME}
)ament_package()
  • 注意其中三个部分: 依赖部分,CPP部分和Python部分
  • 依赖部分
# Find dependencies
find_package(ament_cmake REQUIRED)
find_package(ament_cmake_python REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclpy REQUIRED)
find_package(std_msgs REQUIRED)
  • CPP部分
# Include Cpp "include" directory
include_directories(include)# Create Cpp executable
add_executable(cpp_talker src/cpp_talker.cpp)
ament_target_dependencies(cpp_talker rclcpp)# Install Cpp executables
install(TARGETScpp_talker DESTINATION lib/${PROJECT_NAME}
)
  • python部分
# Install Python modules
ament_python_install_package(${PROJECT_NAME})# Install Python executables
install(PROGRAMSscripts/py_listener.pyDESTINATION lib/${PROJECT_NAME}
)
  • 使用 ament_python_install_package(${PROJECT_NAME}) 安装任何 Python 模块(在此示例中:my_cpp_py_pkg/ 文件夹下的文件),以便您可以从这个或另一个包中找到它们。

  • 然后,我们安装 scripts/py_listener.py 文件。 我们将此文件放在 install lib/ 文件夹中,该文件夹与 ROS2 Cpp 节点的文件夹相同。 因此,所有 Cpp/Python 可执行文件都将位于同一位置。

  • 对于您需要安装的任何新 Python 脚本,只需在此处添加新行。

  • 编译包

cd ~/dev_ws/
colcon build --symlink-install --packages-select my_cpp_py_pkg
  • 执行cpp发布话题信息
 ros2 run my_cpp_py_pkg cpp_talker
  • 效果如下:
$ ros2 run my_cpp_py_pkg cpp_talker
[INFO] [1651803573.152324876] [minimal_publisher]: Publishing: 'Hello, world! 0'
[INFO] [1651803573.652296360] [minimal_publisher]: Publishing: 'Hello, world! 1'
[INFO] [1651803574.152555806] [minimal_publisher]: Publishing: 'Hello, world! 2'
[INFO] [1651803574.652385533] [minimal_publisher]: Publishing: 'Hello, world! 3'
[INFO] [1651803575.152389750] [minimal_publisher]: Publishing: 'Hello, world! 4'
  • 执行python接受话题信息
ros2 run my_cpp_py_pkg py_listener.py
  • 效果如下:
$ ros2 run my_cpp_py_pkg py_listener.py
[INFO] [1651803635.112644593] [minimal_subscriber]: I heard: "Hello, world! 8"
[INFO] [1651803635.597138764] [minimal_subscriber]: I heard: "Hello, world! 9"
[INFO] [1651803636.097224630] [minimal_subscriber]: I heard: "Hello, world! 10"
[INFO] [1651803636.597222975] [minimal_subscriber]: I heard: "Hello, world! 11"
[INFO] [1651803637.096938082] [minimal_subscriber]: I heard: "Hello, world! 12"
[INFO] [1651803637.596770711] [minimal_subscriber]: I heard: "Hello, world! 13"
  • 重要提示:如果您希望使用 --symlink-install 选项进行编译(这样您就可以修改和重新运行脚本而无需重新编译),您必须使用 chmod +x 使您的脚本可执行。
  • 否则当你尝试运行你的节点时,你会得到这个错误:“No executable found”。

ROS2与C++入门教程-在C++包里增加python支持相关推荐

  1. ROS2与C++入门教程-增加头文件

    系列文章目录 ROS2与C++入门教程-目录 ROS2与C++入门教程-新建ros2工作空间 ROS2与C++入门教程-新建ros2包 ROS2与C++入门教程-编写订阅和发布 ROS2与C++入门教 ...

  2. ROS2与C++入门教程-目录 - 创客智造

    来源: https://www.ncnynl.com/archives/201806/2486.html 说明: 介绍如何在ros2下利用c++编程 所有例子放在github里 目录: ROS2与C+ ...

  3. ros2与windows入门教程-windows上安装ROS2 foxy

    系列文章目录 ros2与windows入门教程-windows上安装ROS2 foxy ros2与windows入门教程-控制小乌龟 ros2与windows入门教程-监听和发布话题 ros2与win ...

  4. linux 搭建开发stm32 stlink,ROS2与STM32入门教程-搭建开发环境(ubuntu+eclipse+cubemx+stlink+openocd)...

    ROS2与C++入门教程-搭建开发环境(ubuntu+eclipse+cubemx+stlink+opencd) 说明: 介绍如何在ubuntu下搭建开发环境 环境:ubuntu20.04 + ecl ...

  5. python新手入门教程思路-Python新手入门教程_教你怎么用Python做数据分析

    Python新手入门教程_教你怎么用Python做数据分析 跟大家讲了这么多期的Python教程,有小伙伴在学Python新手教程的时候说学Python比较复杂的地方就是资料太多了,比较复杂.很多网上 ...

  6. Python入门教程:很多人推荐学 Python 入 IT ,如果学完 Python 找不到工作怎么办...

    Python入门教程:很多人推荐学 Python 入 IT ,但是如果学完 Python 找不到工作怎么办,这也是很多人担心的问题. 很多人推荐通过学习 Python 入行 IT 一是因为 Pytho ...

  7. python零基础入门教程视频下载-零基础学Python入门教程,视频资源下载

    课程名称 零基础学Python入门教程,视频资源下载 课程目录 第一章 :Python介绍和安装 01.Python语言的特点 02.Python的发展历史与版本 03.Python的安装 第二章 : ...

  8. ROS2与C++入门教程-创建服务(srv)文件 - 创客智造

    来源:https://www.ncnynl.com/archives/201806/2492.html 说明: 介绍如何创建服务srv文件 步骤: 使用已经建好的工作空间dev_ws 新建包,如果已经 ...

  9. ROS2与C++入门教程-编写服务端和客户端 - 创客智造

    来源:https://www.ncnynl.com/archives/201806/2490.html 说明: 介绍如何编写服务端和客户端 编写服务端步骤: 新建包cpp_srvcli cd ~/de ...

最新文章

  1. 【刷算法】判断链表是否有环以及返回入环节点
  2. [原创]结构在Loadrunner中的应用
  3. 错误:AttributeError: module 'enum' has no attribute 'IntFlag'
  4. python3.6字典有序_为什么Python 3.6以后字典有序并且效率更高?
  5. Xamarin.Forms Layout Challenges – Great Places(已全文翻译)
  6. xss挖掘思路分享_WEB安全(二) :XSS的漏洞挖掘(上)
  7. 熵编码之哈夫曼树(五)
  8. 在线摩尔斯密码加密解密工具
  9. NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy
  10. O2OO是一个汽车故障诊断工具
  11. 牛刀杀鸡-开源社区API之抢楼大作战
  12. .NET c#中调用地图
  13. RN:App版本更新提示方案
  14. 硕士阶段总结《科苑行》之工作习惯
  15. X86-64指令解析
  16. TSN(temporal segment networks)环境配置
  17. 【Go资料】go语言学习资料书籍
  18. 关于定义二维数组时为什么可以省略行,而不可以省略列
  19. 接地气,到底什么才是大数据开发工程师?
  20. 酒店管理系统功能结构图

热门文章

  1. 手机APP渠道推广怎么玩?
  2. POJ 1625 Censored ( Trie图 DP 高精度 )
  3. 大地坐标转换极坐标(球坐标)
  4. React项目中请求跨域解决方法
  5. 【Linux】基本指令和常用应用安装
  6. mac获取ios应用包名
  7. Android studio百度地图之定位到国外
  8. 【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界 摄像机的实现
  9. 个人计算机操作系统支持多用户多任务,windows10是一个多用户多任务操作系统吗...
  10. android接口的作用是什么意思,Android开发中接口的用处