• ROS MarkerArray的几种常见用法


    ros使用过程中,经常会用到rviz可视化各种数据。而在rviz中,marker与markerarray是常用的一种可视化工具,最近也用到过几次了,这里随手记录一下。

    1、makerarray画线

    在marker中常见的就是表示两点之间的连线,而marker或者markerarray可以很好的可视化线条属性,简单示例如下:

    void marker_visualization::Add_Lines_Mark()
    {
        Clear_Lines_Marker();
        //point_line_pub.publish(MarkerArray);
        int len = 10;
        int count = 0;
        for(int i=0;i<len;i++)
        {
            point_lines.ns = "line_mark";    //命名空间namespace  
            //point_lines.type = visualization_msgs::Marker::ARROW;                                                                         
    	    point_lines.type = visualization_msgs::Marker::LINE_LIST;     //类型
            point_lines.pose.orientation.x=0.0;
    	    point_lines.pose.orientation.y=0.0;
    	    point_lines.pose.orientation.z=0.0;
    	    point_lines.pose.orientation.w=1.0;
            //lines.action = visualization_msgs::Marker::ADD;
    	    point_lines.scale.x = 0.1;
    	    //设置线的颜色,a应该是透明度
    	    point_lines.color.r = 1.0;
    	    point_lines.color.g = 0.0;
    	    point_lines.color.b = 0.0;
    	    point_lines.color.a = 1.0;
    	    //这个是指定marker在被自动清除前可以逗留多长时间。这里 ros::Duration()表示不自动删除。如果在lifetime结束之前有新内容到达了,它就会被重置。
            point_lines.lifetime = ros::Duration();
            //线的初始点
            point_lines.id = count;  //与命名空间联合起来,形成唯一的id,这个唯一的id可以将各个标志物区分开来,使得程序可以对指定的标志物进行操作
            geometry_msgs::Point p_start;
            p_start.x = 2*i;
            p_start.y = 2*i;
            p_start.z = 0.0;	
            //将直线存储到marker容器
    	    point_lines.points.push_back(p_start);
            geometry_msgs::Point p_end;
            p_end.x = 2*i+1;
            p_end.y = 2*i+1;
            p_end.z = 0.0;
            point_lines.points.push_back(p_end);
                
            point_lines.header.frame_id = "map";
            point_lines.header.stamp = ros::Time::now();
            MarkerArray.markers.push_back(point_lines);
            point_lines.points.clear();
            count++;
            
        }
        lines_array_pub.publish(MarkerArray);
        point_lines.points.clear();
        MarkerArray.markers.clear();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    在rviz中显示如下:
    在这里插入图片描述

    2、makerarray画箭头

    箭头的表示跟直线差不多,基础代码如下:

    void marker_visualization::Add_Arrow_Mark()
    {
        Clear_Arrow_Marker();
        int len = 10;
        int count = 0;
        tf2::Quaternion Quaternion;
        for(int i=0;i<len;i++)
        {
            lines_arrow.ns = "point_arrow";    //命名空间namespace                                                                          
    	    lines_arrow.type = visualization_msgs::Marker::ARROW;     //类型
    	    lines_arrow.scale.x = 0.5;//箭头长度
            lines_arrow.scale.y = 0.1;
            lines_arrow.scale.z = 0.1;
    	    //设置线的颜色,a是透明度
    	    lines_arrow.color.r = 0.0;
    	    lines_arrow.color.g = 1.0;
    	    lines_arrow.color.b = 0.0;
    	    lines_arrow.color.a = 1.0;
    	    //这个是指定marker在被自动清除前可以逗留多长时间。这里 ros::Duration()表示不自动删除。如果在lifetime结束之前有新内容到达了,它就会被重置。
            lines_arrow.lifetime = ros::Duration();
            //线的初始点
            for(int j=0;j<10;j++)
            {
                lines_arrow.id = count;  //与命名空间联合起来,形成唯一的id,这个唯一的id可以将各个标志物区分开来,使得程序可以对指定的标志物进行操作
                geometry_msgs::Point p_start;
                lines_arrow.pose.position.x = 2*i;
                lines_arrow.pose.position.y = 2*i;
                lines_arrow.pose.position.z = 0;
                p_start.x = 2*i;
                p_start.y = 2*i;
                p_start.z = 0;
                //将直线存储到marker容器
                geometry_msgs::Point p_end;
                
                p_end.x = 2*i+1;
                p_end.y = 2*i+1;
                p_end.z = 0;
                double yaw = atan2((p_end.y-p_start.y), (p_end.x-p_start.x));
                Quaternion.setRPY( 0, 0, yaw );
                lines_arrow.pose.orientation.x = Quaternion.x();
                lines_arrow.pose.orientation.y = Quaternion.y();
                lines_arrow.pose.orientation.z = Quaternion.z();
                lines_arrow.pose.orientation.w = Quaternion.w();
                
                lines_arrow.header.frame_id = "map";
                lines_arrow.header.stamp = ros::Time::now();
                ArrowArray.markers.push_back(lines_arrow);
                count++;
            }
        }
        arrow_array_pub.publish(ArrowArray);
        ArrowArray.markers.clear();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    在这里插入图片描述

    3、makerarray写字

    marker是可以在rviz中的特定位置显示文本的,但是需要注意的是它似乎显示不了汉字:

    void marker_visualization::Add_Txt_Mark()
    {
        Clear_Txt_Marker();
        int len = 10;
        int count = 0;
        tf2::Quaternion Quaternion;
        for(int i=0;i<len;i++)
        {
            txt_mark.header.frame_id="map";
            txt_mark.header.stamp = ros::Time::now();
            txt_mark.ns = "txt_mark";
            //txt_mark.action = visualization_msgs::Marker::ADD;
            txt_mark.pose.orientation.w = 1.0;
            txt_mark.id = count;
            txt_mark.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
    
            txt_mark.scale.z = 0.4;
            txt_mark.color.b = 255;
            txt_mark.color.g = 255;
            txt_mark.color.r = 255;
            txt_mark.color.a = 1;
            geometry_msgs::Pose pose;
            pose.position.x = 2*i+0.2;
            pose.position.y = 2*i+0.2;
            pose.position.z = 0;
            string text = "test";
            txt_mark.text=text;
            txt_mark.pose=pose;
            txt_mark.lifetime = ros::Duration();
            TxtArray.markers.push_back(txt_mark);
            count++;
        }
        txt_array_pub.publish(TxtArray);
        TxtArray.markers.clear();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    显示结果如下:
    在这里插入图片描述

    4、makerarray画圆

    某些时候需要在rviz中表示一些坐标位置的时候,使用一个立体的点是一种很好的方式:

    void marker_visualization::Add_Sphere_Mark()
    {
        Clear_Sphere_Marker();
        int len = 10;
        int count = 0;
        for(int i=0;i<len;i++)
        {
            sphere_mark.header.frame_id = "map";
            sphere_mark.header.stamp = ros::Time::now();
            sphere_mark.ns = "sphere_mark";
            sphere_mark.id = count; 
            sphere_mark.type = visualization_msgs::Marker::SPHERE; 
            sphere_mark.action = visualization_msgs::Marker::ADD;
            sphere_mark.pose.position.x = 2*i;
            sphere_mark.pose.position.y = 2*i;
            sphere_mark.pose.position.z = 2*i;
            sphere_mark.pose.orientation.x = 0.0;
            sphere_mark.pose.orientation.y = 0.0;
            sphere_mark.pose.orientation.z = 0.0;
            sphere_mark.pose.orientation.w = 1.0;
            sphere_mark.scale.x = 0.2;
            sphere_mark.scale.y = 0.2;
            sphere_mark.scale.z = 0.2; 
            sphere_mark.color.r = 1.0;
            sphere_mark.color.g = 1.0;
            sphere_mark.color.b = 0.0;
            sphere_mark.color.a = 1.0;
            count++;        
            SphereArray.markers.push_back(sphere_mark);
        }
        sphere_array_pub.publish(SphereArray);
        SphereArray.markers.clear();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    结果如下:
    在这里插入图片描述

    5、makerarray消除

    在添加了Marker之后,设置marker的 duration_time不起作用,表现形式是:marker一直显示,不会消失;使用delete指令也不能将已经显示在rviz内部的marker删除;所以我们需要用另外一种方式消除marker,简单的来说就是发布一组新的marker覆盖掉当前的marker,我们将其值设置为透明或者长度设置为一个非常小的值之类的都可以实现这个效果,拿第一个画线的例子来说:

    void marker_visualization::Clear_Lines_Marker()
    {
        visualization_msgs::Marker clear_mark;
        for(int i =0;i<10;i++)
        {
            clear_mark.ns = "line_mark";
            clear_mark.id = i; 
            clear_mark.pose.orientation.x=0.0;
    	    clear_mark.pose.orientation.y=0.0;
    	    clear_mark.pose.orientation.z=0.0;
    	    clear_mark.pose.orientation.w=1.0;
            //lines.action = visualization_msgs::Marker::ADD;
    	    clear_mark.scale.x = 0.1;
            clear_mark.scale.y = 0.1;
            clear_mark.scale.z = 0.1;
    	    //设置线的颜色,a应该是透明度
    	    clear_mark.color.r = 1.0;
    	    clear_mark.color.g = 0.0;
    	    clear_mark.color.b = 0.0;
    	    clear_mark.color.a = 1.0;
            geometry_msgs::Point p_start;
            p_start.x = 0.0;
            p_start.y = 0.0;
            p_start.z = 0.0;
            clear_mark.points.push_back(p_start);
            geometry_msgs::Point p_end;
            p_end.x = 0.1;
            p_end.y = 0.0;
            p_end.z = 0.0;
            clear_mark.points.push_back(p_end);
    	    //这个是指定marker在被自动清除前可以逗留多长时间。这里 ros::Duration()表示不自动删除。如果在lifetime结束之前有新内容到达了,它就会被重置。
            clear_mark.lifetime = ros::Duration();
            clear_mark.header.frame_id = "map";
            clear_mark.header.stamp = ros::Time::now();
            MarkerArray.markers.push_back(clear_mark);
            clear_mark.points.clear();
        }
        lines_array_pub.publish(MarkerArray);
        MarkerArray.markers.clear();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    以上是markerarray的一些简单用法,后期有更多用法继续更新。

    如果需要复现的话详细的代码放在:

    https://download.csdn.net/download/YiYeZhiNian/87135596
    
    • 1
  • 相关阅读:
    Springboot 一个注解搞定返回参数key转换 【实用】
    桌面扫码点餐系统(小程序+Java后台)
    数据结构——红黑树
    linux服务端c++开发工具介绍(vscode版)
    K线形态识别_穿头破脚
    C#批量视频处理工具
    SpringMvc决战-【SpringMVC之自定义注解】
    京东资深架构师推荐学习6本实战文档:Redis+Nginx+MySQL+JVM....
    京准电钟 NTP时间同步服务器助力水库水坝水利自动化建设
    SpringCloud微服务(十)——Hystrix服务降级熔断限流
  • 原文地址:https://blog.csdn.net/YiYeZhiNian/article/details/127992204