进阶篇-ROS2系统

要做机器人离不开计算机编程,而计算机编程经过多年的发展,演变出了三种不同且常用的编程思想,分别是:
面向过程编程思想。缩写:POP
面向对象编程思想。缩写:OOP
函数式思想。缩写:FP
3.1 类与对象
在ROS2设计时这种抽象和具体的思想发挥着非常重要的作用,比如说DDS是有很多厂家的,ROS2为了匹配不同厂家的DDS,就设计除了DDS抽象层,而每一个具体的DDS厂家,我们可以称之为一个DDS的对象,是具体的。
3.2 封装、继承与多态
封装就是将属性和行为封装在一起。
继承可以帮我们减少很多的工作量。
同一个鱼类可以有多种不同的类型,即多态。

使用面向对象方式编写ROS2节点
ros2 pkg create example_cpp --build-type ament_cmake --dependencies rclcpp

节点关系CMakeList是关键

很奇怪,程序能跑起来,vscode下面划红线。


安装完ROS就好了,应用平台安装ROS

#include "rclcpp/rclcpp.hpp"

/*
    创建一个类节点,名字叫做Node03,继承自Node.
*/
class Node03 : public rclcpp::Node
//继承rclcpp::Node的所有功能(发布者、订阅者、参数等)。
{

public:
    // 构造函数,有一个参数为节点名称
    Node03(std::string name) : Node(name)
    {
        // 打印一句
        RCLCPP_INFO(this->get_logger(), "大家好,我是%s.",name.c_str());
    }

private:
   
};

int main(int argc, char **argv)
{
    rclcpp::init(argc, argv);
    /*产生一个node_03的节点*/
    //同一 ROS 网络中不能有同名节点,否则会导致旧节点被关闭。
    auto node = std::make_shared<Node03>("node_03");
    /* 运行节点,并检测退出信号*/
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

【Python版本】

#! /usr/bin/env python3
import rclpy
from rclpy.node import Node

class Node04(Node): #class Node04(Node):继承rclpy.node.Node类的所有功能。
   #创建一个Node04节点,并在初始化时输出一个话
   def __init__(self,name):  # Python 类的构造函数。
   	super().__init__(name) #必须显式调用父类构造函数,否则节点无法正确初始化。
   	self.get_logger().info("大家好,我是%s!" % name) #调用父类(rclpy.node.Node)的构造函数并传递节点名称。
   
def main(args=None):
   rclpy.init(args=args) # 初始化rclpy
   node = Node04("node_04")  # 新建一个节点
   rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
   rclpy.shutdown() # 关闭rclpy

修改setup.py

    entry_points={
        'console_scripts': [
            "node_04 = example_py.node_04:main"
        ],
    },


【Colcon使用进阶】
1.1 构建系统与构建工具
两者的区分点在于针对的对象不同,构建系统之针对一个单独的包进行构建,而构建工具重点在于按照依赖关系依次调用构建系统完成一系列功能包的构建。
ROS中用到的构建系统:CMake、ament_cmake、catkin、Python setuptools。
ROS中用到的构建工具:colcon、catkin_make、catkin_make_isolated、catkin_tools。
很明显colcon作为构建工具,通过调用CMake、Python setuptools完成构建。
1.2 常见构建系统
CMake 是一个跨平台构建系统生成器。项目使用独立于平台的文件指定其生成过程。用户通过使用CMake为其平台上的本机工具生成构建系统来构建项目。
1.2.2 Python setuptools
ament_tools支持构建以下软件包:
带有package.xml文件的 ROS 2 包。
带有package.xml普通的 CMake 包。
没有清单文件的普通 CMake 包(从 CMake 文件中提取包名称和依赖项)。
带有package.xml文件的 Python 包。
没有清单文件的 Python 包(从setup.py文件中提取包名称和依赖项)。

4 ROS2节点发现与多机通信

2.选择域ID (短版本)
下面的文本解释了应该在ROS 2中使用的域ID范围的推导。要跳过该背景知识并且只是选择一个安全的数字,只需选择一个介于0和101之间的安全的域ID (包括0和101)。
3.选择域ID (长版本)
DDS使用域ID计算将用于发现和通讯的UDP端口。有关如何计算端口的详细信息,请参见 这篇文章 。我们知道在网络中,UDP端口是 无符号16位整型 。因此可以分配的最大端口号是65535。用链接(http://dev.ros2.fishros.com/doc/Concepts/About-Domain-ID.html#domain-id-to-udp-port-calculator)中的公式计算一下,这意味着可以分配的最高域账号是232,而可以分配的最低域账号是0。

Linux
默认情况下,linux内核使用端口32768-60999作为临时端口。这意味着域ID 0-101 和 215-232 可以安全使用,而不会与临时端口发生冲突。临时端口范围可在Linux中通过在 /proc/sys/net/ipv4/ip_local_port_range 中设置自定义值进行配置。如果使用自定义临时端口范围,则可能需要相应地调整上述数字。

对于计算机上运行的每个ROS 2进程,将创建一个DDS "participant" 。由于每个DDS参与者占用计算机上的两个端口,因此在一台计算机上运行120个以上的ROS 2进程可能会溢出到其他域ID或临时端口。

为了解释原因,我们考虑域ID编号1和2。

域ID 1使用端口7650和7651进行多播。
域ID 2使用端口7900和7901进行多播。
在域ID 1中创建第一个进程 (第0个参与者) 时,端口7660和7661用于单播。
在域ID 1中创建第120个进程 (第119个参与者) 时,端口7898和7899用于单播。
在域ID 1中创建第121个进程 (第120个参与者) 时,端口7900和7901用于单播,并与域ID 2重叠。
如果已知计算机一次只能在一个域ID上,并且域ID足够低,那么创建比这更多的ROS 2进程是安全的。

在选择特定平台域 ID 范围顶部的域 ID 时,还有一个限制因素需要考虑。

posted @ 2025-06-04 18:48  长恨水长东  阅读(50)  评论(0)    收藏  举报