ROS学习之源码——init() 第二篇

本文详细解析了ROS(机器人操作系统)中节点初始化的过程,包括网络、主节点、当前节点、文件日志及参数的初始化步骤。重点介绍了各初始化函数如何处理命名空间、节点名等关键配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继上篇ROS学习之源码——init() 第一篇
在ROS的init(argc, argv, node_name)函数中,依次调用了下面五个函数:

1. network::init(remappings)
void init(const M_string& remappings){
    //查找remappings中是否存在 __hostname 参数
    M_string::const_iterator it = remappings.find("__hostname");
    //存在的话把remapping中相应的键值赋值给全局变量g_host
    if (it != remappings.end()){
        g_host = it->second;
      }
    //同理 查找__ip参数
    else{
        it = remappings.find("__ip");
        if (it != remappings.end()){
            g_host = it->second;
        }
     }
    
    //查找 __tcpros_server_port 参数
    it = remappings.find("__tcpros_server_port");
    if (it != remappings.end()){
        try{
            g_tcpros_server_port = boost::lexical_cast<uint16_t>(it->second);
        }
        catch (boost::bad_lexical_cast&){
            throw ros::InvalidPortException("__tcpros_server_port [" + it->second + "] was not specified as a number within the 0-65535 range");
        }
      }
      //如果没找到__hostname参数,那么调用determineHost()函数
      if (g_host.empty()){
          g_host = determineHost();
      }
}
2. master::init(remappings)
void init(const M_string& remappings){
  //查找__master参数
  M_string::const_iterator it = remappings.find("__master");
  //找到:
  if (it != remappings.end()){
    g_uri = it->second;
  }
  //没找到:
  if (g_uri.empty()){
    char *master_uri_env = NULL;
    #ifdef _MSC_VER
      _dupenv_s(&master_uri_env, NULL, "ROS_MASTER_URI");
    #else
      master_uri_env = getenv("ROS_MASTER_URI");
    #endif
    if (!master_uri_env){
      ROS_FATAL( "ROS_MASTER_URI is not defined in the environment. Either " \
                 "type the following or (preferrably) add this to your " \
                 "~/.bashrc file in order set up your " \
                 "local machine as a ROS master:\n\n" \
                 "export ROS_MASTER_URI=http://localhost:11311\n\n" \
                 "then, type 'roscore' in another shell to actually launch " \
                 "the master program.");
      ROS_BREAK();
    }

    g_uri = master_uri_env;

#ifdef _MSC_VER
    free(master_uri_env);
#endif
  }

  // Split URI into
  if (!network::splitURI(g_uri, g_host, g_port)){
    ROS_FATAL( "Couldn't parse the master URI [%s] into a host:port pair.", g_uri.c_str());
    ROS_BREAK();
  }
}
3. this_node::init(name, remappings, options)
void init(const std::string& name, const M_string& remappings, uint32_t options){
  char *ns_env = NULL;
#ifdef _MSC_VER
  _dupenv_s(&ns_env, NULL, "ROS_NAMESPACE");
#else
  ns_env = getenv("ROS_NAMESPACE");
#endif

  if (ns_env){
    g_namespace = ns_env;
#ifdef _MSC_VER
    free(ns_env);
#endif
  }

  g_name = name;

  bool disable_anon = false;
  //当前节点初始化:
  M_string::const_iterator it = remappings.find("__name");
  if (it != remappings.end()){
    g_name = it->second;
    disable_anon = true;
  }
  //查找命名空间参数:__ns
  it = remappings.find("__ns");
  if (it != remappings.end()){
    g_namespace = it->second;
  }
  //如果没找到参数__ns,把命名空间设置为/
  if (g_namespace.empty()){
    g_namespace = "/";
  }

  g_namespace = (g_namespace == "/")
    ? std::string("/") 
    : ("/" + g_namespace)
    ;


  std::string error;
  if (!names::validate(g_namespace, error)){
    std::stringstream ss;
    ss << "Namespace [" << g_namespace << "] is invalid: " << error;
    throw InvalidNameException(ss.str());
  }

  //参见:6.names::init(remappings)
  names::init(remappings);  

  if (g_name.find("/") != std::string::npos){
    throw InvalidNodeNameException(g_name, "node names cannot contain /");
  }
  if (g_name.find("~") != std::string::npos){
    throw InvalidNodeNameException(g_name, "node names cannot contain ~");
  }

  g_name = names::resolve(g_namespace, g_name);

  if (options & init_options::AnonymousName && !disable_anon){
    char buf[200];
    snprintf(buf, sizeof(buf), "_%llu", (unsigned long long)WallTime::now().toNSec());
    g_name += buf;
  }

  ros::console::setFixedFilterToken("node", g_name);
}
4. file_log::init(remappings)
void init(const M_string& remappings){
  std::string log_file_name;
  M_string::const_iterator it = remappings.find("__log");
  if (it != remappings.end()){
    log_file_name = it->second;
  }

  {
    // Log filename can be specified on the command line through __log
    // If it's been set, don't create our own name
    if (log_file_name.empty()){
      // Setup the logfile appender
      // Can't do this in rosconsole because the node name is not known
      pid_t pid = getpid();
      std::string ros_log_env;
      if ( get_environment_variable(ros_log_env, "ROS_LOG_DIR")){
        log_file_name = ros_log_env + std::string("/");
      }
      else{
        if ( get_environment_variable(ros_log_env, "ROS_HOME")){
          log_file_name = ros_log_env + std::string("/log/");
        }
        else{
          // Not cross-platform?
          if( get_environment_variable(ros_log_env, "HOME") ){
            std::string dotros = ros_log_env + std::string("/.ros/");
            fs::create_directory(dotros);
            log_file_name = dotros + "log/";
            fs::create_directory(log_file_name);
          }
        }
      }

      // sanitize the node name and tack it to the filename
      for (size_t i = 1; i < this_node::getName().length(); i++){
        if (!isalnum(this_node::getName()[i])){
          log_file_name += '_';
        }
        else{
          log_file_name += this_node::getName()[i];
        }
      }

      char pid_str[100];
      snprintf(pid_str, sizeof(pid_str), "%d", pid);
      log_file_name += std::string("_") + std::string(pid_str) + std::string(".log");
    }

    log_file_name = fs::system_complete(log_file_name).string();
    g_log_directory = fs::path(log_file_name).parent_path().string();
  }
}
5. param::init(remappings)
void init(const M_string& remappings){
  M_string::const_iterator it = remappings.begin();
  M_string::const_iterator end = remappings.end();
  for (; it != end; ++it){
    const std::string& name = it->first;
    const std::string& param = it->second;

    if (name.size() < 2){
      continue;
    }

    if (name[0] == '_' && name[1] != '_'){
      std::string local_name = "~" + name.substr(1);

      bool success = false;

      try{
        int32_t i = boost::lexical_cast<int32_t>(param);
        ros::param::set(names::resolve(local_name), i);
        success = true;
      }
      catch (boost::bad_lexical_cast&){

      }

      if (success){
        continue;
      }

      try{
        double d = boost::lexical_cast<double>(param);
        ros::param::set(names::resolve(local_name), d);
        success = true;
      }
      catch (boost::bad_lexical_cast&){

      }

      if (success){
        continue;
      }

      if (param == "true" || param == "True" || param == "TRUE"){
        ros::param::set(names::resolve(local_name), true);
      }
      else if (param == "false" || param == "False" || param == "FALSE"){
        ros::param::set(names::resolve(local_name), false);
      }
      else{
        ros::param::set(names::resolve(local_name), param);
      }
    }
  }

6. names::init(remappings)
void init(const M_string& remappings){
  M_string::const_iterator it = remappings.begin();
  M_string::const_iterator end = remappings.end();
  for (; it != end; ++it){
    const std::string& left = it->first;
    const std::string& right = it->second;

    if (!left.empty() && left[0] != '_' && left != this_node::getName()){
      std::string resolved_left = resolve(left, false);
      std::string resolved_right = resolve(right, false);
      g_remappings[resolved_left] = resolved_right;
      g_unresolved_remappings[left] = right;
    }
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值