【ROS】RVIZ 标记区域绘制

前言

最近,在复现一篇激光雷达检测障碍物的文献,在将雷达数据进行聚类后,需要观察聚类的效果,这个时候需要用Rviz标记,绘制标记框,把学习过程记录一下,方便后续查阅.

1.visualization_msgs/Marker

//各种标志物类型的定义,每一个的具体介绍和形状可以到这里查看:http://wiki.ros.org/rviz/DisplayTypes/Marker
uint8 ARROW=0//箭头
uint8 CUBE=1//立方体
uint8 SPHERE=2//球
uint8 CYLINDER=3//圆柱体
uint8 LINE_STRIP=4//线条(点的连线)
uint8 LINE_LIST=5//线条序列
uint8 CUBE_LIST=6//立方体序列
uint8 SPHERE_LIST=7//球序列
uint8 POINTS=8//点集
uint8 TEXT_VIEW_FACING=9//显示3D的文字
uint8 MESH_RESOURCE=10//网格?
uint8 TRIANGLE_LIST=11//三角形序列
//对标记的操作
uint8 ADD=0
uint8 MODIFY=0
uint8 DELETE=2
uint8 DELETEALL=3

Header header
string ns   //命名空间namespace,就是你理解的那样
int32 id    //与命名空间联合起来,形成唯一的id,这个唯一的id可以将各个标志物区分开来,使得程序可以对指定的标志物进行操作
int32 type  //类型
int32 action    //操作,是添加还是修改还是删除
geometry_msgs/Pose pose       # Pose of the object
geometry_msgs/Vector3 scale   # Scale of the object 1,1,1 means default (usually 1 meter square)
std_msgs/ColorRGBA color      # Color [0.0-1.0]
duration lifetime             # How long the object should last before being automatically deleted.  0 means forever
bool frame_locked             # If this marker should be frame-locked, i.e. retransformed into its frame every timestep

#Only used if the type specified has some use for them (eg. POINTS, LINE_STRIP, ...)
geometry_msgs/Point[] points//这个是在序列、点集中才会用到,指明序列中每个点的位置
#Only used if the type specified has some use for them (eg. POINTS, LINE_STRIP, ...)
#number of colors must either be 0 or equal to the number of points
#NOTE: alpha is not yet used
std_msgs/ColorRGBA[] colors

# NOTE: only used for text markers
string text

# NOTE: only used for MESH_RESOURCE markers
string mesh_resource
bool mesh_use_embedded_materials

