ROS之rviz显示(visualization_msgs/Marker)

参考博客:
(1)ROS之rviz显示历史运动轨迹、路径的各种方法(visualization_msgs/Marker、nav_msgs/Path)
(2)ROS笔记之visualization_msgs-Marker学习
(3)基于ROS发布里程计信息

参考文档:
(1) rvizDisplayTypesMarker
(2) rvizTutorialsMarkers: Basic Shapes

0 前言

(1)在ROS中,odombase_linkmap是常见的坐标系(frame)用于机器人定位和导航。

  • odom坐标系是机器人的里程计坐标系,相对于起始位置的运动。
  • base_link坐标系是机器人的本体坐标系,与机器人的移动无关。
  • map坐标系是机器人所在的全局地图坐标系,提供了固定的参考框架用于定位和导航机器人在全局环境中的位置。

(2)visualization_msgs::MarkerArray是ROS中的消息类型,用于在RViz中发布多个Marker的数组
visualization_msgs::MarkerArray消息由以下字段组成:

markers(std::vector<visualization_msgs::Marker>):包含多个visualization_msgs::Marker对象的数组。每个Marker对象都描述了一个可视化元素,如线箭头文本等。

通过使用visualization_msgs::MarkerArray消息,您可以同时发布多个Marker,并在RViz中以数组的形式显示它们。
(3)visualization_msgs/Marker消息的一些重要字段

  • header:消息的头部信息,包括frame_id和timestamp等。
  • ns:命名空间,用于将Marker分组。
  • id:Marker的唯一标识符,用于标识不同的Marker。
  • type:Marker的类型,指定要显示的形状。可以使用visualization_msgs/Marker消息定义的常量来设置,如visualization_msgs::Marker::SPHERE表示球体。
  • action:Marker的操作类型,指定在RViz中如何处理该Marker。常见的- 操作类型包括ADD、DELETE和DELETEALL。
  • pose:Marker的位姿,指定Marker在三维空间中的位置和方向。
  • scale:Marker的尺寸,用于控制Marker的大小或线宽等属性。
  • color:Marker的颜色,可以设置RGBA值来指定颜色和不透明度。
  • points:用于线条和多边形等形状的点列表。每个点由geometry_msgs/- Point消息表示。
  • text:用于文本形状的字符串内容。
  • lifetime:Marker的生命周期,用于控制Marker在RViz中的显示时间。

(4)各种标志物的类型
可以在rvizDisplayTypesMarker查看
下面列举一些常用的:

ARROW=0//箭头
CUBE=1//立方体
SPHERE=2//球
CYLINDER=3//圆柱体
LINE_STRIP=4//线条(点的连线)
LINE_LIST=5//线条序列
CUBE_LIST=6//立方体序列
SPHERE_LIST=7//球序列
POINTS=8//点集
TEXT_VIEW_FACING=9//显示3D的文字
MESH_RESOURCE=10//网格
TRIANGLE_LIST=11//三角形序列

1 实现在rviz中画出圆形轨迹

参考大佬的博客:ROS在rviz中实时显示轨迹(nav_msgs/Path消息的使用)
(1)新建工程

mkdir -p showpath/src
cd src
catkin_create_pkg showpath roscpp rospy sensor_msgs std_msgs nav_msgs tf
cd ..
catkin_make 

(2)编辑主函数showpath.cpp

#include <ros/ros.h>
#include <ros/console.h>
#include <nav_msgs/Path.h>
#include <std_msgs/String.h>
#include <geometry_msgs/Quaternion.h>
#include <geometry_msgs/PoseStamped.h>
#include <tf/transform_broadcaster.h>
#include <tf/tf.h>

