1. 程式人生 > >qt學習之qt介面控制小烏龜運動(二)

qt學習之qt介面控制小烏龜運動(二)

PS:小編也是新手,在做介面時也走了很多彎路,很多博主寫的不是很明確,所以小編記錄了自己製作的全過程,希望對初學者有用,共同進步。
1.新建工作空間catkin_new,並建立src包,。
2.新建ROS workspace ,儲存在src資料夾內,開啟工程是直接開啟是src下的CMakelist。
3.src目錄右鍵開啟terminal利用命令catkin_create_qt_pkg btn 建立包,並編譯。
4.然後點選project->run,新增節點如圖:
在這裡插入圖片描述
倘若沒有btn檔案,用小錘子編譯再編譯一下,就有了。
5.在4的同時,可以不要btn,直接開啟turtlesim中的node和key,然後點選執行,就可以案件控制小烏龜了
6.介面控制小烏龜程式:
(1)在UI介面拖放幾個按鈕

,並改名字,右擊按鈕轉到槽,在主視窗main_window.cpp檔案中寫入qnode.up();(因為qnode裡面定義的是up和left),另一按鈕同理。
void btn::MainWindow::on_pushButton_clicked()
{
qnode.up();
}
void btn::MainWindow::on_pushButton_2_clicked()
{
qnode.down();
}
void btn::MainWindow::on_pushButton_3_clicked()
{
qnode.left();
}
void btn::MainWindow::on_pushButton_4_clicked()
{
qnode.right();
}
(2)在qnode.hpp中新增:

void up();
void down();
void left();
void right();
(3)主要的是qnode.cpp檔案,首先在標頭檔案中定義:
/**

  • @file /src/qnode.cpp

  • @brief Ros communication central!

  • @date February 2011
    /
    /
    ***************************************************************************
    ** Includes
    /
    #include <ros/ros.h>
    #include <ros/network.h>
    #include
    #include <std_msgs/String.h>
    #include <geometry_msgs/Twist.h>
    #include
    #include “…/include/btn/qnode.hpp”
    /


    ** Namespaces
    /
    namespace btn {
    /
    *
    ** 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,“btn”);
    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", 1);
    start();
    return true;
    }
    bool QNode::init(const std::string &master_url, const std::string &host_url) {
    std::mapstd::string,std::string remappings;
    remappings["__master"] = master_url;
    remappings["__hostname"] = host_url;
    ros::init(remappings,“btn”);
    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", 1);
    start();
    return true;
    }
    /*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::NodeHandle n;
    chatter_publisher=n.advertise<geometry_msgs::Twist>(”/turtle1/cmd_vel”, 1);
    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::NodeHandle n;
    chatter_publisher=n.advertise<geometry_msgs::Twist>(”/turtle1/cmd_vel", 1);
    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::NodeHandle n;
    chatter_publisher=n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1);
    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();
    

    }
    //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::right() {
    ros::NodeHandle n;
    chatter_publisher=n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1);
    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();
    }
    //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::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 btn

一定要修改話題型別和釋出的話題,否則不會驅動。
(4)在main_window.cpp檔案:
/**

  • @file /src/main_window.cpp
  • @brief Implementation for the qt gui.
  • @date February 2011
    /
    /
    ***************************************************************************
    ** Includes
    /
    #include
    #include
    #include
    #include “…/include/btn/main_window.hpp”
    /

    ** Namespaces
    /
    namespace btn {
    using namespace Qt;
    /

    ** Implementation [MainWindow]
    *****************************************************************************/
MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
QMainWindow(parent)
, qnode(argc,argv)
{
ui.setupUi(this); // Calling this incidentally connects all ui’s triggers to on_…() callbacks in this class.
QObject::connect(ui.actionAbout_Qt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt())); // qApp is a global variable for the application
ReadSettings();
setWindowIcon(QIcon(":/images/icon.png"));
ui.tab_manager->setCurrentIndex(0); // ensure the first tab is showing - qt-designer should have this already hardwired, but often loses it (settings?).
QObject::connect(&qnode, SIGNAL(rosShutdown()), this, SLOT(close()));
/*********************
** Logging
*/
ui.view_logging->setModel(qnode.loggingModel());
QObject::connect(&qnode, SIGNAL(loggingUpdated()), this, SLOT(updateLoggingView()));
/

