ROS2中通过launch读取.yaml配置文件启动节点

news/2024/12/25 15:02:41 标签: ros2, launch, yaml

环境:Ubuntu22.04,ROS2-humble
通过修改.yaml配置文件中的参数,可以不用重新编译源代码进行软件调试。

yaml_3">1.yaml文件格式

bag_to_image_node:运行的ROS2节点名称
参数格式参考如下:

yaml">bag_to_image_node:
  ros__parameters:
    greeting: "Hello"
    name: "BUDING DUODUO"
    ExposureTime: 8888

launch_14">2.launch文件

  • launch中要找到YAML文件,可以使用绝对路径
import launch
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, LogInfo
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node

def generate_launch_description():
    current_dir = os.getcwd()  # 获取当前工作目录
    print(f"Current directory: {current_dir}")  # 打印当前目录
    # 声明参数文件路径的启动参数
    return LaunchDescription([
        # 声明一个启动参数,指定参数文件的路径
        DeclareLaunchArgument(
            'config_file',
            default_value='/home/boss-dog/001_test/bag_to_image/src/bag_to_image/config/params.yaml',
            description='Path to the YAML parameter file'
        ),
        
        # 启动节点并加载参数文件
        Node(
            package='bag_to_image',  # 你的包名
            executable='bag_to_image_node',  # 你的可执行文件名
            name='bag_to_image_node',  # 节点名称
            output='screen',
            parameters=[LaunchConfiguration('config_file')],  # 加载指定的 YAML 配置文件
        ),
        
        # 打印日志确认节点启动
        LogInfo(
            condition=launch.conditions.LaunchConfigurationEquals('config_file', ''),
            msg="Starting with default parameter file"
        )
    ])

import launch
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, LogInfo
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
import os

def generate_launch_description():
    current_dir = os.getcwd()  # 获取当前工作目录
    print(f"Current directory: {current_dir}")  # 打印当前目录
    
     # 拼接文件路径
    config_file_path = os.path.join(current_dir, 'install', 'bag_to_image', 'share', 'bag_to_image', 'config', 'params.yaml')
    
    # 声明参数文件路径的启动参数
    return LaunchDescription([
        
        # 启动节点并加载参数文件
        Node(
            package='bag_to_image',  # 你的包名
            executable='bag_to_image_node',  # 你的可执行文件名
            name='bag_to_image_node',  # 节点名称
            output='screen',
            parameters=[config_file_path],  # 加载指定的 YAML 配置文件
        ),
        
        # 打印日志确认节点启动
        LogInfo(
            condition=launch.conditions.LaunchConfigurationEquals('config_file', ''),
            msg="Starting with default parameter file"
        )
    ])

launchinstall_87">3.CMakeList中需要将配置文件和launch文件拷贝到install下

# 复制launch文件
install(
  DIRECTORY launch/
  DESTINATION share/${PROJECT_NAME}/launch
)

# Install config files
install(DIRECTORY config/
  DESTINATION share/${PROJECT_NAME}/config
)

在这里插入图片描述

4.源码

项目结构

bag_to_image
├── CMakeLists.txt
├── config
│   └── params.yaml
├── include
│   └── bag_to_image
├── launch
│   └── start_node.launch.py
├── package.xml
└── src
    └── bag_to_image_node.cpp
  • CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(bag_to_image)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)

add_executable(bag_to_image_node src/bag_to_image_node.cpp)

target_include_directories(bag_to_image_node
    PUBLIC ${PCL_INCLUDE_DIRS}
)

# ROS2中指定节点或库的依赖项
ament_target_dependencies(bag_to_image_node rclcpp) 

install(TARGETS
    bag_to_image_node
    DESTINATION lib/${PROJECT_NAME})

# 复制launch文件
install(
  DIRECTORY launch/
  DESTINATION share/${PROJECT_NAME}/launch
)

# Install config files
install(DIRECTORY config/
  DESTINATION share/${PROJECT_NAME}/config
)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  set(ament_cmake_copyright_FOUND TRUE)
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()
yaml">bag_to_image_node:
  ros__parameters:
    greeting: "Hello"
    name: "BUDING DUODUO"
    ExposureTime: 12345
import launch
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, LogInfo
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
import os

def generate_launch_description():
    current_dir = os.getcwd()  # 获取当前工作目录
    print(f"Current directory: {current_dir}")  # 打印当前目录

     # 拼接文件路径
    config_file_path = os.path.join(current_dir, 'install', 'bag_to_image', 'share', 'bag_to_image', 'config', 'params.yaml')

    # 声明参数文件路径的启动参数
    return LaunchDescription([

        # 启动节点并加载参数文件
        Node(
            package='bag_to_image',  # 你的包名
            executable='bag_to_image_node',  # 你的可执行文件名
            name='bag_to_image_node',  # 节点名称
            output='screen',
            parameters=[config_file_path],  # 加载指定的 YAML 配置文件
        ),

        # 打印日志确认节点启动
        LogInfo(
            condition=launch.conditions.LaunchConfigurationEquals('config_file', ''),
            msg="Starting with default parameter file"
        )
    ])
  • 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>bag_to_image</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="boss_dog@qq.cn">qq</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>
  • bag_to_image_node.cpp
