面向对象C++实现
Subscriber整合
1. 添加subscriber创建
| //初始化subscriber
string poseTopicName = "/turtle1/pose";
subscriber = node->subscribe(poseTopicName, 1000, &MainWindow2::poseCallback, this);
|
2. 添加订阅回调
| void MainWindow2::poseCallback(const turtlesim::Pose::ConstPtr &message) {
count << "callback" << endl;
}
|
问题与解决
调试过程中,发现无法订阅导数据。
原因是在于,QT
维护了一套主线程和子线程通讯的机制。而ROS
也维护了一套,而且他们同时都是往主线程中发送消息,导致主线程阻塞。
- QT发送的是界面渲染的消息
- ROS发送的是订阅回调消息
解决方式一
将 ROS发送订阅回调消息的响应线程修改为非主线程。
实现代码:
| //开启一个异步的轮询器
ros::AsyncSpinner spinner(1);
spinner.start();
|
解决方式二
QT渲染过程中同时也去接收ROS的订阅回调消息。接管QT的渲染机制。
| updateTimer = new QTimer(this);
updateTimer->setInterval(16);
updateTimer->start();
connect(updateTimer, &QTimer::timeout, this, &MainWindow2::onUpdate);
|
渲染与接收逻辑:
| void MainWindow2::onUpdate() {
ros::spinOnce();
update();
if (!ros::ok()) {
close();
}
}
|
完整实例代码
MainWindow2.h
MainWindow2.cpp
turtle_ctrl2.cpp