鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    ros2 launch文件出现Unknown substitution: find

    已定时 已固定 已锁定 已移动 未解决
    ROS 2相关问题
    ros2 launch文件 humble
    1
    1
    666
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • yudonghou123Y
      小猴同学
      最后由 编辑

      系统ubuntu22.04 ROS2 humble
      各位大佬,我在编译运行ROS2的一个launch文件时终端输出以下问题:

      [INFO] [launch]: All log files can be found below /home/user2/.ros/log/2023-02-10-15-26-02-475140-user2-339817
      [INFO] [launch]: Default logging verbosity is set to INFO
      [ERROR] [launch]: Caught exception in launch (see debug for traceback): Caught exception when trying to load file of format [launch]: Error trying to process rule "substitution":
      

      我的launch文件如下:

      <?xml version="1.0"?>
      
      <launch>
      	<arg name="config" default="$(find ros_ads_node)/config/configuration.yaml" />
      
      	<node pkg="ros_ads_node" exec="ros_ads_node" name="ros_ads_node" output="screen">
      	    <param name="name" type="str" value="test_device"/>
      	    <param name="config_file" type="str" value="$(arg config)"/>
      	</node>
      </launch>
      

      用到launch文件的两个参数的cpp文件为:

      #include "Ads_node.h"
      
      #include <iostream>
      #include <unistd.h>
      #include "rclcpp/rclcpp.hpp"
      #include "ros_ads_msgs/msg/ads.hpp"
      #include "ros_ads_msgs/msg/state.hpp"
      
      using namespace ads_node;
      using namespace std::chrono_literals;
      using std::placeholders::_1;
      using std::placeholders::_2;
      using std::placeholders::_3;
      /**
       * @brief ADSNode::initialize initialize the parameters of the node and it's variables
       * @return 1 if the initialization failed
       * @return 0 otherwise
       */
       ADSNode::ADSNode(rclcpp::NodeOptions options)
          : Node("ads_node", options)
      {
      /*     bool ADSNode::initialize()
      { */
      /*     ros::NodeHandle n;
          ros::NodeHandle nprive("~"); */
      /*     std::shared_ptr<rclcpp::Node> nprive; */
          if(rclcpp::Node::has_parameter("name"))
          /* if(nprive->has_parameter("name")) */
          {
              rclcpp::Node::get_parameter("name", m_name);
          }
          else
          {
            RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Param name unknown");
      /*       return 0; */
          }
      
          if(rclcpp::Node::has_parameter("config_file"))
          {
              try { //get parameters from YAML file
                  rclcpp::Node::get_parameter("config_file", m_config_file);
                  YAML::Node config = YAML::LoadFile(m_config_file);
                  if(config[m_name])
                  {
                      m_ADS.setLocalNetID(config[m_name]["localNetID"].as<string>());
                      m_ADS.setRemoteNetID(config[m_name]["remoteNetID"].as<string>());
                      m_ADS.setRemoteIPV4(config[m_name]["remoteIP"].as<string>());
                      m_rate_update = config[m_name]["refresh_rate"].as<int>();
                      m_rate_publish = config[m_name]["publish_rate"].as<int>();
                      m_rate_state = config[m_name]["state_rate"].as<int>();
      
                      if(config[m_name]["publish_on_timer"].size() != 0)
                      {
                          auto onTimer = config[m_name]["publish_on_timer"].as<vector<string>>();
                          for(auto & var: onTimer)
                          {
                              m_publish_on_timer_guard.lock();
                              m_publish_on_timer[var] = pair<string, double>();
                              m_publish_on_timer_guard.unlock();
                              m_variables_guard.lock();
                              m_variables[var] = pair<string, double>();
                              m_variables_guard.unlock();
                          }
                      }
      
                      if(config[m_name]["publish_on_event"].size() != 0)
                      {
                          auto onEvent = config[m_name]["publish_on_event"].as<vector<string>>();
                          for(auto & var: onEvent)
                          {
                              m_publish_on_event_guard.lock();
                              m_publish_on_event[var] = pair<string, double>();
                              m_publish_on_event_guard.unlock();
                              m_variables_guard.lock();
                              m_variables[var] = pair<string, double>();
                              m_variables_guard.unlock();
                          }
                      }
                  }
              } catch (...)
              {
                  RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"Invalid configuration file");
              }
      
          }
          else {
            RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"Error with configuration file");
      /*       return 0; */
          }
      
          try
          {
              RCLCPP_INFO_STREAM(rclcpp::get_logger("rclcpp"),"GO FOR Init Route");
              m_ADS.initRoute();
              RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Init Route done");
          }
          catch(...)
          {
              RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"ERROR while connecting with ADS");
      /*         return 0; */
          }
      
          try
          {
            RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Acquiring ADS variables");
            m_ADS.acquireVariables();
            RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"ADS variables acquired");
      
            RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Aliasing ADS variables");
            m_ADS.setName(m_name);
            m_ADS.setFile(m_config_file);
            m_ADS.bindPLcVar();
            RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Ready to communicate with the remote PLC via ADS.");
          }
          catch(AdsException& e)
          {
            RCLCPP_ERROR_STREAM(rclcpp::get_logger("rclcpp"),e.what());
            RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"ERROR in mapping alias with ADS");
      /*       return 0; */
          }
      
          try
          {
              m_sub_option.callback_group = mp_callback_group_publisher;
              //m_subscriber = this->create_subscription<ros_ads_msgs::msg::ADS>("command", 10, boost::bind(&ADSNode::Subscriber, this, _1),m_sub_option);
              m_subscriber = this->create_subscription<ros_ads_msgs::msg::ADS>("command", 10, [this](ros_ads_msgs::msg::ADS::ConstPtr msg){Subscriber(msg);},m_sub_option);
          
              m_on_event_publisher = this->create_publisher<ros_ads_msgs::msg::ADS>("report_event", 10);
              m_on_timer_publisher = this->create_publisher<ros_ads_msgs::msg::ADS>("report_timer", 10);
              m_state_publisher = this->create_publisher<ros_ads_msgs::msg::State>("state", 10);
      
      /*         m_subscriber = n.subscribe<ros_ads_msgs::msg::ADS>("command", 10, boost::bind(&ADSNode::Subscriber, this, _1));
              m_on_event_publisher = n.advertise<ros_ads_msgs::msg::ADS>("report_event", 10);
              m_on_timer_publisher = n.advertise<ros_ads_msgs::msg::ADS>("report_timer", 10);
              m_state_publisher = n.advertise<ros_ads_msgs::msg::ADS>("state", 10); */
          }
          catch (...)
          {
              RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"ERROR in creating subscriber");
      /*         return 0; */
          }
      
      /*     m_timer_thread   = std::make_shared<boost::thread>(&ADSNode::publishOnTimer,this, m_rate_publish);
          m_update_thread  = std::make_shared<boost::thread>(&ADSNode::update,this, m_rate_update);
          m_checker_thread = std::make_shared<boost::thread>(&ADSNode::publishOnEvent,this, m_rate_update);
          m_state_thread   = std::make_shared<boost::thread>(&ADSNode::publishState,this, m_rate_state); */
      
          m_timer_thread   = this->create_wall_timer(std::chrono::milliseconds(int(m_rate_publish)),std::bind(&ADSNode::publishOnTimer, this),mp_callback_group_subscriber);
          m_update_thread  = this->create_wall_timer(std::chrono::milliseconds(int(m_rate_update)),std::bind(&ADSNode::update, this),mp_callback_group_update);
          m_checker_thread = this->create_wall_timer(std::chrono::milliseconds(int(m_rate_update)),std::bind(&ADSNode::publishOnEvent, this),mp_callback_group_checker);
          m_state_thread   = this->create_wall_timer(std::chrono::milliseconds(int(m_rate_state)),std::bind(&ADSNode::publishState, this),mp_callback_group_state);
      
      /*     return 1;
      } */
      /**
       * @brief ADSNode::update update internal variable values memory
       *
       * Starts by verifying and updating connection state
       *
       * @param timer_rate rate to update at
       */
      }
      
      void ADSNode::update()
      {
      /*     auto loop_rate_update = rclcpp::Rate(timer_rate);
          while(rclcpp::ok())
          { */
              m_variables_guard.lock();
              try
              {
                  m_ADS.connectionCheck();
                  if(m_ADS.getState())
                  {
                      m_ADS.updateMemory();
                      auto variables_map = m_ADS.getVariablesMap();
                      for(auto &[name, pair]: variables_map)
                      { //cast as double for the message
                          m_variables[name].first = pair.first;
                          switch (pair.second.index())
                          {
                          case ros_ads_msgs::BOOL:
                          {
                              m_variables[name].second = static_cast<double>(get<bool>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::UINT8_T:
                          {
                              m_variables[name].second = static_cast<double>(get<uint8_t>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::INT8_T:
                          {
                              m_variables[name].second = static_cast<double>(get<int8_t>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::UINT16_T:
                          {
                              m_variables[name].second = static_cast<double>(get<uint16_t>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::INT16_T:
                          {
                              m_variables[name].second = static_cast<double>(get<int16_t>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::UINT32_T:
                          {
                              m_variables[name].second = static_cast<double>(get<uint32_t>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::INT32_T:
                          {
                              m_variables[name].second = static_cast<double>(get<int32_t>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::INT64_T:
                          {
                              m_variables[name].second = static_cast<double>(get<int64_t>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::FLOAT:
                          {
                              m_variables[name].second = static_cast<double>(get<float>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::DOUBLE:
                          {
                              m_variables[name].second = static_cast<double>(get<double>(pair.second));
                              break;
                          }
                          case ros_ads_msgs::DATE:
                          {
                              tm temp = get<tm>(pair.second);
                              m_variables[name].second = static_cast<double>(mktime(&temp));
                              break;
                          }
                          default:
                          {
      
                          }
                          }
                          m_publish_on_timer_guard.lock();
                          if(m_publish_on_timer.find(name) != m_publish_on_timer.end() && m_ADS.getState())
                          {
                              m_publish_on_timer[name] = m_variables[name];
                          }
                          m_publish_on_timer_guard.unlock();
                      }
                  }
              }
              catch (...)
              {
                  RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"fail timer CB");
              }
              m_variables_guard.unlock();
      /*         loop_rate_update.sleep();
          } */
      }
      
      /**
       * @brief ADSNode::publishState publish state periodically
       * @param timer_rate rate to publish at
       */
      void ADSNode::publishState()
      {
      /*     auto loop_rate_state = rclcpp::Rate(timer_rate);
          while(rclcpp::ok())
          { */
              m_state_msg.header.stamp =this->now();
              m_state_msg.state = m_ADS.getState();
              m_state_msg.error = m_ADS.getADSState();
              m_state_publisher->publish(m_state_msg);
      /*         loop_rate_state.sleep();
          } */
      }
      
      /**
       * @brief ADSNode::publishOnEvent publish variables if an event occured
       * @param timer_rate rate to verify if an event occured at
       */
      void ADSNode::publishOnEvent()
      {
      /*     auto loop_rate_check = rclcpp::Rate(timer_rate);
          while(rclcpp::ok())
          { */
              try
              {
                  if(m_ADS.getState())
                  {
                      m_publish_on_event_guard.lock();
                      auto publish_on_event = m_publish_on_event;
                      m_publish_on_event_guard.unlock();
                      m_variables_guard.lock();
                      auto variables = m_variables;
                      m_variables_guard.unlock();
      
                      m_publish = false;
                      for(auto &[key, pair_] : publish_on_event)
                      {
                          m_checker_temp_value = variables[key];
                          if(pair_ != m_checker_temp_value) // A change has occured
                          {
                              m_publish_on_event_guard.lock();
                              m_publish_on_event[key] = m_checker_temp_value; // Update value
                              m_publish_on_event_guard.unlock();
      
                              if(!m_publish)
                              {
                                  m_publish = true;
                              }
                          }
                      }
                      if (m_publish) // Publish if a change occured
                      {
                          m_on_event_msg.header.stamp = this->now();
                          m_on_event_msg.varnames = vector<string>();
                          m_on_event_msg.vartypes = vector<string>();
                          m_on_event_msg.varvalues = vector<double>();
      
                          for (auto &[key, pair] : publish_on_event)
                          {
                              m_on_event_msg.varnames.push_back(key);
                              auto type = pair.first;
                              m_on_event_msg.vartypes.push_back(type);
                              auto value = pair.second;
                              m_on_event_msg.varvalues.push_back(value);
                          }
                          if(m_on_event_msg.varnames.size() !=0)
                          {
                              m_on_event_publisher->publish(m_on_event_msg);
                          }
                      }
                  }
              }
              catch(...)
              {
                  RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"fail checker CB");
              }
      /*         loop_rate_check.sleep();
          }
       */
      }
      
      /**
       * @brief ADSNode::publishOnTimer publish variables periodically
       * @param timer_rate rate to publish at
       */
      void ADSNode::publishOnTimer()
      {
      
      /*     auto loop_rate_pub = rclcpp::Rate(timer_rate);
          while(rclcpp::ok())
          { */
              try
              {
                  m_on_timer_msg.header.stamp = this->now();
                  m_on_timer_msg.varnames = vector<string>();
                  m_on_timer_msg.vartypes = vector<string>();
                  m_on_timer_msg.varvalues = vector<double>();
      
                  m_publish_on_timer_guard.lock();
                  auto publish_on_timer = m_publish_on_timer;
                  m_publish_on_timer_guard.unlock();
                  
                  for(auto &[name, pair]: publish_on_timer)
                  {
                      m_on_timer_msg.varnames.push_back(name);
                      m_on_timer_msg.vartypes.push_back(pair.first);
                      m_on_timer_msg.varvalues.push_back(pair.second);
                  }
      
      
                  if(m_on_timer_msg.varnames.size() != 0)
                  {
                      m_on_timer_publisher->publish(m_on_timer_msg);
                  }
                  /* loop_rate_pub.sleep(); */
              }
              catch(...)
              {
                  RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"fail pub CB");
              }
      
          /* } */
      }
      
      /**
       * @brief ADSNode::Subscriber send the ADS device the received commands
       * @param msg the command message
       * @return true if the command was successfully sent
       */
      void ADSNode::Subscriber(const ros_ads_msgs::msg::ADS::ConstPtr &msg)
      {
          m_state_publisher->publish(m_state_msg);
          /* bool result = true; */
          auto command = ros_ads_msgs::decode(msg);
      
      /*     try { */
              if(m_ADS.getState())
              {
                  for (auto &[name, value]: command)
                  {
                      m_ADS.adsWriteValue(name, value);
                  }
              }
      /*     } */
      /*     catch (...)
          {
              result = false;
          } */
      
      /*     return result;  */
      }
      
      int main(int argc, char **argv)
      {
          /* rclcpp::init(argc, argv, "ros_ads_node"); */
          rclcpp::init(argc, argv);
      /*     auto node=std::make_shared<ADSNode>();
          node->initialize();
          while(rclcpp::ok())
          {
              rclcpp::spin_some(node);
          } */
          auto node{std::make_shared<ads_node::ADSNode>()};
          rclcpp::executors::MultiThreadedExecutor executor;
          executor.add_node(node);
          executor.spin();
      
          rclcpp::shutdown();
          return 0;
      }
      

      cmakelist文件如下,我是将src中的多个cpp文件放入了一个节点:

      cmake_minimum_required(VERSION 3.8)
      project(ros_ads_node)
      ## Compile as C++17, supported in ROS Kinetic and newer
      
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
      
      set(CMAKE_CXX_STANDARD_REQUIRED ON)
      
      set(CMAKE_CXX_EXTENSIONS OFF)
      if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        add_compile_options(-Wall -Wextra -Wpedantic)
      endif()
      
      find_package(Threads REQUIRED)
      set(CMAKE_BUILD_TYPE debug)
      ##add_definitions(-D _GLIBCXX_USE_CXX11_ABI=0)
      add_subdirectory(lib/ADS/AdsLib)
      ## Find catkin macros and libraries
      ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
      ## is used, also find other catkin packages
      find_package(ament_cmake REQUIRED)
      find_package(rclcpp REQUIRED)
      find_package(std_msgs REQUIRED)
      find_package(ros_ads_msgs REQUIRED)
      find_package(yaml-cpp REQUIRED)
      #find_package(TinyXML REQUIRED)
      
      #include_directories(
      #  include
      #  ${TinyXML_INCLUDE_DIRS}
      #)
      
      add_executable(ros_ads_node src/ADSDecode.cpp src/Ads_node.cpp src/Ads_Interface.cpp)
      add_dependencies(ros_ads_node  ads)
      target_include_directories(ros_ads_node PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>)
      
      target_link_libraries(ros_ads_node ${ament_LIBRARIES} ads -lpthread yaml-cpp)#  ${TinyXML_LIBRARIES}
      target_compile_features(ros_ads_node PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
      ament_target_dependencies(
        ros_ads_node
        "rclcpp"
        "std_msgs"
        "ros_ads_msgs"
      )
      
        install(TARGETS ros_ads_node
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib
        RUNTIME DESTINATION lib/${PROJECT_NAME})
      
        install(DIRECTORY
        launch config
        DESTINATION share/${PROJECT_NAME}/)
      
      if(BUILD_TESTING)
        find_package(ament_lint_auto REQUIRED)
        # the following line skips the linter which checks for copyrights
        # comment the line when a copyright and license is added to all source files
        set(ament_cmake_copyright_FOUND TRUE)
        # the following line skips cpplint (only works in a git repo)
        # comment the line when this package is in a git repo and when
        # a copyright and license is added to all source files
        set(ament_cmake_cpplint_FOUND TRUE)
        ament_lint_auto_find_test_dependencies()
      endif()
      
      ament_package()
      

      请各位大佬帮忙看一下,是哪里的问题,是launch标签错了吗?万分感激

      芜湖

      1 条回复 最后回复 回复 引用 0
      • yudonghou123Y yudonghou123 将这个主题转为问答主题,在
      • 第一个帖子
        最后一个帖子
      皖ICP备16016415号-7
      Powered by NodeBB | 鱼香ROS