ROS msg Topic CPPの勉強メモ

ユーザー定義したmsgをpubulisher(Tx),subscriber(Rx)してROSの中最も重要な部分の中の一つであるTopicについて復習する。

１．ws/src/pkg/msgの下にmsgフィアルにてmsgの中身を定義する。（変数宣言みたいなもん）
![Screenshot from 2023-05-14 18-31-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/3e397264-e824-0dce-2c3a-812f5fb5da2d.png)

~~~~~~~~~~~~~~~~~~~~~~~~~
string name
uint8  sex
uint8  age

uint8 unknown = 0
uint8 male    = 1
uint8 female  = 2
~~~~~~~~~~~~~~~~~~~~~~~~~


２．package.xmlファイルにmsgを使うことをROSにわかってもらうため、下記内容を追加する（includ,buildするため必要な記述のイメージ）
![Screenshot from 2023-05-14 18-34-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/315ae099-bc54-98e1-0498-a441bf9a82ac.png)

３．cmakelists.txtファイルにmsgを使うことをROSにわかってもらうため、下記内容を追加する（buildするために必要な記述のイメージ）３箇所

１箇所目（message_generation追加）
![Screenshot from 2023-05-14 18-39-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/b49d394a-9b48-490b-2312-1ab7c8e5723b.png)

2箇所目(catkin情報の追加)
![Screenshot from 2023-05-14 18-46-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/8741269b-d82f-453a-8503-88c138681695.png)

３箇所目(msgファイル情報の追加)
![Screenshot from 2023-05-14 18-49-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/c1634459-b954-0067-7a37-bca8cf840bb0.png)

これでmsgの追加編集の終わりましたので、buildすればmsgが使えるようになる。試して見る。ターミナルで下記コマンドを実行して確認する
~~~~~~~~~~~~~~~~~
catkin_make
rosmsg show Person
~~~~~~~~~~~~~~~~~
![Screenshot from 2023-05-14 18-54-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/fb0ace25-2af7-80ad-db45-6db71bc7cfcd.png)

ROS上にmsgを使えるように認識できたことをわかったので、今度定義したmsgを使ってnode間に通信して見る。

1.TX側、発表者側 person_publisher.cpp編集
~~~~~~~~~~~~~~~~~
#include <ros/ros.h>
#include "learning_communication/Person.h"
int main(int argc, char **argv)
{
    ros::init(argc, argv, "person_publisher");
    ros::NodeHandle n;
    ros::Publisher person_info_pub = n.advertise<learning_communication::Person>("/person_info", 10);
    ros::Rate loop_rate(1);
    int count = 0;
    while (ros::ok())
    {
    	learning_topic::Person person_msg;
		person_msg.name = "Tom";
		person_msg.age  = 18;
		person_msg.sex  = learning_communication::Person::male;

        ROS_INFO("%s", person_msg.data.c_str());
        person_info_pub.publish(person_msg);

        ros::spinOnce();

        loop_rate.sleep();
    }
    return 0;
}
~~~~~~~~~~~~~~~~~~~

2.RX側、清聴者側　person_subscriber.cpp編集
~~~~~~~~~~~~~~~~~~~
#include <ros/ros.h>
#include "learning_communication/Person.h"

//割り込みcallback function、ここでは表示しているだけだが、実際実用の場面でセンサーのリアルタイムの値に対して動きを変えたり、判断した上アクションするようなことを入れる
void personInfoCallback(const learning_communication::Person::ConstPtr& msg)
{
    ROS_INFO("Subcribe Person Info: name:%s  age:%d  sex:%d", 
		 msg->name.c_str(), msg->age, msg->sex);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "person_subscriber");
    ros::NodeHandle n;
    ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);//"/person_info"は
    ros::spin();//継続的な割り込み待ち
    return 0;
}
~~~~~~~~~~~~~~~~~~~

最後、person_publisher.cppとperson_subscriber.cppをビルトしてくれるようにCmakeLists.txtに登録する
![Screenshot from 2023-05-14 20-59-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/c8912e63-c7a4-b356-c027-82e7801ce7e4.png)

これで編集の部分が全部おわったので、動かして見よう〜
ターミナル１
~~~~~~~~~~~~~~~~~~~~~~
roscore
~~~~~~~~~~~~~~~~~~~~~~

ターミナル２
~~~~~~~~~~~~~~~~~~~~
rosrun learning_communication person_publisher 
~~~~~~~~~~~~~~~~~~~~

ターミナル3
~~~~~~~~~~~~~~~~~~~~
rosrun learning_communication person_subscriber
~~~~~~~~~~~~~~~~~~~~
![Screenshot from 2023-05-14 21-04-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/7f78bdc7-509b-af7d-8085-fd09f85dd2a7.png)



memo:
ros::spinOnce()
    その行が実行されるタイミングで1度だけcallback関数にアクセス
ros::spin()
    その行が実行された後は、メッセージがパブリッシュされるたびにcallback関数にアクセス