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

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