#include <rclcpp/rclcpp.hpp>
#include <iostream>

class ImageSaverNode : public rclcpp::Node
{
public:
    ImageSaverNode() : Node("image_saver_node")
    {
        std::cout << "node..." << std::endl;

        // 获取参数
        this->declare_parameter<std::string>("greeting", "Hello");
        this->declare_parameter<std::string>("name", "ROS2");

        this->declare_parameter<int>("ExposureTime", 50000);

        // 读取参数
        std::string greeting = this->get_parameter("greeting").as_string();
        std::string name     = this->get_parameter("name").as_string();
        int ExposureTime     = this->get_parameter("ExposureTime").as_int();

        // 打印信息
        std::cout << greeting << ", " << name << std::endl;
        std::cout << "ExposureTime: " << ExposureTime << std::endl;
    }

    ~ImageSaverNode() {}
};

int main(int argc, char **argv)
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ImageSaverNode>());
    rclcpp::shutdown();

    std::cout << "run ..." << std::endl;

    return 0;
}

运行结果

在这里插入图片描述

  • 不通过读取.yaml文件直接启动节点
$ source install/setup.bash
$ ros2 run bag_to_image bag_to_image_node 

node...
Hello, ROS2
ExposureTime: 50000
$ source install/setup.bash
$ ros2 launch bag_to_image start_node.launch.py 

[INFO] [launch]: All log files can be found below /home/boss-dog/.ros/log/2024-12-24-20-34-00-600200-boss-dog-106611
[INFO] [launch]: Default logging verbosity is set to INFO
Current directory: /home/boss-dog/001_test/bag_to_image
[INFO] [bag_to_image_node-1]: process started with pid [106612]
[bag_to_image_node-1] node...
[bag_to_image_node-1] Hello, BUDING DUODUO
[bag_to_image_node-1] ExposureTime: 12345

http://www.niftyadmin.cn/n/5799239.html

相关文章

【自动驾驶】3 激光雷达②

4 激光雷达点云检测算法 &#x1f49a;论文标题&#xff1a;3D Object Detection for Autonomous Driving: A Comprehensive Survey&#xff08;面向自动驾驶的3D目标检测&#xff1a;综合调研&#xff09; &#x1f49a;论文地址&#xff1a;https://arxiv.org/pdf/2206.094…

面对小白的C语言学习方法

这是第20篇文章&#xff0c;不来弄一些技术的&#xff0c;弄一些最近的学习心得&#xff0c;怎么更有效地自学C语言 书籍 书籍可以很有效的告知我们专有函数&#xff0c;使用方法还有一些思考方式&#xff0c;缺点是实操差点意思&#xff0c;还是不太能解决实际问题&#xff…

《智驱新材合成:AI 点亮创新路径之光》

在科技浪潮汹涌澎湃的当下&#xff0c;新材料的探寻成为众多领域突破发展瓶颈的关键钥匙。而人工智能&#xff08;AI&#xff09;作为前沿科技的璀璨星辰&#xff0c;正以其独特的创新光芒照亮新材料合成路径的未知之境&#xff0c;引发了科研界与产业界的广泛关注与热议&#…

水电站视频智能监控系统方案设计与技术应用方案

一、背景需求 水电站作为国家重要的能源基地&#xff0c;其安全运行对于保障能源供应和社会稳定具有重要意义。然而&#xff0c;传统的人工监控方式存在着诸多问题&#xff0c;如人力成本高、监控范围有限、反应不及时等。因此&#xff0c;水电站急需引进一种先进的视频智能监控…

http反向代理

通过反向代理实现访问biying,目前访问一些网站需要绕过cloudfare还没有解决,代码如下: from fastapi import FastAPI, Request from fastapi.responses import StreamingResponse import httpx import uvicorn import logging# 设置日志 logging.basicConfig(level=logging.…

【接口自动化连载】使用yaml配置文件自动生成接口case

直接上干货撸代码&#xff0c;有一些是通用的工具类代码&#xff0c;一次性封装永久使用&#xff0c;期待大家的关注&#xff0c;一起加油&#xff01;&#xff01;&#xff01; 配置文件 根据不同的业务需求进行配置&#xff0c;例如Goods服务、Order服务分开配置&#xff0…

shiro注入filter内存马(绕过长度限制)

shiro环境 https://github.com/yyhuni/shiroMemshell&#xff08;实验环境&#xff09; 这里用的 Client_memshell.java package com.example.demo;import javassist.ClassPool; import javassist.CtClass; import org.apache.shiro.crypto.AesCipherService; import org.ap…

一种新型离线强化学习方法 OREO

“Offline Reinforcement Learning for LLM Multi-Step Reasoning”由Huaijie Wang、Shibo Hao等人撰写。论文提出了OREO&#xff08;Offline REasoning Optimization&#xff09;这一离线强化学习方法&#xff0c;用于增强大语言模型&#xff08;LLMs&#xff09;的多步推理能…