c++回撥函式/ROS回撥函式
以下均是個人在實際耕碼的過程中遇到的問題和整理的結果,可能會有不對的地方,望各位指正與交流
------------------------------------------------------------------我會有喵的-------------------------------------------------------------------
c++中的回撥函式:
A "callback" is any function that is called by another function which takes the first function as a parameter.直白點說,就是“函式#"的引數是另一個函式,通過“函式#"呼叫另一個函式,這個“函式#"就是回撥函式。以數學形式來看(雖然不太恰當):Function(y)和Function(g(x))。Function(y)是一個函式,g(x)也是一個函式,那麼Function(g(x))就可以看成是一個回撥過程,g(x)就是回撥函式。
更直接地說,我們一般都是呼叫opencv裡面的庫函式,現在關係反過來了,我們要讓opencv呼叫一個我們自己寫的函式,這個過程就是回撥。那個被opencv呼叫的(我們自己寫的)函式就是回撥函式。接下來舉例規範地說一下:
不帶引數的回撥函式:
//回撥函式 void wordsCallback() { std::cout<<"Hello World!"<<std::endl; } //實現回撥函式的"呼叫函式" void wods(void (*callfuction)()) { callfuction(); } int main(int argc,char* argv[]) { words(wodsCallback); return 0; } 程式的正確輸出結果是:Hello World!
帶引數的回撥函式:
//回撥函式
void wordsCallback(char* s)
{
std::cout<<s<<std::endl;
}
//實現帶參回撥函式的"呼叫函式"
void words(void (*callfuction)(char*),char* s)
{
callfuction(s);
}
int main(int argc,char* argv[])
{
words(wordsCallback,"Hello World!");
return 0;
}
程式的正確輸出結果:Hello World!
接下來我們看看ROS中的回撥函式。一般來說這個回撥函式會用一些比較顯著且比較統一的名字:**Callback(如ScanCallback/CameraCallback),它是在訂閱話題的時候使用的。所以在使用時,我們需要宣告訂閱話題的名稱,然後選擇話題,最後呼叫Callback函式。廢話不多說,舉個例子(突然想吃舉個栗子了啊-------):
ros::Subscriber sub_raw_image = n.subscribe(IMAGE_TOPIC, 2000, imageCallback);
先宣告訂閱的話題的名稱:
sub_raw_image
然後,選擇我們需要訂閱的話題。
IMAGE_TOPIC
題外話,ROS中有很多話題,你可以自己寫,上面這個IMAGE_TOIC就是我自己寫的。當然你也可以使用一些系統提供的。比如你啟動了鐳射雷達,不論是模擬Gazebo中的還是真的鐳射雷達(如rplidar),那你就可以訂閱“/scan”這個話題。
2000代表我們一次性可以快取多少訊息(暫時沒發現這個數字對我的程式會帶來很大的影響,我經常寫成1),最後那個就是回撥函數了。
imageCallback
對於imageCallback的實現需要說一下。ROS中,imageCallback的引數是與你的話題息息相關的,你要跟據訂閱的話題來確定引數。一般來說,程式的主要功能也都是在回撥函式中實現的。你需要的資料,都是要通過話題訂閱的,而訂閱了就肯定有回撥函式。你可以把一個個回撥函式看成是一個個單獨的執行緒。只要你訂閱的訊息一更新,回撥函式就會被呼叫,對新的資料進行處理,程式就這麼不斷的進行下去了。這裡我們仍舊舉例:
void forwardCallback(const nav_msgs::Odometry::ConstPtr &forward_msg){}
void imageCallback(const sensor_msgs::ImageConstPtr &image_msg){}
需要確定的就是這個sensor_msgs::ImageConstPtr和nav_msgs::Odometry::ConstPtr啦!
嗯啊,今天到此結束啦,白白!