在看此篇博文前,请先参考我的上一篇博文https://blog.csdn.net/qq_42263553/article/details/102491415
在按照 我的上篇博文完成之后再进行下面的操作。
我们知道Rviz,我们也经常拿它做2D或者3D可视化,但有时候项目需要我们自己动手写一个类似Rviz的上位机,Rviz就是用Qt写的,我们也理所当然可以用Qt去模拟Rviz的功能。
参考博文:
https://blog.csdn.net/menglanzeng/article/details/83824808
https://blog.csdn.net/qq_30460905/article/details/79210300
这是最关键的一步,需要在之前创建好的Qt-ROS工程中修改这两个文件,因为kinetic的rviz是基于qt5,而indigo上的rviz是基于qt4(后来才发现),所以直接将对于indigo版本的librviz tutorial 移到kinetic下是肯定不行的,所以又去github上找到对应kinetic的教程,原来在CMakeLists.txt文件中加上了判断rviz_QT_VERSION,所以要用qt5的库来编译。要想在带qt界面的ros项目里面调用librviz的关键就是更改CMakeLists.txt文件中的Qt库为Qt5。
注意看added和deleted,对应自己的CMakeLIsts.txt文件进行修改
cmake_minimum_required(VERSION 2.8.0)
project(testgui)
set(CMAKE_INCLUDE_CURRENT_DIR ON)#added
find_package(catkin REQUIRED COMPONENTS roscpp rviz)#deleted qt_build added rviz
find_package(Qt5 REQUIRED Core Widgets)#added
set(QT_LIBRARIES Qt5::Widgets)#added
include_directories(${catkin_INCLUDE_DIRS})
catkin_package()
#rosbuild_prepare_qt4(QtCore QtGui) #deleted
file(GLOB QT_FORMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ui/*.ui)
file(GLOB QT_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} resources/*.qrc)
file(GLOB_RECURSE QT_MOC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} FOLLOW_SYMLINKS include/testgui/*.hpp *.h)#added *.h
QT5_ADD_RESOURCES(QT_RESOURCES_CPP ${QT_RESOURCES})
QT5_WRAP_UI(QT_FORMS_HPP ${QT_FORMS})
QT5_WRAP_CPP(QT_MOC_HPP ${QT_MOC}) #change QT4 to QT5
file(GLOB_RECURSE QT_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} FOLLOW_SYMLINKS src/*.cpp)
add_executable(testgui ${QT_SOURCES} ${QT_RESOURCES_CPP} ${QT_FORMS_HPP} ${QT_MOC_HPP})
target_link_libraries(testgui ${QT_LIBRARIES} ${catkin_LIBRARIES})
install(TARGETS testgui RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
#deleted
#qt_build
# libqt4-dev
# qt_build
# libqt4-dev
#added
rviz
rviz
qtbase5-dev
libqt5-core
libqt5-gui
libqt5-widgets
从这里就开始测试咯
这个就不说啦,先创建这个事件,函数里面的内容稍后再写。
在工程中创建一个设计师类,先放在src文件夹下,然后再手动将其他文件(.h和.ui文件)移动到其他文件夹内。我创建的这个设计师类名字是testrviz。
创建好之后记得要先将其他文件移动到指定文件夹内,然后在Qt中就会刷新。
初始是#include"testrviz.h"
,我们要修改成与Qt工作空间相符的路径,如图
修改成#include "../include/testgui/testrviz.h"
这个是一定得删除的,否则无法编译通过。
删除之后,再在QT中点击小锤子进行编译。
如下代码所示:
void testgui::MainWindow::on_pushButton_clicked()
{
TestRviz *test = new TestRviz();
test->show();
}
同样要先在.hpp文件中包含头文件进来,在mainwindow.hpp中不需要那么麻烦,直接
#include "testrviz.h"
即可。
首先需要配置一下运行的节点,切记!!!在运行之前一定要roscore!!!如图所示。
然后点击按钮就可以看到我们添加的设计师类的界面啦。
接下来就要进入正题了——在创建的界面中显示地图。
先在ui中添加一个VerticalLayout布局和一个按钮。如下图:
废话不多说,我们在创建好的设计师类中加上如下代码:
#ifndef TESTRVIZ_H
#define TESTRVIZ_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace Ui {
class TestRviz;
}
class TestRviz : public QWidget
{
Q_OBJECT
public:
explicit TestRviz(QWidget *parent = 0);
~TestRviz();
void ros_init(int argc,char **argv);
private slots:
void on_pushButton_clicked();
private:
Ui::TestRviz *ui;
rviz::VisualizationManager *manager_;
rviz::RenderPanel *render_panel_;
rviz::Display *map_;
};
#endif // TESTRVIZ_H
这里面librviz和ros的重要头文件不能忘
#include
#include
#include
#include
#include
#include
#include
#include "../include/testgui/testrviz.h"
#include "ui_testrviz.h"
TestRviz::TestRviz(QWidget *parent) :
QWidget(parent),
ui(new Ui::TestRviz)
{
ui->setupUi(this);
int argc;
char **argv;
ros_init(argc,argv);
render_panel_=new rviz::RenderPanel;
manager_=new rviz::VisualizationManager(render_panel_);
render_panel_->initialize(manager_->getSceneManager(),manager_);
manager_->initialize();
//manager_->startUpdate();
ui->verticalLayout->addWidget(render_panel_);
}
void TestRviz::ros_init(int argc, char **argv)
{
ros::init(argc,argv,"rosmap",ros::init_options::AnonymousName);
}
TestRviz::~TestRviz()
{
delete ui;
}
void TestRviz::on_pushButton_clicked()
{
manager_->removeAllDisplays();
rviz::Display *map = manager_->createDisplay( "rviz/Map", "adjustable map", true );
map->subProp( "Topic" )->setValue( "/map" );
rviz::Display *robot = manager_->createDisplay( "rviz/RobotModel", "adjustable robot", true );
robot->subProp( "Robot Description" )->setValue( "robot_description" );
rviz::Display *laser = manager_->createDisplay( "rviz/LaserScan", "adjustable scan", true );
laser->subProp( "Topic" )->setValue( "/scan" );
laser->subProp( "Size (m)" )->setValue( "0.1" );
manager_->startUpdate();
}
这是一定得要的,因为在上面的代码中,点击show按钮实际是订阅了map这个topic,然后调用librviz进行地图显示。所以我们要先发布一个map才可以。
map话题无限制,开启了就行。这里我使用的是仿真来进行。首先我开启了一个gazebo仿真环境,然后再运行了move_base算法。如下图所示:
然后我们看看有没有map这个topic,控制台输入
rostopic list
然后我们可以运行我们的工程了,打开Qt,点击运行。
然后再点击viewmap
点击show,就可以看到我们仿真环境中的地图啦!!
其实这就是rviz,在里面我们同样通过快捷键进行导航(G)和定位(P),但可能颁布不同就不能进行导航,但我们可以手动写一个ROSNode,获取地图坐标,然后再进行发布cmd_vel就可以了。
后续我将对我自己写的上位机进行分享,并在下篇博文中对librviz进行更详细的使用。