ROS之rviz显示历史运动轨迹、路径的各种方法(visualization_msgs/Marker、nav_msgs/Path- 白夜行的狼

2.实践

看了几个代码工程把它直接复制到雷达检测中显示OK,但没有标记区域,看了这篇文章才发现是Fixed Frame的问题,原来需要手动把map,改写成my_frame. 所以在复制到自己工程时在代码中直接将my_frame改成自己相应的坐标参考即可,我将其改为odom.
rviz学习系列—Markers:发送基本形状(c++)
在这里插入图片描述

#include "ros/ros.h"
#include <iostream>
#include <fstream>
#include <sensor_msgs/LaserScan.h>
#include <visualization_msgs/Marker.h>
#define pi  3.1415926535898
#define resolution  2*pi/360
void laserCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
{
    std::vector<float> ranges=msg->ranges;
    std::vector<float> angel(ranges.size());
    int i = 0;
    for(i = 0; i < 360; i++){
        if(i <180){
            angel[i]= -pi + i*resolution;
        }
        else{
            angel[i] = (i-180)*resolution;
        }
    }
    float r = 0.1;
    int temp_n=0;
    int flag=0;
    std::vector<std::vector<int> > temp;
    std::vector<int> temp_cluster;
    for(i = 0;  i < 359; i++){
        if( pow( ranges[i+1] * cos(angel[i+1]) - ranges[i] * cos(angel[i]) , 2 ) + pow( ranges[i+1] * sin(angel[i+1]) - ranges[i] * sin(angel[i]), 2 ) <= pow(r,2) ) {
            if(flag == 0){
                flag = 1;
            }
            temp_cluster.push_back(i);
        }
        else{
            if(flag == 1){
                temp.push_back(temp_cluster);
                temp_cluster.clear();
                temp_n++;
            }
            flag = 0;
        }
    }
    std::cout<<"\n"<<temp.size()<<"\n";
    for(i=0;i<temp.size();i++){

        for(int j=0;j<temp[i].size();j++){
            std::cout<<temp[i][j]<<" ";
        }
        std::cout<<"\n";
    }
}

int main(int argc, char **argv)
{

    ros::init(argc, argv, "perception");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("/scan", 100, laserCallback);
    ros::Rate r(1);
    ros::Publisher marker_pub = nh.advertise<visualization_msgs::Marker>("visualization_marker",1);
    uint32_t shape = visualization_msgs::Marker::CUBE;
    while (ros::ok())
    {
        visualization_msgs::Marker marker;
        // Set the frame ID and timestamp.  See the TF tutorials for information on these.
        marker.header.frame_id = "/odom";
        marker.header.stamp = ros::Time::now();

        // Set the namespace and id for this marker.  This serves to create a unique ID
        // Any marker sent with the same namespace and id will overwrite the old one
        marker.ns = "basic_shapes";
        marker.id = 0;

        // Set the marker type.  Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
        marker.type = shape;

        // Set the marker action.  Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
        marker.action = visualization_msgs::Marker::ADD;

        // Set the pose of the marker.  This is a full 6DOF pose relative to the frame/time specified in the header
        marker.pose.position.x = 0;
        marker.pose.position.y = 0;
        marker.pose.position.z = 0;
        marker.pose.orientation.x = 0.0;
        marker.pose.orientation.y = 0.0;
        marker.pose.orientation.z = 0.0;
        marker.pose.orientation.w = 1.0;

        // Set the scale of the marker -- 1x1x1 here means 1m on a side
        marker.scale.x = 1.0;
        marker.scale.y = 1.0;
        marker.scale.z = 1.0;

        // Set the color -- be sure to set alpha to something non-zero!
        marker.color.r = 0.0f;
        marker.color.g = 1.0f;
        marker.color.b = 0.0f;
        marker.color.a = 1.0;

        marker.lifetime = ros::Duration();

        // Publish the marker
        while (marker_pub.getNumSubscribers() < 1)
        {
            if (!ros::ok())
            {
                return 0;
            }
            ROS_WARN_ONCE("Please create a subscriber to the marker");
            sleep(1);
        }
        marker_pub.publish(marker);

        // Cycle between different shapes
        switch (shape)
        {
            case visualization_msgs::Marker::CUBE:
                shape = visualization_msgs::Marker::SPHERE;
                break;
            case visualization_msgs::Marker::SPHERE:
                shape = visualization_msgs::Marker::ARROW;
                break;
            case visualization_msgs::Marker::ARROW:
                shape = visualization_msgs::Marker::CYLINDER;
                break;
            case visualization_msgs::Marker::CYLINDER:
                shape = visualization_msgs::Marker::CUBE;
                break;
        }

        r.sleep();
    }
    ros::spin();
    return 0;
}

3.将聚类信息添加RVIZ标记区域

#include "ros/ros.h"
#include <iostream>
#include <fstream>
#include <sensor_msgs/LaserScan.h>
#include <visualization_msgs/Marker.h>
#define pi  3.1415926535898
#define resolution  2*pi/360
void laserCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
{
    std::vector<float> ranges=msg->ranges;
    std::vector<float> angel(ranges.size());
    int i = 0;
    for(i = 0; i < 360; i++){
        if(i <180){
            angel[i]= -pi + i*resolution;
        }
        else{
            angel[i] = (i-180)*resolution;
        }
    }
    float r = 0.1;
    int temp_n=0;
    int flag=0;
    std::vector<std::vector<int> > temp;
    std::vector<int> temp_cluster;
    for(i = 0;  i < 359; i++){
        if( pow( ranges[i+1] * cos(angel[i+1]) - ranges[i] * cos(angel[i]) , 2 ) + pow( ranges[i+1] * sin(angel[i+1]) - ranges[i] * sin(angel[i]), 2 ) <= pow(r,2) ) {
            if(flag == 0){
                flag = 1;
            }
            temp_cluster.push_back(i);
        }
        else{
            if(flag == 1){
                temp.push_back(temp_cluster);
                temp_cluster.clear();
                temp_n++;
            }
            flag = 0;
        }
    }
    std::cout<<"\n"<<temp.size()<<"\n";
    for(i=0;i<temp.size();i++){

        for(int j=0;j<temp[i].size();j++){
            std::cout<<temp[i][j]<<" ";
        }
        std::cout<<"\n";
    }
}

int main(int argc, char **argv)
{

    ros::init(argc, argv, "perception");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("/scan", 100, laserCallback);
    ros::Rate r(1);
    ros::Publisher marker_pub = nh.advertise<visualization_msgs::Marker>("visualization_marker",1);
    uint32_t shape = visualization_msgs::Marker::LINE_STRIP;
    while (ros::ok())
    {
        visualization_msgs::Marker marker;
        visualization_msgs::Marker marker2;
        // Set the frame ID and timestamp.  See the TF tutorials for information on these.
        marker.header.frame_id = "/odom";
        marker.header.stamp = ros::Time::now();
        marker2.header.frame_id = "/odom";
        marker2.header.stamp = ros::Time::now();

        // Set the namespace and id for this marker.  This serves to create a unique ID
        // Any marker sent with the same namespace and id will overwrite the old one
        marker.ns = "basic_shapes";
        marker.id = 0;
        marker2.ns = "basic_shapes";
        marker2.id = 1;
        // Set the marker type.  Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
        marker.type = shape;
        marker2.type = shape;
        // Set the marker action.  Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
        marker.action = visualization_msgs::Marker::ADD;
        marker2.action = visualization_msgs::Marker::ADD;
        // Set the pose of the marker.  This is a full 6DOF pose relative to the frame/time specified in the header
        marker.pose.position.x = 0;
        marker.pose.position.y = 0;
        marker.pose.position.z = 0;
        marker.pose.orientation.x = 0.0;
        marker.pose.orientation.y = 0.0;
        marker.pose.orientation.z = 0.0;
        marker.pose.orientation.w = 1.0;

        marker2.pose.position.x = -1;
        marker2.pose.position.y = -1;
        marker2.pose.position.z = 0;
        marker2.pose.orientation.x = 0.0;
        marker2.pose.orientation.y = 0.0;
        marker2.pose.orientation.z = 0.0;
        marker2.pose.orientation.w = 1.0;
        // Set the scale of the marker -- 1x1x1 here means 1m on a side
        marker.scale.x = 0.01;
        marker.scale.y = 0.01;
        marker.scale.z = 0.0;

        marker2.scale.x = 0.01;
        marker2.scale.y = 0.01;
        marker2.scale.z = 0.0;
        // Set the color -- be sure to set alpha to something non-zero!
        marker.color.r = 0.0f;
        marker.color.g = 1.0f;
        marker.color.b = 0.0f;
        marker.color.a = 1.0;

        marker2.color.r = 0.0f;
        marker2.color.g = 0.0f;
        marker2.color.b = 1.0f;
        marker2.color.a = 1.0;
        marker2.lifetime = ros::Duration();
        geometry_msgs:: Point p[5];
        p[0].x = 0; p[0].y = 0;
        p[1].x = 1; p[1].y = 0;
        p[2].x = 1; p[2].y = 1;
        p[3].x = 0; p[3].y = 1;
        p[4].x = 0; p[4].y = 0;
        for (int i = 0; i < 5; i++){
            marker.points.push_back(p[i]);
            marker2.points.push_back(p[i]);
        }
        marker_pub.publish(marker);
        marker_pub.publish(marker2);
        r.sleep();
    }
    ros::spin();
    return 0;
}

在这里插入图片描述
在这里插入图片描述出来两个框了,差不多了,下一步就是对每一个簇中的点求一个矩形框,然后发布出来,未完待续…

4.最小外接矩形

最小外接矩形有点难搞哎!先安排一下矩形吧.

#include "ros/ros.h"
#include <iostream>
#include <fstream>
#include <sensor_msgs/LaserScan.h>
#include <visualization_msgs/Marker.h>
#define pi  3.1415926535898
#define resolution  2*pi/360
ros::Publisher marker_pub;
void laserCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
{
    //______________________对雷达数据粗略聚类___________________________
    std::vector<float> ranges=msg->ranges;
    std::vector<float> angel(ranges.size());
    int i = 0;
    for(i = 0; i < 360; i++){
        if(i <180){
            angel[i]= -pi + i*resolution;
        }
        else{
            angel[i] = (i-180)*resolution;
        }
    }
    std::vector<std::vector<int> > temp;
    std::vector<int> temp_cluster;
    float r = 0.1;
    int temp_n=0;
    int flag=0;
    for(i = 0;  i < 359; i++){
        if( pow( ranges[i+1] * cos(angel[i+1]) - ranges[i] * cos(angel[i]) , 2 ) + pow( ranges[i+1] * sin(angel[i+1]) - ranges[i] * sin(angel[i]), 2 ) <= pow(r,2) ) {
            if(flag == 0){
                flag = 1;
            }
            temp_cluster.push_back(i);
        }
        else{
            if(flag == 1){
                temp.push_back(temp_cluster);
                temp_cluster.clear();
                temp_n++;
            }
            flag = 0;
        }
    }
    //_________________________输出聚类结果_________________________________
    std::cout<<"___________________________"<<temp.size()<<"_____________________________"<<"\n";

    for(i=0;i<temp.size();i++){
        for(int j=0;j<temp[i].size();j++){
            std::cout<<temp[i][j]<<" ";
        }
        std::cout<<"\n";
    }
    //__________________________画矩形框____________________________________
    std::vector<std::vector<float> > square_all;
    std::vector<float> square;
    float x_max = 0;
    float x_min = 0;
    float y_max = 0;
    float y_min = 0;
    int nn=0;
    for(i=0;i<temp.size();i++){
        if(temp[i].size()<=1){
            continue;
        }
        else{
            for(int j=0;j<temp[i].size();j++){
                if(j==0){
                    x_max = ranges[temp[i][j]]*cos(angel[temp[i][j]]);
                    x_min = ranges[temp[i][j]]*cos(angel[temp[i][j]]);
                    y_max = ranges[temp[i][j]]*sin(angel[temp[i][j]]);
                    y_min = ranges[temp[i][j]]*sin(angel[temp[i][j]]);
                }
                if(ranges[temp[i][j]]*cos(angel[temp[i][j]])>x_max){
                    x_max = ranges[temp[i][j]]*cos(angel[temp[i][j]]);
                }
                else if(ranges[temp[i][j]]*cos(angel[temp[i][j]])<x_min){
                    x_min = ranges[temp[i][j]]*cos(angel[temp[i][j]]);
                }

                if(ranges[temp[i][j]]*sin(angel[temp[i][j]])>y_max){
                    y_max = ranges[temp[i][j]]*sin(angel[temp[i][j]]);
                }
                else if(ranges[temp[i][j]]*sin(angel[temp[i][j]])<y_min){
                    y_min =  ranges[temp[i][j]]*sin(angel[temp[i][j]]);
                }
            }
            square.push_back(x_max);
            square.push_back(x_min);
            square.push_back(y_max);
            square.push_back(y_min);
            square_all.push_back(square);
            square.clear();
        }
    }
    //_________________________输出矩形框结果_________________________________
    std::cout<<"*************************"<<square_all.size()<<"*****************************"<<"\n";

    for(i=0;i<square_all.size();i++){
        for(int j=0;j<square_all[i].size();j++){
            std::cout<<square_all[i][j]<<" ";
        }
        std::cout<<"\n";
    }
    //__________________________RVIZ显示___________________________________
        uint32_t shape = visualization_msgs::Marker::LINE_STRIP;

        visualization_msgs::Marker marker;
        visualization_msgs::Marker marker2;
        // Set the frame ID and timestamp.  See the TF tutorials for information on these.
        marker.header.frame_id = "/laser_link";
        marker.header.stamp = ros::Time::now();


        // Set the namespace and id for this marker.  This serves to create a unique ID
        // Any marker sent with the same namespace and id will overwrite the old one
        marker.ns = "basic_shapes";
        marker.id = 0;

        // Set the marker type.  Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
        marker.type = shape;

        // Set the marker action.  Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
        marker.action = visualization_msgs::Marker::ADD;

        // Set the pose of the marker.  This is a full 6DOF pose relative to the frame/time specified in the header
        marker.pose.position.x = square_all[0][1];
        marker.pose.position.y = square_all[0][3];
        marker.pose.position.z = 0;
        marker.pose.orientation.x = 0.0;
        marker.pose.orientation.y = 0.0;
        marker.pose.orientation.z = 0.0;
        marker.pose.orientation.w = 0.0;


        // Set the scale of the marker -- 1x1x1 here means 1m on a side
        marker.scale.x = 0.01;
        marker.scale.y = 0.01;
        marker.scale.z = 0.0;


        // Set the color -- be sure to set alpha to something non-zero!
        marker.color.r = 0.0f;
        marker.color.g = 1.0f;
        marker.color.b = 0.0f;
        marker.color.a = 1.0;


        geometry_msgs:: Point p[5];
        p[0].x = 0; p[0].y = 0;
        p[1].x = square_all[0][0]-square_all[0][1]; p[1].y = 0;
        p[2].x = square_all[0][0]-square_all[0][1]; p[2].y = square_all[0][2]-square_all[0][3];
        p[3].x = 0; p[3].y = square_all[0][2]-square_all[0][3];
        p[4].x = 0; p[4].y = 0;
        for (int i = 0; i < 5; i++){
            marker.points.push_back(p[i]);
        }
        marker_pub.publish(marker);
}

int main(int argc, char **argv)
{

    ros::init(argc, argv, "perception");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("/scan", 100, laserCallback);
    marker_pub = nh.advertise<visualization_msgs::Marker>("visualization_marker",1);

    ros::spin();
    return 0;
}

效果:链接

接下来把剩余其它几个类,加入标记,然后优化,

  1. 二维雷达数据聚类算法
  2. 加入最小外接矩形框
  3. 感觉C++算法还是很注重效率的,可以学习C++的内存管理和指针释放,减少代码运行内存,以及考虑算法的时间复杂度,减少代码运行的时间.
    未完待续…

V2版本

#include "ros/ros.h"
#include <iostream>
#include <fstream>
#include <sensor_msgs/LaserScan.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/MarkerArray.h>
#define pi  3.1415926535898
#define resolution  2*pi/360
ros::Publisher marker_pub;
void laserCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
{
    //______________________对雷达数据粗略聚类___________________________
    std::vector<float> ranges=msg->ranges;
    std::vector<float> angel(ranges.size());
    int i = 0;
    for(i = 0; i < 360; i++){
        if(i <180){
            angel[i]= -pi + i*resolution;
        }
        else{
            angel[i] = (i-180)*resolution;
        }
    }
    std::vector<std::vector<int> > temp;
    std::vector<int> temp_cluster;
    float r = 0.1;
    int temp_n=0;
    int flag=0;
    for(i = 0;  i < 359; i++){
        if( pow( ranges[i+1] * cos(angel[i+1]) - ranges[i] * cos(angel[i]) , 2 ) + pow( ranges[i+1] * sin(angel[i+1]) - ranges[i] * sin(angel[i]), 2 ) <= pow(r,2) ) {
            if(flag == 0){
                flag = 1;
            }
            temp_cluster.push_back(i);
        }
        else{
            if(flag == 1){
                temp.push_back(temp_cluster);
                temp_cluster.clear();
                temp_n++;
            }
            flag = 0;
        }
    }
    //_________________________输出聚类结果_________________________________
    std::cout<<"___________________________"<<temp.size()<<"_____________________________"<<"\n";

    for(i=0;i<temp.size();i++){
        for(int j=0;j<temp[i].size();j++){
            std::cout<<temp[i][j]<<" ";
        }
        std::cout<<"\n";
    }
    //__________________________画矩形框____________________________________
    std::vector<std::vector<float> > square_all;
    std::vector<float> square;
    float x_max = 0;
    float x_min = 0;
    float y_max = 0;
    float y_min = 0;
    int nn=0;
    for(i=0;i<temp.size();i++){
        if(temp[i].size()<=1){
            continue;
        }
        else{
            for(int j=0;j<temp[i].size();j++){
                if(j==0){
                    x_max = ranges[temp[i][j]]*cos(angel[temp[i][j]]);
                    x_min = ranges[temp[i][j]]*cos(angel[temp[i][j]]);
                    y_max = ranges[temp[i][j]]*sin(angel[temp[i][j]]);
                    y_min = ranges[temp[i][j]]*sin(angel[temp[i][j]]);
                }
                if(ranges[temp[i][j]]*cos(angel[temp[i][j]])>x_max){
                    x_max = ranges[temp[i][j]]*cos(angel[temp[i][j]]);
                }
                else if(ranges[temp[i][j]]*cos(angel[temp[i][j]])<x_min){
                    x_min = ranges[temp[i][j]]*cos(angel[temp[i][j]]);
                }

                if(ranges[temp[i][j]]*sin(angel[temp[i][j]])>y_max){
                    y_max = ranges[temp[i][j]]*sin(angel[temp[i][j]]);
                }
                else if(ranges[temp[i][j]]*sin(angel[temp[i][j]])<y_min){
                    y_min =  ranges[temp[i][j]]*sin(angel[temp[i][j]]);
                }
            }
            square.push_back(x_max);
            square.push_back(x_min);
            square.push_back(y_max);
            square.push_back(y_min);
            square_all.push_back(square);
            square.clear();
        }
    }
    //_________________________输出矩形框结果_________________________________
    std::cout<<"*************************"<<square_all.size()<<"*****************************"<<"\n";

    for(i=0;i<square_all.size();i++){
        for(int j=0;j<square_all[i].size();j++){
            std::cout<<square_all[i][j]<<" ";
        }
        std::cout<<"\n";
    }
    //__________________________RVIZ显示___________________________________
        uint32_t shape = visualization_msgs::Marker::CUBE_LIST;

        visualization_msgs::MarkerArray marker1;
        visualization_msgs::Marker marker;
        // Set the frame ID and timestamp.  See the TF tutorials for information on these.
        marker.header.frame_id = "/laser_link";
        marker.header.stamp = ros::Time::now();


        // Set the namespace and id for this marker.  This serves to create a unique ID
        // Any marker sent with the same namespace and id will overwrite the old one
        marker.ns = "basic_shapes";
        marker.id = 0;

        // Set the marker type.  Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
        marker.type = shape;

        // Set the marker action.  Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
        marker.action = visualization_msgs::Marker::ADD;

        // Set the pose of the marker.  This is a full 6DOF pose relative to the frame/time specified in the header
        marker.pose.position.x = square_all[0][1];
        marker.pose.position.y = square_all[0][3];
        marker.pose.position.z = 0;
        marker.pose.orientation.x = 0.0;
        marker.pose.orientation.y = 0.0;
        marker.pose.orientation.z = 0.0;
        marker.pose.orientation.w = 1.0;


        // Set the scale of the marker -- 1x1x1 here means 1m on a side
        marker.scale.x = 0.05;
        marker.scale.y = 0.05;
        marker.scale.z = 0.05;


        // Set the color -- be sure to set alpha to something non-zero!
        marker.color.r = 0.0f;
        marker.color.g = 1.0f;
        marker.color.b = 0.0f;
        marker.color.a = 1.0;

        for(i=0; i<square_all.size(); i++){
            geometry_msgs::Point p[8];
            p[0].x = 0; p[0].y = 0; p[0].z = 0.0;
            p[1].x = square_all[i][0]-square_all[i][1]; p[1].y = 0; p[1].z = 0.0;
            p[2].x = square_all[i][0]-square_all[i][1]; p[2].y = square_all[i][2]-square_all[i][3]; p[2].z = 0.0;
            p[3].x = 0; p[3].y = square_all[i][2]-square_all[i][3]; p[3].z = 0.0;
            p[4].x = 0; p[4].y = 0; p[4].z = 0.01;
            p[5].x = square_all[i][0]-square_all[i][1]; p[5].y = 0; p[5].z = 0.01;
            p[6].x = square_all[i][0]-square_all[i][1]; p[6].y = square_all[i][2]-square_all[i][3]; p[6].z = 0.01;
            p[7].x = 0; p[7].y = square_all[i][2]-square_all[i][3]; p[7].z = 0.01;
            marker.points.clear();
            for (int j = 0; j < 8; j++){
                marker.points.push_back(p[j]);
            }
            marker.id = i;
            marker.pose.position.x = square_all[i][1];
            marker.pose.position.y = square_all[i][3];
            marker.pose.position.z = 0;
            marker1.markers.push_back(marker);
            marker.points.clear();
        }
    marker_pub.publish(marker1);
}

int main(int argc, char **argv)
{

    ros::init(argc, argv, "perception");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("/scan", 100, laserCallback);
    marker_pub = nh.advertise<visualization_msgs::MarkerArray>("visualization_marker",1);

    ros::spin();
    return 0;
}

效果链接

啊,居然这么多立方体,咋变成一个啊…

V3

视频效果链接
可以了,得到想要的效果了.

RVIZ 雷达数据聚类

Tips

消除拖影:V3版本一些拖影,效果不理想,于是发现Marker自带生命周期属性lifetime,看函数名字就知道大致含义.

 marker.lifetime = ros::Duration(0.5);
  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
### 回答1: `visualization_msgs::Marker` 是 ROS (机器人操作系统) 中的一个消息类型,用于在 RViz (ROS 可视化工具) 中显示可视化元素,如点、线、箭头、文本、立方体等。 `visualization_msgs::Marker` 消息包含了显示元素的各种属性,例如颜色、大小、形状、位置、方向等。通过发布 `visualization_msgs::Marker` 消息到 ROS 中的 `/visualization_marker` 主题,可以在 RViz 中显示出对应的可视化元素。 `visualization_msgs::Marker` 消息类型在 ROS 中被广泛使用,特别是在机器人领域中,例如用于显示机器人的位置、姿态、运动轨迹、障碍物等信息。`visualization_msgs::Marker` 是 ROS (机器人操作系统) 中的一个消息类型,用于在 RViz (ROS 可视化工具) 中显示可视化元素,如点、线、箭头、文本、立方体等。 `visualization_msgs::Marker` 消息包含了显示元素的各种属性,例如颜色、大小、形状、位置、方向等。通过发布 `visualization_msgs::Marker` 消息到 ROS 中的 `/visualization_marker` 主题,可以在 RViz 中显示出对应的可视化元素。 在机器人领域中,`visualization_msgs::Marker` 消息类型被广泛使用,例如用于显示机器人的位置、姿态、运动轨迹、障碍物等信息。通过使用 `visualization_msgs::Marker` 消息类型,开发人员可以方便地在 RViz 中实时显示机器人状态和环境信息,从而更好地理解机器人的行为和运动轨迹。是的,您的理解是正确的。`visualization_msgs::Marker` 是 ROS 中的一个消息类型,用于在 RViz 中显示可视化元素。它可以用于表示机器人的位置、姿态、运动轨迹、障碍物等信息,并且通过发布 `visualization_msgs::Marker` 消息到 ROS 中的 `/visualization_marker` 主题,可以在 RViz 中实时显示出对应的可视化元素。这个消息类型在机器人领域中被广泛使用,因为它可以方便地实现机器人状态和环境信息的实时可视化。是的,您的理解是正确的。`visualization_msgs::Marker` 是 ROS 中的一个消息类型,用于在 RViz 中显示可视化元素。它可以用于表示机器人的位置、姿态、运动轨迹、障碍物等信息,并且通过发布 `visualization_msgs::Marker` 消息到 ROS 中的 `/visualization_marker` 主题,可以在 RViz 中实时显示出对应的可视化元素。这个消息类型在机器人领域中被广泛使用,因为它可以方便地实现机器人状态和环境信息的实时可视化。是的,您的理解是正确的。`visualization_msgs::Marker` 是 ROS 中的一个消息类型,用于在 RViz 中显示可视化元素。它可以用于表示机器人的位置、姿态、运动轨迹、障碍物等信息,并且通过发布 `visualization_msgs::Marker` 消息到 ROS 中的 `/visualization_marker` 主题,可以在 RViz 中实时显示出对应的可视化元素。这个消息类型在机器人领域中被广泛使用,因为它可以方便地实现机器人状态和环境信息的实时可视化。`visualization_msgs::Marker`是一个ROS消息类型,用于在3D空间中可视化对象。它可以用于可视化各种类型的物体,如箭头、方框、球体、线段等等。此外,它还可以用于描述文字标签和网格等。`visualization_msgs::Marker`可以用于在ROS系统中可视化机器人的状态、传感器数据等。它是ROS中常用的可视化工具之一,可以帮助开发人员更好地理解机器人系统的行为和状态。`visualization_msgs::Marker` 是一个 ROS 消息类型,用于在可视化工具(如 RViz)中显示可视化元素,如点、线、箭头、文本和三维模型等。可以使用该消息类型来发布可视化信息,以便在可视化工具中显示。`visualization_msgs::Marker` 包含多个字段,例如颜色、大小、形状、位置和方向等,可以通过设置这些字段来控制显示的外观和行为。 我可以为您解释visualization_msgs::marker,它是ROS(机器人操作系统)中一种可视化消息。它是一种被用于在3D空间中可视化2D和3D图形的ROS消息。它们可以用作指示物,标记点,线,圆,球,箭头,框等等。visualization_msgs::Marker是ROS(机器人操作系统)中的一个消息类型,用于在3D环境中可视化渲染出各种形状、颜色、尺寸等可视化元素。Marker消息可以用于表示机器人的传感器数据、路径规划、障碍物、地图等内容,并通过ROS系统发布给其他节点进行可视化展示和处理。Marker可以包含多种类型的可视化元素,如点、线、箭头、立方体、球体等,可以通过设置颜色、透明度、尺寸等属性来定制化显示效果。在ROS机器人系统中,Marker被广泛应用于机器人仿真、导航、运动规划等领域,是一个非常重要的可视化工具。visualization_msgs::Marker是ROS中的一种消息类型,用于在3D场景中显示可视化元素,例如点、线、箭头、球体、立方体等。Marker可以用于ROS的可视化工具,例如RViz,将机器人的状态、传感器数据等可视化出来。通过指定Marker的类型、大小、颜色、姿态等属性,可以方便地呈现复杂的机器人行为和环境信息。visualization_msgs::Marker 是一个 ROS 消息类型,用于在 RViz 中可视化 3D 物体。它可以用于显示点、线、箭头、网格、球体、立方体等基本几何体,也可以用于显示文本、图像和颜色。Marker 由一个 header 和一组描述其属性和内容的字段组成,可以通过 ROS 发布者订阅者模型来发布和接收。在 RViz 中,可以选择 Marker 的类型、颜色、大小和位置等属性,以便更好地呈现 3D 场景。`visualization_msgs::marker` 是ROS中用于可视化的消息类型之一。可以用它来发布三维模型、箭头、线段、文本等可视化内容,用于在RViz等工具中显示。该消息类型包含了许多字段,如颜色、尺寸、姿态等,可以自定义以达到不同的展示效果。visualization_msgs::Marker是ROS中的一个消息类型,用于在可视化工具中显示3D模型或其他形状。它包含了用于定义形状、颜色、位置和方向等属性的字段。它可以用于在rviz中显示机器人的运动轨迹、传感器数据、障碍物等等。Marker消息类型支持多种不同的形状,包括箭头、立方体、球体、圆柱体等等,可以通过设置Marker的type字段进行选择。通过发布Marker消息到ROS话题,可以让可视化工具实时显示机器人的状态和环境信息,方便调试和可视化分析。 我可以为您解释visualization_msgs::marker,它是ROS机器人操作系统(ROS)中使用的一种消息格式,用来在3D世界中标记点、线、形状等。它可以用来在3D空间中渲染和可视化数据。visualization_msgs::Marker是ROS中的一种消息类型,用于描述可视化元素,例如点、线、箭头和文本等。它通常用于将机器人的状态或环境的特征显示出来,以便用户更直观地理解机器人的运动和周围环境的变化。Marker消息可以通过ROS话题传递,以便其他节点接收并进行可视化。通过使用Marker消息,开发人员可以快速方便地在ROS系统中实现可视化功能。visualization_msgs::Marker是ROS中的一种消息类型,用于描述3D场景中的图形对象。这些图形对象可以是基本形状(如立方体、球体、圆柱体等),也可以是复杂的网格模型。此外,Marker还可以用不同的颜色、尺寸、透明度和坐标系来渲染,以便于可视化和交互。在ROS中,Marker通常用于将机器人的状态、传感器数据、任务进度等信息以图形化的方式呈现出来,方便用户进行监控和调试。visualization_msgs::Marker 是 ROS 中一个消息类型,用于在可视化工具中显示各种类型的可视化元素。Marker 可以用于表示三维物体的形状、大小、颜色、方向等信息,比如箭头、盒子、球体、文字等。Marker 可以在 RViz 等可视化工具中显示,也可以在自定义的可视化应用程序中使用。visualization_msgs::marker是ROS中的消息类型之一,用于描述3D可视化中的标记(marker)。Marker可以是几何体、文本、箭头等各种形状,还可以设置颜色、透明度、坐标等属性。Marker可以被用于在ROS中可视化机器人的状态、障碍物、路径等信息,方便用户理解和调试机器人的行为。在ROS中,可以使用rviz等工具来展示Marker。`visualization_msgs::Marker` 是 ROS 中一个消息类型,用于在三维空间中可视化对象。它可以用于表示点、线、箭头、立方体、球体、文字等基本几何形状,也可以使用自定义模型文件来表示更复杂的形状。`visualization_msgs::Marker` 消息包含了对象的位置、方向、大小、颜色、透明度等信息,可以用于在 RVizROS 可视化工具中显示三维对象。visualization_msgs::Marker 是 ROS 中一个用于可视化的消息类型。它允许用户定义并发布可视化的基本形状、箭头、文字、网格等,以及设置它们的位置、姿态、颜色、大小等属性。Marker 可以用于显示机器人、传感器数据、目标点、障碍物等,方便用户进行可视化调试和展示。在 RViz 等可视化工具中,可以通过订阅 Marker 消息来显示对应的可视化对象。`visualization_msgs::marker`是ROS中一个用于可视化的消息类型。它被广泛用于可视化机器人、传感器、地图和其他ROS系统的状态和行为。这个消息类型描述了一个形状(如立方体、球体、箭头等)和其在三维空间中的位置、姿态、大小、颜色等属性。使用`visualization_msgs::marker`,可以将这些形状发布到ROS中的各种可视化工具,如RViz、Gazebo等,以便用户更直观地了解系统的状态和行为。visualization_msgs::Marker 是一个 ROS(机器人操作系统)中的消息类型,用于可视化标记的发送和接收。这些标记可以是 3D 几何体、箭头、文字和其他形状,可以用于显示机器人、障碍物、路径等。Marker 消息包含了标记的 ID、类型、位置、方向、大小、颜色等属性,可以用于描述和显示各种物体和信息。在 ROS 中,Marker 消息被广泛用于机器人感知、规划和控制中的可视化任务。visualization_msgs::Marker是ROS(机器人操作系统)中的一种消息类型,用于在三维空间中显示可视化标记(visualization markers)。 该消息类型包含了一些属性,如标记的类型、位置、方向、大小、颜色、透明度等等,可以用于在RViz等可视化工具中显示各种类型的可视化标记,比如箭头、立方体、球体、文字等等。 使用该消息类型可以方便地在ROS系统中实现各种可视化效果,从而方便地进行机器人的状态监控、运动规划、路径跟踪等任务。`visualization_msgs::marker` 是一个ROS(机器人操作系统)中的消息类型,用于在3D空间中可视化物体、线条、文本等。`visualization_msgs::marker` 可以用于在ROS系统中的可视化工具(如RViz)中显示机器人、传感器、障碍物、路径等信息。 `visualization_msgs::marker` 消息类型包含了各种可视化元素的信息,例如:可视化元素的类型(如立方体、球体、箭头等)、颜色、位置、大小、方向等。使用该消息类型可以让ROS系统中的节点(如机器人控制节点、感知节点等)与可视化工具进行交互,以便实时地显示机器人和环境的状态。 我可以为您解释visualization_msgs::marker,它是ROS中的一种特殊消息类型,用于在ROS可视化系统中发布和接收2D/3D标记。它可以用于显示独立的点、线、面和其他形状,以及更复杂的形状,如圆柱体和球体。visualization_msgs::Marker是ROS(机器人操作系统)中用于可视化的消息类型之一。Markers可以用来在三维空间中表示点、线、箭头、立方体、球体、文字等。Markers广泛应用于ROS机器人系统的调试、可视化和交互中。可以通过发布Marker消息到ROS系统中的RViz(一种3D可视化工具)中,实现机器人状态的实时展示和调试。visualization_msgs::marker 是 ROS (机器人操作系统) 中的一种消息类型,用于在可视化工具中显示三维物体的位置、方向、大小和形状等信息。它通常与ROS中的其它功能一起使用,如运动规划、目标追踪和机器人操作等,以便对机器人的状态进行实时可视化。这个消息类型包含了许多参数,包括标记类型、颜色、透明度、缩放比例、持续时间和坐标系等,可以根据需要进行设置和修改。`visualization_msgs::Marker` 是 ROS(机器人操作系统)中的一种消息类型,用于在可视化工具(如RViz)中呈现可视化元素(如点、线、箭头、文本等)。 使用 `visualization_msgs::Marker`,您可以指定元素的类型、位置、方向、颜色、大小、透明度等属性,并将其发布到 ROS 中的特定话题上。RViz 可以从该话题中订阅元素,并在其虚拟场景中呈现它们。 在 ROS 中,`visualization_msgs::Marker` 是一种常见的消息类型,可用于可视化机器人的状态、感知数据和行为等。`visualization_msgs::Marker`是ROS(机器人操作系统)中的一种消息类型,用于在RVizROS可视化工具)中可视化3D对象,如点、线、箭头、球体、立方体、文本等。 `visualization_msgs::Marker`还可以指定颜色、尺寸、透明度和持续时间等属性,以便更好地控制可视化效果。它是一种常用的消息类型,用于在ROS机器人中进行可视化和调试。`visualization_msgs::marker`是ROS中的一种消息类型,用于在可视化工具(如RViz)中显示可视化标记(visualization markers),如箭头、方块、圆柱等形状。通过在ROS节点之间发布和订阅`visualization_msgs::marker`消息,可以实现在RViz中显示各种形状的3D标记,这对于机器人的调试和可视化非常有用。`visualization_msgs::marker`消息包含许多字段,如标记的ID、类型、姿态、颜色和尺寸等。开发者可以根据自己的需要设置这些字段,以创建不同类型和形状的标记。visualization_msgs::Marker 是 ROS(机器人操作系统)中的一个消息类型,用于描述可视化元素,例如箭头、立方体、圆柱体等。 该消息类型包含了各种属性,例如位置、方向、颜色、比例、形状等,可以用于在三维空间中可视化不同类型的对象。例如,可以使用 visualization_msgs::Marker 来表示机器人的位置、方向和关节状态,也可以用它来表示环境中的障碍物或路径。 在 ROS 中,可视化是非常重要的,因为它可以帮助机器人系统操作者理解机器人的状态和行为,以及在调试和测试机器人时提供有用的信息。因此,使用 visualization_msgs::Marker 是 ROS 中可视化工具箱中的一个关键组件。visualization_msgs::Marker是ROS中一个用于可视化的消息类型。它可以用于将3D对象渲染为RViz中的可视化元素,如箭头、立方体、球体、线条、网格等等。Marker消息包含有关如何呈现对象的信息,例如颜色、大小、形状、位置、方向和持续时间等。Marker消息可以通过ROS话题在节点之间传递,并且在RViz中可以轻松地订阅和查看。visualization_msgs::Marker 是 ROS(机器人操作系统)中的一种消息类型,用于在 RVizROS 的可视化工具)中显示三维图形。Marker 可以表示点、线、箭头、立方体、球体、文字等等,可以用于可视化机器人或其他物体的运动、传感器数据、地图信息等等。Marker 包含了图形的位置、姿态、尺寸、颜色等属性,并且可以在 RViz 中进行交互操作。`visualization_msgs::Marker` 是 ROS(机器人操作系统)中的一种消息类型,用于在 3D 空间中可视化显示形状、文本、箭头等对象。它通常被用于可视化机器人、传感器、地图等数据。Marker 消息可以被发布到 ROS 中的可视化工具,如 RViz,以便用户可以在 3D 空间中观察和交互这些对象。 Marker 消息包括了很多属性,如类型(点、线、立方体、球体等)、颜色、位置、方向、大小等,这些属性可以通过设置 Marker 消息的字段来进行定义和控制。例如,可以设置 Marker 的类型为球体,并指定其半径、位置和颜色,以在 RViz 中显示一个红色的球体。 在 ROS 中,可以使用 C++ 或 Python 编写节点来发布 Marker 消息,并将其发布到 ROS 网络中。接收到这些消息的可视化工具将会把它们解析并渲染到 3D 空间中。 ### 回答2: visualization_msgs::marker是ROS(机器人操作系统)中用于可视化的消息类型之一。可视化在机器人领域中非常重要,因为它允许我们通过视觉化界面观察机器人的动作和行为,从而更好地理解机器人的表现。 visualization_msgs::marker包含了一组用于定义和描述3D对象的数据结构,例如点、线、虚线、箭头、球体和立方体等。这些数据结构可以用于创建虚拟的3D场景,并以可视化形式显示在ROS的话题中。机器人系统通过订阅相关话题可以实时地获取这些场景信息,从而动态地观察机器人的行为和环境变化。 除了常规的3D场景外,visualization_msgs::marker还引入了很多有用的概念,例如:颜色、透明度、尺寸、缩放比例、坐标系等。这些特性使得场景的可视化更加丰富多彩,并更容易被理解和识别。 此外,visualization_msgs::marker还有一些高级功能,例如:动画、文本标签和动态更新等。这些功能都可以通过相应的API接口实现,从而快速地创建自定义的3D场景。 总之,visualization_msgs::marker是ROS中一个非常重要的机器人可视化工具,可以帮助我们更好地理解机器人的表现,并为机器人系统的设计和开发提供更加有效的方式。 ### 回答3: visualization_msgs::marker是ROS的一个消息类型,用于可视化展示机器人或其他物体的位置、方向、大小、颜色等信息。在工业机器人、移动机器人、虚拟现实、游戏开发等领域都有广泛应用。 visualization_msgs::marker消息包含了大量的可视化信息,例如: 1. Marker类型:代表展示的形状类型,包括线、立方体、球体、箭头、文本等。 2. Marker位置:表示展示物体的3D位置信息,可以是二维或三维坐标。 3. Marker姿态:包括方向、旋转轴、旋转角度等信息,可以指示物体的朝向、运动方向等。 4. Marker大小和缩放:可以通过设置大小和缩放系数,控制展示物体的大小。 5. Marker颜色:可以指定展示物体的颜色,包括红、绿、蓝、透明度等。 6. Marker文本、图片等:可以在可视化界面中展示一些文本、图片等信息。 使用visualization_msgs::marker,机器人或其他物体的位置、方向、大小、颜色等信息都能够清晰地展示在可视化界面中。例如,在运动控制中,可以将机器人的位置、朝向、状态等信息以可视化的方式展示出来,方便操作者进行观察和控制;在虚拟现实或游戏开发中,可以使用Marker实现游戏场景元素的渲染和实现。 总而言之,visualization_msgs::marker是ROS的一个重要消息类型,具有广泛的应用场景,可以将机器人和其他物体的位置、方向、大小、颜色、文本等信息以可视化方式展示出来,方便交互和控制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RockWang.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值