interactive_markers 源码详细分析

interactive_markers 源码详细分析

工作区路径:/home/cp/work2/ros2Learn/ros2_humble/src/ros-visualization/interactive_markers
版本:2.3.3,许可证 BSD

interactive_markers3D 可交互标记 的通信库:Server 端(应用/规划器)发布 InteractiveMarker,Client 端(RViz2)渲染并回传用户操作(拖拽、菜单点击)。提供 C++ 与 Python 双实现。


1. 仓库结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
interactive_markers/
├── include/interactive_markers/
│ ├── interactive_marker_server.hpp # Server API
│ ├── interactive_marker_client.hpp # Client API
│ ├── menu_handler.hpp # 右键菜单
│ ├── message_context.hpp # 序列号/上下文
│ ├── tools.hpp # 辅助工具
│ └── exceptions.hpp
├── src/
│ ├── interactive_marker_server.cpp
│ ├── interactive_marker_client.cpp
│ ├── menu_handler.cpp
│ ├── message_context.cpp
│ └── tools.cpp
├── interactive_markers/ # Python 包
│ ├── interactive_marker_server.py
│ └── menu_handler.py
└── test/

2. 通信协议

用户InteractiveMarkerClient (RViz)InteractiveMarkerServer用户InteractiveMarkerClient (RViz)InteractiveMarkerServerGetInteractiveMarkers (service)初始 marker 列表/update (InteractiveMarkerUpdate)拖拽/点击/feedback (InteractiveMarkerFeedback)FeedbackCallback/update (增量)
接口 话题/服务 消息类型
初始同步 {ns}/get_interactive_markers GetInteractiveMarkers srv
增量更新 {ns}/update InteractiveMarkerUpdate
用户反馈 {ns}/feedback InteractiveMarkerFeedback

topic_namespace 由构造参数指定,通常为节点私有 namespace。


3. InteractiveMarkerServer

3.1 核心 API

1
2
3
4
5
6
7
8
9
class InteractiveMarkerServer {
void insert(const InteractiveMarker & marker);
void insert(const InteractiveMarker & marker, FeedbackCallback cb);
bool erase(const std::string & name);
void clear();
bool setPose(...);
bool setCallback(...);
void applyChanges(); // 批量提交,此前修改不发布
};

关键设计insert/erase/setPose 仅写入 pending 队列,必须调用 applyChanges() 才会发布 UPDATE 消息。

3.2 构造与 ROS 接口

1
2
3
get_interactive_markers_service_ = create_service(..., topic_namespace + "/get_interactive_markers");
update_pub_ = create_publisher(..., topic_namespace + "/update");
feedback_sub_ = create_subscription(..., topic_namespace + "/feedback", processFeedback);

使用 node interfaces 注入(NodeBaseInterface 等),支持 composable node;也提供 NodePtr 模板便捷构造。

3.3 applyChanges 流程

遍历 pending_updates_,对每条记录执行 INSERT/UPDATE/ERASE/POSE_UPDATE,组装 InteractiveMarkerUpdate 并 publish。

3.4 Feedback 处理

processFeedback 校验 marker 存在、序列号、回调注册,调用用户 FeedbackCallback,必要时更新 marker pose 并再次 applyChanges()


4. InteractiveMarkerClient

4.1 职责

1
2
3
/// Handles topic subscription, error detection and tf transformations.
/// After connecting, sends GetInteractiveMarkers for initial state.
/// On error (update loss, tf failure), connection is reset.

4.2 状态机

State 含义
STATE_IDLE 未连接
STATE_INITIALIZE 等待 service 响应
STATE_RUNNING 正常接收 update

4.3 connect 流程

1
2
3
get_interactive_markers_client_ = create_client(..., topic_namespace + "/get_interactive_markers");
feedback_pub_ = create_publisher(..., topic_namespace + "/feedback");
update_sub_ = create_subscription(..., topic_namespace + "/update", ...);

支持 TF:带时间戳的 marker 变换到 target_frame(依赖 tf2::BufferCoreInterface)。

4.4 回调类型

  • UpdateCallback — 收到 update
  • InitializeCallback — 初始 service 完成
  • ResetCallback — 连接重置
  • StatusCallback — 调试/错误信息

5. MenuHandler

MenuHandler 管理 marker 附加的 菜单项(CHECK、RADIO、FEEDBACK 等),与 Server 的 marker 描述合并后一并发布。用户点击菜单项时通过 InteractiveMarkerFeedbackMENU_SELECT 事件回传。


6. MessageContext

维护 update 消息的 sequence_number,Client 用于检测丢包并触发 reset。


7. Python 实现

interactive_markers/interactive_marker_server.py 镜像 C++ Server API,供纯 Python 节点(如简单 demo)使用。生产环境 RViz/MoveIt 多使用 C++ Server。


8. 依赖

1
2
3
4
5
interactive_markers
├── rclcpp / rclpy
├── visualization_msgs (InteractiveMarker, Update, Feedback, GetInteractiveMarkers)
├── tf2 / tf2_geometry_msgs
└── builtin_interfaces

9. 下游

消费者 角色
rviz2 InteractiveMarkerClient + 渲染
MoveIt 规划场景交互 marker
Nav2 初始 pose / goal pose 工具
自定义节点 Server 发布 marker

10. 测试

  • test_interactive_marker_server.cpp — Server insert/apply/feedback
  • test_interactive_marker_client.cpp — Client 连接与 update 队列(MAX_UPDATE_QUEUE_SIZE = 100

11. 设计特点与局限

特点 说明
批量 applyChanges 减少 update 消息风暴
序列号同步 检测丢包并重连
Node interface 注入 适配 component 与测试
C++/Python 双 API 灵活集成
局限 说明
忘记 applyChanges 常见使用错误
TF 依赖 带 stamp 的 marker 需可用变换
QoS 需匹配 update/feedback 与 RViz 配置需一致

12. 推荐阅读顺序

  1. interactive_marker_server.hpp — Server API 与 applyChanges 语义
  2. interactive_marker_server.cppapplyChanges / processFeedback
  3. interactive_marker_client.hpp + .cpp — Client 状态机
  4. menu_handler.hpp — 菜单扩展
  5. RViz2 interactive_marker_display(在 ros2/rviz 仓库)

13. 小结

interactive_markers 定义了 RViz 3D 交互的 标准 Server/Client 协议:service 全量同步 + topic 增量更新 + feedback 回传。应用侧用 Server 管理 marker 生命周期,RViz 用 Client 显示并捕获用户输入。

文章互动

阅读 --

留言

0 条留言

正在加载留言…