先来看看NodeHandle类的主要成员函数:
发布话题,返回一个Publisher,负责广播topic
订阅一个话题,收到话题中的消息后触发回调函数
类似于发布话题,还可以发布服务
客户端通过调用服务节点完成某项任务
创建定时器,按一定周期执行指定的函数
从参数服务中获得某个参数
bool | getParam (const std::string &key, std::string &s) const |
对应的就是设置参数
void | setParam (const std::string &key, const char *s) const |
ROS编程时的代码
NodeHandle n;
Publisher pub = n.advertise<std_msgs::String>("topic_m",1000);
类NodeHandle的构造函数:
//默认构造函数
NodeHandle(const std::string& ns = std::string(), const M_string& remappings = M_string());
//拷贝构造函数
NodeHandle(const NodeHandle& rhs);
//根据父句柄构造当前句柄,并指定命名空间
NodeHandle(const NodeHandle& parent, const std::string& ns);
NodeHandle(const NodeHandle& parent, const std::string& ns, const M_string& remappings);
其中第一个是默认构造函数,NodeHandle n 语句也会调用第一个构造函数,该构造函数的代码实现如下:
NodeHandle::NodeHandle(const std::string& ns, const M_string& remappings)
: namespace_(this_node::getNamespace())
, callback_queue_(0)
, collection_(0){
std::string tilde_resolved_ns;
//去除命名空间中的波浪号
if (!ns.empty() && ns[0] == '~')
tilde_resolved_ns = names::resolve(ns);
else
tilde_resolved_ns = ns;
//四个构造函数都是通过调用construct()函数实现的
construct(tilde_resolved_ns, true);
initRemappings(remappings);
}
在n.advertise<std_msgs::String>("topic_m", 1000)中使用了句柄NodeHandle的advertise函数,接下来看一下advertise函数是怎么定义的。
//一个简单的广播话题的函数, 至少传入两个参数,topic:话题名字,必须独一无二,不能重复, queue_size:发送到subscriber的消息缓存数量
template <class M>
Publisher advertise(const std::string& topic, uint32_t queue_size, bool latch = false){
//话题广播时的配置选项
AdvertiseOptions ops;
//n.advertise<std_msgs::String>("topic_m",1000)语句运行时<M>为: <std_msgs::String>
//真心看不懂下面一句的语法, 貌似在调用对象ops的成员函数init(),估计类似于opt.init<M>(topic, queue_size);
ops.template init<M>(topic, queue_size);
ops.latch = latch;
return advertise(ops);//又调用了下面的advertise()函数
}
//一个配置选项较为全面的广播话题的函数
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();
}
//智能指针callback指向SubscriberCallBacks对象,不知道干嘛用的
SubscriberCallbacksPtr callbacks(new SubscriberCallbacks(ops.connect_cb, ops.disconnect_cb,
ps.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;
}
//最终返回的Publisher对象只能广播<std_msgs::String>类型的话题
return Publisher();
}