1 安裝QT-ROS插件
本插件在安裝過程中自行安裝QT,無需額外安裝。
1.1 Ubuntu16.04 安裝步驟
打開Terminal,輸入:
sudo add-apt-repository ppa:levi-armstrong/qt-libraries-xenial
sudo add-apt-repository ppa:levi-armstrong/ppa
sudo apt-get update && sudo apt-get install qt57creator-plugin-ros
可能需要刪除舊的PPA:
sudo add-apt-repository --remove ppa:beineri/opt-qt57-xenial
sudo add-apt-repository --remove ppa:beineri/opt-qt571-xenial
如果您收到錯誤,請手動刪除它:
sudo rm /etc/apt/sources.list.d/beineri-opt-qt57-xenial-xenial.list
sudo rm /etc/apt/sources.list.d/beineri-opt-qt571-xenial-xenial.list
1.2 測試插件
由於插件的更新,不需要安裝qtcreator,插件自己依賴安裝。
安裝完成後在指令行輸入qt,按Tab鍵看自己安裝的。如圖:
然後輸入存在的qtcreatot-ros回車,qtcreator就啓動了,就會看到有關於ros的創建選項了。如圖:
安裝有問題可以借鑑:
- http://blog.csdn.net/zhangrelay/article/details/52068657
- http://blog.csdn.net/u013453604/article/details/52186375
- http://blog.csdn.net/qq_30460905/article/details/79034633
2 使用QT編寫ROS程序
2.1 實現步驟
- Terminal新建工作空間catkin_qt,並創建src文件夾
mkdir -p catkin_qt/src
- Terminal運行插件
qtcreator-ros
然後點擊New Project,命名爲catkin_qt(工程名稱),選擇第一步新建的功能包路徑catkin_qt,點擊Next,Finish。
這樣新建的ROS.workspace就在新建的文件夾路徑下了。文件夾內如圖所示:
- 創建測試包rostest
在QT界面下,打開工程目錄,右鍵選擇src文件夾,在當前路徑下打開Terminal並創建測試功能包:
catkin_create_qt_pkg rostest
注意:需要預先安裝建包工具:
sudo apt-get install ros-kinetic-qt-ros
注意catkin_qt/devel/setup.bash路徑添加到bash文件中
- 修改運行設置
點擊Projects,選擇Run選型,添加Add Run Step選項,Package和Target選項都選爲新建的rostest,如圖所示
- 設計UI
在UI界面拖放幾個按鈕,右鍵更改Text名稱爲up,down,left,right
然後右鍵Go to slot…
選擇clicked()
這樣就新建了4個按鍵點擊事件,如圖所示:
- 添加控制函數
打開主窗口qnode.hpp,註釋void run(),並添加代碼前進後退左轉右轉指令,如圖所示:
然後寫qnode.cpp文件,主要是一處頭文件,兩處ros通信程序,以及四個控制函數的修改。
/**
* @file /src/qnode.cpp
*
* @brief Ros communication central!
*
* @date February 2011
**/
/*****************************************************************************
** Includes
*****************************************************************************/
#include <ros/ros.h>
#include <ros/network.h>
#include <string>
#include <std_msgs/String.h>
#include <geometry_msgs/Twist.h> //添加的地方
#include <sstream>
#include "../include/rostest/qnode.hpp"
/*****************************************************************************
** Namespaces
*****************************************************************************/
namespace rostest {
/*****************************************************************************
** Implementation
*****************************************************************************/
QNode::QNode(int argc, char** argv ) :
init_argc(argc),
init_argv(argv)
{}
QNode::~QNode() {
if(ros::isStarted()) {
ros::shutdown(); // explicitly needed since we use ros::start();
ros::waitForShutdown();
}
wait();
}
bool QNode::init() {
ros::init(init_argc,init_argv,"rostest");
if ( ! ros::master::check() ) {
return false;
}
ros::start(); // explicitly needed since our nodehandle is going out of scope.
ros::NodeHandle n;
// Add your ros communications here.
//添加的地方
chatter_publisher = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1000);
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,"rostest");
if ( ! ros::master::check() ) {
return false;
}
ros::start(); // explicitly needed since our nodehandle is going out of scope.
ros::NodeHandle n;
// Add your ros communications here.
//添加的地方
chatter_publisher = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1000);
start();
return true;
}
/*註釋run()
void QNode::run() {
ros::Rate loop_rate(1);
int count = 0;
while ( ros::ok() ) {
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
chatter_publisher.publish(msg);
log(Info,std::string("I sent: ")+msg.data);
ros::spinOnce();
loop_rate.sleep();
++count;
}
std::cout << "Ros shutdown, proceeding to close the gui." << std::endl;
Q_EMIT rosShutdown(); // used to signal the gui for a shutdown (useful to roslaunch)
}
*/
//---------------------主要添加的程序--------------------------------
void QNode::up()
{
ros::Rate loop_rate(1);
if( ros::ok() )
{
geometry_msgs::Twist msg;
msg.linear.x = 1.0;
msg.angular.z = 0.0;
chatter_publisher.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
}
void QNode::down()
{
ros::Rate loop_rate(1);
if( ros::ok() )
{
geometry_msgs::Twist msg;
msg.linear.x = -1.0;
msg.angular.z = 0.0;
chatter_publisher.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
}
void QNode::left()
{
ros::Rate loop_rate(1);
if( ros::ok() )
{
geometry_msgs::Twist msg;
msg.linear.x = 0.0;
msg.angular.z = 1.0;
chatter_publisher.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
}
void QNode::right()
{
ros::Rate loop_rate(1);
if( ros::ok() )
{
geometry_msgs::Twist msg;
msg.linear.x = 0.0;
msg.angular.z = -1.0;
chatter_publisher.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
}
//--------------------------------------------------------------------
void QNode::log( const LogLevel &level, const std::string &msg) {
logging_model.insertRows(logging_model.rowCount(),1);
std::stringstream logging_model_msg;
switch ( level ) {
case(Debug) : {
ROS_DEBUG_STREAM(msg);
logging_model_msg << "[DEBUG] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Info) : {
ROS_INFO_STREAM(msg);
logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Warn) : {
ROS_WARN_STREAM(msg);
logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Error) : {
ROS_ERROR_STREAM(msg);
logging_model_msg << "[ERROR] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Fatal) : {
ROS_FATAL_STREAM(msg);
logging_model_msg << "[FATAL] [" << ros::Time::now() << "]: " << msg;
break;
}
}
QVariant new_row(QString(logging_model_msg.str().c_str()));
logging_model.setData(logging_model.index(logging_model.rowCount()-1),new_row);
Q_EMIT loggingUpdated(); // used to readjust the scrollbar
}
} // namespace rostest
把控制函數添加進按鈕觸發函數中(設計UI的那四個按鍵函數)
如圖所示:
- 編譯運行
可以在運行設置Turtlesim_node,如圖所示:
然後點擊小錘子編譯,完成編譯。
- 若main_window.hpp出現按鈕事件函數聲明錯誤:‘slots’ does not name a type
可將private slots:改爲 private Q_SLOTS:
主要是因爲編譯器c++和ros編譯器識別不同type。
2.2 測試QT程序
1.啓動roscore
2.運行qt程序
3.勾選環境變量按鈕,點擊connect連接
4.使用按鍵進行控制小烏龜
3 參考資料
參考資料:
https://blog.csdn.net/weixin_43377151/article/details/84306914
https://blog.csdn.net/qq_39989653/article/details/79189605
https://blog.csdn.net/LOVE1055259415/article/details/80575432
此部分代碼已上傳github:
https://github.com/ShuaiWang-Code/ROS-ROBOT/tree/master/QT-ROS