在rviz中标记机器人的轨迹需要用到类visualization_msgs::Marker
,其重要成员如下: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//各种标志物类型的定义,也是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可以将各个标志物区分开来,使得程序可以对指定的标志物进行操作,如果再次执行相同id,会删除上一次的标记
int32 type //类型,指哪种形状
int32 action //操作,是添加还是修改还是删除
geometry_msgs/Pose pose # 位姿
geometry_msgs/Vector3 scale # 默认1,指1米大小。一般要小于1
std_msgs/ColorRGBA color # Color [0.0-1.0],其实是普通颜色值除以255
duration lifetime # 在自动删除前维持多久,0表示永久。注意类型为duration,所以要用ros::Duration(1)初始化
bool frame_locked # If this marker should be frame-locked, i.e. retransformed into its frame every timestep
geometry_msgs/Point[] points//这个是在序列、点集中才会用到,指明序列中每个点的位置
# 数量必须是0或与点数相同,alpha还不能用
std_msgs/ColorRGBA[] colors
#只用于文本标识
string text
string mesh_resource
bool mesh_use_embedded_materials
ns和id变量每次不能同时一样,否则后面的操作会覆盖前面的操作,也就一直只能看到最新的了。建议每次让id+=1或者从命令行输入,
对Marker的pose和scale必须赋值, 否则发布会报警,不能正常显示。1
2
3
4
5
6
7
8
9
10
11marker.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;
// 缺一不可,不能有0
marker.scale.x = 0.3;
marker.scale.y = 0.3;
marker.scale.z = 0.3;
如果报警Non-empty points array is ignored.
可以忽略
代码
我写了代码如下,在rviz上标记机器人当前位置,形状为球体,id从命令行输入,id为0时清除所有标识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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
int main( int argc, char** argv )
{
ros::init(argc, argv, "basic_shapes");
ros::NodeHandle nh;
if(argc !=2)
{
ROS_ERROR("no marker id !");
return -1;
}
visualization_msgs::Marker marker;
ros::Publisher marker_pub = nh.advertise<visualization_msgs::Marker>("visualization_marker", 1);
uint32_t shape = visualization_msgs::Marker::SPHERE;
// 获取当前位姿,阻塞至获取成功
boost::shared_ptr<geometry_msgs::Pose const> edge = ros::topic::waitForMessage<geometry_msgs::Pose>("robot_pose",nh);
if( atoi(argv[1])==0 )
{
marker.action = visualization_msgs::Marker::DELETEALL;
ROS_WARN("All marker in rviz will be removed !");
}
else
marker.action = visualization_msgs::Marker::ADD;
// Set the frame ID and timestamp. See the TF tutorials for information on these.
marker.header.frame_id = "/map";
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 = atoi(argv[1]);
marker.type = shape;
// 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 = edge->position.x;
marker.pose.position.y = edge->position.y;
marker.pose.position.z = edge->position.z;
marker.pose.orientation.x = edge->orientation.x;
marker.pose.orientation.y = edge->orientation.y;
marker.pose.orientation.z = edge->orientation.z;
marker.pose.orientation.w = edge->orientation.w;
// Set the scale of the marker -- 1x1x1 here means 1m on a side
marker.scale.x = 0.1;
marker.scale.y = 0.1;
marker.scale.z = 0.1;
// Set the color -- set alpha to something non-zero!
marker.color.r = 0.0f;
marker.color.g = 0.0f;
marker.color.b = 1.0f;
// 不要是0,否则报警 Marker is fully transparent (color.a is 0.0).
marker.color.a = 1.0;
// 不加参数就是0,标识生命期为永久
marker.lifetime = ros::Duration();
// 如果rviz里没有订阅话题visualization_marker,等待2秒
while (marker_pub.getNumSubscribers() < 1)
{
if (!ros::ok())
{
return 0;
}
ROS_WARN_ONCE("Please create a subscriber to the marker");
sleep(2);
}
// 这样比较好,有了订阅者再发布
marker_pub.publish(marker);
return 0;
}
打开rviz,后添加Marker
,设置话题:
机器人在导航状态,所以Fixed Frame
是/map
在终端运行rosrun add_marker marker 1
,会添加标识成功
运行rosrun map_server map_saver
不会保存标识,因为它和地图无关,只是rviz里的显示,否则就成了地图上的障碍物了。
因为发布了Marker消息,在rviz里订阅后观测到,所以重启rviz后就没有标识了
参考:
官方marker教程
ROS之rviz显示历史运动轨迹、路径的各种方法
github: rviz_visual_tools