如何理解ROS的ros::NodeHandle,学习ROS一年后的体会

1, 一个节点(Node)可以有多个节点句柄(NodeHandle)

虽然一般最多看见两个NodeHandle(e.g, nh和pnh),但是一个节点(Node)可以有多个节点句柄(NodeHandle),可以是一个,可以是两个,可以是三个,甚至更多,但是他们都指向同一个节点

2, 节点句柄的名称任意

节点句柄的名称任意,但一般约定俗成为nh(表示一般句柄)和pnhprivate_nh(表示私有句柄),nh是node handle的缩写。

ros::NodeHandle nh;//ok
ros::NodeHandle pnh;//ok
ros::NodeHandle publisher_nh;//ok
ros::NodeHandle subscriber_nh;//ok

3, 节点句柄初始化主要的写法可以分为三类

ros::NodeHandle nh;//普通句柄,通常用于topic和service的调用
ros::NodeHandle nh("~");//私有句柄,通常用于参数的调用
ros::NodeHandle nh("some_namespace");//可以这么用,但通常不用

因为话题和服务通常是多个节点共用的,所以一般用普通的初始化方式,这样A节点定义的话题,能够被B节点看到。
而私有节点句柄通常将节点名称(用~表示)作为一个子命名空间(私有可以理解为:make it private to this node),这样便于管理参数,因为参数通常和节点是配套使用的,使用私有节点句柄可以避免名称冲突。比如,控制器A有PID参数(P,I,D),控制器B也有PID参数(P,I,D),那么如果仅查找P I D,那么就会有两个结果,造成混乱,而如果查找B:I,那么我就知道是B控制器的I参数。

假设节点名称为node_name,节点所处的命名空间为node_namespace

ros::init(argc, argv, "node_name");//所在的命名空间为node_namespace
ros::NodeHandle nh_1;
ros::NodeHandle nh_2("~");
ros::NodeHandle nh_3("some_namespace");
nh_1.param("param_name", param_name_variable, kDefaultParamName);
//将参数服务器中有“param_name”名字的参数读取进来,
//赋值给param_name_variable变量
//如果这个参数不存在,那么将默认值kDefaultParamName赋值给param_name_variable变量
nh_2.param("param_name", param_name_variable, kDefaultParamName);
nh_3.param("param_name", param_name_variable, kDefaultParamName);
节点句柄初始化方式ROS真正寻找(resolve)的参数
ros::NodeHandle nh_1;/node_namespace/param_name
ros::NodeHandle nh_2("~");/node_namespace/node_name/param_name
ros::NodeHandle nh_3("some_namespace");/node_namespace/some_namespace/param_name

4, 在类中声明节点句柄

我现在遇到的节点,通常都是以类的形式编写,然后在主函数中实例化,
类似于:

class DemoNode{
private:
  ros::NodeHandle nh_;
  
  ros::Publisher pub_;
  ros::Subscriber sub_;
  ros::Rate rate_;
}

DemoNode::DemoNode() :rate_(kDefaultHilFrequency) {
  ros::NodeHandle pnh("~");

  bool sensor_level_hil;
  std::string actuators_pub_topic;
  std::string hil_controls_sub_topic;
  pnh.param("actuators_pub_topic", actuators_pub_topic, std::string(mav_msgs::default_topics::COMMAND_ACTUATORS));
  pnh.param("hil_controls_sub_topic", hil_controls_sub_topic, kDefaultHilControlsSubTopic);
  pub_ = nh_.advertise<mav_msgs::Actuators>(actuators_pub_topic, 1);
  sub_ = nh_.subscribe(hil_controls_sub_topic, 1,&HilInterfaceNode::HilControlsCallback, this);
}

int main(int argc, char** argv) {
  ros::init(argc, argv, "this_is_a_node");
  DemoNode demo_node;
  ros::spin();
  return 0;
}

可以看到,节点句柄作为类的数据成员,私有节点句柄用来读取参数,普通节点句柄用来调用订阅和发布函数(access topic)。

参考

Accessing Private Names from a NodeHandle
Node Handles, Parameters, and Topics

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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系统进行更高级的交互和通信。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值