main (int argc, char **argv)
{
    ros::init (argc, argv, "showpath");

    ros::NodeHandle ph;
    ros::Publisher path_pub = ph.advertise<nav_msgs::Path>("trajectory",1, true);

    ros::Time current_time, last_time;
    current_time = ros::Time::now();
    last_time = ros::Time::now();

    nav_msgs::Path path;
    //nav_msgs::Path path;
    path.header.stamp=current_time;
    path.header.frame_id="odom";


    double x = 0.0;
    double y = 0.0;
    double th = 0.0;
    double vx = 0.1; // x方向速度
    double vy = -0.1;// y方向速度
    double vth = 0.1;// 角速度 

    ros::Rate loop_rate(1);
    while (ros::ok())
    {

        current_time = ros::Time::now();
        //compute odometry in a typical way given the velocities of the robot
        double dt = 0.1;
        double delta_x = (vx * cos(th) - vy * sin(th)) * dt;
        double delta_y = (vx * sin(th) + vy * cos(th)) * dt;
        double delta_th = vth * dt;

        x += delta_x;
        y += delta_y;
        th += delta_th;


        geometry_msgs::PoseStamped this_pose_stamped;
        this_pose_stamped.pose.position.x = x;
        this_pose_stamped.pose.position.y = y;

        geometry_msgs::Quaternion goal_quat = tf::createQuaternionMsgFromYaw(th);
        this_pose_stamped.pose.orientation.x = goal_quat.x;
        this_pose_stamped.pose.orientation.y = goal_quat.y;
        this_pose_stamped.pose.orientation.z = goal_quat.z;
        this_pose_stamped.pose.orientation.w = goal_quat.w;

        this_pose_stamped.header.stamp=current_time;
        this_pose_stamped.header.frame_id="odom";
        path.poses.push_back(this_pose_stamped);

        path_pub.publish(path);
        ros::spinOnce();               // check for incoming messages

        last_time = current_time;
        loop_rate.sleep();
    }

    return 0;
}

(3)vim CMakeLists.txt

add_executable(showpath src/showpath.cpp)
target_link_libraries(showpath ${catkin_LIBRARIES})

(4)编译和运行
移动到创建的工程工作区间

catkin_make

(5)在不同的终端下输入

roscore

source ./devel/setup.bash
rosrun showpath showpath

rostopic echo /trajectory

rosrun rviz rviz

在globel option的Fixed Fram输入odom
左边点击add
选中path
在path的topic选项中选
/trajectory
在这里插入图片描述

2 visualization_msgs/Marker

visualization_msgs::Marker消息类型中,pose.position字段用于描述可视化元素的位置。它是一个geometry_msgs::Point类型的字段,包含了三个分量xyz,分别表示可视化元素在坐标系中的位置。这个位置是可视化元素的中心点或基准点。

  1. 首先需要发布visualization_marker话题
ros::Publisher vis_pub = node_handle.advertise<visualization_msgs::Marker>( "visualization_marker", 0 );
  1. 然后只需填写一条visualization_msgs/Marker消息并发布即可
visualization_msgs::Marker marker;
marker.header.frame_id = "base_link";
marker.header.stamp = ros::Time();
marker.ns = "my_namespace";
marker.id = 0;
marker.type = visualization_msgs::Marker::SPHERE;
marker.action = visualization_msgs::Marker::ADD;
marker.pose.position.x = 1;
marker.pose.position.y = 1;
marker.pose.position.z = 1;
marker.pose.orientation.x = 0.0;
marker.pose.orientation.y = 0.0;
marker.pose.orientation.z = 0.0;
marker.pose.orientation.w = 1.0;
marker.scale.x = 1;
marker.scale.y = 0.1;
marker.scale.z = 0.1;
marker.color.a = 1.0; // Don't forget to set the alpha!
marker.color.r = 0.0;
marker.color.g = 1.0;
marker.color.b = 0.0;
//only if using a MESH_RESOURCE marker type:
marker.mesh_resource = "package://pr2_description/meshes/base_v0/base.dae";
vis_pub.publish(marker);

别忘了设置marker.color.a = 1,否则marker不可见

还有一个visualization_msgs/MarkerArray消息,它允许您同时发布多个marker。在这种情况下,您希望在visualization_marker_array主题中发布。
参考代码:

#include <ros/ros.h>
#include <visualization_msgs/MarkerArray.h>
#include <visualization_msgs/Marker.h>

