ros線程下使用Qt的socket(tcp)或者更好的解決方式

因爲ros的action和service都是單獨運行在線程裏,所以想在action中調用qt的tcp不是發不出去數據就是接收不到數據。這裏經過測試,發現可以如下修改使用,不過不建議這樣用,是因爲軟件架構沒有設計好纔出此下策。
如下

    Q_EMIT tcpSendMsg();

    tcpClient_->waitForReadyRead(5);
    
        while(i--)
    {
        msDelay(10);

        while(tcpClient_->bytesAvailable()>0)
        {
            QByteArray datagram;
            datagram.resize(tcpClient_->bytesAvailable());
            tcpClient_->read(datagram.data(),datagram.size());

            QString rcvMsg  = QString::fromUtf8(datagram,datagram.size());

            //if(datagram.at(0) == 'O')
            //{
            std::string x_value,y_value,angle;

            x_value = get_du_string(datagram,0);
            y_value = get_du_string(datagram,13);
            angle = get_du_string(datagram,26);

            std::string final_data;

            final_data = x_value + "," + y_value + "," + angle;

            recv_data = QString(final_data.c_str());

            return true;

        }
    }

在線程和主線程通過信號槽機制,讓主線程發送數據,當然tcpsocket對象是在主線程實例化的,然後通過指針傳遞給工作線程(即ros的線程), tcpClient_->waitForReadyRead(5);這一句非常關鍵,還有參數5一定要寫,5代表5秒後函數返回,不然函數會阻塞在這裏,導致數據接收錯亂。
好了,把其他代碼也放在這裏

    QObject::connect(&qnode, SIGNAL(tcpSendMsg()), this, SLOT(ui_tcpSendMsg()));
void MainWindow::ui_tcpSendMsg()
{
    //send data to vision server
    QByteArray datagram;
    //datagram = send_data.toUtf8();

    QString order = "54 31 0d 0a";

    //change to hex str;
    QStringList hexStr = order.split(" ",QString::SkipEmptyParts);
    int hexSize = hexStr.size();
    for(int i=0;i<hexSize;i++){
        QString hexSubStr = hexStr.at(i);
        datagram.append(ConvertHexStr(hexSubStr));
    }
    datagram.resize(hexSize);

    if(datagram.size()==0)   return;
    tcpClientSocket->write(datagram.data(), datagram.size());

}

難道要這麼痛苦的用以上這種方式嗎?當然不是,發現一個開源的夾爪包,自己用系統的socket進行通訊,是完全沒有像qt這樣的問題,而且他有串口和網絡通訊2種方式,對於像我這樣的小白再好不過的學習教程。另他還有端口綁定腳本,真是不錯
分享如下:
https://github.com/MRwangmaomao/dh_hand_driver

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章