前回Qt Cretorで作成したGUIをROSノード化しました.
今回はROSの基本通信Pub/Subの機能の追加方法を記載します.
内容
1.pub
・GUIでボタンの追加 => ボタン右クリックのSLOT設定を押して,イベントハンドラー関数を生成
・前回の記事で作成した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
トピックが配信されます
2.sub
次はsubscriber GUIを作成します
・まずGUIにlabelを設置します
・次に各プログラムを以下のように変更します
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テキストが変更されました
さいごに
Qt Creatorを使うとボタンのコールバック関数などを自動生成できたり楽でいいですね!
参考