ros launch文件編寫和節點啓動順序控制

ROS可以通過launch文件進行節點的管理、初始參數的設置,但是launch文件不能指定節點的啓動順序,因此本文簡單介紹下通過launch進行節點啓動管理,通過shell來控制節點啓動順序。

1,我將讀取參數的代碼片段放在了ros::init(argc,argv,"node_name")之後,首先定義變量類型,然後用ros::param::get進行參數獲取。其中"~"表示該參數是一個私有參數,即在launch文件中,其應該寫在

<node pkg=....

 ......

 /node>

之間。更全面的關於私有變量、命名空間會在後文有解釋。

如下示例:

    ros::init(argc,argv,"PCAN_Test");
    init();

    //parameter load test start ......

    string dev_name;
    ros::param::get("~dev_name",dev_name);
    ROS_INFO("PCAN Device:%s",dev_name.c_str());

    bool fifo_send_on=false;
    ros::param::get("~fifo_send_on",fifo_send_on);
    ROS_INFO("FIFO send :%s",fifo_send_on==false?"false":"true");

    bool display_on=false;
    ros::param::get("~display_on",display_on);
    ROS_INFO("Data display:%s",display_on==false?"false":"true");
    //parameter load test end ......
定義了三個變量,dev_name用來配置pcan usb的端口,fifo_send_on和display則控制是否fifo發送,是否打開數據顯示。此次dev_name使用時dev_name.c_str()可以匹配const char類型,該操作是取出string 存儲的串地址,內容和string相同。

    if(dev_name.c_str() !="")
        pcan_handle = funLINUX_CAN_Open(dev_name.c_str(), O_RDWR );
    else
    {
        pcan_handle = funLINUX_CAN_Open(szDevNode, O_RDWR );//use mapping function
        dev_name=DEFAULT_NODE;
    }
    //judge whether the call is success.if pcan_handle=null,the call would be failed
    if(pcan_handle){
        printf("CAN Bus test: %s have been opened\n", dev_name.c_str());
        errno = funCAN_VersionInfo(pcan_handle, txt);
        if (!errno)
            printf("CAN Bus test: driver version = %s\n", txt);
        else {
            perror("CAN Bus test: CAN_VersionInfo()");
        }
        if (wBTR0BTR1) {
                errno = funCAN_Init(pcan_handle, wBTR0BTR1, nExtended);
                if (errno) {
                    perror("CAN Bus test: CAN_Init()");
                }
                else
                    printf("Device Info: %s; CAN_BAUD_1M; CAN_INIT_TYPE_ST\n", dev_name.c_str());
            }
    }
    else
        printf("CAN Bus test: can't open %s\n", dev_name.c_str());

    //initial a talker to publish the force data and can id.
    ros::NodeHandle force_handle;
    ros::Publisher force_pub=force_handle.advertise<beginner_tutorials::ForceData>("ArrayForcePUB",1);//advertise a topic named "ArrayForceDEV"
    ros::Rate loop_rate(500);
    //data receive test
    while(ros::ok())
    {   //HANDLE h,ros::Publisher pub,int server_fifo_fd,bool display_on,bool publish_on,bool fifo_send_on
        read_loop(pcan_handle,force_pub,server_fifo_fd,display_on,true,fifo_send_on);
        if(fifo_send_on)  printf("Send Count No.%d\t\n",send_count);
        ros::spinOnce();
        loop_rate.sleep();
    }
2,launch文件中則如下進行設置,pkg後對應文件的包名,type後是CMakeList.txt中對應該文件add_executable(pcan_test src/pcan_test)中可執行文件的名稱,在python中則是文件名,因爲python的可執行文件就是文件本身(解釋性語言,同matlab),所以此次若用c++編程不要誤寫爲文件名全稱,name表示節點啓動後的名稱,該名稱會覆蓋ros::init中初始化的名稱,output後參數表示從屏幕輸出打印信息,否則,打印信息會存儲到某個臨時文件裏。

參數裏name是ros::param::get()中第一個字符串去掉“~”後的名稱,launch會在運行時進行查找匹配,type是變量類型,value是具體值。以下爲launch文件全文。

<launch>
	<node pkg="beginner_tutorials" type="pcan_test" name="PCAN_Test" output="screen">
	<param name="dev_name" type="string" value="/dev/pcan1" />
	<param name="fifo_send_on" type="bool" value="false" />	
	<param name="display_on" type="bool" value="false" />	
	</node>	
</launch>
注:只需要在src下建立launch文件夾,然後在其中創建launch文件即可,不需要做其他工作。
3,上面關於ros::param::get內容介紹較爲簡單,一個更爲全面的launch的例子如下,包含launch中私有變量和公有變量例子

<param name="camera_topic_root" value="/camera/image_rect">
<group ns="group_ns">
    <param name="camera_topic_ns" value="/camera/image_rect">
    <node name="node_name" pkg="foo" type="bar" >
        <param name="camera_topic_private" value="/camera/image_rect">
    </node>
</group>
group爲一個節點組,可以通過某種設置進行整個組內的節點啓停控制,參考ROS launch整理中詳細介紹。 ns爲命名空間。
則用ros::param::get時有如下三種如下包含關係的變量,其中
/camera_topic_root
/group_ns/camera_topic_ns
/group_ns/node_name/camera_topic_private
因此如果通過ros::param::get來進行參數獲取,則應如下所示:
ros::param::get("/camera_topic_root",camera_topic);    // /camera_topic_root
ros::param::get("camera_topic_ns",camera_topic);       // /group_ns/camera_topic_ns
ros::param::get("~camera_topic_private",camera_topic); // /group_ns/node_name/camera_topic_private
4,在ubuntu下進行節點啓動順序控制的簡單策略就是通過shell實現。

新建文件後命名爲xxx.sh。

#!/bin/bash

roslaunch bhand_controller bhand_controller.launch &
sleep 5
echo "bhand controller starting success!"

roslaunch beginner_tutorials bhand_force_control.launch &
sleep 0.1
wait
exit 0
第一行表示用bash執行,sleep表示演示,echo用來輸出一定內容,有關ubuntu shell的其他操作,注意不用忘記句子後的"&"符號,可以自行查詢相關資料。因此策略就是如果某個節點必須先執行,可以單獨爲其寫一個launch文件,然後通過shell控制先行啓動。

編寫保存後,在終端要給xxx.sh執行權限,sudo chmod a+x xxx.sh,之後可通過./xxx.sh進行啓動,xxx代表任意字符。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章