面向对象C++实现Qt
Node 创建
1. 创建node启动的cpp文件
在src
目录下创建turtle_control.cpp
,代码如下:
| #include "ros/ros.h"
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
string nodeName = "qt_turtle_ctrl";
// 创建节点
ros::init(argc,argv,nodeName);
ros::NodeHandle node;
return 0;
}
|
2. 配置CMake
来到CMakeLists.txt
文件中,添加如下:
| add_executable(turtle_control src/turtle_control.cpp)
target_link_libraries(turtle_control
${catkin_LIBRARIES}
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::PrintSupport
)
|
Tip
add_executable
是把turtle_control.cpp
标记为可执行的
target_link_libraries
是为turtle_control.cpp
提供链接库的,值得注意的是,${catkin_LIBRARIES}
是ros的依赖库,Qt5::Core
,Qt5::Gui
,Qt5::Wigets
,Qt5::PrintSupport
是qt的依赖库。
Qt UI的创建
1. Qt 窗体构建
Tip
通过分析,可以先构建Qt窗体头文件,并且实现
2. 根据需求进行UI布局
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | //窗体设置
setWindowTitle("小乌龟控制");
//设置窗体大小
resize(400, 120);
//设置布局
layout = new QFormLayout();
setLayout(layout);
//添加输入框
editLinear = new QLineEdit();
layout->addRow("线速度", editLinear);
//添加输入框
editAngular = new QLineEdit();
layout->addRow("角速度", editAngular);
//添加按钮
btnSend = new QPushButton("发送");
layout->addRow(btnSend);
|
3. 事件添加
| //添加事件
btnSend->connect(btnSend, &QPushButton::clicked, this, &MainWindow::clickSend);
|
整合Qt和Node
基本整合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | int main(int argc, char **argv) {
string nodeName = "turtle_control";
//创建节点
ros::init(argc, argv, nodeName);
ros::NodeHandle node;
//Qt程序添加
QApplication app(argc, argv);
//创建窗体
MainWindow window;
window.show();
return app.exec();
}
|
UI和Node结合
在开发过程中,窗体window通常是需要有node
对象的,因为node
对象可以创造我们想要的Publisher等对象。
这个时候,我们可以将node
通过参数传入到window中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | int main(int argc, char **argv) {
string nodeName = "turtle_control";
//创建节点
ros::init(argc, argv, nodeName);
ros::NodeHandle node;
//Qt程序添加
QApplication app(argc, argv);
//创建窗体
MainWindow window(&node);
window.show();
return app.exec();
}
|
Publisher创建
1. 创建publisher对象
| const ros::Publisher &publisher = node.advertise(topicName, 1000);
|
Tip
值得注意的是,在创建publisher对象时,这里要去确定的有两个点,第一就是topicName,第二就是传递的消息类型。
此处我们只能确定topic 的名称,给小乌龟发送数据的topic为/turtle1/cmd_vel
2. 确定消息传递的数据类型
通过rostopic命令查询主题对应的消息类型
| rostopic type /turtle1/cmd_vel
|
得到的结果为geometry_msgs/Twist
接下来我们需要导入这个消息类型对应的库
| #include "geometry_msgs/Twist.h"
|
接下来就是确定publisher创建时候的类型
| const ros::Publisher &publisher = node.advertise<geometry_msgs::Twist>(topicName, 1000);
|
Tip
一些规律的掌握,消息类型为geometry_msgs/Twist
,需要导入的头文件为geometry_msgs/Twist.h
,需要确定的编码类型为geometry_msgs::Twist
3. 发送消息
| //创建消息
geometry_msgs::Twist twist;
//填充消息数据
twist.linear.x = linearX;
twist.angular.z = angularZ * M_PI / 180;
//发送消息
publisher->publish(twist);
|
完整实例代码
MainWindow1.h
MainWindow1.cpp
turtle_ctrl1.cpp