欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ros::spin() 和 ros::spinOnce()函數(shù)的區(qū)別及詳解

 更新時(shí)間:2016年10月01日 09:20:04   作者:小萌是個(gè)球  
這篇文章主要介紹了ros::spin() 和 ros::spinOnce()函數(shù)的區(qū)別及詳解的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,感謝興趣的朋友一起看看吧

1 函數(shù)意義

首先要知道,這倆兄弟學(xué)名叫ROS消息回調(diào)處理函數(shù)。它倆通常會(huì)出現(xiàn)在ROS的主循環(huán)中,程序需要不斷調(diào)用ros::spin() 或 ros::spinOnce(),兩者區(qū)別在于前者調(diào)用后不會(huì)再返回,也就是你的主程序到這兒就不往下執(zhí)行了,而后者在調(diào)用后還可以繼續(xù)執(zhí)行之后的程序。

其實(shí)消息回調(diào)處理函數(shù)的原理非常簡(jiǎn)單。我們都知道,ROS存在消息發(fā)布訂閱機(jī)制,什么?不知道?不知道還不快去:http://wiki.ros.org/ROS/Tutorials (ROS官方基礎(chǔ)教程) 瞅瞅。

好,我們繼續(xù),如果你的程序?qū)懥讼嚓P(guān)的消息訂閱函數(shù),那么程序在執(zhí)行過(guò)程中,除了主程序以外,ROS還會(huì)自動(dòng)在后臺(tái)按照你規(guī)定的格式,接受訂閱的消息,但是所接到的消息并不是立刻就被處理,而是必須要等到ros::spin()或ros::spinOnce()執(zhí)行的時(shí)候才被調(diào)用,這就是消息回到函數(shù)的原理,怎么樣,簡(jiǎn)單吧,至于為什么這么設(shè)計(jì)?咳咳,嗯,肯定有他的道理。。。

2 區(qū)別

就像上面說(shuō)的,ros::spin() 在調(diào)用后不會(huì)再返回,也就是你的主程序到這兒就不往下執(zhí)行了,而 ros::spinOnce() 后者在調(diào)用后還可以繼續(xù)執(zhí)行之后的程序。

其實(shí)看函數(shù)名也能理解個(gè)差不多,一個(gè)是一直調(diào)用;另一個(gè)是只調(diào)用一次,如果還想再調(diào)用,就需要加上循環(huán)了。

這里一定要記住,ros::spin()函數(shù)一般不會(huì)出現(xiàn)在循環(huán)中,因?yàn)槌绦驁?zhí)行到spin()后就不調(diào)用其他語(yǔ)句了,也就是說(shuō)該循環(huán)沒(méi)有任何意義,還有就是spin()函數(shù)后面一定不能有其他語(yǔ)句(return 0 除外),有也是白搭,不會(huì)執(zhí)行的。ros::spinOnce()的用法相對(duì)來(lái)說(shuō)很靈活,但往往需要考慮調(diào)用消息的時(shí)機(jī),調(diào)用頻率,以及消息池的大小,這些都要根據(jù)現(xiàn)實(shí)情況協(xié)調(diào)好,不然會(huì)造成數(shù)據(jù)丟包或者延遲的錯(cuò)誤。

3 常見(jiàn)使用方法

這里需要特別強(qiáng)調(diào)一下,如果大兄弟你的程序?qū)懥讼嚓P(guān)的消息訂閱函數(shù),那千萬(wàn)千萬(wàn)千萬(wàn)不要忘了在相應(yīng)位置加上ros::spin()或者ros::spinOnce()函數(shù),不然你是永遠(yuǎn)都得不到另一邊發(fā)出的數(shù)據(jù)或消息的,博主血的教訓(xùn),萬(wàn)望緊記。。。

3.1 ros::spin()

ros::spin()函數(shù)用起來(lái)比較簡(jiǎn)單,一般都在主程序的最后,加入該語(yǔ)句就可。例子如下:

發(fā)送端:

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char **argv)
{
  ros::init(argc, argv, "talker");
  ros::NodeHandle n;
  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
  ros::Rate loop_rate(10);
  int count = 0;
  while (ros::ok())
  {
    std_msgs::String msg;
    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();
    ROS_INFO("%s", msg.data.c_str());
    /**
     * 向 Topic: chatter 發(fā)送消息, 發(fā)送頻率為10Hz(1秒發(fā)10次);消息池最大容量1000。
     */
    chatter_pub.publish(msg);
    loop_rate.sleep();
    ++count;
  }
  return 0;
}

接收端:

#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
  ros::init(argc, argv, "listener");
  ros::NodeHandle n;
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
  /**
   * ros::spin() 將會(huì)進(jìn)入循環(huán), 一直調(diào)用回調(diào)函數(shù)chatterCallback(),每次調(diào)用1000個(gè)數(shù)據(jù)。
   * 當(dāng)用戶(hù)輸入Ctrl+C或者ROS主進(jìn)程關(guān)閉時(shí)退出,
   */
  ros::spin();
  return 0;
}

3.2 ros::spinOnce()