int main(int argc, char** argv)
{
    ros::init(argc, argv, "marker_publisher");
    ros::NodeHandle nh;

    ros::Publisher marker_array_pub = nh.advertise<visualization_msgs::MarkerArray>("marker_array", 10);
    ros::Publisher marker_pub = nh.advertise<visualization_msgs::Marker>("marker", 10);

    // 创建MarkerArray消息
    visualization_msgs::MarkerArray marker_array;

    // 创建第一个Marker
    visualization_msgs::Marker marker1;
    marker1.header.frame_id = "map";
    marker1.header.stamp = ros::Time::now();
    marker1.lifetime = ros::Duration();  // 设置持久化属性为false
    marker1.ns = "marker1";
    marker1.id = 1;
    marker1.type = visualization_msgs::Marker::SPHERE;
    marker1.pose.position.x = 1.0;
    marker1.pose.position.y = 2.0;
    marker1.pose.position.z = 0.0;
    marker1.pose.orientation.w = 1.0;
    marker1.scale.x = 0.5;
    marker1.scale.y = 0.5;
    marker1.scale.z = 0.5;
    marker1.color.r = 1.0;
    marker1.color.g = 0.0;
    marker1.color.b = 0.0;
    marker1.color.a = 1.0;

    // 创建第二个Marker
    visualization_msgs::Marker marker2;
    marker2.header.frame_id = "map";
    marker2.header.stamp = ros::Time::now();
    marker2.lifetime = ros::Duration();  // 设置持久化属性为false
    marker2.ns = "marker2";
    marker2.id = 2;
    marker2.type = visualization_msgs::Marker::CUBE;
    marker2.pose.position.x = -1.0;
    marker2.pose.position.y = 2.0;
    marker2.pose.position.z = 0.0;
    marker2.pose.orientation.w = 1.0;
    marker2.scale.x = 0.5;
    marker2.scale.y = 0.5;
    marker2.scale.z = 0.5;
    marker2.color.r = 0.0;
    marker2.color.g = 1.0;
    marker2.color.b = 0.0;
    marker2.color.a = 1.0;

    marker_array.markers.clear();
    marker_array.markers.push_back(marker1);
    marker_array.markers.push_back(marker2);

    ros::Rate rate(1);  // 发布频率为1Hz

    while (ros::ok()) {
        // 发布MarkerArray消息
        marker_array_pub.publish(marker_array);

        // 发布单个Marker消息
        marker_pub.publish(marker1);

        ros::spinOnce();
        rate.sleep();
    }

    return 0;
}

请注意,附加到上面标记消息的时间戳是ros::Time(),它是时间Zero (0)。RViz对此的处理与其他任何时间都不同。如果使用ros::Time::now()或任何其他非零值,则rviz只会在该时间与当前时间足够近的情况下显示标记,其中“足够近”取决于TF。然而,在时间为0的情况下,无论当前时间如何,标记都会显示。

3 实战

(1)新建一个工程

mkdir -p catkin_ws/src
cd catkin_ws
catikin_create_pkg test roscpp rospy std_msgs nav_msgs tf
catkin_make

(2)在catkin_ws/src/test/src目录下新建test.cpp,修改CMakeLists.txt

vim test.cpp
#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>
#include <visualization_msgs/Marker.h>

ros::Publisher car_model;
visualization_msgs::Marker car_marker;

void visual_car(const double x, const double y, const double th)
{
    car_marker.pose.orientation = tf::createQuaternionMsgFromYaw(th);
    car_marker.header.frame_id = "map";
    car_marker.header.stamp = ros::Time::now();
    car_marker.ns = "basic_shapes";
    
    car_marker.id = 0;
    car_marker.type = visualization_msgs::Marker::CUBE;// 立方体
    car_marker.action = visualization_msgs::Marker::ADD;

    car_marker.pose.position.x = 3.0;
    car_marker.pose.position.y = 4.0;
    car_marker.pose.position.z = 0;
    car_marker.scale.x = 4.0; // 车长
    car_marker.scale.y = 2.0; // 车宽
    car_marker.scale.z = 1.5; // 车高
    car_marker.color.a = 1.0;
    car_marker.color.r = 1.0f;
    car_marker.color.g = 1.0f;
    car_marker.color.b = 0.0f;
    car_marker.lifetime = ros::Duration();
    car_model.publish(car_marker);
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "Car");
    ros::NodeHandle n;
    car_model = n.advertise<visualization_msgs::Marker>("/ydw/car", 100);
    
    ros::Rate rate(10);
    while (ros::ok())
    {
        visual_car(0.0, 0.0, 0.0);
        rate.sleep();
    }
    return 0;
}
vim CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(test)

