RViz學(xué)習(xí)筆記(二) - Markers: 發(fā)送基本的形狀

這一節(jié)將會(huì)學(xué)習(xí)怎么使用visualization_msgs/Marker message發(fā)送一個(gè)基本形狀到rviz

1 介紹

不像別的顯示組件, Marker Display能讓你直接可視化數(shù)據(jù)而不需要rviz知道任何東西贞远。我們這一節(jié)就要學(xué)習(xí)怎么發(fā)送幾個(gè)基本幾何形狀。

2 創(chuàng)建一個(gè)package

在開(kāi)始之前活合,先創(chuàng)建一個(gè)package:
catkin_create_pkg using_markers roscpp visualization_msgs
我在此之前重新創(chuàng)建了一個(gè)工作區(qū)棵癣,然后才創(chuàng)建包的上祈,可以看一下之前的教程。

3 發(fā)送Markers

3.1 源碼

打開(kāi)using_markers package:
一定要在工作空間并且source 了setup.bash
roscd using_markers
新建:
vim src/basic_shapes.cpp
把下面的代碼粘貼到src/basic_shapes.cpp:

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

int main( int argc, char** argv )
{
  ros::init(argc, argv, "basic_shapes");
  ros::NodeHandle n;
  ros::Rate r(1);
  ros::Publisher marker_pub = n.advertise<visualization_msgs::Marker>("visualization_marker", 1);

  // Set our initial shape type to be a cube
  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 = "/my_frame";
    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();
  }
}

現(xiàn)在編輯 using_markers package里面的CMakeLists.txt 文件腿箩,增加下面的內(nèi)容在最后面:

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

3.2 代碼解析

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

我們將ROS包含了進(jìn)來(lái)豪直,還包含了visualization_msgs/Marker 消息的定義。

int main( int argc, char** argv )
{
  ros::init(argc, argv, "basic_shapes");
  ros::NodeHandle n;
  ros::Rate r(1);
  ros::Publisher marker_pub = n.advertise<visualization_msgs::Marker>("visualization_marker", 1);

我們初始化了ROS珠移,然后在visualization_marker topic上面創(chuàng)建了一個(gè)publisher弓乙。

uint32_t shape = visualization_msgs::Marker::CUBE;

這里我們創(chuàng)建了一個(gè)整型來(lái)追蹤我們將要發(fā)布什么形狀。因?yàn)槲覀儗⒁l(fā)布的四種形狀都是以相同的形式發(fā)送的钧惧,所以我們只需要切換形狀就好了暇韧。

 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 = "/my_frame";
    marker.header.stamp = ros::Time::now();

這里開(kāi)始了程序的實(shí)質(zhì)的部分。首先我們創(chuàng)建了一個(gè)visualization_msgs/Marker浓瞪,然后開(kāi)始填充它懈玻。在這里我們的frame_id設(shè)置為/my_frame,這里只是作為一個(gè)例子,所以才這么取名字的乾颁,在一個(gè)運(yùn)行的系統(tǒng)中涂乌,這個(gè)應(yīng)該是你想要的坐標(biāo)系相對(duì)于這個(gè)的解釋,反正就是你要搞個(gè)有意義點(diǎn)的名字英岭。

 marker.ns = "basic_shapes";
 marker.id = 0;

命名空間(ns)和id是用來(lái)給這個(gè)marker創(chuàng)建一個(gè)唯一的名字的湾盒。如果接收到一個(gè)相同命名空間和id的marker,那新的就會(huì)把老的替換掉诅妹。

marker.type = shape;

這個(gè)就是指定我們會(huì)發(fā)送哪種形狀過(guò)去罚勾。我們把它設(shè)定成shape,這樣我們改變shape就可以改變發(fā)送的形狀吭狡。

marker.action = visualization_msgs::Marker::ADD;

這個(gè)是用來(lái)指定我們要對(duì)marker做什么的尖殃,有ADD和DELETE兩個(gè)選項(xiàng),ADD其實(shí)是創(chuàng)建或者修改的意思划煮,看注釋還增加了一個(gè)新的選項(xiàng)——DELETALL送丰。

    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;

這里我們?cè)O(shè)置了marker的姿態(tài)。geometry_msgs/Pose message包含了一個(gè)geometry_msgs/Vector3來(lái)指定位置弛秋,還有一個(gè)geometry_msgs/Quaternion來(lái)指定方向蚪战。這里我們把方向設(shè)置為身份方向(w=1.0)

    marker.scale.x = 1.0;
    marker.scale.y = 1.0;
    marker.scale.z = 1.0;

這里指定了標(biāo)記的規(guī)模牵现,對(duì)于基本形狀铐懊,1表示在這邊長(zhǎng)度是1米邀桑。

    marker.color.r = 0.0f;
    marker.color.g = 1.0f;
    marker.color.b = 0.0f;
    marker.color.a = 1.0;

