ROS学习之源码——NodeHandle

先来看看NodeHandle类的主要成员函数:
发布话题,返回一个Publisher,负责广播topic
Publisher advertise (const std::string &topic, uint32_t queue_size, bool latch=false)
订阅一个话题,收到话题中的消息后触发回调函数
Subscriber subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
类似于发布话题,还可以发布服务
ServiceServer advertiseService (const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
客户端通过调用服务节点完成某项任务
ServiceClient       serviceClient (const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
创建定时器,按一定周期执行指定的函数
Timer createTimer (Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
从参数服务中获得某个参数
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();
}
  • 13
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ros::NodeHandleROS中的一个重要类,用于与ROS系统进行通信和交互。它提供了一系列方法和功能,用于创建和管理ROS节点、发布和订阅ROS话题、调用和提供ROS服务等。 以下是ros::NodeHandle的一些常见用法和功能: 1. 创建NodeHandle对象: ```cpp #include <ros/ros.h> int main(int argc, char** argv) { // 初始化ROS节点 ros::init(argc, argv, "my_node"); // 创建NodeHandle对象 ros::NodeHandle nh; // 其他操作... return 0; } ``` 2. 发布和订阅ROS话题: ```cpp #include <ros/ros.h> #include <std_msgs/String.h> int main(int argc, char** argv) { ros::init(argc, argv, "my_node"); ros::NodeHandle nh; // 创建发布者 ros::Publisher pub = nh.advertise<std_msgs::String>("my_topic", 10); // 创建订阅者 ros::Subscriber sub = nh.subscribe("my_topic", 10, callback); // 其他操作... ros::spin(); return 0; } void callback(const std_msgs::String::ConstPtr& msg) { // 处理接收到的消息 } ``` 3. 调用和提供ROS服务: ```cpp #include <ros/ros.h> #include <std_srvs/Empty.h> bool my_service(std_srvs::Empty::Request& req, std_srvs::Empty::Response& res) { // 处理服务请求 return true; } int main(int argc, char** argv) { ros::init(argc, argv, "my_node"); ros::NodeHandle nh; // 创建服务服务器 ros::ServiceServer server = nh.advertiseService("my_service", my_service); // 创建服务客户端 ros::ServiceClient client = nh.serviceClient<std_srvs::Empty>("my_service"); // 其他操作... return 0;} ``` 4. 获取ROS参数: ```cpp #include <ros/ros.h> int main(int argc, char** argv) { ros::init(argc, argv, "my_node"); ros::NodeHandle nh; // 获取参数 int my_param; nh.getParam("my_param", my_param); // 设置参数 nh.setParam("my_param", 123); // 其他操作... return 0; } ``` 这些只是ros::NodeHandle的一部分功能,它还提供了许多其他方法和功能,用于与ROS系统进行更高级的交互和通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值