find_package(catkin REQUIRED COMPONENTS
  nav_msgs
  roscpp
  rospy
  std_msgs
  tf
)

catkin_package(
  INCLUDE_DIRS include
)

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

add_executable(test1 src/test.cpp)

target_link_libraries(test1
  ${catkin_LIBRARIES}
)

(3)编译,开启如下终端,空行代表新建一个终端

catkin_make

roscore

source devel/setup.bash
rosrun test test1

rosrun rviz rviz

(4)打开rviz界面之后添加Marker
在这里插入图片描述

  • 16
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: `visualization_msgs/marker` 是 ROS 中一个常用的消息类型,用于在可视化工具(如RViz)中显示可视化标记。 `visualization_msgs/marker` 中定义了一组用于描述可视化标记的字段,包括标记类型、位置、方向、颜色、尺寸等等。通过发布这个消息,可将标记显示在可视化工具中,方便用户查看和调试。 常见的标记类型包括箭头、立方体、球体、线段等等,可以通过修改消息中的字段来控制标记的外观和行为。 ### 回答2: visualization_msgs/markerROS机器人操作系统)中一种消息类型,用于在RViz中可视化数据。它是ROS中一种常见的消息类型之一,广泛应用于机器人控制、数据可视化和仿真等领域。它的主要作用是用于在RViz显示各种数据对象,包括点、线、面、文本、箭头等。因此,visualization_msgs/marker常被视为“虚拟现实的图像”。 在ROS系统中,RViz是一种开源的3D可视化工具,它能够以可视化方式显示ROS节点所产生和接收的消息。通过使用ROS中预定义的消息类型,如visualization_msgs/marker,可以将实时数据以一种直观的方式呈现给用户。同时,RViz还支持用户自定义消息类型,因此可以满足不同领域、不同应用场景的需求。 在使用visualization_msgs/marker时,开发者需要定义其参数,以指定所需可视化对象的类型、形状、颜色、坐标、大小等属性。例如,可以使用visualization_msgs/marker定义一个球体,其参数包括形状(SPHERE)、大小(scale)、颜色(color)、位置(pose)等。通过将所定义的marker发布到ROS节点上,RViz将自动显示该对象,并可以进行实时更新和互动操作。 总之,visualization_msgs/markerROS系统中一种重要的消息类型,可用于实现ROS节点的数据可视化功能。它提供了丰富的参数和灵活的使用方式,可适应不同领域、不同应用场景的需求,为机器人控制、数据可视化和仿真等领域的开发者和用户提供了强大的工具和支持。 ### 回答3: visualization_msgs/markerROS中的一个消息类型,用于可视化机器人的图形或场景,在可视化过程中通过发布和订阅ROS消息来实现数据交换。例如,当机器人需要显示它当前运动的轨迹时,可以通过发布visualization_msgs/marker消息来显示,这是一种高效且方便的方法。 visualization_msgs/marker包含了许多属性,如颜色、大小、形状、位置等,可以非常灵活地用于机器人的可视化。其主要属性如下: 1.图形类型:可以选择点、线、立方体、球体、箭头等多种图形类型。 2.位置和方向:可以设置图形的位置和方向,以便在场景中呈现出合适的姿态。 3.颜色:可以指定图形的颜色,让机器人更加生动形象。 4.大小:可以根据需要进行相应的调整,使得图形更加美观。 5.生命周期:可以设置图形的生命周期,让图形在一定的时间后消失,从而更好地模拟机器人在现实世界中的行为。 6.相对标记:可以将图形标记为相对而非绝对的,这对于机器人的局部移动非常有用。 总之,visualization_msgs/marker机器人可视化的一个重要组成部分,它可以将机器人的状态、动作、运动等信息直观地展现出来,帮助用户更好地理解机器人的行为,同时也为机器人的控制和运动提供了有力的支持。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值