当前位置: 首页 > article >正文

ROS2中的图形化显示---visualization_msgs

一、核心消息类型解析

1.1 基础标记类型 (Marker)
# Marker.msg 关键字段
uint32 type          # 形状类型枚举
string ns            # 命名空间(用于分组)
int32 id             # 唯一标识符
float32 scale        # 缩放系数
std_msgs/ColorRGBA color
geometry_msgs/Pose pose

类型枚举对照表

#define ARROW 0
#define CUBE 1
#define SPHERE 2
#define CYLINDER 3
#define LINE_STRIP 4  // 折线
#define TEXT_VIEW_FACING 9
#define MESH_RESOURCE 10  // 3D模型
1.2 标记数组 (MarkerArray)
# MarkerArray.msg
visualization_msgs/Marker[] markers

二、高级应用模式

2.1 动态标记生命周期控制
// 创建临时标记(5秒后自动消失)
marker.lifetime = rclcpp::Duration(5, 0); 

// 删除标记
marker.action = visualization_msgs::msg::Marker::DELETE;

// 删除整个命名空间
marker.action = visualization_msgs::msg::Marker::DELETEALL;
2.2 交互式标记
// 添加菜单交互
marker.menu_entries.resize(1);
marker.menu_entries[0].title = "Reset";
marker.menu_entries[0].command = "reset_system";

三、RViz2集成示例

3.1 发布三角形标记
auto marker = visualization_msgs::msg::Marker();
marker.header.frame_id = "map";
marker.type = visualization_msgs::msg::Marker::TRIANGLE_LIST;

// 定义三个顶点
geometry_msgs::msg::Point p1, p2, p3;
p1.x = 0.0; p1.y = 0.0;
p2.x = 1.0; p2.y = 0.0;
p3.x = 0.5; p3.y = 1.0;

marker.points.push_back(p1);
marker.points.push_back(p2);
marker.points.push_back(p3);

// 设置颜色
marker.color.r = 1.0; 
marker.color.a = 0.8;

// 发布到/markers话题
marker_pub_->publish(marker);
3.2 创建运动轨迹
// 初始化LINE_STRIP类型标记
marker.type = visualization_msgs::msg::Marker::LINE_STRIP;
marker.scale.x = 0.1;  // 线宽

// 添加路径点
for(auto& pose : trajectory) {
    geometry_msgs::msg::Point p;
    p.x = pose.position.x;
    p.y = pose.position.y;
    marker.points.push_back(p);
}

// 渐变色处理
for(int i=0; i<marker.points.size(); ++i) {
    std_msgs::msg::ColorRGBA color;
    color.r = 1.0 - (float)i/marker.points.size();
    color.g = (float)i/marker.points.size();
    color.a = 1.0;
    marker.colors.push_back(color);
}

四、性能优化策略

  1. 批处理机制
// 单次发布多个标记
visualization_msgs::msg::MarkerArray marker_array;
for(int i=0; i<100; i++) {
    marker_array.markers.push_back(createMarker(i));
}
pub_->publish(marker_array);
  1. 静态标记优化
// 对固定不变的标记设置持续存在
marker.lifetime = rclcpp::Duration(0,0);  // 永久显示
  1. LOD控制
// 根据距离调整细节层次
marker.scale.x = calculateLODScale(distance);

五、调试与可视化工具

5.1 RViz2配置技巧
  1. 创建新显示类型:Marker / MarkerArray
  2. 设置坐标系到<Fixed Frame>
  3. 通过Namespace Filter筛选特定标记
5.2 命令行诊断
# 查看标记数据
ros2 topic echo /visualization_marker

# 带宽监控
ros2 topic bw /visualization_marker_array

六、安全注意事项

  1. 坐标系一致性:确保所有frame_id在TF树中存在
  2. ID冲突预防:使用UUID生成唯一标识符
  3. 内存管理:定期清理不再使用的标记
// 安全ID生成示例
#include <uuid_msgs/msg/unique_id.hpp>
uuid_msgs::msg::UniqueID generateUUID() {
    uuid_msgs::msg::UniqueID id;
    // 实现UUID生成逻辑
    return id;
}

七、高级应用场景

  1. SLAM地图可视化
  2. 机器人运动规划演示
  3. 传感器数据覆盖显示
  4. 仿真环境物体标注

最新版本支持Web可视化(通过Foxglove Studio等工具),可通过rosbridge_suite实现浏览器端渲染。


四、ROS2中的典型应用场景

  1. 处理消息数组
// 遍历激光雷达数据点
for(auto& point : laser_scan_msg->ranges) {
    processPoint(point);
}
  1. 操作TF变换
// 遍历tf2缓冲中的坐标变换
for(auto& transform : tf_buffer._frameIDs) {
    checkTransform(transform);
}

五、三种变体写法对比

写法特点适用场景
auto&引用方式,避免拷贝修改容器元素
const auto&常量引用,只读访问查看元素不修改
auto值拷贝方式POD简单类型

示例:

// 修改轨迹点
for(auto& pose : trajectory) {
    pose.position.x += 1.0; // 修改原数据
}

// 只读访问
for(const auto& pose : trajectory) {
    RCLCPP_INFO(logger, "X: %.2f", pose.position.x);
}

六、特殊容器注意事项

  1. std::map遍历
for(auto& [key, value] : my_map) { // C++17结构化绑定
    processPair(key, value);
}
  1. Eigen矩阵遍历
// 需转换为内存连续存储
Eigen::MatrixXd matrix;
for(auto& element : matrix.reshaped()) {
    element *= 2.0;
}

七、调试技巧

当出现begin/end相关编译错误时,检查:

  1. 容器是否实现begin()/end()方法
  2. 是否包含正确的头文件
  3. C++标准是否设置为11或更高

错误示例处理:

// 错误:指针不能直接迭代
std::vector<geometry_msgs::msg::Pose>* ptr = &trajectory;
for(auto& pose : ptr) {} 

// 正确解引用:
for(auto& pose : *ptr) { ✔️ }


http://www.kler.cn/a/564237.html

相关文章:

  • UML各种图
  • P9420 [蓝桥杯 2023 国 B] 子 2023
  • unity学习59: 滑动条 和 滚动条 滚动区域
  • SpringBoot备份神通数据库
  • Is Noise Conditioning Necessary for Denoising Generative Models?论文阅读笔记
  • IoT 测试:智能互联时代的质量保障
  • 【Elasticsearch】(Java 版)
  • Spring如何解决循环依赖?
  • 家用可燃气体探测器——家庭燃气安全的坚实防线
  • 文件跨国传输如何防丢包?重传机制解析
  • 自然语言处理(NLP):文本向量化从文字到数字的原理
  • Spring MVC视图解析器的定制与应用
  • java项目之基于ssm的线上旅游体验系统(源码+文档)
  • 论文阅读笔记:Deep Face Recognition: A Survey
  • vscode+vue前端开发环境配置
  • 几个api
  • 包子凑数——蓝桥杯真题Python
  • 如何利用爬虫技术测试淘宝商品详情接口
  • 修改CentOS 8 yum源
  • 2025年02月27日Github流行趋势