ros使用过程中,经常会用到rviz可视化各种数据。而在rviz中,marker与markerarray是常用的一种可视化工具,最近也用到过几次了,这里随手记录一下。
在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();
}
箭头的表示跟直线差不多,基础代码如下:
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();
}
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();
}
某些时候需要在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();
}
在添加了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();
}
以上是markerarray的一些简单用法,后期有更多用法继续更新。
如果需要复现的话详细的代码放在:
https://download.csdn.net/download/YiYeZhiNian/87135596