ros2 launch 用法以及一些基础功能函数的示例

2024-06-03 02:44

本文主要是介绍ros2 launch 用法以及一些基础功能函数的示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • launch
    • 启动一个节点的launch示例
    • launch文件中添加节点的namespace
    • launch文件中的话题名称映射
    • launch文件中向节点内传入命令行参数
    • launch文件中向节点内传入rosparam
    • 使用方法
    • 多节点启动
    • 命令行参数配置
    • 资源重映射
    • ROS参数设置
    • 加载参数文件
    • 在launch文件中使用条件变量
    • action的分组
    • action的启动延时控制
    • Launch文件包含,在launch文件中调用另一个launch文件
    • 在launch文件中运行脚本
    • 在launch文件中设置环境变量或读取环境变量
    • launch 用法以及一些基础功能函数的示例
    • 参数文件编译配置

launch

##前言

ros2 launch文件中最主要的概念是action,ros2 launch把每一个要执行的节点,文件,脚本,功能等全部抽象成action,用统一的接口来控制其启动,最主要的结构是:

def generate_launch_description():return LaunchDescription([action_1,action_2,...action_n])

要启动的节点或其他launch文件全部都传入LaunchDescription()函数中,该函数中接受一个或多launch.actionslaunch_ros.actions类型的对象,以下列举一下常用的action:

launch_ros.actions.Node· 此函数功能是启动一个ros2节点;
launch_ros.actions.PushRosNamespace· 此函数功能是给一个节点或组设置命名空间;
launch.actions.IncludeLaunchDescription· 此函数功能是直接引用另一个launch文件;
launch.actions.SetLaunchConfiguration· 此函数功能是在launch文件内声明一个参数,并给定参数值;
launch.actions.SetEnvironmentVariable· 此函数功能是声明一个环境变量并给定环境变量的值;
launch.actions.AppendEnvironmentVariable· 此函数将对一个环境变量追加一个值,如果不存在则创建;
launch.actions.DeclareLaunchArgument· 此函数功能是声明一个启动描述参数,该参数具有名称、默认值和文档;
launch.actions.TimerAction· 此函数功能是在一段时间后执行一个或多个action;
launch.actions.GroupAction· 此函数功能是将action分组,同组内的action可以统一设定参数方便集中管理;
launch.actions.ExecuteProcess· 此函数功能是根据输入执行一个进程或脚本;
launch.actions.EmitEvent· 此函数功能是发出一个事件,触发以注册的事件函数被调用;
launch.actions.RegisterEventHandler· 此函数功能是注册一个事件;
launch.actions.UnregisterEventHandler· 此函数功能是删除一个注册过的事件;

启动一个节点的launch示例

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')])

或者:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')return LaunchDescription([action_1])

launch文件名为test.launch.py,调用launch文件启动节点:

ros2 launch ros2_test test.launch.py

launch文件中添加节点的namespace

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen',namespace='my_ros2_test')])

设置了namespace后,此节点的话题前会加上namespace的前缀,例如原来的话题名称’/test’,设置后变为’/my_ros2_test/test’

注意,有以下情况namespace无效:

节点本来就已经有了namespace了,后续会介绍将节点分组,整组节点可以设置统一的namespace,此时如果有个节点已经设置过namespace,则在此设置不会生效;
定义发布节点的时候,topic名字的前面加上了符号/;

launch文件中的话题名称映射

话题映射的字段是remappings,语法示例如下:

remappings=[('src1', 'dest1'),('src2', 'dest2'),...
]

如果需要话题名称映射的话要将该字段加入到节点的函数内,假如节点内有个test1话题要映射到test2,示例如下:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",remappings=[("test1", "test2")])])

launch文件中向节点内传入命令行参数

参数字段是arguments,语法示例如下:

arguments=['arg1', 'arg2', ...]

如果需要向ros2_test_publisher_node节点中传入命令行参数,示例如下:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",arguments=['arg1', 'arg2'])])

传入的参数可以从节点启动时main函数中的argc参数获取到参数个数,argv参数获取到参数内容,详情参考c++的命令行参数获取;