對(duì)于ros::spinOnce()的使用,雖說(shuō)比ros::spin()更自由,可以出現(xiàn)在程序的各個(gè)部位,但是需要注意的因素也更多。比如:

1 對(duì)于有些傳輸特別快的消息,尤其需要注意合理控制消息池大小和ros::spinOnce()執(zhí)行頻率; 比如消息送達(dá)頻率為10Hz, ros::spinOnce()的調(diào)用頻率為5Hz,那么消息池的大小就一定要大于2,才能保證數(shù)據(jù)不丟失,無(wú)延遲。

/**接收端**/<br>#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  /*...TODO...*/ 
}
int main(int argc, char **argv)
{
  ros::init(argc, argv, "listener");
  ros::NodeHandle n;
  ros::Subscriber sub = n.subscribe("chatter", 2, chatterCallback);
  ros::Rate loop_rate(5);
  while (ros::ok())
  {
    /*...TODO...*/ 
    ros::spinOnce();
    loop_rate.sleep();
  }
  return 0;
}

2 ros::spinOnce()用法很靈活,也很廣泛,具體情況需要具體分析。但是對(duì)于用戶(hù)自定義的周期性的函數(shù),最好和ros::spinOnce并列執(zhí)行,不太建議放在回調(diào)函數(shù)中;

/*...TODO...*/
ros::Rate loop_rate(100);
while (ros::ok())
{
  /*...TODO...*/
  user_handle_events_timeout(...);
  ros::spinOnce();         
  loop_rate.sleep();
}

相關(guān)文章

  • 詳解JS中如何終止foreach循環(huán)

    詳解JS中如何終止foreach循環(huán)

    forEach專(zhuān)門(mén)用來(lái)循環(huán)數(shù)組,可以直接取到元素,同時(shí)也可以取到index值,終止forEach存在局限性,不能continue跳過(guò)或者break終止循環(huán),所以本文給大家詳細(xì)介紹了在JS中如何終止foreach循環(huán),需要的朋友可以參考下
    2024-01-01
  • uniapp實(shí)現(xiàn)微信H5掃碼功能的完整步驟

    uniapp實(shí)現(xiàn)微信H5掃碼功能的完整步驟

    在uni-app官網(wǎng)上發(fā)現(xiàn)uni-app不支持H5掃碼功能,但是下面的提示說(shuō)明可以通過(guò)微信的JS-SDK實(shí)現(xiàn)掃碼功能,下面這篇文章主要給大家介紹了關(guān)于uniapp實(shí)現(xiàn)微信H5掃碼功能的完整步驟,需要的朋友可以參考下
    2022-11-11
  • 輸入自動(dòng)提示搜索提示功能的javascript:sugggestion.js

    輸入自動(dòng)提示搜索提示功能的javascript:sugggestion.js

    該js文件中的代碼實(shí)現(xiàn)了[輸入自動(dòng)搜索提示]功能,如百度、google搜索框中輸入一些字符會(huì)以下拉列表形式給出一些提示,提高了用戶(hù)體驗(yàn)
    2013-09-09
  • 用Javascript獲取頁(yè)面元素的具體位置

    用Javascript獲取頁(yè)面元素的具體位置

    制作網(wǎng)頁(yè)的過(guò)程中,你有時(shí)候需要知道某個(gè)元素在網(wǎng)頁(yè)上的確切位置,在接下來(lái)的文章中為大家介紹下使用js是如何實(shí)現(xiàn)的
    2013-12-12
  • Javascript發(fā)送AJAX請(qǐng)求實(shí)例代碼

    Javascript發(fā)送AJAX請(qǐng)求實(shí)例代碼

    這篇文章主要介紹了Javascript發(fā)送AJAX請(qǐng)求的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-08-08
  • layui動(dòng)態(tài)渲染生成select的option值方法

    layui動(dòng)態(tài)渲染生成select的option值方法

    今天小編就為大家分享一篇layui動(dòng)態(tài)渲染生成select的option值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-09-09
  • javascript常用的方法分享

    javascript常用的方法分享

    本文給大家分享了幾個(gè)javascript中常用的方法,十分的實(shí)用,也很簡(jiǎn)單,有需要的小伙伴可以參考下。
    2015-07-07
  • Bootstrap 3 按鈕標(biāo)簽實(shí)例代碼

    Bootstrap 3 按鈕標(biāo)簽實(shí)例代碼

    這篇文章主要介紹了Bootstrap 3 按鈕標(biāo)簽實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • 過(guò)慮特殊字符輸入的js代碼

    過(guò)慮特殊字符輸入的js代碼

    有時(shí)候需要客戶(hù)端限制一些特殊字符的輸入,下面是具體的代碼,需要的朋友可以參考下。
    2010-08-08
  • ajax請(qǐng)求前端跨域問(wèn)題原因及解決方案

    ajax請(qǐng)求前端跨域問(wèn)題原因及解決方案

    這篇文章主要為大家介紹了ajax請(qǐng)求前端跨域問(wèn)題原因及解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10

最新評(píng)論