質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
コールバック

コールバックは他のコードに引数として渡されるコードのことを指します。

Q&A

2回答

2651閲覧

ROSでのコールバック関数呼び出しについて

退会済みユーザー

退会済みユーザー

総合スコア0

コールバック

コールバックは他のコードに引数として渡されるコードのことを指します。

0グッド

0クリップ

投稿2020/01/16 07:10

前提・実現したいこと

ROS素人です。
find_hsvでカメラ画像から高明度領域を検出し、領域ごとの識別番号、中心座標(x,y)を取得します。
center_subにおいてトピックellipses_centerに配信されているそれらのデータを表示するサブスクライバを作成します。

たいのですが、どうにもコールバック関数が呼び出されていないようです。
ellipses_centerのデータは更新され続けているのは確認できているのですが、何故コールバック関数が呼ばれないのでしょうか。

発生している問題・エラーメッセージ

center_subにおいてトピックellipses_centerに配信されているデータを表示するサブスクライバを作成したいのですが、どうにもコールバック関数が呼び出されていないようです。
ellipses_centerのデータは更新され続けているのは確認できているのですが、何故コールバック関数が呼ばれないのでしょうか。

該当のソースコード

C++

1//find_hsv 2#include <ros/ros.h> 3#include <image_transport/image_transport.h> 4#include <cv_bridge/cv_bridge.h> 5#include <sensor_msgs/image_encodings.h> 6#include <opencv2/imgproc/imgproc.hpp> 7#include <opencv2/highgui/highgui.hpp> 8#include <iostream> 9#include "find_color/Ellipses.h" 10#include "find_color/Ellipse.h" 11 12using namespace std; 13using namespace cv; 14 15static const std::string OPENCV_WINDOW = "Image window"; 16 17class ImageConverter 18{ 19 ros::NodeHandle nh_; 20 ros::Publisher point_pub_; 21 image_transport::ImageTransport it_; 22 image_transport::Subscriber image_sub_; 23 image_transport::Publisher image_pub_; 24 find_color::Ellipses centers; 25 find_color::Ellipse center; 26 27 public: 28 ImageConverter() 29 : it_(nh_) 30 { 31 image_sub_ = it_.subscribe("/usb_cam/image_raw", 1, 32 &ImageConverter::imageCb, this); 33 image_pub_ = it_.advertise("/image_converter/output_video", 1); 34 point_pub_ = nh_.advertise<find_color::Ellipses>("/ellipses_center", 1); 35 36 cv::namedWindow("fit_ellipse", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO); 37 } 38 39 ~ImageConverter() 40 { 41 cv::destroyWindow("fit_ellipse"); 42 } 43 44void find_color_(cv::Mat& mat) 45 { 46 47 Mat hsv; 48 cvtColor(mat,hsv,COLOR_BGR2HSV); 49 50 Mat dst; 51 52 Scalar s_min = Scalar(0, 0, 230); 53 Scalar s_max = Scalar(250, 255, 255); 54 55 56 inRange(hsv,s_min,s_max,dst); 57 58 cout<<"dst channels:"<<dst.channels()<<endl; 59 60 int c0=0,c255=0,other=0; 61 for(int i=0;i<dst.rows;i++){ 62 for(int j=0;j<dst.cols;j++){ 63 int v = dst.at<uchar>(i,j); 64 if(v == 0){ 65 c0++; 66 }else if(v == 255){ 67 c255++; 68 }else{ 69 other++; 70 } 71 } 72 } 73 74 cout<<"0 count:"<<c0<<",255 count:"<<c255<<",other value count:"<<other<<endl; 75 76 cv::erode(dst,dst,cv::Mat(),cv::Point(1,1),6); 77 cv::dilate(dst,dst,cv::Mat(),cv::Point(1,1),6); 78 79 cv::medianBlur(dst,dst,15); 80 81 vector< vector<Point> > contours; 82 vector<Vec4i> hierarchy; 83 Mat temp; 84 dst.copyTo(temp); 85 86 findContours(temp,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE ); 87 88 cout<<"contours size:"<<contours.size()<<endl; 89 cout<<"hierarchy size:"<<hierarchy.size()<<endl; 90 91 int j = 0; 92 93 for(int i = 0; i < contours.size(); ++i) { 94 size_t count = contours[i].size(); 95 if(count < 0 || count > 1000) continue; 96 97 j++; 98 99 cv::Mat pointsf; 100 cv::Mat(contours[i]).convertTo(pointsf, CV_32F); 101 cv::RotatedRect box = cv::fitEllipse(pointsf); 102 cv::ellipse(mat, box, cv::Scalar(0,0,255), 2, CV_AA); 103 104 center.num = j; 105 center.xcenter = box.center.x; 106 center.ycenter = box.center.y; 107 108 centers.ellipses.push_back(center); 109 } 110 point_pub_.publish(centers); 111 112 ; 113 cv::imshow("fit_ellipse",mat); 114 } 115 116void imageCb(const sensor_msgs::ImageConstPtr& msg) 117 { 118 cv_bridge::CvImagePtr cv_ptr; 119 try 120 { 121 cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8); 122 } 123 catch (cv_bridge::Exception& e) 124 { 125 ROS_ERROR("cv_bridge exception: %s", e.what()); 126 return; 127 } 128 129 find_color_(cv_ptr->image); 130 131 cv::waitKey(3); 132 133 image_pub_.publish(cv_ptr->toImageMsg()); 134 } 135 136}; 137 138 139 140int main(int argc, char** argv) 141{ 142 ros::init(argc, argv, "image_converter"); 143 ImageConverter ic; 144 ros::spin(); 145 return 0; 146} 147

C++

1//center_sub 2#include "ros/ros.h" 3#include <stdio.h> 4#include "find_color/Ellipses.h" 5#include "find_color/Ellipse.h" 6#include <iostream> 7using namespace std; 8 9void chatterCallback(const find_color::Ellipse center) 10{ 11 cout << "num = " << center.num << 12 "xcenter = " << center.xcenter << 13 "ycenter = " << center.ycenter << endl; 14} 15 16int main(int argc, char **argv) 17{ 18 19 ros::init(argc, argv, "subscriber"); 20 ros::NodeHandle nh; 21 ros::Subscriber point_sub_ = nh.subscribe("/ellipses_center", 1, chatterCallback); 22 ros::spin(); 23 24 return 0; 25} 26

補足情報(FW/ツールのバージョンなど)

実行環境
ROS kinetic
ubuntumate16.04

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

cpp

1point_pub_ = nh_.advertise<find_color::Ellipses>("/ellipses_center", 1);

cpp

1void chatterCallback(const find_color::Ellipse center) 2... 3ros::Subscriber point_sub_ = nh.subscribe("/ellipses_center", 1, chatterCallback);

find_color::Ellipses, find_color::Ellipseはそれぞれ独自定義したROSメッセージだと理解しましたが、Susbscriberのコールバック関数が受け取るメッセージ型が、Publisherのメッセージ型と異なるからではないでしょうか。

投稿2020/04/18 11:53

sin_250

総合スコア112

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ここによるとubuntuのバージョンによるものらしいです.

投稿2020/03/18 19:49

dark-eater-kei

総合スコア1248

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問