Qt Creatorで作成したGUIでROSメッセージのPub・Sub

前回Qt Cretorで作成したGUIをROSノード化しました.

https://qiita.com/hoshianaaa/items/59688c7e6bd31b0eafac

今回はROSの基本通信Pub/Subの機能の追加方法を記載します.

# 内容

## 1.pub

・GUIでボタンの追加 => ボタン右クリックのSLOT設定を押して,イベントハンドラー関数を生成

![Screenshot from 2021-12-11 10-28-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/c868201c-4c92-0397-e479-8fc9094ec843.png)

・前回の記事で作成したROSノードプログラム元に各プログラムを以下のように変更します

```main.cpp
#include "mainwindow.h"

#include <QApplication>
#include <ros/ros.h>


int main(int argc, char *argv[])
{

    ros::init(argc, argv, "aaa");

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    ros::Rate loop_rate(20);
    while (ros::ok()){
      ros::spinOnce();
      a.processEvents();
      loop_rate.sleep();
    }
}

```

```mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <ros/ros.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_released();

private:
    Ui::MainWindow *ui;
    ros::NodeHandle nh_;
    ros::Publisher string_pub_;
};
#endif // MAINWINDOW_H
```

```mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"

#include <ros/ros.h>
#include <std_msgs/String.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    ui->setupUi(this);
    string_pub_ = nh_.advertise<std_msgs::String>("chatter", 10);

}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_released()
{
    std_msgs::String string_msg;
    string_msg.data="string";
    string_pub_.publish(string_msg);
    ROS_INFO("pub: %s", string_msg.data.c_str());
}
```

結果

roscoreを起動して,Qt Creatorから実行すると以下のようなGUIが立ち上がり,
ボタンを押すと`/chatter`トピックが配信されます

![Screenshot from 2021-12-11 10-31-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/45703d2d-9939-b17f-c4f4-82ad47b2d54a.png)

## 2.sub

次はsubscriber GUIを作成します

・まずGUIにlabelを設置します

![Screenshot from 2021-12-11 10-36-37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/27e33cb3-87b5-028a-1081-b529a7e677dc.png)


・次に各プログラムを以下のように変更します

```main.cpp
#include "mainwindow.h"

#include <QApplication>
#include <ros/ros.h>


int main(int argc, char *argv[])
{

    ros::init(argc, argv, "aaa");

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    ros::Rate loop_rate(20);
    while (ros::ok()){
      ros::spinOnce();
      a.processEvents();
      loop_rate.sleep();
    }
}
```

```mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"

#include <ros/ros.h>
#include <std_msgs/String.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    ui->setupUi(this);
    ui->label->setText("Hello World!");
    string_sub_ = nh_.subscribe("chatter", 10, &MainWindow::stringCallback, this);
    printf("register\n");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::stringCallback(const std_msgs::String& string_msg){
  QString text = QString::fromStdString(string_msg.data);
  ui->label->setText(text);
  ROS_INFO("sub: %s", string_msg.data.c_str());
}
```

```mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <ros/ros.h>
#include <std_msgs/String.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    ros::NodeHandle nh_;
    ros::Subscriber string_sub_;
    void stringCallback(const std_msgs::String& msg);
};
#endif // MAINWINDOW_H
```

結果

実行して`chatter`トピックにメッセージを送信するとGUI上のlabelテキストが変更されました

![Screenshot from 2021-12-11 10-41-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/be3c276e-a1ea-d84c-79a3-9813f1baecf4.png)

# さいごに

Qt Creatorを使うとボタンのコールバック関数などを自動生成できたり楽でいいですね!

# 参考

https://qiita.com/srs/items/93ab82b96637f405e657