我是靠谱客的博主 鳗鱼黑猫,最近开发中收集的这篇文章主要介绍ROS学习之源码——init() 第二篇,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

继上篇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:nn" 
                 "export ROS_MASTER_URI=http://localhost:11311nn" 
                 "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;
    }
  }
}

最后

以上就是鳗鱼黑猫为你收集整理的ROS学习之源码——init() 第二篇的全部内容,希望文章能够帮你解决ROS学习之源码——init() 第二篇所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部