日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ROS学习(十四):ROS Spinning

發布時間:2025/6/17 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ROS学习(十四):ROS Spinning 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ROS 單線程與多線程 Spinning

roscpp 不為應用程序指定具體的線程模型。

允許回調函數調用任意數量的線程

必須要調用線程,否則訂閱、服務等回調將永遠不會被調用

常見的解決方案是,在主函數開頭用 ros::spin()

注意:回調序列對內部的網絡通訊沒有影響,只能影響回調發生的時刻。它們將影響訂閱序列,取決于處理回調函數的速度、消息到達的速度、消息是否丟棄等。

1、單線程

最簡單最常用的單線程為:ros::spin()

ros::init(argc, argv, "my_node"); ros::NodeHandle nh; ros::Subscriber sub = nh.subscribe(...); ... ros::spin();

所有用戶的調用程序將從 ros::spin()開始調用。只到節點關閉(ros::shutdown() or a Ctrl-C),ros::spin()才有返回值。

另一個常用的模式是周期性的 ros::spinOnce()

ros::Rate r(10); // 10 hz while (should_continue) {... do some work, publish some messages, etc. ...ros::spinOnce();r.sleep(); }

ros::spinOnce()將在那一刻調用所有等待調用的函數。

執行一個自己的spin()函數很簡單:

#include <ros/callback_queue.h> ros::NodeHandle n; while (ros::ok()) {ros::getGlobalCallbackQueue()->callAvailable(ros::WallDuration(0.1)); }

spinOnce() 類似:

#include <ros/callback_queue.h>ros::getGlobalCallbackQueue()->callAvailable(ros::WallDuration(0));

注:spin()和spinonce()真的意味著單線程應用程序,而不是從多個線程中調用的一次優化。

2、多線程

ros::MultiThreadedSpinner

阻塞式線程,類似于ros::spin(),你可以在它的構造器上指定一定數量的線程數,但如果不指定或設置為0,則會在每個CPU上執行一個線程。

ros::MultiThreadedSpinner spinner(4); // Use 4 threads spinner.spin(); // spin() will not return until the node has been shutdown

ros::AsyncSpinner (since 0.10)

一個更有用的線程。它不用spin() 回調,而用start()和stop(),當它銷毀時候就會自動關閉

ros::AsyncSpinner spinner(4); // Use 4 threads spinner.start(); ros::waitForShutdown();

3、回調序列

創建回調序列:

#include <ros/callback_queue.h> ... ros::CallbackQueue my_queue;

CallbackQueue 有兩種方法調用回調函數: callAvailable() 和callOne()。

callavailable()調用隊列里所有的。callone()只會調用回調在隊列最舊的。

callAvailable()和callOne()都會有一個超時選項,在返回前,它會在超時時間內等待回調有效。

如果是0,同時隊列沒有回調,則直接返回。

4、高級回調序列

上面spin()執行的語句,有調用到 ros::getGlobalCallbackQueue(),默認所有的回調都會放到全局隊列,由ros::spin() 處理。

自定義回調序列:

1、subscribe(), advertise(), advertiseService()

2、NodeHandle

ros::AsyncSpinner spinner(0, &my_callback_queue); spinner.start();

這個可使用所有訂閱,服務,定時器等,回調通過my_callback_queue而不是 roscpp的默認隊列。意味著ros::spin() 和ros::spinOnce() 不會處理這些回調。你需要單獨處理這些回調。

你可以通過手工調用 ros::CallbackQueue::callAvailable() 和ros::CallbackQueue::callOne()方法處理。

my_callback_queue.callAvailable(ros::WallDuration()); // alternatively, .callOne(ros::WallDuration()) to only call a single callback instead of all available

各種*Spinner對象可以使用指向回調隊列的指針而不是默認值:

ros::AsyncSpinner spinner(0, &my_callback_queue); spinner.start();

或者:

ros::MultiThreadedSpinner spinner(0); spinner.spin(&my_callback_queue);

參考

http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning

總結

以上是生活随笔為你收集整理的ROS学习(十四):ROS Spinning的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。