ROS專題----nodelet簡明筆記
ROS專題----nodelet簡明筆記
------
此頁面包含使用nodelet的教程。強烈建議您已經回顧了pluginlib教程做這些教程了。
運行節點
這將顯示如何在系統中運行節點。
將節點移植到節點
來自使用nodelet的其他包/堆棧的教程:
Kobuki控制器教程:為Kobuki編寫您自己的基于節點的控制器
------
$ roslaunch nodelet_tutorial_math plus.launch
... logging to /home/relaybot/.ros/log/7f42ed06-088b-11e7-99c2-70f1a1ca7552/roslaunch-relaybot-desktop-8447.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://relaybot-desktop:34104/
SUMMARY
========
PARAMETERS
* /Plus2/value: 10
* /Plus3/value: 2.5
* /rosdistro: kinetic
* /rosversion: 1.12.7
NODES
/
Plus (nodelet/nodelet)
Plus2 (nodelet/nodelet)
Plus3 (nodelet/nodelet)
standalone_nodelet (nodelet/nodelet)
ROS_MASTER_URI=http://localhost:11311
core service [/rosout] found
process[standalone_nodelet-1]: started with pid [8485]
process[Plus-2]: started with pid [8486]
process[Plus2-3]: started with pid [8487]
process[Plus3-4]: started with pid [8488]
[ INFO] [1489489721.430571269]: Loading nodelet /Plus of type nodelet_tutorial_math/Plus to manager standalone_nodelet with the following remappings:
[ INFO] [1489489721.430679072]: /Plus/out -> /remapped_output
[ INFO] [1489489721.439768636]: waitForService: Service [/standalone_nodelet/load_nodelet] has not been advertised, waiting...
type is nodelet_tutorial_math/Plus
[ INFO] [1489489721.444581734]: Loading nodelet /Plus2 of type nodelet_tutorial_math/Plus to manager standalone_nodelet with the following remappings:
[ INFO] [1489489721.451421641]: waitForService: Service [/standalone_nodelet/load_nodelet] has not been advertised, waiting...
[ INFO] [1489489721.872693083]: Initializing nodelet with 4 worker threads.
[ INFO] [1489489721.886004455]: waitForService: Service [/standalone_nodelet/load_nodelet] is now available.
[ INFO] [1489489721.891109441]: waitForService: Service [/standalone_nodelet/load_nodelet] is now available.
------
#include
#include
#include
#include
#include
#include
namespace nodelet_tutorial_math
{
class Plus : public nodelet::Nodelet
{
public:
Plus()
: value_(0)
{}
private:
virtual void onInit()
{
ros::NodeHandle& private_nh = getPrivateNodeHandle();
private_nh.getParam("value", value_);
pub = private_nh.advertise
sub = private_nh.subscribe("in", 10, &Plus::callback, this);
}
void callback(const std_msgs::Float64::ConstPtr& input)
{
std_msgs::Float64Ptr output(new std_msgs::Float64());
output->data = input->data + value_;
NODELET_DEBUG("Adding %f to get %f", value_, output->data);
pub.publish(output);
}
ros::Publisher pub;
ros::Subscriber sub;
double value_;
};
PLUGINLIB_DECLARE_CLASS(nodelet_tutorial_math, Plus, nodelet_tutorial_math::Plus, nodelet::Nodelet);
}
------
------
運行節點
建立
我們假設nodelet_tutorial_math已經被編譯并且roscore正在運行。
rosmake nodelet_tutorial_math roscore
打開經理
一個nodelet會內運行NodeletManager。節點管理器是一個c ++程序,它被設置為監聽ROS服務,并且是動態加載節點的可執行文件。在這種情況下,我們將運行一個獨立的管理器,但在許多情況下,這些管理器將嵌入在運行的節點中。
rosrun nodelet nodelet manager __name:= nodelet_manager
為了清楚起見,我們已將此節點重命名為nodelet_manager。
啟動節點
Nodelet也通過使用nodelet可執行文件遠程啟動。
這個代碼做什么:這里調用的nodelet可執行文件將聯系nodelet_manager并要求它實例化nodelet_tutorial_math / Plus節點的一個實例。它將通過名稱nodelet1,以及任何重新映射,如果應用于nodelet中的代碼。參數也出現在右邊的命名空間中。
rosrun nodelet nodelet load nodelet_tutorial_math / Plus nodelet_manager __name:= nodelet1 nodelet1 / in:= foo _value:= 1.1
如果你做一個rostopic列表,你會看到:
/ foo / nodelet1 / out
如果你看看rosnode列表的輸出,你會看到:
/ nodelet1 / nodelet_manager
測試操作
在單獨的端子運行:
rostopic pub / foo std_msgs / Float64 5.0 -r 10
rostopic echo / nodelet1 / out
將顯示:6.1是5.0 + 1.1。
在roslaunch文件中使用
下面是一個示例啟動文件(在nodelet_tutorial_math?pkg?中可用),其中多個nodelet在同一獨立管理器上運行:
------
將節點移植到nodelet
工作進行中...(參見nodelet_tutorial_math一個例子)
添加必要的#includes
去掉int main()
子類nodelet :: Nodelet
將代碼從構造函數移動到onInit()
添加PLUGINLIB_EXPORT_CLASS宏
在包清單中對節點添加
請在包清單的
創建.xml文件以將nodelet定義為插件
對CMakeLists.txt進行必要的更改(注釋掉一個rosbuild_add_executable,添加一個rosbuild_add_library)
最小節點
MyNodeletClass.h
#include
MyNodeletClass.cpp
//這應該是在實現(.cpp文件) #include
nodelet_plugins.xml
package.xml
... ...
mynodelet.launch
------
nodelet
高水平
Nodelets旨在提供一種在單個進程中在單個機器上運行多個算法的方法,而不會在傳遞消息進程時產生復制成本。roscpp具有在同一節點內的發布和訂閱調用之間進行零拷貝指針傳遞的優化。為了做到這一點,nodelet允許將類動態加載到同一個節點,然而它們提供了簡單的單獨命名空間,使得盡管nodelet在同一個進程中,它仍然像一個獨立的節點。這進一步擴展了,它在運行時使用pluginlib是動態可加載的。
應用程序
高吞吐量數據流可以由許多節點組成,然后加載到同一進程,以避免復制和網絡流量。
設計目標
使用現有的C ++ ROS接口。
允許節點之間的數據的零拷貝傳遞
動態加載為插件以打破構建時間依賴性
位置透明,除了性能改進
在節點或節點中編寫代碼將有最小的不同。
技術
定義將用于動態加載的基類nodelet :: Nodelet。所有nodelet都將繼承這個基類,并且可以使用pluginlib進行動態加載。
它將提供命名空間,自動重映射參數和參數,就像它們是第一個類節點一樣。
將有一個nodelet_manager進程,一個或多個nodelet可以加載到其中。它們之間的任何通信都可以使用帶有boost共享指針的零拷貝roscpp發布調用。
基本用法
節點使用: nodelet加載pkg /類型管理器 - 在管理器管理器上啟動pkg / Type類型的節點 nodelet standalone pkg / Type - 在獨立節點中啟動pkg / Type類型的節點 nodelet unload name manager - 按名稱從manager卸載nodelet節點 nodelet管理器 - 啟動節點管理器節點
對于命令行和啟動文件示例,請參閱本教程運行節點
API
nodelet :: Nodelet
公共方法:
切換行號
1 Nodelet()//動態加載時使用的默認構造函數 2 void init(const std :: string&name,const ros :: M_string&remapping_args,const std :: vector < std :: string >&my_argv); //這個方法是一個nodelet應該如何啟動。參數是管理器啟動節點所需的參數。這將初始化nodelet基類,然后調用子類的onInit()方法。 3
子類中使用的受保護成員和方法:
切換行號
1 std :: string getName()//獲取nodelet的名稱 2 ros :: NodeHandle& getNodeHandle()//獲取節點句柄(提供此節點的自定義重映射和名稱) 3 ros :: NodeHandle& getPrivateNodeHandle()//獲取私有節點句柄(在其私有命名空間中提供此節點的自定義重映射) 4 ros :: NodeHandle& getMTNodeHandle()//使用Multi Threaded回調隊列獲取節點句柄。(提供此節點的自定義重映射和名稱) 5 ros :: NodeHandle& getMTPrivateNodeHandle()//使用多線程回調隊列獲取私有節點句柄。(在其私有命名空間中提供此節點定制重新映射) 6 ros :: CallbackQueue& getMTCallbackQueue()//獲取回調隊列(從管理器可用線程池) 7 std :: vector < std :: string > getMyArgv()//獲取命令行參數到剝離ROS和nodelet特定args的nodelet。 8
用于在子類中啟動ROS API的初始化方法:
切換行號
1 virtual void onInit()= 0 // Virtual,并且必須被子類覆蓋。必須將ROS基礎結構的所有初始化都放入此函數中。 2
這些是rosconsole宏周圍的節點感知包裝器。它們包括詳細程度級別DEBUG,INFO,WARN,ERROR和FATAL。這些宏只會在nodelet方法中編譯。
它們通過在運行的nodelet的名稱中設置命名的日志記錄器來操作,以便您可以?區分在運行的兩個相同類型的節點的輸出?同一位經理。他們也有優勢,你可以轉一個具體nodelet進入調試,而不是所有特定類型的節點。
切換行號
1 #包括“nodelet / nodelet.h” 2 3 // ...在一個nodelet方法 4 NODELET_DEBUG(“ 我的調試語句”) 5 NODELET_DEBUG_STREAM(“ 我的調試語句” <<(double)1.0) 6 NODELET_DEBUG_COND(1 == 1,“ my debug_statement ”) 7 NODELET_DEBUG_STREAM_COND(1 == 1,“ 我的調試語句” <<(double)1.0)
如果希望no-copy pub / sub工作,您必須將消息發布為shared_ptr。有關更多詳細信息,請參閱roscpp / Overview / Publishers和訂閱者#Intraprocess_Publishing。
線程模型
節點管理器具有線程池,該線程池在管理器內運行的所有節點之間共享。這由參數“num_worker_threads”設置。
在nodelet中運行的代碼中有兩種可能的線程API。默認線程模型有一個線程用于所有回調。還有一個多線程API。
這個方法在init上調用,不應該阻塞或做重要的工作。
使用方法getNodeHandle()和getPrivateNodeHandle()將保證所有回調串行到達。
使用方法getMTNodeHandle()和getMTPrivateNodeHandle()回調將分布在管理器的線程池中。
它是節點創建自己的線程進行操作的有效操作。這些線程應該在析構函數中正確清理。
所有nodelet共享管理器的線程池。如果nodelet阻塞線程,它們可能會阻止其他nodelet獲得回調。確保管理器配置了足夠的線程以防止阻止。注意:即使單個線程的節點句柄也可以每個節點使用池的1個線程。
------
任務調度 單片機
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。