launch文件中向节点内传入rosparam

字段是parameter,语法示例如下:

parameters=[{'port': '/dev/ttyUsb0'},...
]

如果需要在launch文件中发布某个节点空间下的parameter,示例如下:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",parameter=[{'port': '/dev/ttyUSB0'}])])

如果需要参数的值可以从外部调用launch文件时灵活更改,则可以使用变量的形式作为参数的值,在文件中给定默认值,若外部给定则以外部给定的值为准,若外部不给则以默认值为准:

port_var = LaunchConfiguration('port', default='/dev/ttyS1')

同时还可以使用DeclareLaunchArgument函数增加对参数的描述,增加描述后可以通过ros2 launch的命令行工具展示出每个launch文件中有哪些rosparam以及他的默认值和具体含义:

DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'
)

如果文件中加入了参数介绍则可以通过以下指令看到launch文件中有哪些可以自定义的参数以及参数含义:

ros2 launch ros2_test test.launch.py --show-args

所以如果launch文件中存在可配置参数,应该在LaunchDescription中添加DeclareLaunchArgument,让其他使用者明白变量名,以及他的含义是什么;

完整的launch文件如下:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import LaunchConfigurationdef generate_launch_description():port_var = LaunchConfiguration('port', default='/dev/ttyS1')return LaunchDescription([DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",parameter=[{'port': port_var}])])

此时我们可以把参数通过调用launch的时候传入到节点中:

ros2 launch ros2_test test.launch.py port_var:=/dev/ttyUSB2

在ros2_test_publisher_node节点中如果要想获取该参数,需要先声明parameter,然后再进行get:

this->declare_parameter<std::string>("port");
string port_str;
this->get_parameter_or<std::string>("port", port_str, "null");
if (port_str != "null") RCLCPP_INFO(this->get_logger(), "get ros2param port value : %s", port_str.c_str());

使用方法

官方推荐用python编写launch,如果launch文件不在功能包中,随便建立以.launch.py结尾的文件后,在当前目录直接运行即可,如果在功能包中可采用下面方式运行。如下代码。

ros2 launch turtlesim_mimic_launch.py  # 在文件中直接启动launch
ros2 launch <package_name> <launch_file_name> # 在功能包中启动launch

文件内容实例如下:

from launch import LaunchDescription           # launch文件的描述类
from launch_ros.actions import Node            # 节点启动的描述类def generate_launch_description():             # 自动生成launch文件的函数return LaunchDescription([                 # 返回launch文件的描述信息Node(                                  # 配置一个节点的启动package='learning_topic',          # 节点所在的功能包executable='topic_helloworld_pub', # 节点的可执行文件),Node(                                  # 配置一个节点的启动package='learning_topic',          # 节点所在的功能包executable='topic_helloworld_sub', # 节点的可执行文件名),])

多节点启动

from launch import LaunchDescription           # launch文件的描述类
from launch_ros.actions import Node            # 节点启动的描述类def generate_launch_description():             # 自动生成launch文件的函数return LaunchDescription([                 # 返回launch文件的描述信息Node(                                  # 配置一个节点的启动package='learning_topic',          # 节点所在的功能包executable='topic_helloworld_pub', # 节点的可执行文件),Node(                                  # 配置一个节点的启动package='learning_topic',          # 节点所在的功能包executable='topic_helloworld_sub', # 节点的可执行文件名),])

命令行参数配置

import osfrom ament_index_python.packages import get_package_share_directory # 查询功能包路径的方法from launch import LaunchDescription    # launch文件的描述类
from launch_ros.actions import Node     # 节点启动的描述类def generate_launch_description():      # 自动生成launch文件的函数rviz_config = os.path.join(          # 找到配置文件的完整路径get_package_share_directory('learning_launch'),'rviz','turtle_rviz.rviz')return LaunchDescription([           # 返回launch文件的描述信息Node(                             # 配置一个节点的启动package='rviz2',               # 节点所在的功能包executable='rviz2',            # 节点的可执行文件名name='rviz2',                  # 对节点重新命名arguments=['-d', rviz_config]  # 加载命令行参数)])

资源重映射

from launch import LaunchDescription      # launch文件的描述类
from launch_ros.actions import Node       # 节点启动的描述类def generate_launch_description():        # 自动生成launch文件的函数return LaunchDescription([            # 返回launch文件的描述信息Node(                             # 配置一个节点的启动package='turtlesim',          # 节点所在的功能包namespace='turtlesim1',       # 节点所在的命名空间executable='turtlesim_node',  # 节点的可执行文件名name='sim'                    # 对节点重新命名),Node(                             # 配置一个节点的启动package='turtlesim',          # 节点所在的功能包namespace='turtlesim2',       # 节点所在的命名空间executable='turtlesim_node',  # 节点的可执行文件名name='sim'                    # 对节点重新命名),Node(                             # 配置一个节点的启动package='turtlesim',          # 节点所在的功能包executable='mimic',           # 节点的可执行文件名name='mimic',                 # 对节点重新命名remappings=[                  # 资源重映射列表('/input/pose', '/turtlesim1/turtle1/pose'),         # 将/input/pose话题名修改为/turtlesim1/turtle1/pose('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),  # 将/output/cmd_vel话题名修改为/turtlesim2/turtle1/cmd_vel])])

ROS参数设置

from launch import LaunchDescription                   # launch文件的描述类
from launch.actions import DeclareLaunchArgument       # 声明launch文件内使用的Argument类
from launch.substitutions import LaunchConfiguration, TextSubstitutionfrom launch_ros.actions import Node                    # 节点启动的描述类def generate_launch_description():                     # 自动生成launch文件的函数background_r_launch_arg = DeclareLaunchArgument('background_r', default_value=TextSubstitution(text='0')     # 创建一个Launch文件内参数(arg)background_r)background_g_launch_arg = DeclareLaunchArgument('background_g', default_value=TextSubstitution(text='84')    # 创建一个Launch文件内参数(arg)background_g)background_b_launch_arg = DeclareLaunchArgument('background_b', default_value=TextSubstitution(text='122')   # 创建一个Launch文件内参数(arg)background_b)return LaunchDescription([                                      # 返回launch文件的描述信息background_r_launch_arg,                                     # 调用以上创建的参数(arg)background_g_launch_arg,background_b_launch_arg,Node(                                                        # 配置一个节点的启动package='turtlesim',executable='turtlesim_node',                              # 节点所在的功能包name='sim',                                               # 对节点重新命名parameters=[{                                             # ROS参数列表'background_r': LaunchConfiguration('background_r'),   # 创建参数background_r'background_g': LaunchConfiguration('background_g'),   # 创建参数background_g'background_b': LaunchConfiguration('background_b'),   # 创建参数background_b}]),])

加载参数文件

import osfrom ament_index_python.packages import get_package_share_directory  # 查询功能包路径的方法from launch import LaunchDescription   # launch文件的描述类
from launch_ros.actions import Node    # 节点启动的描述类def generate_launch_description():     # 自动生成launch文件的函数config = os.path.join(              # 找到参数文件的完整路径get_package_share_directory('learning_launch'),'config','turtlesim.yaml')return LaunchDescription([          # 返回launch文件的描述信息Node(                            # 配置一个节点的启动package='turtlesim',          # 节点所在的功能包executable='turtlesim_node',  # 节点的可执行文件名namespace='turtlesim2',       # 节点所在的命名空间name='sim',                   # 对节点重新命名parameters=[config]           # 加载参数文件)])

在launch文件中使用条件变量

字段是condition,语法示例如下:

condition=IfCondition(variable)

IfCondition(variable)函数内只接受true, false, 0, 1参数,如果节点启动的描述中加入该字段并且参数值为false或0则节点不启动

完整的launch文件如下:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfConditiondef generate_launch_description():variable = LaunchConfiguration('start_flag', default='true')return LaunchDescription([DeclareLaunchArgument('start_flag',default_value=variable,description='This is the ros2_test_publisher_node start flag'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",condition=IfCondition(variable))])

此时

运行:ros2 launch ros2_test test.launch.py 节点会正常启动

运行:ros2 launch ros2_test test.launch.py start_flag:=false 节点不会启动

进阶的IfCondition函数使用方式:

由于LaunchConfiguration()函数的返回是一个对象,所以我们不可以拿来直接做运算,但是可以使用PythonExpression()做参数的表达式运算,语法如下:

PythonExpression([variable, '== 1']) 或
PythonExpression([variable, '+ 1 == 2']) 或
PythonExpression([variable, "== 'test'"]) 等等

完整的launch文件如下:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfConditiondef generate_launch_description():port_var = LaunchConfiguration('port', default='/dev/ttyS1')return LaunchDescription([DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",condition=IfCondition(PythonExpression([port_var, "== '/dev/ttyUSB0'"])))])

此时

运行:ros2 launch ros2_test test.launch.py 节点不会启动

运行:ros2 launch ros2_test test.launch.py port_var:=/dev/ttyUSB0 节点正常启动

action的分组

GroupAction():函数可以将一个或多个action加入到一个组中,组内可以共用参数,控制整组节点全部启动或全部不启动等,方便action的管理,需要接受的部分参数有:

  • actions:接受一个list, [action_1, action_2,…],列表中装要执行的action
  • condition:条件变量参数
  • launch_configuration:参数

PushRosNamespace()函数的作用是向test_group中设置组内的namespace,但是action_1中已经设置过了namespace,所以此时不会生效,该namespace只会在action_2中生效;

实例一:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import GroupAction
from launch_ros.actions import PushRosNamespacedef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen',namespace='my_ros2_test')action_2 = Node(package='ros2_test',executable='ros2_test_subscriber_node',name='ros2_test_subscriber_node',output='screen')test_group = GroupAction(actions=[PushRosNamespace("my_group_test"),action_1, action_2])return LaunchDescription([test_group])

action的启动延时控制

TimerAction():函数可以在指定的时间后执行一个action,需要接受参数有

  • period:接受一个float, 延迟的时间
  • actions:接受一个list, [action_1, action_2,…],列表中装要执行的action

实例一:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import TimerActiondef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')return LaunchDescription([TimerAction(period=5.0, actions=[action_1])])

Launch文件包含,在launch文件中调用另一个launch文件

PythonLaunchDescriptionSource() :在launch文件中调用其他launch需要调用函数,参数是被调用launch的路径。

实例一:

import osfrom ament_index_python.packages import get_package_share_directory  # 查询功能包路径的方法from launch import LaunchDescription                 # launch文件的描述类
from launch.actions import IncludeLaunchDescription  # 节点启动的描述类
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import GroupAction               # launch文件中的执行动作
from launch_ros.actions import PushRosNamespace      # ROS命名空间配置def generate_launch_description():                   # 自动生成launch文件的函数parameter_yaml = IncludeLaunchDescription(        # 包含指定路径下的另外一个launch文件PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('learning_launch'), 'launch'),'/parameters_nonamespace.launch.py']))parameter_yaml_with_namespace = GroupAction(      # 对指定launch文件中启动的功能加上命名空间actions=[PushRosNamespace('turtlesim2'),parameter_yaml])return LaunchDescription([                        # 返回launch文件的描述信息parameter_yaml_with_namespace])

实例二:

import os
from ament_index_python import get_package_share_directory
from launch import LaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen'),PythonLaunchDescriptionSource(os.path.join(get_package_share_directory('ros2_test'),'launch/test_subscriber.launch.py'))])

实例三:

from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import ThisLaunchFileDir
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration
from launch.actions import IncludeLaunchDescriptiondef generate_launch_description():inlucde_other_file = LaunchConfiguration('inlucde_other_file', default='true')test_var = LaunchConfiguration('test_var', default='test_var_2')return launch.LaunchDescription([IncludeLaunchDescription(PythonLaunchDescriptionSource([ThisLaunchFileDir(), '/test_subscriber.launch.py']),condition=IfCondition(inlucde_other_file),launch_arguments={'test_var': test_var}.items())])

在launch文件中运行脚本

ExecuteProcess():运行脚本同样可实现启动某个节点,同时该函数还支持condition、additional_env等参数的设置。

实例一:

from launch import LaunchDescription
from launch.actions import ExecuteProcessdef generate_launch_description():return LaunchDescription([ExecuteProcess(cmd=['ros2', 'run', 'ros2_test', 'ros2_test_publisher_node'],output="screen")])

在launch文件中设置环境变量或读取环境变量

SetEnvironmentVariable(var_name, var_value):函数用于设置环境变量,接受两个参数分别是要设置的环境变量名称和环境变量的值;

EnvironmentVariable(var_name):函数用于获取环境变量的值,返回值类型是一个对象,输入参数是要获取的环境变量名称;

完整launch文件实例:

from launch import LaunchDescription
from launch.actions import SetEnvironmentVariable, ExecuteProcess
from launch.substitutions import EnvironmentVariabledef generate_launch_description():return LaunchDescription([SetEnvironmentVariable('PRODUCT_MODEL', 'spray_robot'),ExecuteProcess(cmd=['echo', EnvironmentVariable('PRODUCT_MODEL')],output='screen')])

运行看到以下输出

[INFO] [echo-1]: process started with pid [195168]
[echo-1] spray_robot
[INFO] [echo-1]: process has finished cleanly [pid 195168]

launch 用法以及一些基础功能函数的示例

ros2 launch文件中最主要的概念是action,ros2 launch把每一个要执行的节点,文件,脚本,功能等全部抽象成action,用统一的接口来控制其启动,最主要的结构是:

def generate_launch_description():return LaunchDescription([action_1,action_2,...action_n])

要启动的节点或其他launch文件全部都传入LaunchDescription()函数中,该函数中接受一个或多launch.actionslaunch_ros.actions类型的对象,以下列举一下常用的action:

launch_ros.actions.Node· 此函数功能是启动一个ros2节点;
launch_ros.actions.PushRosNamespace· 此函数功能是给一个节点或组设置命名空间;
launch.actions.IncludeLaunchDescription· 此函数功能是直接引用另一个launch文件;
launch.actions.SetLaunchConfiguration· 此函数功能是在launch文件内声明一个参数,并给定参数值;
launch.actions.SetEnvironmentVariable· 此函数功能是声明一个环境变量并给定环境变量的值;
launch.actions.AppendEnvironmentVariable· 此函数将对一个环境变量追加一个值,如果不存在则创建;
launch.actions.DeclareLaunchArgument· 此函数功能是声明一个启动描述参数,该参数具有名称、默认值和文档;
launch.actions.TimerAction· 此函数功能是在一段时间后执行一个或多个action;
launch.actions.GroupAction· 此函数功能是将action分组,同组内的action可以统一设定参数方便集中管理;
launch.actions.ExecuteProcess· 此函数功能是根据输入执行一个进程或脚本;
launch.actions.EmitEvent· 此函数功能是发出一个事件,触发以注册的事件函数被调用;
launch.actions.RegisterEventHandler· 此函数功能是注册一个事件;
launch.actions.UnregisterEventHandler· 此函数功能是删除一个注册过的事件;

参数文件编译配置

功能包里面的参数文件,需要在setup.py里面做以下配置,编译的时候才能拷贝到include里面去

from setuptools import setup
import os
from glob import globpackage_name = 'learning_launch'setup(name=package_name,version='0.0.0',packages=[package_name],data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),(os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*.launch.py'))),(os.path.join('share', package_name, 'config'), glob(os.path.join('config', '*.*'))),(os.path.join('share', package_name, 'rviz'), glob(os.path.join('rviz', '*.*'))),],install_requires=['setuptools'],zip_safe=True,maintainer='hcx',maintainer_email='huchunxu@guyuehome.com',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts': [],},
)

这篇关于ros2 launch 用法以及一些基础功能函数的示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1025813

相关文章

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数