** Auto Start
**********************/
if ( ui.checkbox_remember_settings->isChecked() ) {
on_button_connect_clicked(true);
}
}
MainWindow::~MainWindow() {}

/*****************************************************************************
** Implementation [Slots]
*****************************************************************************/

void MainWindow::showNoMasterMessage() {
QMessageBox msgBox;
msgBox.setText(“Couldn’t find the ros master.”);
msgBox.exec();
close();
}
/*

  • These triggers whenever the button is clicked, regardless of whether it
  • is already checked or not.
    /
    void MainWindow::on_button_connect_clicked(bool check ) {
    if ( ui.checkbox_use_environment->isChecked() ) {
    if ( !qnode.init() ) {
    showNoMasterMessage();
    } else {
    ui.button_connect->setEnabled(false);
    }
    } else {
    if ( ! qnode.init(ui.line_edit_master->text().toStdString(),
    ui.line_edit_host->text().toStdString()) ) {
    showNoMasterMessage();
    } else {
    ui.button_connect->setEnabled(false);
    ui.line_edit_master->setReadOnly(true);
    ui.line_edit_host->setReadOnly(true);
    ui.line_edit_topic->setReadOnly(true);
    }
    }
    }
    void MainWindow::on_checkbox_use_environment_stateChanged(int state) {
    bool enabled;
    if ( state == 0 ) {
    enabled = true;
    } else {
    enabled = false;
    }
    ui.line_edit_master->setEnabled(enabled);
    ui.line_edit_host->setEnabled(enabled);
    //ui.line_edit_topic->setEnabled(enabled);
    }
    /
    ****************************************************************************
    ** Implemenation [Slots][manually connected]
    ***************************************************************************/
    /
  • This function is signalled by the underlying model. When the model changes,
  • this will drop the cursor down to the last line in the QListview to ensure
  • the user can always see the latest log message.
    /
    void MainWindow::updateLoggingView() {
    ui.view_logging->scrollToBottom();
    }
    /
    ****************************************************************************
    ** Implementation [Menu]
    /
    void MainWindow::on_actionAbout_triggered() {
    QMessageBox::about(this, tr(“About …”),tr(“

    PACKAGE_NAME Test Program 0.10

    Copyright Yujin Robot

    This package needs an about description.

    ”));
    }
    /
    ** Implementation [Configuration]
    *****************************************************************************/
    void MainWindow::ReadSettings() {
    QSettings settings(“Qt-Ros Package”, “btn”);
    restoreGeometry(settings.value(“geometry”).toByteArray());
    restoreState(settings.value(“windowState”).toByteArray());
    QString master_url = settings.value(“master_url”,QString(“http://192.168.1.2:11311/”)).toString();
    QString host_url = settings.value(“host_url”, QString(“192.168.1.3”)).toString();
    //QString topic_name = settings.value(“topic_name”, QString("/chatter")).toString();
    ui.line_edit_master->setText(master_url);
    ui.line_edit_host->setText(host_url);
    //ui.line_edit_topic->setText(topic_name);
    bool remember = settings.value(“remember_settings”, false).toBool();
    ui.checkbox_remember_settings->setChecked(remember);
    bool checked = settings.value(“use_environment_variables”, false).toBool();
    ui.checkbox_use_environment->setChecked(checked);
    if ( checked ) {
    ui.line_edit_master->setEnabled(false);
    ui.line_edit_host->setEnabled(false);
    //ui.line_edit_topic->setEnabled(false);
    }
    }
    void MainWindow::WriteSettings() {
    QSettings settings(“Qt-Ros Package”, “btn”);
    settings.setValue(“master_url”,ui.line_edit_master->text());
    settings.setValue(“host_url”,ui.line_edit_host->text());
    //settings.setValue(“topic_name”,ui.line_edit_topic->text());
    settings.setValue(“use_environment_variables”,QVariant(ui.checkbox_use_environment->isChecked()));
    settings.setValue(“geometry”, saveGeometry());
    settings.setValue(“windowState”, saveState());
    settings.setValue(“remember_settings”,QVariant(ui.checkbox_remember_settings->isChecked()));
    }
    void MainWindow::closeEvent(QCloseEvent *event)
    {
    WriteSettings();
    QMainWindow::closeEvent(event);
    }
    }
    //namespace btn
    void btn::MainWindow::on_pushButton_clicked()
    {
    qnode.up();
    }
    void btn::MainWindow::on_pushButton_2_clicked()
    {
    qnode.down();
    }
    void btn::MainWindow::on_pushButton_3_clicked()
    {
    qnode.left();
    }
    void btn::MainWindow::on_pushButton_4_clicked()
    {
    qnode.right();
    }

最後,編譯執行就可以了,(首先在project加入turtlesim小烏龜的節點,然後啟動roscore歐)。點選connect連線,就可以按鍵控制了。

PS:1、標頭檔案包含問題:

用外掛建立或匯入ROS package之後還需要修改.workspace檔案,

在標籤下加入下面這行

/opt/ros/indigo/include
1
這樣就可以使得Qt找到ros標頭檔案,比如<ros/ros.h>
加入:

/opt/ros/kinetic/include

**2.connect前一定要、一定要在use environment variable前打鉤或者輸入ROS IP。

相關推薦

qt學習qt介面控制烏龜運動

PS:小編也是新手,在做介面時也走了很多彎路,很多博主寫的不是很明確,所以小編記錄了自己製作的全過程,希望對初學者有用,共同進步。 1.新建工作空間catkin_new,並建立src包,。 2.新建ROS workspace ,儲存在src資料夾內,開啟工程是直

Qt總結七:QPaintEvent繪製雷達圖

前言 這裡使用另一套框架寫的雷達掃描圖 這裡PaintEvent事件比上一個版本寫的好,但是不喜歡Widget巢狀的方式,後續會把兩個版本整合到一起。  一、實現原理 雷達效果包括三個部分:背景、轉動的扇形和閃爍的點。  (1)背景的實現很簡單

Pthon學習路 第四篇 Python基礎

pri bsp programs -s alt 如果 lex class 算數運算 1.運算符:+ - *(乘法) /(除法) %(求余) //(求商) **(求冪) 2.成員運算:in not in:判斷單個字符或者子序列在不在字符串中。(n

Spring學習Spring三種裝配機制:顯示裝配bean

  今天我們介紹一下Spring三種裝配機制中的另外兩種裝配方式:JavaConfig和XML配置,這兩種方式區別於自動化裝配方式都屬於顯示裝配。 1、Java程式碼裝配bean 首先,我們通過在Config類中使用@Bean註解來宣告bean; @Bean註

深度學習卷積神經網路程式設計實現

void conv_bprop(Layer *layer, Layer *prev_layer, bool *pconnection) { int index = 0; int size = prev_layer->map_w * prev_layer->map_h; // delta

Vue學習原始碼分析--Vue.js依賴收集

為什麼要依賴收集 先看下面這段程式碼 new Vue({ template: `<div> <span>text1:</span> {{text1}}

Qt學習路十三—— 再談TCP/IP多客戶端連線伺服器

一、TCP和UDP的區別這裡我會用一個表格來顯示這兩者的區別比較項TCPUDP是否連線面向連線無連線傳輸是否可靠可靠不可靠流量控制提供不提供工作方式全雙工可以是全雙工應用場合大量資料少量資料速度慢快二、incomingConnection函式這個函式和之前講過的newConn

學習路,網絡編程

多人 困難 get err lose imp 出現 popen one 一,socket進階 在前面的博客中講到了一些基本的計算機網絡知識,有一點也是為我在要考傳輸與交換看到一個題,然後就看到說ARP屬於網絡層,因為ARP協議跟網絡相關,但是我前面的博客說的是ARP協議屬於

JavaScript學習白篇

好好學習 ,天天向上。Are you ready? --------------------if swich語句------------------ 一、程式中流程控制有哪些結構? 1. 順序結構 : 從上到下,依次執行每一條語句,不允許跳過任何一條語句。 2. 選擇結構 : 根據條

QT控制元件精講單元檢視Item Views

    Qt Creator有4種Item Views。如圖     View Widget的Qt類和名稱介紹如下表:     控制元件類     控制元件名 &nb

學習安全測試——httrack的安裝和使用

type mas track base launch 驗證 解決方案 我沒 ted httrack是一款免費的網站鏡像程序,簡單理解就是可以在網站結構(網頁及一些主要信息文件),下載到本地,可離線瀏覽,我是按照搭建成功後的console直譯過來的 下面說下安裝: 我都是在L

selenium 時間日期控制元件的處理

我們不去搞時間日期空間,我們把它當成一個普通的input框處理就好了! 但是,很多此型別input框都是禁止手動輸入的,怎麼辦? 很簡單,用js把禁止輸入的readonly屬性幹掉就好了。 來吧,看一下示例: 示例網址:http://www.sucaijiayuan.com/api/demo.php?

zigbee ZStack-2.5.1a原始碼分析 無線接收控制LED

本文描述ZStack-2.5.1a 模板及無線接收移植相關內容。 main HAL_BOARD_INIT // HAL_TURN_OFF_LED1 InitBoard HalDriverInit HalAdcInit

Java學習路 第五章 面向物件1

面向物件(1) 1、認識物件 (1)萬物皆物件。 (2)物件=特點或特徵(屬性)+行為或(方法)。 (3)物件由屬性和方法組成,一定要具體到個體上。 2、認識類 (1)類是一些具有共同屬性和方法的物件的一個抽象。 (2)類是一個概念,不是具體的一個物件。 (3)

一起學Netty十八netty原始碼學習netty server端原始碼初讀

server端是使用了Reactor模式對nio進行了一些封裝,Reactor模式網上有很多資料,不贅述,瞭解了這個模式開始看原始碼 netty的版本是4.0.21.Final <dependency> <groupId>io.netty<

基於QT的多執行緒視訊監控的實現

二丶接著上一節,這節主要講,多屏分割,多屏相互切換   視訊監控很重要的一個環節就是多屏切換了,這裡主要實現的是 1,2,4,8,16,32,64 分屏的相互切換,最多是64分屏。(1)QT 常用到的佈

ABP框架理論學習後臺工作(Jobs)和後臺工作者Workers

返回總目錄 本篇目錄 介紹 ABP提供了後臺工作和後臺工作者,它們會在應用程式的後臺執行緒中執行一些任務。 後臺工作 後臺工作以佇列和持續的方式在後臺給一些即將被執行的任務排隊。你可能因為某些原因需要後臺工作,比如: 執行長時間執行的任務。比如,一個使用者按了“report”按鈕來啟動一個長時間執行的報

UIView詳解十:控制元件改變座標系convertRect:

一、示例 如下圖所示,橙色view是藍色view的子控制元件,藍色view是綠色view的子控制元件。由於橙色view的frame是參考藍色view的,因此,如果需要獲取橙色view相對於綠色view的位置,就必須進行座標系的轉換。 二、實現方法 UIView類中提供瞭如下四個方法,可以改變座標系

Netty netty原始碼學習netty server端原始碼初讀

上一篇簡單的分析了一下NioEventLoop,ServerBootstrap等元件的建立過程做的一些操作 現在我們一起看下當SingleThreadEventExecutor.java中的thread啟動後,netty做的一些最最重要的一些操作 我們接著昨天的程

ROS學習tf.3編寫一個tf接收器C++

ROS.tf3編寫一個tf接收器(C++)宣告:本教程來自於ROS.WIKI,本人在整理過程中可能出現一些錯誤和問題,有問題可以去檢視官網版本也可以諮詢本人在之前的教程中,我們建立了一個tf廣播公司向tf釋出一隻烏龜的姿勢。 在本教程中,我們將建立一個tf接收器來開始使用tf