marker的顏色就像指定 std_msgs/ColorRGBA。每個(gè)數(shù)字介于0-1之間科乎。最后一個(gè)a(alpha)表示透明度壁畸,0表示完全透明。

marker.lifetime = ros::Duration();

這個(gè)是指定marker在被自動(dòng)清除前可以逗留多長(zhǎng)時(shí)間茅茂。這里 ros::Duration()表示不自動(dòng)刪除捏萍。
如果在lifetime結(jié)束之前有新內(nèi)容到達(dá)了,它就會(huì)被重置空闲。

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);

這里是等待訂閱者出現(xiàn)令杈。你也可以在這個(gè)地方啟動(dòng)訂閱者。

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;
    }

這個(gè)就是確定要發(fā)送那個(gè)marker的碴倾。根據(jù)上一句發(fā)送的內(nèi)容切換到下一個(gè)

 r.sleep();
  }

睡眠逗噩,然后跳回循環(huán)頂部。

3.3 編譯源碼

$ cd %TOP_DIR_YOUR_CATKIN_WORKSPACE%
$ catkin_make

3.4 運(yùn)行代碼

rosrun using_markers basic_shapes

出現(xiàn)錯(cuò)誤可能是你沒(méi)有創(chuàng)建工作空間的原因跌榔,參考前面的教程創(chuàng)建异雁。
這個(gè)時(shí)候會(huì)有一句黃色的Warning提醒你沒(méi)有訂閱者,使我們程序里輸出的提醒僧须。

4 查看Marker

新窗口中編譯rviz:
rosmake
運(yùn)行rviz:
rosrun rviz rviz
如果沒(méi)有出現(xiàn)任何東西纲刀,可能是我前面跳過(guò)了一些內(nèi)容的原因,因?yàn)榻坛讨惺褂玫能浖姹靖业牟灰粯拥F剑晕姨^(guò)了那部分內(nèi)容示绊,想看可以點(diǎn)這里
我找到了一個(gè)解決辦法可以用:

5 沒(méi)有顯示解決辦法

可能會(huì)看到這樣一個(gè)錯(cuò)誤暂论,并且沒(méi)有顯示圖像:

No tf data.  Actual error: Fixed Frame [map] does not exist

首先安裝basic_shapes:
$ catkin_make install
然后新窗口運(yùn)行ROS:
roscore
在打開(kāi)一個(gè)窗口運(yùn)行發(fā)送程序:
$ rosrun using_markers basic_shapes
然后新窗口輸入:

$ rosrun tf static_transform_publisher 0.0 0.0 0.0 0.0 0.0 0.0 map my_frame 100 

我覺(jué)得真正對(duì)我的問(wèn)題起作用的是這個(gè)面褐。
然后再運(yùn)行rviz:

$ rosrun rviz rviz

然后新建一個(gè)Marker,就可以看到了空另。
Marker的topic一欄跟我們程序里定義的topic一樣盆耽。

問(wèn)題

上面的

$ rosrun tf static_transform_publisher 0.0 0.0 0.0 0.0 0.0 0.0 map my_frame 100 

能夠讓左邊的Global Status變成正常的,不過(guò)我發(fā)現(xiàn)一個(gè)方法也可以解決收不到數(shù)據(jù)的問(wèn)題扼菠。
在我們的程序里摄杂,定義了 marker.header.frame_id = "/my_frame";這樣的話,應(yīng)該把global option里面的Fixed Frame改成/my_frame與之對(duì)應(yīng)循榆,這樣就可以用了析恢。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市秧饮,隨后出現(xiàn)的幾起案子映挂,更是在濱河造成了極大的恐慌泽篮,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柑船,死亡現(xiàn)場(chǎng)離奇詭異帽撑,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)鞍时,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門亏拉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人逆巍,你說(shuō)我怎么就攤上這事及塘。” “怎么了锐极?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵笙僚,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我灵再,道長(zhǎng)肋层,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任檬嘀,我火速辦了婚禮槽驶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鸳兽。我一直安慰自己掂铐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布揍异。 她就那樣靜靜地躺著全陨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衷掷。 梳的紋絲不亂的頭發(fā)上辱姨,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音戚嗅,去河邊找鬼雨涛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛懦胞,可吹牛的內(nèi)容都是我干的替久。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼躏尉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蚯根!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起胀糜,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤颅拦,失蹤者是張志新(化名)和其女友劉穎蒂誉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體距帅,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡右锨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锥债。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陡蝇。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖哮肚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情广匙,我是刑警寧澤允趟,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站鸦致,受9級(jí)特大地震影響潮剪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜分唾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一抗碰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绽乔,春花似錦弧蝇、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至睦授,卻和暖如春两芳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背去枷。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工怖辆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人删顶。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓竖螃,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親翼闹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子斑鼻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容