使用Qt界面加载ROS库嵌入Rviz,显示加载保存点云PCL

使用Qt界面加载ROS库嵌入Rviz,显示加载保存点云PCL

  • 在Qt中加载ROS库
  • Qt界面中启动ROS
  • 嵌入Rviz,并显示点云,载入与保存PCD文件

在Qt中加载ROS库

本文使用Qt4.9.2,首先打开Qt软件,新建一个Qt界面工程。
使用Qt界面加载ROS库嵌入Rviz,显示加载保存点云PCL_第1张图片
建立成功后我们打开.pro文件,在其中加入下面几句话:

INCLUDEPATH += /opt/ros/melodic/include \
               /usr/include/pcl-1.8 \
               /usr/include/eigen3 \
               /usr/include/vtk-6.3

LIBS += /opt/ros/melodic/lib/lib*.so
LIBS += /usr/lib/x86_64-linux-gnu/libpcl_*.so
LIBS += /usr/lib/x86_64-linux-gnu/libvtk*.so

其中melodic替换成各位自己的ROS版本名称,以及PCL、Eigen、vtk等库的版本都替换成各位本机的版本。
配置好后各位可以试下能否编译通过。
如果出现编译无法通过,或者出现一些ROS有关库没有到,可能的原因是应为在启动Qt的时候并没有加擦ROS环境变量,解决办法,在Qt的.desktop文件中加入bash -i -c 命令启动,或者通过命令行启动qtcreate
至此,在Qt界面环境中引入ROS库已完成。

Qt界面中启动ROS

首先在工程中新建两个新文件,命名为qnode.hqnode.cpp,如下图:
使用Qt界面加载ROS库嵌入Rviz,显示加载保存点云PCL_第2张图片
之后我们在qnode.h中加入如下代码:

#ifndef QNODE_H
#define QNODE_H

#include <ros/ros.h>
#include <std_msgs/Int32.h>
#include <std_msgs/Bool.h>
#include <QThread>

#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/conversions.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/conversions.h>
#include <boost/thread.hpp>
#include <pthread.h>

namespace lzy {

class QNode : public QThread
{
    Q_OBJECT
public:
    QNode(int argc, char **argv);
    virtual ~QNode();
    bool init();
    bool init(const std::string &master_url, const std::string &host_url);
    void run();
    
Q_SIGNALS:
    void RosShutdown();

private:
    int init_argc_;
    char **init_argv_;
};
}  // namespace lzy
#endif  // QNODE_H

qnode.cpp文件中加入如下代码:

#include "qnode.h"

namespace lzy {

QNode::QNode(int argc, char **argv)
    : init_argc_(argc)
    , init_argv_(argv)
{
}

QNode::~QNode()
{
    if (ros::isStarted())
    {
        ros::shutdown();
        ros::waitForShutdown();
    }
    wait();
}

bool QNode::init()
{
    ros::init(init_argc_, init_argv_, "qt_slam_ui_node");
    if (!ros::master::check())
    {
        return false;
    }
    ros::start();
    ros::NodeHandle nh;
    start();
    return true;
}

bool QNode::init(const std::string &master_url, const std::string &host_url)
{
    std::map<std::string, std::string> remappings;
    remappings["__master"]   = master_url;
    remappings["__hostname"] = host_url;
    ros::init(remappings, "qt_slam_ui_node");
    if (!ros::master::check())
    {
        return false;
    }

    ros::start();  // explicitly needed since our nodehandle is going out of scope.
    ros::NodeHandle nh;
    start();
    return true;
}

void QNode::run()
{
    ros::spin();
    Q_EMIT RosShutdown();
}
}  // namespace lzy

更改main.cpp文件如下:

#include "mainwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWidget w(argc, argv);
    w.show();

    return a.exec();
}

mainwidget.h文件加入声明:

 lzy::QNode qnode_;

在mianwidget.cpp中加入:

MainWidget::MainWidget(int argc, char **argv, QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainWidget)
    , qnode_(argc, argv)
    {
      ui->setupUi(this);
      connect(&qnode_, SIGNAL(RosShutdown()), this, SLOT(close()));
    }
    
void MainWidget::ShowNoMasterMessage()
{
    QMessageBox msgBox;
    msgBox.setText("Couldn't find the ros master.");
    msgBox.exec();
    // close();
}

然后在ui界面中添加一个按钮,在槽中调用qnode.init()函数便可以启动node节点。
在启动node节点前程序会校验roscore是否启动,所以需要先启动roscore才可以启动程序。

嵌入Rviz,并显示点云,载入与保存PCD文件

这部分改天更新,先给大家看下效果图。
使用Qt界面加载ROS库嵌入Rviz,显示加载保存点云PCL_第3张图片

你可能感兴趣的:(ROS,Qt,qt,ubuntu,c++)