Skip to content
Snippets Groups Projects
Select Git revision
  • 0518f267a3bf32f7481fcb0faaf2348cf8cda14f
  • master default
  • TEMPORARY_MERGE_PR_576
  • TEMPORARY_MERGE_PR_571
  • TEMPORARY_MERGE_PR_544
  • TEMPORARY_MERGE_PR_563
  • pancetta-patch-8
  • fieldsIO
  • neuralpint
  • TEMPORARY_MERGE_PR_525
  • vtk
  • pancetta-patch-7
  • TEMPORARY_MERGE_PR_502
  • TEMPORARY_MERGE_PR_501
  • TEMPORARY_MERGE_PR_498
  • v6
  • new-release
  • TEMPORARY_MERGE_PR_476
  • TEMPORARY_MERGE_PR_480
  • TEMPORARY_MERGE_PR_478
  • fix_JF
  • v5.6
  • v5.5.3
  • v5.5.2
  • v5.5.1
  • 5.5.0
26 results

compression_convergence_controller.py

Blame
  • ThreadDataTransfert.cpp 14.24 KiB
    /**
     * @file ThreadDataTransfert.cpp
     * @author   Ulrich Kemloh <kemlohulrich@gmail.com>
     * @version 0.1
     * Copyright (C) <2009-2010>
     *
     * @section LICENSE
     * This file is part of OpenPedSim.
     *
     * OpenPedSim is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * any later version.
     *
     * OpenPedSim is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with OpenPedSim. If not, see <http://www.gnu.org/licenses/>.
     *
     * @section DESCRIPTION
     * This class provides a thread utility that is charged of
     * asynchronously receive trajectories (streaming)
     * and  put them in the adequate data structure to be read by the Visualisation Thread.
     *
     * \brief Thread that reads data from the socket and parse it
     *
     *
     *
     *  Created on: 24.05.2009
     *
     */
    
    
    #include <cstdlib>
    #include <iostream>
    #include <limits>
    
    
    #include <QtXml/QtXml>
    #include <QtNetwork/QtNetwork>
    #include <QThread>
    #include <QObject>
    #include <QMessageBox>
    #include <QString>
    
    
    #include "SystemSettings.h"
    #include "ThreadDataTransfert.h"
    #include "SyncData.h"
    #include "Frame.h"
    #include "FrameElement.h"
    
    #include "network/TraVisToServer.h"
    #include "geometry/FacilityGeometry.h"
    #include "general/Macros.h"
    #include "Debug.h"
    
    
    //using namespace std;
    
    
    ThreadDataTransfer::ThreadDataTransfer(QObject *parent):
        QThread(parent)
    {
        m_port=SystemSettings::getListeningPort();
        tcpServer=NULL;
        headerParsed=false;
        errNr=0;
        finished=false;
        //Debug::setDebugLevel(Debug::ALL);
    }
    
    ThreadDataTransfer::~ThreadDataTransfer()
    {
    
    }
    
    void ThreadDataTransfer::shutdown()
    {
        finished=true;
    }
    
    void ThreadDataTransfer::run()
    {
    
        finished=false;
    
        //
        //	std::cerr <<">> starting server" <<std::endl;
        //
        //	//	udpSocket = new QUdpSocket();
        //	//	udpSocket->bind(QHostAddress::LocalHost,SystemSettings::getListeningPort());
        //	//
        //	//	if(!connect(udpSocket, SIGNAL(readyRead()),
        //	//			this, SLOT(slotProcessPendingDatagrams()))){
        //	//		cerr<<"could not create the udp connection"<<endl;
        //	//	}
        //
        //	tcpServer = new QTcpServer(/*this->parent()*/);
        //	if(!connect(tcpServer, SIGNAL(newConnection()), this, SLOT(slotHandleConnection()))){
        //		cerr<<"could not create connection newconnection"<<endl;
        //	}
        //	connect(tcpServer, SIGNAL(error(QAbstractSocket::SocketError)),
        //				this, SLOT(displayError(QAbstractSocket::SocketError)));
        //
        //	if (!tcpServer->listen(QHostAddress::LocalHost,SystemSettings::getListeningPort())) {
        //		cerr<<"\nI can't listen, sorry"<<endl;
        //		QMessageBox::critical(0, tr("TraVisTo Server"),
        //				tr("Unable to start the server: %1.")
        //				.arg(tcpServer->errorString()));
        //		quit();
        //	}
        //
        //	if(tcpServer->isListening ())
        //		cout<<"\nTraVisTo is listening on port "<< tcpServer->serverPort()<<endl;
    
        QString data;
        TraVisToServer* server = new TraVisToServer(SystemSettings::getListeningPort());
        if(!server->isListening()) {
            emit signal_errorMessage("could not connect, make sure that the port is not used by another program.\n "
                                     "Restarting the application may solve the issue!");
            emit signal_controlSequence("CONTROL_RESET");
    
        } else
            do {
                emit signal_CurrentAction("waiting for data");
                server->receiveMessage(data);
    
                if(!data.isEmpty())
                    slotProcessMessage(data);
    
            } while(finished!=true);
    
        server->close();
    }
    
    void ThreadDataTransfer::slotHandleConnection()
    {
    
        Debug::Messages("handling new connection");
    
        QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
        connect(clientConnection, SIGNAL(disconnected()),
                clientConnection, SLOT(deleteLater()));
    
        connect(clientConnection, SIGNAL(readyRead()), this, SLOT(slotReadMessage()));
    
        connect(clientConnection, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(displayError(QAbstractSocket::SocketError)));
        //Q_DECLARE_METATYPE( QAbstractSocket::SocketError );
        Debug::Messages("juhuuuu");
    }
    
    void ThreadDataTransfer::slotReadMessage()
    {
        Debug::Messages("new post");
        //slotProcessMessage();
    }
    
    void ThreadDataTransfer::slotProcessMessage(QString& data)
    {
        QDomDocument doc("");
    
        //data = "<travisto>\n" +data+ "</travisto>";
        //cout<<data.toStdString()<<endl;
    
        QString errorMsg="";
        doc.setContent(data,&errorMsg);
    
        if(!errorMsg.isEmpty()) {
            errNr++;
            //Debug::Error(">> %s",(const char *)errorMsg.toStdString().c_str());
            //Debug::Error(">> %s",(const char *)data.toStdString().c_str());
            return;
        }
    
        QDomNode header =doc.elementsByTagName("header").item(0);
        QDomNode geometry =doc.elementsByTagName("geometry").item(0);
        QDomNode shapes =doc.elementsByTagName("shape").item(0);
    
        QDomNodeList dataList = doc.elementsByTagName("frame");
    
        if(!header.isNull()) {
            parseHeaderNode(header);
            Debug::Messages("header received and parsed");
        }
        if(!shapes.isNull()) {
            parseShapeNode(shapes);
            Debug::Messages("header received and parsed");
        }
    
        if(!geometry.isNull()) {
            //emit signal_loadGeometry(data);
            geoData=data;
            Debug::Messages("geometry received and parsed");
            //parseGeometryNode(geometry);
        }
        if(!dataList.isEmpty()) {
            parseDataNode(dataList);
        }
    
        data.clear();
    }
    
    void ThreadDataTransfer::slotConnectionClosed()
    {
        Debug::Error("connection lost");
    }
    
    
    void ThreadDataTransfer::parseHeaderNode(QDomNode header )
    {
    
    
        emit signal_CurrentAction("parsing new header");
    
        bool ok;
        numberOfAgents = getTagValueFromElement(header, "agents").toInt(&ok);
    
        if(!ok) {
            Debug::Error("The number of agents is invalid");
            Debug::Error("The number must be between 1...65355");
            emit signal_errorMessage("The number of agents is invalid");
            numberOfAgents=1000;
        }
    
        if(numberOfAgents==extern_trajectories_firstSet.getNumberOfAgents()) {
            // only clear
            emit signal_stopVisualisationThread(false);
        } else {
            emit signal_stopVisualisationThread(true);
        }
    
        QString frameRateStr=getTagValueFromElement(header, "frameRate");
        frameRate =frameRateStr.toFloat(&ok);
    
        if(!ok) {
            Debug::Error("The frame rate is invalid");
            Debug::Error("The number must be between 1...1000");
            QMessageBox msgBox;
            msgBox.setText("The frame rate is invalid");
            msgBox.setInformativeText("The number must be between 1...1000,  I will consider 25");
            msgBox.setStandardButtons(QMessageBox::Ok);
            msgBox.setIcon(QMessageBox::Critical);
            msgBox.exec();
            frameRate=25;
        }
    
        //get the header version
        if(header.toElement().hasAttributes()) {
            QString version=header.toElement().attribute("version");
            QStringList query = version.split(".");
            int major=0;
            int minor=0;
            int patch=0;
            switch (query.size() ) {
            case 1:
                major=query.at(0).toInt();
                break;
            case 2:
                major=query.at(0).toInt();
                minor=query.at(1).toInt();
                break;
            case 3:
                major=query.at(0).toInt();
                minor=query.at(1).toInt();
                patch=query.at(2).toInt();
                break;
            }
            InitHeader(major,minor,patch);
            //cout<<"version found:"<<at.value(i).toStdString()<<endl;exit(0);
        }
    
        headerParsed=true;
    }
    
    QString ThreadDataTransfer::getTagValueFromElement(QDomNode node,
            const char * tagName)
    {
        if (node.isNull())
            return "";
        return node.toElement().namedItem(tagName).firstChild().nodeValue();
    
    }
    
    void ThreadDataTransfer::parseDataNode(QDomNodeList frames)
    {
    
        for (int i = 0; i < frames.length(); i++)
        {
            QDomElement el = frames.item(i).toElement();
            QDomNodeList agents = el.elementsByTagName("agent");
            int frame_id=el.attribute("ID").toInt();
            Frame *newFrame = new Frame(frame_id); // TODO: get the right frame id
    
            for (int i = 0; i < agents.length(); i++) {
                bool ok=false;
                int id=agents.item(i).toElement().attribute("ID").toInt(&ok);
                if(!ok) continue; // invalid ID
                double xPos=agents.item(i).toElement().attribute(_jps_xPos,"0").toDouble()*FAKTOR;
                double yPos=agents.item(i).toElement().attribute(_jps_yPos,"0").toDouble()*FAKTOR;
                double zPos=agents.item(i).toElement().attribute(_jps_zPos,"0").toDouble()*FAKTOR;
    
                double dia_a=agents.item(i).toElement().attribute(_jps_radiusA).toDouble(&ok)*FAKTOR;
                if(!ok)dia_a=std::numeric_limits<double>::quiet_NaN();
                double dia_b=agents.item(i).toElement().attribute(_jps_radiusB).toDouble(&ok)*FAKTOR;
                if(!ok)dia_b=std::numeric_limits<double>::quiet_NaN();
                double el_angle=agents.item(i).toElement().attribute(_jps_ellipseOrientation).toDouble(&ok);
                if(!ok) {
                    el_angle=std::numeric_limits<double>::quiet_NaN();
                }
                double el_color=agents.item(i).toElement().attribute(_jps_ellipseColor).toDouble(&ok);
                if(!ok)el_color=std::numeric_limits<double>::quiet_NaN();
    
                double pos[3]= {xPos,yPos,zPos};
                //double vel[3]={xVel,yPos,zPos};
                //double ellipse[7]={el_x,el_y,el_z,dia_a,dia_b,el_angle,el_color};
                //double para[2]={agent_color,el_angle};
                double angle[3]= {0,0,el_angle};
                double radius[3]= {dia_a,dia_b,30.0};
    
                FrameElement *element = new FrameElement(id-1);
                element->SetPos(pos);
                element->SetOrientation(angle);
                element->SetRadius(radius);
                element->SetColor(el_color);
                newFrame->addElement(element);
            }
    
            //adding the new frame to the right dataset
            newFrame->ComputePolyData();
            extern_trajectories_firstSet.addFrame(newFrame);
            //	frameNumbers++;
        }
    
        if(headerParsed==true) {
            //		static int count=1;
            //		count++;
            //		if (count<100) return; // start after 100 frames
            emit signal_startVisualisationThread(geoData,numberOfAgents,frameRate);
            headerParsed=false;
        }
    }
    
    
    void ThreadDataTransfer::slotDisplayError(QAbstractSocket::SocketError socketError)
    {
    
        switch (socketError) {
    
        case QAbstractSocket::RemoteHostClosedError:
            Debug::Error( "The host closes the connection ");
            break;
    
        case QAbstractSocket::HostNotFoundError:
            Debug::Error("The host was not found. Please check the ");
            Debug::Error("host name and port settings.");
            break;
    
        case QAbstractSocket::ConnectionRefusedError:
            Debug::Error("The connection was refused by the peer. ");
            Debug::Error("Make sure the fortune server is running");
            Debug::Error("and check that the host name and port ");
            Debug::Error("settings are correct.");
            break;
    
        default:
            Debug::Error("TraVisTo Client:");
            Debug::Error("The following error occurred: ");
            //cerr<< clientConnection->errorString().toStdString()<<endl;
            break;
        }
    
    
    }
    
    void ThreadDataTransfer::slotProcessPendingDatagrams()
    {
        Debug::Messages("connected");
        while (udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
            udpSocket->readDatagram(datagram.data(), datagram.size());
            //		Debug::Messages("%s",(const char *) datagram.data().c_str()));
        }
    }
    
    
    void ThreadDataTransfer::parseShapeNode(QDomNode shape)
    {
    
    
        QDomNodeList agents = shape.toElement().elementsByTagName("agentInfo");
        QStringList heights;
        QStringList colors;
        for (int i = 0; i < agents.length(); i++) {
    
            bool ok=false;
            int id=agents.item(i).toElement().attribute("ID").toInt(&ok);
            if(!ok) continue; // invalid ID
            double height=agents.item(i).toElement().attribute("height").toDouble(&ok);
            if(!ok)height=std::numeric_limits<double>::quiet_NaN();
    
            int color=agents.item(i).toElement().attribute("color").toDouble(&ok);
            if(!ok)color=std::numeric_limits<int>::quiet_NaN();
            //cout <<"id= " <<id <<" height= "<<height<<" color= "<<color<<endl;
    
            //if(!std::isnan(height)) {
    	if(height!=height) {
                heights.append(QString::number(id));
                heights.append(QString::number(height));
            }
            if(color!=color) {
                colors.append(QString::number(id));
                colors.append(QString::number(color));
            }
    
        }
    
        extern_trajectories_firstSet.setInitialHeights(heights);
        extern_trajectories_firstSet.setInitialColors(colors);
    }
    
    void ThreadDataTransfer::InitHeader(int major, int minor, int patch)
    {
        // set the parsing String map
        if(minor==5 && patch==0) {
            _jps_xPos=QString("xPos");
            _jps_yPos=QString("yPos");
            _jps_zPos=QString("zPos");
            _jps_radiusA=QString("radiusA");
            _jps_radiusB=QString("radiusB");
            _jps_ellipseOrientation=QString("ellipseOrientation");
            _jps_ellipseColor=QString("ellipseColor");
        } else if ( (minor==6) || (minor==5 && patch==1) ) {
            _jps_xPos=QString("x");
            _jps_yPos=QString("y");
            _jps_zPos=QString("z");
            _jps_radiusA=QString("rA");
            _jps_radiusB=QString("rB");
            _jps_ellipseOrientation=QString("eO");
            _jps_ellipseColor=QString("eC");
        } else {
          std::cout<<"unsupported header version: "<<major<<"."<<minor<<"."<<patch<<std::endl;
          std::cout<<"Please use 0.5 0.5.1 or 0.6 "<<std::endl;
        }
    }