roscpp源码阅读

roscpp doxgen

这只是我摘取的一些主要代码

  • node_handle.cpp
//NodeHandle的构造函数
void NodeHandle::construct(const std::string& ns, bool validate_name)
{
    ros::start();
}

  • init.h
#This method enters a loop, processing callbacks.  This method should only be used
# * if the NodeHandle API is being used.

void spin()

CallbackQueuePtr g_global_queue;

//参数的remapping
void init(const M_string& remappings, const std::string& name, uint32_t options)
{
    network::init(remappings);
    master::init(remappings);
    // names:: namespace is initialized by this_node
    this_node::init(name, remappings, options);
    file_log::init(remappings);
    param::init(remappings);
}
  • init.cpp
//开启一系列的线程,注册信号
void ros::start()
{
    PollManager::instance()->addPollThreadListener(checkForShutdown);
    XMLRPCManager::instance()->bind("shutdown", shutdownCallback);

    initInternalTimerManager();

    TopicManager::instance()->start();
    ServiceManager::instance()->start();
    ConnectionManager::instance()->start();
    PollManager::instance()->start();
    XMLRPCManager::instance()->start();

    ROSCPP_LOG_DEBUG("Started node [%s], pid [%d], bound on [%s], xmlrpc port [%d], tcpros port [%d], using [%s] time", 
               this_node::getName().c_str(), getpid(), network::getHost().c_str(), 
               XMLRPCManager::instance()->getServerPort(), ConnectionManager::instance()->getTCPPort(), 
               Time::useSystemTime() ? "real" : "sim");
}

  • node_handle.cpp
//发布topic
Publisher NodeHandle::advertise(AdvertiseOptions& ops)
{
  ops.topic = resolveName(ops.topic);
  if (ops.callback_queue == 0)
  {
    if (callback_queue_)
    {
      ops.callback_queue = callback_queue_;
    }
    else
    {
      ops.callback_queue = getGlobalCallbackQueue();
    }
  }

  SubscriberCallbacksPtr callbacks(boost::make_shared<SubscriberCallbacks>(ops.connect_cb, ops.disconnect_cb, 
                                                                           ops.tracked_object, ops.callback_queue));
//重点
  if (TopicManager::instance()->advertise(ops, callbacks))
  {
    Publisher pub(ops.topic, ops.md5sum, ops.datatype, *this, callbacks);

    {
      boost::mutex::scoped_lock lock(collection_->mutex_);
      collection_->pubs_.push_back(pub.impl_);
    }

    return pub;
  }

  return Publisher();
}

//与server的通信,在server端注册发布topic的node
bool TopicManager::advertise(const AdvertiseOptions& ops, const SubscriberCallbacksPtr& callbacks)
{

  PublicationPtr pub;

  {
    boost::recursive_mutex::scoped_lock lock(advertised_topics_mutex_);

     pub = PublicationPtr(boost::make_shared<Publication>(ops.topic, ops.datatype, ops.md5sum, ops.message_definition, ops.queue_size, ops.latch, ops.has_header));
    pub->addCallbacks(callbacks);
    advertised_topics_.push_back(pub);
  }

  {
    boost::mutex::scoped_lock lock(advertised_topic_names_mutex_);
    advertised_topic_names_.push_back(ops.topic);
  }


  XmlRpcValue args, result, payload;
  args[0] = this_node::getName();
  args[1] = ops.topic;
  args[2] = ops.datatype;
  args[3] = xmlrpc_manager_->getServerURI();
  master::execute("registerPublisher", args, result, payload, true);

  return true;
}


//订阅topic
Subscriber NodeHandle::subscribe(SubscribeOptions& ops)
{
  ops.topic = resolveName(ops.topic);
  if (ops.callback_queue == 0)
  {
    if (callback_queue_)
    {
      ops.callback_queue = callback_queue_;
    }
    else
    {
      ops.callback_queue = getGlobalCallbackQueue();
    }
  }

  if (TopicManager::instance()->subscribe(ops))
  {
    Subscriber sub(ops.topic, *this, ops.helper);

    {
      boost::mutex::scoped_lock lock(collection_->mutex_);
      collection_->subs_.push_back(sub.impl_);
    }

    return sub;
  }

  return Subscriber();
}

//参数的set,get
bool NodeHandle::getParam(const std::string& key, std::map<std::string, std::string>& map) const
{
  return param::get(resolveName(key), map);
}

bool get(const std::string& key, std::map<std::string, std::string>& map)
{
  return getImpl(key, map, false);
}

bool getImpl(const std::string& key, XmlRpc::XmlRpcValue& v, bool use_cache)
{
  std::string mapped_key = ros::names::resolve(key);
  if (mapped_key.empty()) mapped_key = "/";


      // parameter we've never seen before, register for update from the master
      if (g_subscribed_params.insert(mapped_key).second)
      {
        XmlRpc::XmlRpcValue params, result, payload;
        params[0] = this_node::getName();
        params[1] = XMLRPCManager::instance()->getServerURI();
        params[2] = mapped_key;

        if (!master::execute("subscribeParam", params, result, payload, false))
        {
          ROS_DEBUG_NAMED("cached_parameters", "Subscribe to parameter [%s]: call to the master failed", mapped_key.c_str());
          g_subscribed_params.erase(mapped_key);
          use_cache = false;
        }
        else
        {
          ROS_DEBUG_NAMED("cached_parameters", "Subscribed to parameter [%s]", mapped_key.c_str());
        }
      }
}


  XmlRpc::XmlRpcValue params, result;
  params[0] = this_node::getName();
  params[1] = mapped_key;

  // We don't loop here, because validateXmlrpcResponse() returns false
  // both when we can't contact the master and when the master says, "I
  // don't have that param."
  bool ret = master::execute("getParam", params, result, v, false);

  if (use_cache)
  {
    boost::mutex::scoped_lock lock(g_params_mutex);

    ROS_DEBUG_NAMED("cached_parameters", "Caching parameter [%s] with value type [%d]", mapped_key.c_str(), v.getType());
    g_params[mapped_key] = v;
  }

  return ret;
}

The most widely used methods are:

  • Setup:

    • ros::init()
  • Publish / subscribe messaging:

    • advertise()
    • subscribe()
  • RPC services:

    • advertiseService()
    • serviceClient()
    • ros::service::call()
  • Parameters:

    • getParam()
    • setParam()
posted @ 2016-06-10 17:05  逍遥客33  阅读(1858)  评论(0编辑  收藏  举报