面向对象C++实现

Subscriber整合

1. 添加subscriber创建

1
2
3
//初始化subscriber
string poseTopicName = "/turtle1/pose";
subscriber = node->subscribe(poseTopicName, 1000, &MainWindow2::poseCallback, this);

2. 添加订阅回调

1
2
3
void MainWindow2::poseCallback(const turtlesim::Pose::ConstPtr &message) {
    count << "callback" << endl;
}

问题与解决

调试过程中,发现无法订阅导数据。

原因是在于,QT维护了一套主线程和子线程通讯的机制。而ROS也维护了一套,而且他们同时都是往主线程中发送消息,导致主线程阻塞。

  • QT发送的是界面渲染的消息
  • ROS发送的是订阅回调消息

解决方式一

将 ROS发送订阅回调消息的响应线程修改为非主线程。

实现代码:

1
2
3
//开启一个异步的轮询器
ros::AsyncSpinner spinner(1);
spinner.start();

解决方式二

QT渲染过程中同时也去接收ROS的订阅回调消息。接管QT的渲染机制。

1
2
3
4
5
updateTimer = new QTimer(this);
updateTimer->setInterval(16);
updateTimer->start();

connect(updateTimer, &QTimer::timeout, this, &MainWindow2::onUpdate);

渲染与接收逻辑:

1
2
3
4
5
6
7
8
void MainWindow2::onUpdate() {
  ros::spinOnce();
  update();

  if (!ros::ok()) {
    close();
  }
}

完整实例代码

MainWindow2.h

MainWindow2.cpp

turtle_ctrl2.cpp