From 1a2df71785201deb534bab4695c50497f91ce644 Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Thu, 5 Apr 2018 11:28:04 +0200 Subject: [PATCH 01/11] add field of view and fmu communicate support --- CMakeLists.txt | 19 +- include/appconfig.h | 19 + include/fmureceiver.h | 108 +++++ include/glfieldofview.h | 23 ++ include/glvehicle.h | 7 + include/glwidget.h | 12 + include/mainwindow.h | 53 ++- include/osireader.h | 76 +++- include/tcpreceiver.h | 3 +- include/types.h | 1 + src/appconfig.cpp | 54 +++ src/fmureceiver.cpp | 307 ++++++++++++++ src/glfieldofview.cpp | 60 +++ src/glvehicle.cpp | 14 + src/glwidget.cpp | 57 ++- src/main.cpp | 1 + src/mainwindow.cpp | 724 ++++++++++++++++++++++++++++++--- src/mainwindow.ui | 857 +++++++++++++++++++++++++--------------- src/osiparser.cpp | 170 ++++---- src/osireader.cpp | 337 ++++++++++++++-- 20 files changed, 2407 insertions(+), 495 deletions(-) create mode 100644 include/fmureceiver.h create mode 100644 include/glfieldofview.h create mode 100644 src/fmureceiver.cpp create mode 100644 src/glfieldofview.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2267c5a..ee9d693 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ set(SOURCES src/gltrafficsign.cpp src/qrc_resources.cpp src/osiparser.cpp + src/glfieldofview.cpp + src/fmureceiver.cpp ) set(HEADERS @@ -55,9 +57,20 @@ set(HEADERS include/glpoint.h include/gltrafficsign.h include/osiparser.h + include/glfieldofview.h + include/fmureceiver.h +) + + +include_directories( + /usr/local/include/fmi-library + ${CMAKE_CURRENT_LIST_DIR}/include +) + +link_directories( + /usr/local/lib/fmi-library ) -include_directories(include) add_executable(${PROJECT_NAME} ${HEADERS} @@ -72,7 +85,9 @@ target_link_libraries(${PROJECT_NAME} Qt5::OpenGL Qt5::Network - open_simulation_interface_pic + open_simulation_interface + fmilib_shared protobuf zmq ) + diff --git a/include/appconfig.h b/include/appconfig.h index 8b3765e..b9e8a66 100644 --- a/include/appconfig.h +++ b/include/appconfig.h @@ -21,20 +21,39 @@ class AppConfig QString ch1IPAddress_; QString ch1PortNum_; DataType ch1DataType_; + bool ch1FMURxCheck_; + QString ch1LoadFMURx_; QString ch1LoadFile_; DataType ch1PlaybackDataType_; int ch1DeltaDelay_; bool ch1EnableSendOut_; QString ch1SendOutPortNum_; + bool ch1FMUTxCheck_; + QString ch1LoadFMUTx_; + bool ch1ShowFOV_; + float ch1MinRadius_; + float ch1MaxRadius_; + float ch1AzimuthPos_; + float ch1AzimuthNeg_; + QString ch2IPAddress_; QString ch2PortNum_; DataType ch2DataType_; + bool ch2FMURxCheck_; + QString ch2LoadFMURx_; QString ch2LoadFile_; DataType ch2PlaybackDataType_; int ch2DeltaDelay_; bool ch2EnableSendOut_; QString ch2SendOutPortNum_; + bool ch2FMUTxCheck_; + QString ch2LoadFMUTx_; + bool ch2ShowFOV_; + float ch2MinRadius_; + float ch2MaxRadius_; + float ch2AzimuthPos_; + float ch2AzimuthNeg_; bool combineChannel_; bool showGrid_; diff --git a/include/fmureceiver.h b/include/fmureceiver.h new file mode 100644 index 0000000..1545636 --- /dev/null +++ b/include/fmureceiver.h @@ -0,0 +1,108 @@ +/// +/// @file +/// @copyright Copyright (C) 2017, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +/// +/// @brief +/// + + + +#pragma once + +#include + +#include + +#include "osi_sensordata.pb.h" +#include "imessagesource.h" +#include "types.h" + + +extern "C" { +#include +#include +} + +#define FMI_INTEGER_SENSORDATA_IN_BASELO_IDX 0 +#define FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX 1 +#define FMI_INTEGER_SENSORDATA_IN_SIZE_IDX 2 +#define FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX 3 +#define FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX 4 +#define FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX 5 +#define FMI_INTEGER_LAST_IDX FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX +#define FMI_INTEGER_VARS (FMI_INTEGER_LAST_IDX + 1) + + + + +class FMUReceiver: public QObject, public IMessageSource +{ + Q_OBJECT + + public: + FMUReceiver(); + + signals: + void Connected(DataType dataType); + void Disconnected(const QString& message = ""); + void MessageReceived(const osi::SensorData& sensorData, + const DataType datatype); + + public slots: + void DisconnectRequested(); + void ConnectRequested(const QString& ipAddress, + const QString& port, + const QString& fmuPath, + DataType dataType); + + private: + + void ReceiveLoop(); + + + bool isRunning_; + bool isThreadTerminated_; + DataType currentDataType_; + + + // FMU interface + fmi2_import_t* fmu_; + fmi2_callback_functions_t callBackFunctions_; + jm_callbacks callbacks_; + fmi_import_context_t* context_; + + jm_status_enu_t jmStatus_; + fmi2_status_t fmiStatus_; + + fmi2_real_t tStart_; + fmi2_real_t tEnd_; + fmi2_real_t tCurrent_; + fmi2_real_t hStep_; + + std::string ip_; + std::string port_; + std::string FMUPath_; + std::string tmpPath_; + enum class LogLevel + { + Warn, + Debug + }; + LogLevel logLevel_; + + std::string currentBuffer_; + + fmi2_value_reference_t vr_[FMI_INTEGER_VARS]; + fmi2_integer_t integerVars_[FMI_INTEGER_VARS]; + + // initialize fmu wrapper specific logger, create fmi import context and check fmi version + bool initializeFMUWrapper(); + // import fmu binary file + bool importFMU(); + // setup and initialize FMU + bool initializeFMU(); + // protobuf accessors + bool get_fmi_sensor_data_in(osi::SensorData& data); +}; + + diff --git a/include/glfieldofview.h b/include/glfieldofview.h new file mode 100644 index 0000000..0f059c2 --- /dev/null +++ b/include/glfieldofview.h @@ -0,0 +1,23 @@ + + + + +#pragma once +#include "globject.h" + +class GLFieldOfView : public GLObject +{ + public: + GLFieldOfView(QOpenGLFunctions_4_3_Core* functions, + const float minRadius, + const float maxRadius, + const float azimuthPosAngle, + const float azimuthNegAngle); + + void UpdateParameter(const float minRadius, + const float maxRadius, + const float azimuthPosAngle, + const float azimuthNegAngle); +}; + + diff --git a/include/glvehicle.h b/include/glvehicle.h index a7f437d..cf3ce03 100644 --- a/include/glvehicle.h +++ b/include/glvehicle.h @@ -12,4 +12,11 @@ class GLVehicle : public GLObject { public: GLVehicle(QOpenGLFunctions_4_3_Core* functions, QString id, float xExtend, float zExtend); + + GLVehicle(QOpenGLFunctions_4_3_Core* functions, + QString id, + QVector3D v0, + QVector3D v1, + QVector3D v2, + QVector3D v3); }; diff --git a/include/glwidget.h b/include/glwidget.h index d8dabbd..f4de771 100644 --- a/include/glwidget.h +++ b/include/glwidget.h @@ -14,6 +14,8 @@ #include "lane.h" #include "imessagesource.h" +#include "glfieldofview.h" + #include #include #include @@ -35,6 +37,13 @@ class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_3_Core void UpdateIMessageSource(IMessageSource* msgSource); + void UpdateFOVPaint(const bool showFOV); + + void UpdateFOVParam(const float minRadius, + const float maxRadius, + const float azimuthPosAngle, + const float azimuthNegAngle); + signals: void DisplayObjectInformation(GLObject* object); void SetTrackingEnabled(bool enable); @@ -87,4 +96,7 @@ class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_3_Core QOpenGLShaderProgram shaderProgram_; QMap& treeNodes_; + bool showFOV_; + GLFieldOfView* objFOV_; + }; diff --git a/include/mainwindow.h b/include/mainwindow.h index 7cafb34..13efdf4 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -18,6 +18,7 @@ class GLWidget; class TCPReceiver; +class FMUReceiver; class AppConfig; class OsiParser; class OsiReader; @@ -35,6 +36,8 @@ class MainWindow : public QMainWindow explicit MainWindow(QWidget* parent = nullptr); ~MainWindow(); + void LocalUpdate(); + signals: void UpdateGrid(); void UpdateLane(); @@ -47,11 +50,23 @@ class MainWindow : public QMainWindow const QString& port, const DataType dataType); + void FMUConnectRequested(const QString& ipAddress, + const QString& port, + const QString& fmuPath, + const DataType dataType); + + void FMUConnectRequested2(const QString& ipAddress, + const QString& port, + const QString& fmuPath, + const DataType dataType); + void StartPlaybackRequested(const QString& fileName, - const DataType dataType); + const DataType dataType, + const QString& fmuPath); void StartPlaybackRequested2(const QString& fileName, - const DataType dataType); + const DataType dataType, + const QString& fmuPath); public slots: void EnableExport(bool enable); @@ -91,9 +106,29 @@ class MainWindow : public QMainWindow void RBPlayback(); void RBPlayback2(); + void CBDataTypeCon(int index); + void CBDataTypePlay(int index); + void CBDataTypeCon2(int index); + void CBDataTypePlay2(int index); + void ToggleShowFOV(); + void ToggleShowFOV2(); + + void CheckBoxFMURx(); + void CheckBoxFMURx2(); + void LoadFMURxEdited(const QString& text); + void LoadFMURxBrowse(); + void LoadFMURxEdited2(const QString& text); + void LoadFMURxBrowse2(); + + void CheckBoxFMUTx(); + void CheckBoxFMUTx2(); + void LoadFMUTxEdited(const QString& text); + void LoadFMUTxBrowse(); + void LoadFMUTxEdited2(const QString& text); + void LoadFMUTxBrowse2(); + void LoadFileEdited(const QString& text); void LoadFileBrowse(); - void LoadFileEdited2(const QString& text); void LoadFileBrowse2(); @@ -112,6 +147,9 @@ class MainWindow : public QMainWindow void CombineChannels(); + void ShowFOV(); + void ShowFOV2(); + private: @@ -184,6 +222,9 @@ class MainWindow : public QMainWindow void ShowErrorMessage(const QString& errMsg); + void EnableShowFOV(const bool enable); + void EnableShowFOV2(const bool enable); + // Configurations AppConfig config_; @@ -211,12 +252,14 @@ class MainWindow : public QMainWindow Ui::MainWindow *ui_; GLWidget* glWidget_; - TCPReceiver* receiver_; + TCPReceiver* tcpReceiver_; + FMUReceiver* fmuReceiver_; OsiReader* reader_; OsiParser* osiparser_; GLWidget* glWidget2_; - TCPReceiver* receiver2_; + TCPReceiver* tcpReceiver2_; + FMUReceiver* fmuReceiver2_; OsiReader* reader2_; OsiParser* osiparser2_; diff --git a/include/osireader.h b/include/osireader.h index 5792c0f..411d310 100644 --- a/include/osireader.h +++ b/include/osireader.h @@ -8,8 +8,8 @@ #pragma once -#include -#include +#include +#include #include @@ -24,6 +24,24 @@ #include "types.h" + +extern "C" { +#include +#include +} + +#define FMI_INTEGER_SENSORDATA_IN_BASELO_IDX 0 +#define FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX 1 +#define FMI_INTEGER_SENSORDATA_IN_SIZE_IDX 2 +#define FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX 3 +#define FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX 4 +#define FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX 5 +#define FMI_INTEGER_LAST_IDX FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX +#define FMI_INTEGER_VARS (FMI_INTEGER_LAST_IDX + 1) + + + + class OsiReader: public QObject, public IMessageSource { Q_OBJECT @@ -31,11 +49,13 @@ class OsiReader: public QObject, public IMessageSource public: OsiReader(int* deltaDelay, const bool& enableSendOut, - const std::string& zmqPubPortNum); + const std::string& pubPortNum, + const bool &enalbeFMU, + const std::string &fmuPath = ""); QString SetupConnection(bool enable); - void SetSendOutPortNum(const std::string& port) { zmqPubPortNumber_ = port; } + void SetSendOutPortNum(const std::string& port) { pubPortNumber_ = port; } signals: void Connected(DataType dataType); @@ -46,7 +66,9 @@ class OsiReader: public QObject, public IMessageSource const DataType datatype); public slots: - void StartReadFile(const QString& osiFileName, const DataType dataType); + void StartReadFile(const QString& osiFileName, + const DataType dataType, + const QString& fmuPath); void StopReadFile(); void SliderValueChanged(int newValue); @@ -59,8 +81,12 @@ class OsiReader: public QObject, public IMessageSource void SaveHeader(); void SendMessageLoop(); + void SendOutMessage(const std::string& message); - void ZMQSendOutMessage(const std::string& message); + QString SetZMQConnection(); + QString FreeZMQConnection(); + QString SetFMUConnection(); + void FreeFMUConnection(); @@ -80,10 +106,46 @@ class OsiReader: public QObject, public IMessageSource const int* const deltaDelay_; const bool& enableSendOut_; - std::string zmqPubPortNumber_; + std::string pubPortNumber_; + std::string currentBuffer_; + + // ZMQ zmq::context_t zmqContext_; zmq::socket_t zmqPublisher_; + // FMU + const bool& enableFMU_; + fmi2_import_t* fmu_; + fmi2_callback_functions_t callBackFunctions_; + jm_callbacks callbacks_; + fmi_import_context_t* fmuContext_; + jm_status_enu_t jmStatus_; + fmi2_status_t fmiStatus_; + fmi2_real_t tStart_; + fmi2_real_t tEnd_; + fmi2_real_t tCurrent_; + fmi2_real_t hStep_; + std::string FMUPath_; + std::string tmpPath_; + enum class LogLevel + { + Warn, + Debug + }; + LogLevel logLevel_; + fmi2_value_reference_t vr_[FMI_INTEGER_VARS]; + fmi2_integer_t integerVars_[FMI_INTEGER_VARS]; + + // Initialize fmu wrapper specific logger, create fmi import context and check fmi version + bool initializeFMUWrapper(); + // import fmu binary file + bool importFMU(); + // setup and Initialize FMU + bool initializeFMU(); + // protobuf accessors + void set_fmi_sensor_data_out(); + + // read from input file: data type is always SensorData DataType defaultDatatype_ = DataType::Groundtruth; const QString defaultHeaderPrifix_ = "Header_"; diff --git a/include/tcpreceiver.h b/include/tcpreceiver.h index f0b81f5..d526c06 100644 --- a/include/tcpreceiver.h +++ b/include/tcpreceiver.h @@ -26,7 +26,6 @@ class TCPReceiver : public QObject, public IMessageSource signals: void Connected(DataType dataType); void Disconnected(const QString& message = ""); - void ExportOsiMessage(); void MessageReceived(const osi::SensorData& sensorData, const DataType datatype); @@ -52,3 +51,5 @@ class TCPReceiver : public QObject, public IMessageSource DataType currentDataType_; }; + + diff --git a/include/types.h b/include/types.h index bad24d6..42349f2 100644 --- a/include/types.h +++ b/include/types.h @@ -60,6 +60,7 @@ struct MessageStruct QVector3D velocitie; QVector3D acceleration; osi::Dimension3d dimension; + QVector basePoly; }; using Message = QVector; diff --git a/src/appconfig.cpp b/src/appconfig.cpp index 4b4ed7a..2c17ab5 100644 --- a/src/appconfig.cpp +++ b/src/appconfig.cpp @@ -10,20 +10,38 @@ AppConfig::AppConfig(QString fileName) : ch1IPAddress_("") , ch1PortNum_("") , ch1DataType_(DataType::Groundtruth) + , ch1FMURxCheck_(false) + , ch1LoadFMURx_("") , ch1LoadFile_("") , ch1PlaybackDataType_(DataType::Groundtruth) , ch1DeltaDelay_(0) , ch1EnableSendOut_(false) , ch1SendOutPortNum_("5564") + , ch1FMUTxCheck_(false) + , ch1LoadFMUTx_("") + , ch1ShowFOV_(false) + , ch1MinRadius_(0.1) + , ch1MaxRadius_(1) + , ch1AzimuthPos_(1) + , ch1AzimuthNeg_(-1) , ch2IPAddress_("") , ch2PortNum_("") , ch2DataType_(DataType::Groundtruth) + , ch2FMURxCheck_(false) + , ch2LoadFMURx_("") , ch2LoadFile_("") , ch2PlaybackDataType_(DataType::Groundtruth) , ch2DeltaDelay_(0) , ch2EnableSendOut_(false) , ch2SendOutPortNum_("5564") + , ch2FMUTxCheck_(false) + , ch2LoadFMUTx_("") + , ch2ShowFOV_(false) + , ch2MinRadius_(0.1) + , ch2MaxRadius_(1) + , ch2AzimuthPos_(1) + , ch2AzimuthNeg_(-1) , combineChannel_(false) , showGrid_(true) @@ -60,20 +78,38 @@ AppConfig::Load() ch1IPAddress_ = root.elementsByTagName("CH1IpAddress").at(0).toElement().text(); ch1PortNum_ = root.elementsByTagName("CH1PortNumber").at(0).toElement().text(); ch1DataType_ = (DataType)root.elementsByTagName("CH1DataType").at(0).toElement().text().toInt(); + ch1FMURxCheck_ = root.elementsByTagName("CH1FMURxCheck").at(0).toElement().text() == "1" ? true : false; + ch1LoadFMURx_ = root.elementsByTagName("CH1LoadFMURx").at(0).toElement().text(); ch1LoadFile_ = root.elementsByTagName("CH1LoadFile").at(0).toElement().text(); ch1PlaybackDataType_ = (DataType)root.elementsByTagName("CH1PlaybackDataType").at(0).toElement().text().toInt(); ch1DeltaDelay_ = root.elementsByTagName("CH1DeltaDelay").at(0).toElement().text().toInt(); ch1EnableSendOut_ = root.elementsByTagName("CH1EnableSendOut").at(0).toElement().text() == "1" ? true : false; ch1SendOutPortNum_ = root.elementsByTagName("CH1SendOutPortNumber").at(0).toElement().text(); + ch1FMUTxCheck_ = root.elementsByTagName("CH1FMUTxCheck").at(0).toElement().text() == "1" ? true : false; + ch1LoadFMUTx_ = root.elementsByTagName("CH1LoadFMUTx").at(0).toElement().text(); + ch1ShowFOV_ = root.elementsByTagName("CH1ShowFOV").at(0).toElement().text() == "1" ? true : false; + ch1MinRadius_ = root.elementsByTagName("CH1MinRadius").at(0).toElement().text().toFloat(); + ch1MaxRadius_ = root.elementsByTagName("CH1MaxRadius").at(0).toElement().text().toFloat(); + ch1AzimuthPos_ = root.elementsByTagName("CH1AzimuthPos").at(0).toElement().text().toFloat(); + ch1AzimuthNeg_ = root.elementsByTagName("CH1AzimuthNeg").at(0).toElement().text().toFloat(); ch2IPAddress_ = root.elementsByTagName("CH2IpAddress").at(0).toElement().text(); ch2PortNum_ = root.elementsByTagName("CH2PortNumber").at(0).toElement().text(); ch2DataType_ = (DataType)root.elementsByTagName("CH2DataType").at(0).toElement().text().toInt(); + ch2FMURxCheck_ = root.elementsByTagName("CH2FMUCheck").at(0).toElement().text() == "1" ? true : false; + ch2LoadFMURx_ = root.elementsByTagName("CH2LoadFMU").at(0).toElement().text(); ch2LoadFile_ = root.elementsByTagName("CH2LoadFile").at(0).toElement().text(); ch2PlaybackDataType_ = (DataType)root.elementsByTagName("CH2PlaybackDataType").at(0).toElement().text().toInt(); ch2DeltaDelay_ = root.elementsByTagName("CH2DeltaDelay").at(0).toElement().text().toInt(); ch2EnableSendOut_ = root.elementsByTagName("CH2EnableSendOut").at(0).toElement().text() == "1" ? true : false; ch2SendOutPortNum_ = root.elementsByTagName("CH2SendOutPortNumber").at(0).toElement().text(); + ch2FMUTxCheck_ = root.elementsByTagName("CH2FMUTxCheck").at(0).toElement().text() == "1" ? true : false; + ch2LoadFMUTx_ = root.elementsByTagName("CH2LoadFMUTx").at(0).toElement().text(); + ch2ShowFOV_ = root.elementsByTagName("CH2ShowFOV").at(0).toElement().text() == "1" ? true : false; + ch2MinRadius_ = root.elementsByTagName("CH2MinRadius").at(0).toElement().text().toFloat(); + ch2MaxRadius_ = root.elementsByTagName("CH2MaxRadius").at(0).toElement().text().toFloat(); + ch2AzimuthPos_ = root.elementsByTagName("CH2AzimuthPos").at(0).toElement().text().toFloat(); + ch2AzimuthNeg_ = root.elementsByTagName("CH2AzimuthNeg").at(0).toElement().text().toFloat(); combineChannel_ = root.elementsByTagName("CombineChannel").at(0).toElement().text() == "1" ? true : false; showGrid_ = root.elementsByTagName("ShowGrid").at(0).toElement().text() == "1" ? true : false; @@ -116,20 +152,38 @@ AppConfig::Save() writer.writeTextElement("CH1IpAddress", ch1IPAddress_); writer.writeTextElement("CH1PortNumber", ch1PortNum_); writer.writeTextElement("CH1DataType", QString::number(static_cast(ch1DataType_))); + writer.writeTextElement("CH1FMURxCheck", QString::number(ch1FMURxCheck_)); + writer.writeTextElement("CH1LoadFMURx", ch1LoadFMURx_); writer.writeTextElement("CH1LoadFile", ch1LoadFile_); writer.writeTextElement("CH1PlaybackDataType", QString::number(static_cast(ch1PlaybackDataType_))); writer.writeTextElement("CH1DeltaDelay", QString::number(static_cast(ch1DeltaDelay_))); writer.writeTextElement("CH1EnableSendOut", QString::number(ch1EnableSendOut_)); writer.writeTextElement("CH1SendOutPortNumber", ch1SendOutPortNum_); + writer.writeTextElement("CH1FMUTxCheck", QString::number(ch1FMUTxCheck_)); + writer.writeTextElement("CH1LoadFMUTx", ch1LoadFMUTx_); + writer.writeTextElement("CH1ShowFOV", QString::number(ch1ShowFOV_)); + writer.writeTextElement("CH1MinRadius", QString::number(static_cast(ch1MinRadius_))); + writer.writeTextElement("CH1MaxRadius", QString::number(static_cast(ch1MaxRadius_))); + writer.writeTextElement("CH1AzimuthPos", QString::number(static_cast(ch1AzimuthPos_))); + writer.writeTextElement("CH1AzimuthNeg", QString::number(static_cast(ch1AzimuthNeg_))); writer.writeTextElement("CH2IpAddress", ch2IPAddress_); writer.writeTextElement("CH2PortNumber", ch2PortNum_); writer.writeTextElement("CH2DataType", QString::number(static_cast(ch2DataType_))); + writer.writeTextElement("CH2FMUCheck", QString::number(ch2FMURxCheck_)); + writer.writeTextElement("CH2LoadFMU", ch2LoadFMURx_); writer.writeTextElement("CH2LoadFile", ch2LoadFile_); writer.writeTextElement("CH2PlaybackDataType", QString::number(static_cast(ch2PlaybackDataType_))); writer.writeTextElement("CH2DeltaDelay", QString::number(static_cast(ch2DeltaDelay_))); writer.writeTextElement("CH2EnableSendOut", QString::number(ch2EnableSendOut_)); writer.writeTextElement("CH2SendOutPortNumber", ch2SendOutPortNum_); + writer.writeTextElement("CH2FMUTxCheck", QString::number(ch2FMUTxCheck_)); + writer.writeTextElement("CH2LoadFMUTx", ch2LoadFMUTx_); + writer.writeTextElement("CH2ShowFOV", QString::number(ch2ShowFOV_)); + writer.writeTextElement("CH2MinRadius", QString::number(static_cast(ch2MinRadius_))); + writer.writeTextElement("CH2MaxRadius", QString::number(static_cast(ch2MaxRadius_))); + writer.writeTextElement("CH2AzimuthPos", QString::number(static_cast(ch2AzimuthPos_))); + writer.writeTextElement("CH2AzimuthNeg", QString::number(static_cast(ch2AzimuthNeg_))); writer.writeTextElement("CombineChannel", QString::number(combineChannel_)); writer.writeTextElement("ShowGrid", QString::number(showGrid_)); diff --git a/src/fmureceiver.cpp b/src/fmureceiver.cpp new file mode 100644 index 0000000..2d542ba --- /dev/null +++ b/src/fmureceiver.cpp @@ -0,0 +1,307 @@ +#include "fmureceiver.h" + + + +/** +* local functions +*/ +static void fmuWrapperLogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message) +{ + switch (log_level) + { + case jm_log_level_fatal: + qDebug() << (message); + break; + case jm_log_level_error: + case jm_log_level_warning: + qDebug() << message; + break; + case jm_log_level_nothing: + case jm_log_level_info: + case jm_log_level_verbose: + case jm_log_level_debug: + case jm_log_level_all: + qDebug() << message; + break; + } +} + +static void* decode_integer_to_pointer(fmi2_integer_t hi, fmi2_integer_t lo) +{ +#if PTRDIFF_MAX == INT64_MAX + union addrconv + { + struct + { + int lo; + int hi; + } base; + unsigned long long address; + } myaddr; + myaddr.base.lo = lo; + myaddr.base.hi = hi; + return reinterpret_cast(myaddr.address); +#elif PTRDIFF_MAX == INT32_MAX + return reinterpret_cast(lo); +#else +#error "Cannot determine 32bit or 64bit environment!" +#endif +} + +FMUReceiver::FMUReceiver() + : IMessageSource() + + , isRunning_(false) + , isThreadTerminated_(false) + , currentDataType_(DataType::Groundtruth) +{ +} + +void FMUReceiver::ConnectRequested(const QString &ipAddress, const QString &port, const QString& fmuPath, DataType dataType) +{ + if (!fmuPath.isEmpty()) + { + logLevel_ = LogLevel::Warn; + ip_ = ipAddress.toStdString(); + port_ = port.toStdString(); + FMUPath_ = fmuPath.toStdString(); + tmpPath_ = FMUPath_.substr(0, FMUPath_.find_last_of("/\\")); + + // Start initialization + if (!initializeFMUWrapper()) + { + QString message = "FMU Wrapper initialization failed!"; + emit Disconnected(message); + return; + } + + fmu_ = fmi2_import_parse_xml(context_, tmpPath_.c_str(), 0); + + if (!fmu_) + { + QString message = "Error parsing modeldescription.xml of fmu "; + emit Disconnected(message); + return; + } + + if (fmi2_import_get_fmu_kind(fmu_) == fmi2_fmu_kind_me) + { + QString message = "Only Co-Simulation 2.0 is supported by this code"; + emit Disconnected(message); + return; + } + + if (!importFMU()) + { + QString message = "Could not create the DLL loading mechanism (error: " + QString(fmi2_import_get_last_error(fmu_)) + ")."; + emit Disconnected(message); + return; + } + + if (!initializeFMU()) + { + QString message = "FMU initialization failed:" + QString(fmi2_import_get_last_error(fmu_)); + emit Disconnected(message); + return; + } + } + else + { + QString message = "fmu_path is empty"; + emit Disconnected(message); + return; + } + + isPaused_ = false; + isRunning_ = true; + QtConcurrent::run(this, &FMUReceiver::ReceiveLoop); + + isConnected_ = true; + emit Connected(currentDataType_); +} + +void +FMUReceiver::DisconnectRequested() +{ + if (!isConnected_) + { + return; + } + + isThreadTerminated_ = false; + isRunning_ = false; + + while (!isThreadTerminated_) + { + QThread::msleep(50); + } + + isConnected_ = false; + emit Disconnected(); +} + +void +FMUReceiver::ReceiveLoop() +{ + while (isRunning_) + { + bool msgReceived = false; + + if (!isPaused_) + { + fmi2_boolean_t newStep = fmi2_true; + time_t timeC = time(NULL); + fmiStatus_ = fmi2_import_do_step(fmu_, (fmi2_real_t)timeC, hStep_, newStep); + + osi::SensorData sd; + if (get_fmi_sensor_data_in(sd)) + { + qDebug() << "FMU SensorData Receive data"; + msgReceived = true; + emit MessageReceived(sd, currentDataType_); + } + else + { +// qDebug() << "FMU SensorData receiving error"; + } + } + + if (!msgReceived) + { + QThread::msleep(5); + } + } + + isThreadTerminated_ = true; +} + +bool +FMUReceiver::initializeFMUWrapper() +{ + // TODO: config or use default values? + callbacks_.malloc = malloc; + callbacks_.calloc = calloc; + callbacks_.realloc = realloc; + callbacks_.free = free; + callbacks_.logger = fmuWrapperLogger; + if (logLevel_ == LogLevel::Warn) + { + callbacks_.log_level = jm_log_level_warning; + } + else + { + callbacks_.log_level = jm_log_level_debug; + } + callbacks_.context = 0; + + context_ = fmi_import_allocate_context(&callbacks_); + fmi_version_enu_t version = fmi_import_get_fmi_version(context_, FMUPath_.c_str(), tmpPath_.c_str()); + + if (version != fmi_version_2_0_enu) + { + qDebug() << "The code only supports version 2.0"; + return false; + } + return true; +} + +bool +FMUReceiver::importFMU() +{ + // TODO: config or use default values? + callBackFunctions_.logger = fmi2_log_forwarding; + callBackFunctions_.allocateMemory = calloc; + callBackFunctions_.freeMemory = free; + callBackFunctions_.componentEnvironment = fmu_; + + jmStatus_ = fmi2_import_create_dllfmu(fmu_, fmi2_fmu_kind_cs, &callBackFunctions_); + + if (jmStatus_ == jm_status_error) + { + return false; + } + return true; +} + +bool +FMUReceiver::initializeFMU() +{ + // TODO: config or use default values? + // TODO: alternative solution for start values & verify parameters for setup and initiliazation functions + // start values + fmi2_string_t instanceName = "Test CS model instance"; + + fmi2_string_t fmuLocation = ""; + fmi2_boolean_t visible = fmi2_false; + fmi2_real_t relativeTol = 1e-4; + + tStart_ = 0; + tCurrent_ = tStart_; + fmi2_boolean_t StopTimeDefined = fmi2_false; + + // Do we need it? + fmi2_string_t fmuGUID; + fmuGUID = fmi2_import_get_GUID(fmu_); + + jmStatus_ = fmi2_import_instantiate(fmu_, instanceName, fmi2_cosimulation, fmuLocation, visible); + fmiStatus_ = fmi2_import_setup_experiment(fmu_, fmi2_true, relativeTol, tStart_, StopTimeDefined, tEnd_); + fmiStatus_ = fmi2_import_enter_initialization_mode(fmu_); + fmiStatus_ = fmi2_import_exit_initialization_mode(fmu_); + + vr_[FMI_INTEGER_SENSORDATA_IN_BASELO_IDX] = FMI_INTEGER_SENSORDATA_IN_BASELO_IDX; + vr_[FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX] = FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX; + vr_[FMI_INTEGER_SENSORDATA_IN_SIZE_IDX] = FMI_INTEGER_SENSORDATA_IN_SIZE_IDX; + vr_[FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX] = FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX; + vr_[FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX] = FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX; + vr_[FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX] = FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX; + + integerVars_[FMI_INTEGER_SENSORDATA_IN_BASELO_IDX] = 0; + integerVars_[FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX] = 0; + integerVars_[FMI_INTEGER_SENSORDATA_IN_SIZE_IDX] = 0; + + integerVars_[FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX] = 0; + integerVars_[FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX] = 0; + integerVars_[FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX] = 0; + + /* Boolean Variables defined in the OSMPCNetworkProxy.h */ + // #define FMI_BOOLEAN_DUMMY_IDX 0 + // #define FMI_BOOLEAN_SENDER_IDX 1 + // #define FMI_BOOLEAN_RECEIVER_IDX 2 + fmi2_boolean_t booleanVars_[3]; + booleanVars_[0] = 0; + booleanVars_[1] = 0; + booleanVars_[2] = 1; + fmi2_status_t status1 = fmi2_import_set_boolean(fmu_, vr_, 3, booleanVars_); + + /* String Variables */ + // #define FMI_STRING_ADDRESS_IDX 0 + // #define FMI_STRING_PORT_IDX 1 + + fmi2_string_t stringVars_[2]; + stringVars_[0] = ip_.c_str(); + stringVars_[1] = port_.c_str(); + fmi2_status_t status2 = fmi2_import_set_string(fmu_, vr_, 2, stringVars_); + + return status1 == fmi2_status_ok && status2 == fmi2_status_ok; +} + +bool +FMUReceiver::get_fmi_sensor_data_in(osi::SensorData& data) +{ + fmiStatus_ = fmi2_import_get_integer(fmu_, vr_, FMI_INTEGER_VARS, integerVars_); +// qDebug() << "rx buffer size: " << integerVars_[FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX]; + if (integerVars_[FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX] > 0) + { + void* buffer = decode_integer_to_pointer(integerVars_[FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX], + integerVars_[FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX]); + + qDebug() << "rx buffer: " << (char*) buffer; + + return data.ParseFromArray(buffer, integerVars_[FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX]); + } + + return false; +} + + + diff --git a/src/glfieldofview.cpp b/src/glfieldofview.cpp new file mode 100644 index 0000000..d74edf1 --- /dev/null +++ b/src/glfieldofview.cpp @@ -0,0 +1,60 @@ +#include "glfieldofview.h" +#include + + +GLFieldOfView::GLFieldOfView(QOpenGLFunctions_4_3_Core* functions, + const float minRadius, + const float maxRadius, + const float azimuthPosAngle, + const float azimuthNegAngle) + : GLObject(GL_LINE_LOOP, functions) +{ + UpdateParameter(minRadius, maxRadius, azimuthPosAngle, azimuthNegAngle); +} + + +void +GLFieldOfView::UpdateParameter(const float minRadius, + const float maxRadius, + const float azimuthPosAngle, + const float azimuthNegAngle) +{ + vertices_.clear(); + + float angle = azimuthNegAngle; + + int minSlices = 50; + int maxSlices = 200; + float minAngleSteps = (azimuthPosAngle - azimuthNegAngle) / (float)minSlices; + float maxAngleSteps = (azimuthPosAngle - azimuthNegAngle) / (float)maxSlices; + + for (int i = 0; i <= minSlices; ++i) + { + float x = minRadius * sin(angle); + float z = minRadius * cos(angle); + vertices_ << QVector3D(x, 0, z); + + angle += minAngleSteps; + } + + QVector outCurve; + angle = azimuthNegAngle; + + for (int i = 0; i <= maxSlices; ++i) + { + float x = maxRadius * sin(angle); + float z = maxRadius * cos(angle); + outCurve << QVector3D(x, 0, z); + + angle += maxAngleSteps; + } + + for (int i = outCurve.size() - 1; i >= 0; --i) + { + vertices_ << outCurve[i]; + } +} + + + + diff --git a/src/glvehicle.cpp b/src/glvehicle.cpp index d2a3c4b..3c1ddb0 100644 --- a/src/glvehicle.cpp +++ b/src/glvehicle.cpp @@ -16,3 +16,17 @@ GLVehicle::GLVehicle(QOpenGLFunctions_4_3_Core* functions, << QVector3D(xHalfExtend, 0, -zHalfExtend) << QVector3D(-xHalfExtend, 0, -zHalfExtend); } + +GLVehicle::GLVehicle(QOpenGLFunctions_4_3_Core* functions, + QString id, + QVector3D v0, + QVector3D v1, + QVector3D v2, + QVector3D v3) + : GLObject(GL_QUADS, functions, id) +{ + vertices_ << v0 << v1 << v2 << v3; +} + + + diff --git a/src/glwidget.cpp b/src/glwidget.cpp index 3b25fc2..4e560d7 100644 --- a/src/glwidget.cpp +++ b/src/glwidget.cpp @@ -3,6 +3,7 @@ #include "gltriangle.h" #include "glpoint.h" #include "global.h" +#include "glfieldofview.h" #include "customtreewidgetitem.h" //#include @@ -40,6 +41,8 @@ GLWidget::GLWidget(QWidget* parent, , simulationObjects_() , shaderProgram_() , treeNodes_(treeNodes) + , showFOV_(false) + , objFOV_(nullptr) { installEventFilter(this); } @@ -50,6 +53,24 @@ GLWidget::UpdateIMessageSource(IMessageSource* msgSource) msgSource_ = msgSource; } +void +GLWidget::UpdateFOVPaint(const bool showFOV) +{ + showFOV_ = showFOV; + this->update(); +} + +void +GLWidget::UpdateFOVParam(const float minRadius, + const float maxRadius, + const float azimuthPosAngle, + const float azimuthNegAngle) +{ + objFOV_->UpdateParameter(minRadius, maxRadius, azimuthPosAngle, azimuthNegAngle); + objFOV_->UpdateVertexBuffer(); + UpdateFOVPaint(true); +} + void GLWidget::initializeGL() { @@ -110,8 +131,12 @@ GLWidget::initializeGL() center->Init(); staticObjects_.append(center); - isOpenGLInitizalized_ = true; + objFOV_ = new GLFieldOfView(this, 0, 1, 1, -1); + objFOV_->SetColor(Qt::yellow); + objFOV_->SetOrientation(M_PI_2); + objFOV_->Init(); + isOpenGLInitizalized_ = true; } void @@ -149,7 +174,7 @@ GLWidget::paintGL() } } } - //mutex2.unlock(); + //mutex2.unlock(); // TODO: Mutex for object list? //mutex.lock(); @@ -163,6 +188,9 @@ GLWidget::paintGL() RenderObject(object->GetTextObject()); } } + + if(showFOV_) + RenderObject(objFOV_); //mutex.unlock(); } @@ -413,7 +441,25 @@ GLWidget::MessageParsed(const Message& message, object->isVisible_ = true; object->SetPosition(msg.position, false); - object->SetOrientation(msg.orientation); + + if(msg.basePoly.size() == 4) + { + object->vertices_.clear(); + object->vertices_ << msg.basePoly[0] << msg.basePoly[1] << msg.basePoly[2] << msg.basePoly[3]; + object->SetOrientation(msg.orientation); + } + else + { + osi::Dimension3d dimension = msg.dimension; + object->vertices_.clear(); + object->vertices_ << QVector3D(-dimension.width()/2, 0, dimension.length()/2) + << QVector3D(dimension.width()/2, 0, dimension.length()/2) + << QVector3D(dimension.width()/2, 0, -dimension.length()/2) + << QVector3D(-dimension.width()/2, 0, -dimension.length()/2); + object->SetOrientation(msg.orientation + M_PI_2); + } + object->UpdateVertexBuffer(); + if (object->GetTextObject()) { object->GetTextObject()->isVisible_ = true; @@ -451,7 +497,10 @@ GLWidget::MessageParsed(const Message& message, type == ObjectType::MotorBike || type == ObjectType::Bicycle ) { - newObject = new GLVehicle(this, msg.id, msg.dimension.length(), msg.dimension.width()); + if(msg.basePoly.size() == 4) + newObject = new GLVehicle(this, msg.id, msg.basePoly[0], msg.basePoly[1], msg.basePoly[2], msg.basePoly[3]); + else + newObject = new GLVehicle(this, msg.id, msg.dimension.length(), msg.dimension.width()); } else { diff --git a/src/main.cpp b/src/main.cpp index 4d16841..3115d70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); MainWindow window; window.show(); + window.LocalUpdate(); return app.exec(); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 94d3cc1..3a27264 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2,6 +2,7 @@ #include "ui_mainwindow.h" #include "customtreewidgetitem.h" #include "tcpreceiver.h" +#include "fmureceiver.h" #include "glwidget.h" #include "global.h" #include "osiparser.h" @@ -46,13 +47,15 @@ MainWindow::MainWindow(QWidget *parent) , ui_(new Ui::MainWindow) , glWidget_(nullptr) - , receiver_(new TCPReceiver()) - , reader_(new OsiReader(&config_.ch1DeltaDelay_, config_.ch1EnableSendOut_, config_.ch1SendOutPortNum_.toStdString())) + , tcpReceiver_(new TCPReceiver()) + , fmuReceiver_(new FMUReceiver()) + , reader_(new OsiReader(&config_.ch1DeltaDelay_, config_.ch1EnableSendOut_, config_.ch1SendOutPortNum_.toStdString(), config_.ch1FMUTxCheck_, config_.ch1LoadFMUTx_.toStdString())) , osiparser_(new OsiParser(config_.osiMsgSaveThreshold_)) , glWidget2_(nullptr) - , receiver2_(new TCPReceiver()) - , reader2_(new OsiReader(&config_.ch2DeltaDelay_, config_.ch2EnableSendOut_, config_.ch2SendOutPortNum_.toStdString())) + , tcpReceiver2_(new TCPReceiver()) + , fmuReceiver2_(new FMUReceiver()) + , reader2_(new OsiReader(&config_.ch2DeltaDelay_, config_.ch2EnableSendOut_, config_.ch2SendOutPortNum_.toStdString(), config_.ch2FMUTxCheck_, config_.ch2LoadFMUTx_.toStdString())) , osiparser2_(new OsiParser(config_.osiMsgSaveThreshold_)) , colorWidgets_() @@ -74,19 +77,14 @@ MainWindow::MainWindow(QWidget *parent) ui_->objectTree->header()->setSortIndicator(0, Qt::AscendingOrder); ui_->objectTree_2->header()->setSortIndicator(0, Qt::AscendingOrder); - glWidget_ = new GLWidget(this, receiver_, treeNodes_, config_); + glWidget_ = new GLWidget(this, tcpReceiver_, treeNodes_, config_); ui_->glLayout->addWidget(glWidget_); glWidget_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - glWidget2_ = new GLWidget(this, receiver2_, treeNodes2_, config_); + glWidget2_ = new GLWidget(this, tcpReceiver2_, treeNodes2_, config_); ui_->glLayout_2->addWidget(glWidget2_); glWidget2_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - ConnectSignalsToSlots(); - InitComboBoxes(); - InitLaneTypeMenu(); - InitLoadConfigure(); - QSurfaceFormat format; format.setDepthBufferSize(24); format.setSamples(4); @@ -95,6 +93,15 @@ MainWindow::MainWindow(QWidget *parent) glWidget_->setFormat(format); glWidget2_->setFormat(format); + ui_->saveOSIMessage->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + ui_->saveOSIMessage->setIcon(playIcon_); + ui_->saveOSIMessage_2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + ui_->saveOSIMessage_2->setIcon(playIcon_); + + ConnectSignalsToSlots(); + InitComboBoxes(); + InitLaneTypeMenu(); + InitLoadConfigure(); InitLegendGroupBox(); ToggleSrcGroups(); ToggleSrcGroups2(); @@ -103,14 +110,18 @@ MainWindow::MainWindow(QWidget *parent) EnableSlider(false); EnableSlider2(false); - ui_->saveOSIMessage->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - ui_->saveOSIMessage->setIcon(playIcon_); - ui_->saveOSIMessage_2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - ui_->saveOSIMessage_2->setIcon(playIcon_); - QTimer::singleShot(1000, this, SLOT(showMaximized())); } +void +MainWindow::LocalUpdate() +{ + ShowFOV(); + ShowFOV2(); + ToggleShowFOV(); + ToggleShowFOV2(); +} + MainWindow::~MainWindow() { // Call all deletes in reversed order! @@ -118,8 +129,10 @@ MainWindow::~MainWindow() delete glWidget2_; delete osiparser_; delete osiparser2_; - delete receiver_; - delete receiver2_; + delete tcpReceiver_; + delete fmuReceiver_; + delete tcpReceiver2_; + delete fmuReceiver2_; delete reader_; delete reader2_; delete ui_; @@ -131,6 +144,7 @@ MainWindow::RBConnection() isSrcConnection_ = true; UpdateGLWidgetMessageSource(); ToggleSrcGroups(); + ToggleShowFOV(); } void @@ -139,6 +153,7 @@ MainWindow::RBConnection2() isSrcConnection2_ = true; UpdateGLWidgetMessageSource2(); ToggleSrcGroups2(); + ToggleShowFOV2(); } void @@ -147,6 +162,7 @@ MainWindow::RBPlayback() isSrcConnection_ = false; UpdateGLWidgetMessageSource(); ToggleSrcGroups(); + ToggleShowFOV(); } void @@ -155,11 +171,219 @@ MainWindow::RBPlayback2() isSrcConnection2_ = false; UpdateGLWidgetMessageSource2(); ToggleSrcGroups2(); + ToggleShowFOV2(); +} + +void +MainWindow::CBDataTypeCon(int index) +{ + if(index == 1) + { + ui_->showFOV->setEnabled(true); + glWidget_->UpdateFOVPaint(ui_->showFOV->isChecked()); + EnableShowFOV(!ui_->showFOV->isChecked()); + } + else + { + ui_->showFOV->setEnabled(false); + glWidget_->UpdateFOVPaint(false); + EnableShowFOV(false); + } +} + +void +MainWindow::CBDataTypePlay(int index) +{ + if(index == 1) + { + ui_->showFOV->setEnabled(true); + glWidget_->UpdateFOVPaint(ui_->showFOV->isChecked()); + EnableShowFOV(!ui_->showFOV->isChecked()); + } + else + { + ui_->showFOV->setEnabled(false); + glWidget_->UpdateFOVPaint(false); + EnableShowFOV(false); + } +} + +void +MainWindow::CBDataTypeCon2(int index) +{ + if(index == 1) + { + ui_->showFOV_2->setEnabled(true); + glWidget2_->UpdateFOVPaint(ui_->showFOV_2->isChecked()); + EnableShowFOV2(!ui_->showFOV_2->isChecked()); + } + else + { + ui_->showFOV_2->setEnabled(false); + glWidget2_->UpdateFOVPaint(false); + EnableShowFOV2(false); + } +} + +void +MainWindow::CBDataTypePlay2(int index) +{ + if(index == 1) + { + ui_->showFOV_2->setEnabled(true); + glWidget2_->UpdateFOVPaint(ui_->showFOV_2->isChecked()); + EnableShowFOV2(!ui_->showFOV_2->isChecked()); + } + else + { + ui_->showFOV_2->setEnabled(false); + glWidget2_->UpdateFOVPaint(false); + EnableShowFOV2(false); + } +} + +void +MainWindow::ToggleShowFOV() +{ + if(isSrcConnection_) + CBDataTypeCon(ui_->dataType->currentIndex()); + else + CBDataTypePlay(ui_->playbackDataType->currentIndex()); +} + +void +MainWindow::ToggleShowFOV2() +{ + if(isSrcConnection2_) + CBDataTypeCon2(ui_->dataType_2->currentIndex()); + else + CBDataTypePlay2(ui_->playbackDataType_2->currentIndex()); +} + +void +MainWindow::CheckBoxFMURx() +{ + bool enableFmu = ui_->checkBoxFMURx->isChecked(); + ui_->loadFMURx->setEnabled(enableFmu); + ui_->loadFMURxBrowse->setEnabled(enableFmu); +} + +void +MainWindow::CheckBoxFMURx2() +{ + bool enableFmu = ui_->checkBoxFMURx_2->isChecked(); + ui_->loadFMURx_2->setEnabled(enableFmu); + ui_->loadFMURxBrowse_2->setEnabled(enableFmu); +} + +void +MainWindow::LoadFMURxEdited(const QString& text) +{ + ui_->loadFMURx->setText(text); + ui_->loadFMURx->setToolTip(text); +} + +void +MainWindow::LoadFMURxBrowse() +{ + QString fileName = ui_->loadFMURx->text(); + + fileName = QFileDialog::getOpenFileName(this, + tr("Load file"), fileName, tr("FMU Files (*.fmu)")); + + if(!fileName.isEmpty()) + { + ui_->loadFMURx->setText(fileName); + ui_->loadFMURx->setToolTip(fileName); + } +} + +void +MainWindow::LoadFMURxEdited2(const QString& text) +{ + ui_->loadFMURx_2->setText(text); + ui_->loadFMURx_2->setToolTip(text); +} + +void +MainWindow::LoadFMURxBrowse2() +{ + QString fileName = ui_->loadFMURx_2->text(); + + fileName = QFileDialog::getOpenFileName(this, + tr("Load file"), fileName, tr("FMU Files (*.fmu)")); + + if(!fileName.isEmpty()) + { + ui_->loadFMURx_2->setText(fileName); + ui_->loadFMURx_2->setToolTip(fileName); + } +} + +void +MainWindow::CheckBoxFMUTx() +{ + bool enableFmu = ui_->checkBoxFMUTx->isChecked(); + ui_->loadFMUTx->setEnabled(enableFmu); + ui_->loadFMUTxBrowse->setEnabled(enableFmu); +} + +void +MainWindow::CheckBoxFMUTx2() +{ + bool enableFmu = ui_->checkBoxFMUTx_2->isChecked(); + ui_->loadFMUTx_2->setEnabled(enableFmu); + ui_->loadFMUTxBrowse_2->setEnabled(enableFmu); +} + +void +MainWindow::LoadFMUTxEdited(const QString& text) +{ + ui_->loadFMUTx->setText(text); + ui_->loadFMUTx->setToolTip(text); +} + +void +MainWindow::LoadFMUTxBrowse() +{ + QString fileName = ui_->loadFMUTx->text(); + + fileName = QFileDialog::getOpenFileName(this, + tr("Load file"), fileName, tr("FMU Files (*.fmu)")); + + if(!fileName.isEmpty()) + { + ui_->loadFMUTx->setText(fileName); + ui_->loadFMUTx->setToolTip(fileName); + } +} + +void +MainWindow::LoadFMUTxEdited2(const QString& text) +{ + ui_->loadFMUTx_2->setText(text); + ui_->loadFMUTx_2->setToolTip(text); +} + +void +MainWindow::LoadFMUTxBrowse2() +{ + QString fileName = ui_->loadFMUTx_2->text(); + + fileName = QFileDialog::getOpenFileName(this, + tr("Load file"), fileName, tr("FMU Files (*.fmu)")); + + if(!fileName.isEmpty()) + { + ui_->loadFMUTx_2->setText(fileName); + ui_->loadFMUTx_2->setToolTip(fileName); + } } void MainWindow::LoadFileEdited(const QString& text) { + ui_->loadFile->setText(text); ui_->loadFile->setToolTip(text); } @@ -181,6 +405,7 @@ MainWindow::LoadFileBrowse() void MainWindow::LoadFileEdited2(const QString& text) { + ui_->loadFile_2->setText(text); ui_->loadFile_2->setToolTip(text); } @@ -202,13 +427,23 @@ MainWindow::LoadFileBrowse2() void MainWindow::EnableSendToNetwork() { - ui_->sendOutPortNum->setEnabled(ui_->enableSendToNetwork->checkState() == Qt::Checked); + bool enableSend = ui_->enableSendToNetwork->checkState() == Qt::Checked; + ui_->sendOutPortNum->setEnabled(enableSend); + bool enableFMU = ui_->checkBoxFMUTx->checkState() == Qt::Checked; + ui_->checkBoxFMUTx->setEnabled(enableSend); + ui_->loadFMUTx->setEnabled(enableSend && enableFMU); + ui_->loadFMUTxBrowse->setEnabled(enableSend && enableFMU); } void MainWindow::EnableSendToNetwork2() { - ui_->sendOutPortNum_2->setEnabled(ui_->enableSendToNetwork_2->checkState() == Qt::Checked); + bool enableSend = ui_->enableSendToNetwork_2->checkState() == Qt::Checked; + ui_->sendOutPortNum_2->setEnabled(enableSend); + bool enableFMU = ui_->checkBoxFMUTx_2->checkState() == Qt::Checked; + ui_->checkBoxFMUTx_2->setEnabled(enableSend); + ui_->loadFMUTx_2->setEnabled(enableSend && enableFMU); + ui_->loadFMUTxBrowse_2->setEnabled(enableSend && enableFMU); } void @@ -350,6 +585,13 @@ MainWindow::CheckFieldsValidity() ui_->portNumber->text().toUInt(&success); if(success == false) errMsg += " Port number should be valid integer!\n"; + + // Rx FMU file + if(ui_->checkBoxFMURx->isChecked() && QFileInfo::exists(ui_->loadFMURx->text()) == false) + { + success = false; + errMsg += " Connection FMU file doesn't exist!\n"; + } } else { @@ -367,6 +609,15 @@ MainWindow::CheckFieldsValidity() if(success == false) errMsg += " Port number should be valid positive integer!\n"; } + + // Tx FMU file + if( ui_->enableSendToNetwork->isChecked() && + ui_->checkBoxFMUTx->isChecked() && + QFileInfo::exists(ui_->loadFMUTx->text()) == false ) + { + success = false; + errMsg += " Send FMU file doesn't exist!\n"; + } } if(errMsg.isEmpty() == false) @@ -397,6 +648,13 @@ MainWindow::CheckFieldsValidity2() ui_->portNumber_2->text().toUInt(&success); if(success == false) errMsg += " Port number should be valid integer!\n"; + + // Rx FMU file + if(ui_->checkBoxFMURx_2->isChecked() && QFileInfo::exists(ui_->loadFMURx_2->text()) == false) + { + success = false; + errMsg += " Connection FMU file doesn't exist!\n"; + } } else { @@ -414,6 +672,15 @@ MainWindow::CheckFieldsValidity2() if(success == false) errMsg += " Port number should be valid positive integer!\n"; } + + // Tx FMU file + if( ui_->enableSendToNetwork_2->isChecked() && + ui_->checkBoxFMUTx_2->isChecked() && + QFileInfo::exists(ui_->loadFMUTx_2->text()) == false ) + { + success = false; + errMsg += " Send FMU file doesn't exist!\n"; + } } if(errMsg.isEmpty() == false) @@ -443,6 +710,23 @@ MainWindow::ConnectSignalsToSlots() connect(ui_->rbConnection_2, &QRadioButton::clicked, this, &MainWindow::RBConnection2); connect(ui_->rbPlayback_2, &QRadioButton::clicked, this, &MainWindow::RBPlayback2); + // fmu rx + connect(ui_->checkBoxFMURx, &QCheckBox::clicked, this, &MainWindow::CheckBoxFMURx); + connect(ui_->checkBoxFMURx_2, &QCheckBox::clicked, this, &MainWindow::CheckBoxFMURx2); + connect(ui_->loadFMURx, &QLineEdit::textEdited, this, &MainWindow::LoadFMURxEdited); + connect(ui_->loadFMURxBrowse, &QPushButton::clicked, this, &MainWindow::LoadFMURxBrowse); + connect(ui_->loadFMURx_2, &QLineEdit::textEdited, this, &MainWindow::LoadFMURxEdited2); + connect(ui_->loadFMURxBrowse_2, &QPushButton::clicked, this, &MainWindow::LoadFMURxBrowse2); + + + // fmu rx + connect(ui_->checkBoxFMUTx, &QCheckBox::clicked, this, &MainWindow::CheckBoxFMUTx); + connect(ui_->checkBoxFMUTx_2, &QCheckBox::clicked, this, &MainWindow::CheckBoxFMUTx2); + connect(ui_->loadFMUTx, &QLineEdit::textEdited, this, &MainWindow::LoadFMUTxEdited); + connect(ui_->loadFMUTxBrowse, &QPushButton::clicked, this, &MainWindow::LoadFMUTxBrowse); + connect(ui_->loadFMUTx_2, &QLineEdit::textEdited, this, &MainWindow::LoadFMUTxEdited2); + connect(ui_->loadFMUTxBrowse_2, &QPushButton::clicked, this, &MainWindow::LoadFMUTxBrowse2); + // load/save playback file connect(ui_->loadFile, &QLineEdit::textEdited, this, &MainWindow::LoadFileEdited); connect(ui_->loadFileBrowse, &QPushButton::clicked, this, &MainWindow::LoadFileBrowse); @@ -450,7 +734,7 @@ MainWindow::ConnectSignalsToSlots() connect(ui_->loadFileBrowse_2, &QPushButton::clicked, this, &MainWindow::LoadFileBrowse2); // enable sent out - connect(ui_->enableSendToNetwork, &QCheckBox::clicked, this, &MainWindow::EnableSendToNetwork); + connect(ui_->enableSendToNetwork, &QCheckBox::clicked, this, &MainWindow::EnableSendToNetwork); connect(ui_->enableSendToNetwork_2, &QCheckBox::clicked, this, &MainWindow::EnableSendToNetwork2); // Play/Pause @@ -459,17 +743,29 @@ MainWindow::ConnectSignalsToSlots() // signals and slots related to connection status // If not queued, this signal will block the GUI. Same applies for Connect/Disconnect in TCPReceiver. - connect(this, &MainWindow::ConnectRequested, receiver_, &TCPReceiver::ConnectRequested, Qt::QueuedConnection); - connect(receiver_, &TCPReceiver::Connected, this, &MainWindow::Connected); - connect(receiver_, &TCPReceiver::Disconnected, this, &MainWindow::Disconnected); - connect(receiver_, &TCPReceiver::Connected, glWidget_, &GLWidget::Connected, Qt::DirectConnection); - connect(receiver_, &TCPReceiver::Disconnected, glWidget_, &GLWidget::Disconnected, Qt::DirectConnection); - - connect(this, &MainWindow::ConnectRequested2, receiver2_, &TCPReceiver::ConnectRequested, Qt::QueuedConnection); - connect(receiver2_, &TCPReceiver::Connected, this, &MainWindow::Connected2); - connect(receiver2_, &TCPReceiver::Disconnected, this, &MainWindow::Disconnected2); - connect(receiver2_, &TCPReceiver::Connected, glWidget2_, &GLWidget::Connected, Qt::DirectConnection); - connect(receiver2_, &TCPReceiver::Disconnected, glWidget2_, &GLWidget::Disconnected, Qt::DirectConnection); + connect(this, &MainWindow::ConnectRequested, tcpReceiver_, &TCPReceiver::ConnectRequested, Qt::QueuedConnection); + connect(tcpReceiver_, &TCPReceiver::Connected, this, &MainWindow::Connected); + connect(tcpReceiver_, &TCPReceiver::Disconnected, this, &MainWindow::Disconnected); + connect(tcpReceiver_, &TCPReceiver::Connected, glWidget_, &GLWidget::Connected, Qt::DirectConnection); + connect(tcpReceiver_, &TCPReceiver::Disconnected, glWidget_, &GLWidget::Disconnected, Qt::DirectConnection); + + connect(this, &MainWindow::ConnectRequested2, tcpReceiver2_, &TCPReceiver::ConnectRequested, Qt::QueuedConnection); + connect(tcpReceiver2_, &TCPReceiver::Connected, this, &MainWindow::Connected2); + connect(tcpReceiver2_, &TCPReceiver::Disconnected, this, &MainWindow::Disconnected2); + connect(tcpReceiver2_, &TCPReceiver::Connected, glWidget2_, &GLWidget::Connected, Qt::DirectConnection); + connect(tcpReceiver2_, &TCPReceiver::Disconnected, glWidget2_, &GLWidget::Disconnected, Qt::DirectConnection); + + connect(this, &MainWindow::FMUConnectRequested, fmuReceiver_, &FMUReceiver::ConnectRequested, Qt::QueuedConnection); + connect(fmuReceiver_, &FMUReceiver::Connected, this, &MainWindow::Connected); + connect(fmuReceiver_, &FMUReceiver::Disconnected, this, &MainWindow::Disconnected); + connect(fmuReceiver_, &FMUReceiver::Connected, glWidget_, &GLWidget::Connected, Qt::DirectConnection); + connect(fmuReceiver_, &FMUReceiver::Disconnected, glWidget_, &GLWidget::Disconnected, Qt::DirectConnection); + + connect(this, &MainWindow::FMUConnectRequested2, fmuReceiver2_, &FMUReceiver::ConnectRequested, Qt::QueuedConnection); + connect(fmuReceiver2_, &FMUReceiver::Connected, this, &MainWindow::Connected2); + connect(fmuReceiver2_, &FMUReceiver::Disconnected, this, &MainWindow::Disconnected2); + connect(fmuReceiver2_, &FMUReceiver::Connected, glWidget2_, &GLWidget::Connected, Qt::DirectConnection); + connect(fmuReceiver2_, &FMUReceiver::Disconnected, glWidget2_, &GLWidget::Disconnected, Qt::DirectConnection); connect(this, &MainWindow::StartPlaybackRequested, reader_, &OsiReader::StartReadFile, Qt::QueuedConnection); connect(reader_, &OsiReader::Connected, this, &MainWindow::Connected); @@ -490,8 +786,11 @@ MainWindow::ConnectSignalsToSlots() connect(reader2_, &OsiReader::UpdateSliderValue, this, &MainWindow::UpdateSliderValue2); //Main loop: receive(read) -> parse -> update objects - connect(receiver_, &TCPReceiver::MessageReceived, osiparser_, &OsiParser::ParseReceivedMessage, Qt::QueuedConnection); - connect(receiver2_, &TCPReceiver::MessageReceived, osiparser2_, &OsiParser::ParseReceivedMessage, Qt::QueuedConnection); + connect(tcpReceiver_, &TCPReceiver::MessageReceived, osiparser_, &OsiParser::ParseReceivedMessage, Qt::QueuedConnection); + connect(tcpReceiver2_, &TCPReceiver::MessageReceived, osiparser2_, &OsiParser::ParseReceivedMessage, Qt::QueuedConnection); + + connect(fmuReceiver_, &FMUReceiver::MessageReceived, osiparser_, &OsiParser::ParseReceivedMessage, Qt::QueuedConnection); + connect(fmuReceiver2_, &FMUReceiver::MessageReceived, osiparser2_, &OsiParser::ParseReceivedMessage, Qt::QueuedConnection); connect(reader_, &OsiReader::MessageSendout, osiparser_, &OsiParser::ParseReceivedMessage, Qt::QueuedConnection); connect(reader2_, &OsiReader::MessageSendout, osiparser2_, &OsiParser::ParseReceivedMessage, Qt::QueuedConnection); @@ -556,6 +855,15 @@ MainWindow::ConnectSignalsToSlots() // menu quit connect(ui_->actionQuit, &QAction::triggered, this, &MainWindow::Quit); + + // FOV connection + connect(ui_->showFOV, &QToolButton::clicked, this, &MainWindow::ShowFOV); + connect(ui_->showFOV_2, &QToolButton::clicked, this, &MainWindow::ShowFOV2); + connect(ui_->dataType, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::CBDataTypeCon); + connect(ui_->playbackDataType, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::CBDataTypePlay); + connect(ui_->dataType_2, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::CBDataTypeCon2); + connect(ui_->playbackDataType_2, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::CBDataTypePlay2); + } void @@ -613,6 +921,19 @@ MainWindow::EnableSrcGroups2(bool enable) void MainWindow::EnableConnectionGroup1(bool enable) { + ui_->checkBoxFMURx->setEnabled(enable); + if(enable) + { + bool enableFmu = ui_->checkBoxFMURx->isChecked(); + ui_->loadFMURx->setEnabled(enableFmu); + ui_->loadFMURxBrowse->setEnabled(enableFmu); + } + else + { + ui_->loadFMURx->setEnabled(false); + ui_->loadFMURxBrowse->setEnabled(false); + } + ui_->ipAddress->setEnabled(enable); ui_->portNumber->setEnabled(enable); ui_->dataType->setEnabled(enable); @@ -621,6 +942,19 @@ MainWindow::EnableConnectionGroup1(bool enable) void MainWindow::EnableConnectionGroup2(bool enable) { + ui_->checkBoxFMURx_2->setEnabled(enable); + if(enable) + { + bool enableFmu = ui_->checkBoxFMURx_2->isChecked(); + ui_->loadFMURx_2->setEnabled(enableFmu); + ui_->loadFMURxBrowse_2->setEnabled(enableFmu); + } + else + { + ui_->loadFMURx_2->setEnabled(false); + ui_->loadFMURxBrowse_2->setEnabled(false); + } + ui_->ipAddress_2->setEnabled(enable); ui_->portNumber_2->setEnabled(enable); ui_->dataType_2->setEnabled(enable); @@ -634,7 +968,12 @@ MainWindow::EnablePlaybackGroup1(bool enable) ui_->playbackDataType->setEnabled(enable); ui_->deltaDelay->setEnabled(enable); ui_->enableSendToNetwork->setEnabled(enable); - ui_->sendOutPortNum->setEnabled(enable && ui_->enableSendToNetwork->checkState() == Qt::Checked); + bool enableSend = ui_->enableSendToNetwork->checkState() == Qt::Checked; + ui_->sendOutPortNum->setEnabled(enable && enableSend); + ui_->checkBoxFMUTx->setEnabled(enable && enableSend); + bool enableFMU = ui_->checkBoxFMUTx->checkState() == Qt::Checked; + ui_->loadFMUTx->setEnabled(enable && enableSend && enableFMU); + ui_->loadFMUTxBrowse->setEnabled(enable && enableSend && enableFMU); } void @@ -645,7 +984,12 @@ MainWindow::EnablePlaybackGroup2(bool enable) ui_->playbackDataType_2->setEnabled(enable); ui_->deltaDelay_2->setEnabled(enable); ui_->enableSendToNetwork_2->setEnabled(enable); - ui_->sendOutPortNum_2->setEnabled(enable && ui_->enableSendToNetwork_2->checkState() == Qt::Checked); + bool enableSend = ui_->enableSendToNetwork_2->checkState() == Qt::Checked; + ui_->sendOutPortNum_2->setEnabled(enable && enableSend); + ui_->checkBoxFMUTx_2->setEnabled(enable && enableSend); + bool enableFMU = ui_->checkBoxFMUTx_2->checkState() == Qt::Checked; + ui_->loadFMUTx_2->setEnabled(enable && enableSend && enableFMU); + ui_->loadFMUTxBrowse_2->setEnabled(enable && enableSend && enableFMU); } void @@ -711,7 +1055,10 @@ MainWindow::UpdateGLWidgetMessageSource() { if(isSrcConnection_) { - glWidget_->UpdateIMessageSource(receiver_); + if(ui_->checkBoxFMURx->isChecked()) + glWidget_->UpdateIMessageSource(fmuReceiver_); + else + glWidget_->UpdateIMessageSource(tcpReceiver_); } else { @@ -724,7 +1071,10 @@ MainWindow::UpdateGLWidgetMessageSource2() { if(isSrcConnection2_) { - glWidget2_->UpdateIMessageSource(receiver2_); + if(ui_->checkBoxFMURx_2->isChecked()) + glWidget2_->UpdateIMessageSource(fmuReceiver2_); + else + glWidget2_->UpdateIMessageSource(tcpReceiver2_); } else { @@ -796,6 +1146,18 @@ MainWindow::UpdateConfigure() config_.ch1DataType_ = (DataType)ui_->dataType->currentIndex(); } + if(config_.ch1FMURxCheck_ != (ui_->checkBoxFMURx->checkState() == Qt::Checked)) + { + saveChange = true; + config_.ch1FMURxCheck_ = (ui_->checkBoxFMURx->checkState() == Qt::Checked); + } + + if(config_.ch1LoadFMURx_ != ui_->loadFMURx->text()) + { + hasChange = true; + config_.ch1LoadFMURx_ = ui_->loadFMURx->text(); + } + if(config_.ch1LoadFile_ != ui_->loadFile->text()) { hasChange = true; @@ -827,6 +1189,19 @@ MainWindow::UpdateConfigure() reader_->SetSendOutPortNum(config_.ch1SendOutPortNum_.toStdString()); } + if(config_.ch1FMUTxCheck_ != (ui_->checkBoxFMUTx->checkState() == Qt::Checked)) + { + hasChange = true; + config_.ch1FMUTxCheck_ = (ui_->checkBoxFMUTx->checkState() == Qt::Checked); + } + + if(config_.ch1LoadFMUTx_ != ui_->loadFMUTx->text()) + { + hasChange = true; + config_.ch1LoadFMUTx_ = ui_->loadFMUTx->text(); +// reader_->SetSendOutFMUPath(config_.ch1LoadFMUTx_.toStdString()); + } + if(hasChange || saveChange) config_.Save(); @@ -857,6 +1232,18 @@ MainWindow::UpdateConfigure2() config_.ch2DataType_ = (DataType)ui_->dataType_2->currentIndex(); } + if(config_.ch2FMURxCheck_ != (ui_->checkBoxFMURx->checkState() == Qt::Checked)) + { + saveChange = true; + config_.ch2FMURxCheck_ = (ui_->checkBoxFMURx->checkState() == Qt::Checked); + } + + if(config_.ch2LoadFMURx_ != ui_->loadFMURx->text()) + { + hasChange = true; + config_.ch2LoadFMURx_ = ui_->loadFMURx->text(); + } + if(config_.ch2LoadFile_ != ui_->loadFile_2->text()) { hasChange = true; @@ -888,6 +1275,18 @@ MainWindow::UpdateConfigure2() reader2_->SetSendOutPortNum(config_.ch2SendOutPortNum_.toStdString()); } + if(config_.ch2FMUTxCheck_ != (ui_->checkBoxFMUTx_2->checkState() == Qt::Checked)) + { + hasChange = true; + config_.ch2FMUTxCheck_ = (ui_->checkBoxFMUTx_2->checkState() == Qt::Checked); + } + + if(config_.ch2LoadFMUTx_ != ui_->loadFMUTx_2->text()) + { + hasChange = true; + config_.ch2LoadFMUTx_ = ui_->loadFMUTx_2->text(); + } + if(hasChange || saveChange) config_.Save(); @@ -902,9 +1301,17 @@ MainWindow::InitLoadConfigure() ui_->ipAddress->setText(config_.ch1IPAddress_); ui_->portNumber->setText(config_.ch1PortNum_); ui_->dataType->setCurrentIndex( static_cast(config_.ch1DataType_) ); + + if(config_.ch1FMURxCheck_) + ui_->checkBoxFMURx->setCheckState(Qt::Checked); + else + ui_->checkBoxFMURx->setCheckState(Qt::Unchecked); + ui_->loadFMURx->setText(config_.ch1LoadFMURx_); + ui_->loadFile->setText(config_.ch1LoadFile_); ui_->playbackDataType->setCurrentIndex( static_cast(config_.ch1PlaybackDataType_) ); ui_->deltaDelay->setText(QString::number(config_.ch1DeltaDelay_)); + if(config_.ch1EnableSendOut_) ui_->enableSendToNetwork->setCheckState(Qt::Checked); else @@ -912,12 +1319,39 @@ MainWindow::InitLoadConfigure() ui_->sendOutPortNum->setText(config_.ch1SendOutPortNum_); reader_->SetSendOutPortNum(config_.ch1SendOutPortNum_.toStdString()); + if(config_.ch1FMUTxCheck_) + ui_->checkBoxFMUTx->setCheckState(Qt::Checked); + else + ui_->checkBoxFMUTx->setCheckState(Qt::Unchecked); + ui_->checkBoxFMUTx->setEnabled(config_.ch1EnableSendOut_); + ui_->loadFMUTx->setEnabled(config_.ch1EnableSendOut_ && config_.ch1FMUTxCheck_); + ui_->loadFMUTx->setText(config_.ch1LoadFMUTx_); + + if(config_.ch1ShowFOV_) + ui_->showFOV->setCheckState(Qt::Checked); + else + ui_->showFOV->setCheckState(Qt::Unchecked); + ui_->minRadius->setText(QString::number(config_.ch1MinRadius_)); + ui_->maxRadius->setText(QString::number(config_.ch1MaxRadius_)); + ui_->azimuthPos->setText(QString::number(config_.ch1AzimuthPos_)); + ui_->azimuthNeg->setText(QString::number(config_.ch1AzimuthNeg_)); + + + ui_->ipAddress_2->setText(config_.ch2IPAddress_); ui_->portNumber_2->setText(config_.ch2PortNum_); ui_->dataType_2->setCurrentIndex( static_cast(config_.ch2DataType_) ); + + if(config_.ch2FMURxCheck_) + ui_->checkBoxFMURx_2->setCheckState(Qt::Checked); + else + ui_->checkBoxFMURx_2->setCheckState(Qt::Unchecked); + ui_->loadFMURx_2->setText(config_.ch2LoadFMURx_); + ui_->loadFile_2->setText(config_.ch2LoadFile_); ui_->playbackDataType_2->setCurrentIndex( static_cast(config_.ch2PlaybackDataType_) ); ui_->deltaDelay_2->setText(QString::number(config_.ch2DeltaDelay_)); + if(config_.ch2EnableSendOut_) ui_->enableSendToNetwork_2->setCheckState(Qt::Checked); else @@ -925,6 +1359,25 @@ MainWindow::InitLoadConfigure() ui_->sendOutPortNum_2->setText(config_.ch2SendOutPortNum_); reader2_->SetSendOutPortNum(config_.ch2SendOutPortNum_.toStdString()); + if(config_.ch2FMUTxCheck_) + ui_->checkBoxFMUTx_2->setCheckState(Qt::Checked); + else + ui_->checkBoxFMUTx_2->setCheckState(Qt::Unchecked); + ui_->checkBoxFMUTx_2->setEnabled(config_.ch2EnableSendOut_); + ui_->loadFMUTx_2->setEnabled(config_.ch2EnableSendOut_ && config_.ch2FMUTxCheck_); + ui_->loadFMUTx_2->setText(config_.ch2LoadFMUTx_); + + if(config_.ch2ShowFOV_) + ui_->showFOV_2->setCheckState(Qt::Checked); + else + ui_->showFOV_2->setCheckState(Qt::Unchecked); + ui_->minRadius_2->setText(QString::number(config_.ch2MinRadius_)); + ui_->maxRadius_2->setText(QString::number(config_.ch2MaxRadius_)); + ui_->azimuthPos_2->setText(QString::number(config_.ch2AzimuthPos_)); + ui_->azimuthNeg_2->setText(QString::number(config_.ch2AzimuthNeg_)); + + + ui_->actionCombiCh->setChecked(config_.combineChannel_); ui_->actionShowGrid->setChecked(config_.showGrid_); ui_->actionShowObject->setChecked(config_.showObjectDetails_); @@ -1053,6 +1506,132 @@ MainWindow::CombineChannels() config_.Save(); } +void +MainWindow::ShowFOV() +{ + // fetch data + if(ui_->showFOV->isChecked()) + { + QString err; + bool success = false; + float minR = ui_->minRadius->text().toFloat(&success); + if(!success) + err += "input valid minimum radius parameter in Channel 1\n"; + + float maxR = ui_->maxRadius->text().toFloat(&success); + if(!success) + err += "input valid maximum radius parameter in Channel 1\n"; + + float aPos = ui_->azimuthPos->text().toFloat(&success); + if(!success) + err += "input valid azimuth positive angle in Channel 1\n"; + + float aNeg = ui_->azimuthNeg->text().toFloat(&success); + if(!success) + err += "input valid azimuth negtive angle in Channel 1\n"; + + if(err.isEmpty()) + { + config_.ch1ShowFOV_ = true; + config_.ch1MinRadius_ = minR; + config_.ch1MaxRadius_ = maxR; + config_.ch1AzimuthPos_ = aPos; + config_.ch1AzimuthNeg_ = aNeg; + EnableShowFOV(false); + aPos = (aPos/180)*M_PI; + aNeg = (aNeg/180)*M_PI; + glWidget_->UpdateFOVParam(minR, maxR, aPos, aNeg); + } + else + { + config_.ch1ShowFOV_ = false; + EnableShowFOV(true); + glWidget_->UpdateFOVPaint(false); + ui_->showFOV->setChecked(false); + ShowErrorMessage(err); + } + } + else + { + EnableShowFOV(true); + glWidget_->UpdateFOVPaint(false); + } + + config_.Save(); +} + +void +MainWindow::ShowFOV2() +{ + // fetch data + if(ui_->showFOV_2->isChecked()) + { + QString err; + bool success = false; + float minR = ui_->minRadius_2->text().toFloat(&success); + if(!success) + err += "input valid minimum radius parameter in Channel 2\n"; + + float maxR = ui_->maxRadius_2->text().toFloat(&success); + if(!success) + err += "input valid maximum radius parameter in Channel 2\n"; + + float aPos = ui_->azimuthPos_2->text().toFloat(&success); + if(!success) + err += "input valid azimuth positive angle in Channel 2\n"; + + float aNeg = ui_->azimuthNeg_2->text().toFloat(&success); + if(!success) + err += "input valid azimuth negtive angle in Channel 2\n"; + + if(err.isEmpty()) + { + config_.ch2ShowFOV_ = true; + config_.ch2MinRadius_ = minR; + config_.ch2MaxRadius_ = maxR; + config_.ch2AzimuthPos_ = aPos; + config_.ch2AzimuthNeg_ = aNeg; + EnableShowFOV2(false); + aPos = (aPos/180)*M_PI; + aNeg = (aNeg/180)*M_PI; + glWidget2_->UpdateFOVParam(minR, maxR, aPos, aNeg); + } + else + { + config_.ch2ShowFOV_ = false; + EnableShowFOV2(true); + glWidget2_->UpdateFOVPaint(false); + ui_->showFOV_2->setChecked(false); + ShowErrorMessage(err); + } + } + else + { + EnableShowFOV2(true); + glWidget2_->UpdateFOVPaint(false); + } + + config_.Save(); +} + +void +MainWindow::EnableShowFOV(const bool enable) +{ + ui_->minRadius->setEnabled(enable); + ui_->maxRadius->setEnabled(enable); + ui_->azimuthNeg->setEnabled(enable); + ui_->azimuthPos->setEnabled(enable); +} + +void +MainWindow::EnableShowFOV2(const bool enable) +{ + ui_->minRadius_2->setEnabled(enable); + ui_->maxRadius_2->setEnabled(enable); + ui_->azimuthNeg_2->setEnabled(enable); + ui_->azimuthPos_2->setEnabled(enable); +} + void MainWindow::ChooseBoundaryLanes() { @@ -1170,14 +1749,25 @@ MainWindow::Play() if(isSrcConnection_) { - emit ConnectRequested(config_.ch1IPAddress_, - config_.ch1PortNum_, - config_.ch1DataType_); + if(ui_->checkBoxFMURx->isChecked()) + { + emit FMUConnectRequested(config_.ch1IPAddress_, + config_.ch1PortNum_, + config_.ch1LoadFMURx_, + config_.ch1DataType_); + } + else + { + emit ConnectRequested(config_.ch1IPAddress_, + config_.ch1PortNum_, + config_.ch1DataType_); + } } else { emit StartPlaybackRequested(config_.ch1LoadFile_, - config_.ch1PlaybackDataType_); + config_.ch1PlaybackDataType_, + config_.ch1LoadFMUTx_); } } @@ -1188,10 +1778,12 @@ MainWindow::TogglePause() if(isConnected_) { - receiver_->isPaused_ = isPlaying_; + if(ui_->checkBoxFMURx->isChecked()) + fmuReceiver_->isPaused_ = isPlaying_; + else + tcpReceiver_->isPaused_ = isPlaying_; } - - if(isPlayed_) + else if(isPlayed_) { if(isPlaying_) { @@ -1216,9 +1808,16 @@ void MainWindow::Stop() { if(isConnected_) - receiver_->DisconnectRequested(); + { + if(ui_->checkBoxFMURx->isChecked()) + fmuReceiver_->DisconnectRequested(); + else + tcpReceiver_->DisconnectRequested(); + } else if(isPlayed_) + { reader_->StopReadFile(); + } ResetSliderTime(); } @@ -1230,14 +1829,25 @@ MainWindow::Play2() if(isSrcConnection2_) { - emit ConnectRequested2(config_.ch2IPAddress_, - config_.ch2PortNum_, - config_.ch2DataType_); + if(ui_->checkBoxFMURx_2->isChecked()) + { + emit FMUConnectRequested2(config_.ch2IPAddress_, + config_.ch2PortNum_, + config_.ch2LoadFMURx_, + config_.ch2DataType_); + } + else + { + emit ConnectRequested2(config_.ch2IPAddress_, + config_.ch2PortNum_, + config_.ch2DataType_); + } } else { emit StartPlaybackRequested2(config_.ch2LoadFile_, - config_.ch1PlaybackDataType_); + config_.ch2PlaybackDataType_, + config_.ch2LoadFMUTx_); } } @@ -1248,7 +1858,10 @@ MainWindow::TogglePause2() if(isConnected2_) { - receiver2_->isPaused_ = isPlaying2_; + if(ui_->checkBoxFMURx_2->isChecked()) + fmuReceiver2_->isPaused_ = isPlaying_; + else + tcpReceiver2_->isPaused_ = isPlaying2_; } else if(isPlayed2_) { @@ -1275,9 +1888,16 @@ void MainWindow::Stop2() { if(isConnected2_) - receiver2_->DisconnectRequested(); + { + if(ui_->checkBoxFMURx_2->isChecked()) + fmuReceiver2_->DisconnectRequested(); + else + tcpReceiver2_->DisconnectRequested(); + } else if(isPlayed2_) + { reader2_->StopReadFile(); + } ResetSliderTime2(); } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index f437162..c3cf6e7 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -9,8 +9,8 @@ 0 0 - 1076 - 926 + 1445 + 1378 @@ -272,7 +272,20 @@ - + + + + + Qt::Horizontal + + + + 20 + 20 + + + + @@ -292,7 +305,7 @@ - + @@ -328,7 +341,7 @@ - + Data: @@ -360,18 +373,39 @@ - - - - Qt::Horizontal + + + + + + + + + + 25 + 25 + + + + ... + + + + + + + + + - - - 20 - 20 - + + + + + + FMU: - + @@ -405,8 +439,21 @@ - - + + + 0 + + + + + + + + Data: + + + + Qt::Horizontal @@ -419,192 +466,278 @@ - - + + + + + + to Port: + + + + + + + + 60 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + - + 0 0 - - - 25 - 25 - - - Load: + Delay: - - - - - 50 - 25 - + + + + - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + Send - - - - - 25 - 25 - + + + + + 0 + 0 + - + 25 25 - ... + Load: - - - - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 20 - 20 - + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 80 + 16777215 + + + + 0 + + + + + + + ms + + + + + + + + + 0 + + + + + + 50 + 25 + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 25 + 25 + + + + + 25 + 25 + + + + ... + + + + + + + + + - + - - + + - Data: + FMU: - - + + + + + + + + + + 25 + 25 + + + + ... + + + + - - - 0 + + + Qt::Vertical - - 0 + + + 20 + 10 + - - 0 + + + + + + Show Field of View + + + + 0 - - - - Qt::Horizontal - - - - 20 - 20 - + + + + AP - + - - - - - 0 - 0 - - + + + + + + + + - Delay: + m - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 80 - 16777215 - - + + - 0 + MaxR - - + + - ms + deg - - - - Qt::Horizontal + + + + MinR - - - 40 - 20 - + + + + + + m - + - - - - - - 0 - - - + + Qt::Horizontal @@ -616,38 +749,25 @@ - - - - - + + + + + - Send to Port: + AN - - - - - 60 - 16777215 - - - + + - - - - Qt::Horizontal - - - - 20 - 20 - + + + + deg - + @@ -977,7 +1097,7 @@ - + @@ -1015,7 +1135,7 @@ - + @@ -1051,7 +1171,7 @@ - + Data: @@ -1096,6 +1216,40 @@ + + + + FMU: + + + + + + + + + + + + + 25 + 25 + + + + ... + + + + + + + + + + + + @@ -1128,21 +1282,134 @@ - - - - - Qt::Horizontal + + + 0 + + + + + 0 + + + + + + 50 + 0 + + + + + 80 + 16777215 + + + + 0 + + + + + + + ms + + + + + + + + + + + to Port: + + + + + + + + 60 + 16777215 + + + + + + + + Qt::Horizontal + + + + 20 + 20 + + + + + + + + + + 0 + + + + + + 50 + 25 + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 25 + 25 + + + + + 25 + 25 + + + + ... + + + + + + + + + Send - - - 20 - 20 - + + + + + + - + - + @@ -1157,54 +1424,22 @@ - Load: + Load: - - - - - 50 - 25 - - - + + + - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - 25 - 25 - - - - - 25 - 25 - - - ... + - - - - - - 0 - - - + + Qt::Horizontal @@ -1216,91 +1451,103 @@ - + Data: - + + + + Delay: + + + + + + + + FMU: + + + + + + + + + + + + + 25 + 25 + + + + ... + + + + + - + + + Show Field of View + + + + + 0 - - - - Qt::Horizontal - - - - 20 - 20 - - - + + - - + + - Delay: + AP - - - - - 50 - 0 - - - - - 80 - 16777215 - - + + + + + - 0 + m - - + + - ms + deg - - - - Qt::Horizontal - - - - 40 - 20 - + + + + + + + MinR - + - - - - - - 0 - - - + + Qt::Horizontal @@ -1312,38 +1559,36 @@ - - - - - + + - Send to Port: + m - - - - - 60 - 16777215 - + + + + MaxR - - - - Qt::Horizontal + + + + AN - - - 40 - 20 - + + + + + + + + + deg - + @@ -1517,7 +1762,7 @@ 0 0 - 1076 + 1445 22 @@ -1668,10 +1913,6 @@ portNumber_2 dataType_2 playPauseButton - loadFile - loadFileBrowse - loadFile_2 - loadFileBrowse_2 playPauseButton_2 saveOSIMessage saveOSIMessage_2 diff --git a/src/osiparser.cpp b/src/osiparser.cpp index 93bbc08..6882b97 100644 --- a/src/osiparser.cpp +++ b/src/osiparser.cpp @@ -148,44 +148,33 @@ OsiParser::ParseGroundtruth(Message& objectMessage, for (int i = 0; i < currentGroundTruth_.lane_size(); ++i) { - osi::Lane lane = currentGroundTruth_.lane(i); + const osi::Lane& lane = currentGroundTruth_.lane(i); LaneStruct tmpLane; tmpLane.id = lane.id().value(); // DRAW_CENTER_LINES + QVector centerLines; + for (int a = 0; a < lane.center_line_size(); ++a) { - // lane > > - QVector centerLines; - for (int a = 0; a < lane.center_line_size(); ++a) - { - osi::Vector3d centerLine = lane.center_line(a); - centerLines.append(QVector3D(-centerLine.x(), 0, centerLine.y())); - } - - tmpLane.centerLanes.append(centerLines); + const osi::Vector3d& centerLine = lane.center_line(a); + centerLines.append(QVector3D(centerLine.y(), 0, centerLine.x())); } + tmpLane.centerLanes.append(centerLines); // DRAW_LANE_BOUNDARIES + for (int b = 0; b < lane.lane_boundary_size(); ++b) { - // lanes > > - QVector> laneBoundaries; + const osi::LaneBoundary& laneBoundary = lane.lane_boundary(b); + QVector boundaryLines; - for (int b = 0; b < lane.lane_boundary_size(); ++b) + for (int c = 0; c < laneBoundary.boundary_line_size(); ++c) { - osi::LaneBoundary laneBoundary = lane.lane_boundary(b); - QVector boundaryLines; - - for (int c = 0; c < laneBoundary.boundary_line_size(); ++c) - { - osi::BoundaryPoint boundaryLine = laneBoundary.boundary_line(c); - osi::Vector3d position = boundaryLine.position(); - boundaryLines.append(QVector3D(-position.x(), 0, position.y())); - } - - laneBoundaries.append(boundaryLines); + const osi::BoundaryPoint& boundaryLine = laneBoundary.boundary_line(c); + const osi::Vector3d& position = boundaryLine.position(); + boundaryLines.append(QVector3D(position.y(), 0, position.x())); } - tmpLane.boundaryLanes= laneBoundaries; + tmpLane.boundaryLanes.append(boundaryLines); } laneMessage.append(tmpLane); @@ -223,8 +212,8 @@ OsiParser::ParseGroundtruthMovingObject(Message& objectMessage, tmpMsg.name = "ID: " + idStr; tmpMsg.type = objectType; tmpMsg.isEgoVehicle = isEgoVehicle; - tmpMsg.orientation = orientation; - tmpMsg.position = QVector3D(-position.x(), 0, position.y()); + tmpMsg.orientation = orientation+M_PI_2; + tmpMsg.position = QVector3D(position.y(), 0, position.x()); tmpMsg.realPosition = QVector3D(position.x(), position.y(), position.z()); tmpMsg.velocitie = QVector3D(velocity.x(), velocity.y(), velocity.z()); tmpMsg.acceleration = QVector3D(acceleration.x(), acceleration.y(), acceleration.z()); @@ -269,8 +258,8 @@ OsiParser::ParseGroundtruthStationaryObject(Message& objectMessage, tmpMsg.name = "ID: " + idStr; tmpMsg.type = objectType; tmpMsg.isEgoVehicle = isEgoVehicle; - tmpMsg.orientation = orientation; - tmpMsg.position = QVector3D(-position.x(), 0, position.y()); + tmpMsg.orientation = orientation+M_PI_2; + tmpMsg.position = QVector3D(position.y(), 0, position.x()); tmpMsg.realPosition = QVector3D(position.x(), position.y(), position.z()); tmpMsg.velocitie = QVector3D(velocity.x(), velocity.y(), velocity.z()); tmpMsg.acceleration = QVector3D(acceleration.x(), acceleration.y(), acceleration.z()); @@ -330,63 +319,54 @@ OsiParser::ParseSensorData(Message& objectMessage, for (int i = 0; i < currentSensorData_.lane_size(); ++i) { - osi::DetectedLane lane = currentSensorData_.lane(i); + const osi::DetectedLane& lane = currentSensorData_.lane(i); if(lane.existence_probability() == 1) { LaneStruct tmpLane; tmpLane.id = lane.lane().id().value(); // DRAW_CENTER_LINES + QVector centerLines; + for (int a = 0; a < lane.lane().center_line_size(); ++a) { - // lane > > - QVector centerLines; - for (int a = 0; a < lane.lane().center_line_size(); ++a) + const osi::Vector3d& centerLine = lane.lane().center_line(a); + if(centerLine.x() != 0 || centerLine.y() != 0 || centerLine.z() != 0) { - osi::Vector3d centerLine = lane.lane().center_line(a); - if(centerLine.x() != 0 || centerLine.y() != 0 || centerLine.z() != 0) - { - centerLines.append(QVector3D(centerLine.x(), 0, -centerLine.y())); - } - else - { - tmpLane.centerLanes.append(centerLines); - centerLine.Clear(); - } + centerLines.append(QVector3D(centerLine.x(), 0, -centerLine.y())); + } + else if(!centerLines.empty()) + { + tmpLane.centerLanes.append(centerLines); + centerLines.clear(); } - - tmpLane.centerLanes.append(centerLines); } + if(!centerLines.empty()) + tmpLane.centerLanes.append(centerLines); // DRAW_LANE_BOUNDARIES + for (int b = 0; b < lane.lane().lane_boundary_size(); ++b) { - // lanes > > - QVector> laneBoundaries; + const osi::LaneBoundary& laneBoundary = lane.lane().lane_boundary(b); + QVector boundaryLines; - for (int b = 0; b < lane.lane().lane_boundary_size(); ++b) + for (int c = 0; c < laneBoundary.boundary_line_size(); ++c) { - osi::LaneBoundary laneBoundary = lane.lane().lane_boundary(b); - QVector boundaryLines; + const osi::BoundaryPoint& boundaryLine = laneBoundary.boundary_line(c); + const osi::Vector3d& position = boundaryLine.position(); - for (int c = 0; c < laneBoundary.boundary_line_size(); ++c) + if(position.x() != 0 || position.y() != 0 || position.z() != 0) { - osi::BoundaryPoint boundaryLine = laneBoundary.boundary_line(c); - osi::Vector3d position = boundaryLine.position(); - - if(position.x() != 0 || position.y() != 0 || position.z() != 0) - { - boundaryLines.append(QVector3D(position.x(), 0, -position.y())); - } - else - { - laneBoundaries.append(boundaryLines); - boundaryLines.clear(); - } + boundaryLines.append(QVector3D(position.x(), 0, -position.y())); + } + else if(!boundaryLines.empty()) + { + tmpLane.boundaryLanes.append(boundaryLines); + boundaryLines.clear(); } - - laneBoundaries.append(boundaryLines); } - tmpLane.boundaryLanes= laneBoundaries; + if(!boundaryLines.empty()) + tmpLane.boundaryLanes.append(boundaryLines); } laneMessage.append(tmpLane); @@ -394,13 +374,11 @@ OsiParser::ParseSensorData(Message& objectMessage, } } - /* * * Parse a moving SensorData Object * */ - void OsiParser::ParseSensorDataMovingObject(Message& objectMessage, const osi::BaseMoving& baseObject, @@ -416,13 +394,6 @@ OsiParser::ParseSensorDataMovingObject(Message& objectMessage, osi::Vector3d velocity = baseObject.velocity(); osi::Vector3d acceleration = baseObject.acceleration(); float orientation = baseObject.orientation().yaw(); - osi::Dimension3d dimension = baseObject.dimension(); - - if (dimension.width() == 0 && dimension.length() == 0) - { - dimension.set_width(1.0f); - dimension.set_length(1.0f); - } MessageStruct tmpMsg; tmpMsg.id = Global::GetObjectTypeName(objectType) + idStr; @@ -434,7 +405,25 @@ OsiParser::ParseSensorDataMovingObject(Message& objectMessage, tmpMsg.realPosition = QVector3D(position.x(), position.y(), position.z()); tmpMsg.velocitie = QVector3D(velocity.x(), velocity.y(), velocity.z()); tmpMsg.acceleration = QVector3D(acceleration.x(), acceleration.y(), acceleration.z()); - tmpMsg.dimension = dimension; + + if(baseObject.base_polygon_size() == 4) + { + for(int i = 0; i < 4; ++i) + { + const osi::Vector2d& vertice = baseObject.base_polygon(i); + tmpMsg.basePoly.push_back(QVector3D(vertice.x() - position.x(), 0, -vertice.y()+position.y())); + } + } + else + { + osi::Dimension3d dimension = baseObject.dimension(); + if (dimension.width() == 0 && dimension.length() == 0) + { + dimension.set_width(1.0f); + dimension.set_length(1.0f); + } + tmpMsg.dimension = dimension; + } objectMessage.append(tmpMsg); } @@ -459,13 +448,6 @@ OsiParser::ParseSensorDataStationaryObject(Message& objectMessage, osi::Vector3d velocity = tmp; osi::Vector3d acceleration = tmp; float orientation = baseObject.orientation().yaw(); - osi::Dimension3d dimension = baseObject.dimension(); - - if (dimension.width() == 0 && dimension.length() == 0) - { - dimension.set_width(1.0f); - dimension.set_length(1.0f); - } MessageStruct tmpMsg; tmpMsg.id = Global::GetObjectTypeName(objectType) + idStr; @@ -477,8 +459,26 @@ OsiParser::ParseSensorDataStationaryObject(Message& objectMessage, tmpMsg.realPosition = QVector3D(position.x(), position.y(), position.z()); tmpMsg.velocitie = QVector3D(velocity.x(), velocity.y(), velocity.z()); tmpMsg.acceleration = QVector3D(acceleration.x(), acceleration.y(), acceleration.z()); - tmpMsg.dimension = dimension; - + + if(baseObject.base_polygon_size() == 4) + { + for(int i = 0; i < 4; ++i) + { + const osi::Vector2d& vertice = baseObject.base_polygon(i); + tmpMsg.basePoly.push_back(QVector3D(vertice.x(), 0, -vertice.y())); + } + } + else + { + osi::Dimension3d dimension = baseObject.dimension(); + if (dimension.width() == 0 && dimension.length() == 0) + { + dimension.set_width(1.0f); + dimension.set_length(1.0f); + } + tmpMsg.dimension = dimension; + } + objectMessage.append(tmpMsg); } diff --git a/src/osireader.cpp b/src/osireader.cpp index 67e2fb5..e16328e 100644 --- a/src/osireader.cpp +++ b/src/osireader.cpp @@ -7,10 +7,60 @@ #include #include "osireader.h" +/** +* local functions +*/ + +static void fmuWrapperLogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message) +{ + switch (log_level) + { + case jm_log_level_fatal: + qDebug() << (message); + break; + case jm_log_level_error: + case jm_log_level_warning: + qDebug() << message; + break; + case jm_log_level_nothing: + case jm_log_level_info: + case jm_log_level_verbose: + case jm_log_level_debug: + case jm_log_level_all: + qDebug() << message; + break; + } +} + +static void encode_pointer_to_integer(const void* ptr, fmi2_integer_t& hi, fmi2_integer_t& lo) +{ +#if PTRDIFF_MAX == INT64_MAX + union addrconv + { + struct + { + int lo; + int hi; + } base; + unsigned long long address; + } myaddr; + myaddr.address = reinterpret_cast(ptr); + hi = myaddr.base.hi; + lo = myaddr.base.lo; +#elif PTRDIFF_MAX == INT32_MAX + hi = 0; + lo = reinterpret_cast(ptr); +#else +#error "Cannot determine 32bit or 64bit environment!" +#endif +} + OsiReader::OsiReader(int* deltaDelay, const bool& enableSendOut, - const std::string& zmqPubPortNum) + const std::string& pubPortNum, + const bool& enalbeFMU, + const std::string& fmuPath) : IMessageSource() , isRunning_(false) , isReadTerminated_(false) @@ -26,16 +76,36 @@ OsiReader::OsiReader(int* deltaDelay, , deltaDelay_(deltaDelay) , enableSendOut_(enableSendOut) - , zmqPubPortNumber_(zmqPubPortNum) + , pubPortNumber_(pubPortNum) + , zmqContext_(1) , zmqPublisher_(zmqContext_, ZMQ_PUB) + + , enableFMU_(enalbeFMU) + , fmu_(nullptr) + , callBackFunctions_() + , callbacks_() + , fmuContext_(nullptr) + , jmStatus_() + , fmiStatus_() + , tStart_(0) + , tEnd_(0) + , tCurrent_(0) + , hStep_(0) + , FMUPath_(fmuPath) + , tmpPath_() + , logLevel_(LogLevel::Warn) + , currentBuffer_() + , vr_() + , integerVars_() { } void -OsiReader::StartReadFile(const QString& osiFileName, const DataType dataType) +OsiReader::StartReadFile(const QString& osiFileName, const DataType dataType, const QString& fmuPath) { zmqPublisher_.close(); + FMUPath_ = fmuPath.toStdString(); QString errMsg = SetupConnection(true); bool success = errMsg.isEmpty(); @@ -109,6 +179,7 @@ OsiReader::StopReadFile() } QString errMsg = SetupConnection(false); + FreeFMUConnection(); isConnected_ = false; emit Disconnected(errMsg); @@ -168,7 +239,7 @@ OsiReader::SliderValueChanged(int newValue) { uint64_t curStamp = GetTimeStampInNanoSecond(osiSD); MessageSendout(osiSD, defaultDatatype_); - ZMQSendOutMessage(str_line); + SendOutMessage(str_line); // update slider value in millisecond level int sliderValue = curStamp / 1000000; UpdateSliderValue(sliderValue); @@ -369,7 +440,7 @@ OsiReader::SendMessageLoop() preTimeStamp = curStamp; MessageSendout(osiSD, defaultDatatype_); - ZMQSendOutMessage(str_line); + SendOutMessage(str_line); // update slider value in millisecond level int sliderValue = (curStamp - firstTimeStamp) / 1000000; UpdateSliderValue(sliderValue); @@ -413,12 +484,20 @@ OsiReader::SendMessageLoop() } void -OsiReader::ZMQSendOutMessage(const std::string& message) +OsiReader::SendOutMessage(const std::string& message) { + currentBuffer_ = message; + if(enableSendOut_ && enableFMU_ && fmu_ != nullptr) + { + set_fmi_sensor_data_out(); + fmi2_boolean_t newStep = fmi2_true; + time_t timeC = time(NULL); + fmiStatus_ = fmi2_import_do_step(fmu_, (fmi2_real_t)timeC, hStep_, newStep); + } if(enableSendOut_ && zmqPublisher_.connected()) { - zmq::message_t zmqMessage(message.size()); - memcpy(zmqMessage.data(), message.data(), message.size()); + zmq::message_t zmqMessage(currentBuffer_.size()); + memcpy(zmqMessage.data(), currentBuffer_.data(), currentBuffer_.size()); zmqPublisher_.send(zmqMessage); } } @@ -427,38 +506,234 @@ QString OsiReader::SetupConnection(bool enable) { QString errMsg; - if(enable && enableSendOut_) + if(enable && enableSendOut_ && enableFMU_) { - if(!zmqPublisher_.connected()) - { - zmqPublisher_ = zmq::socket_t(zmqContext_, ZMQ_PUB); - zmqPublisher_.setsockopt(ZMQ_LINGER, 100); - try - { - zmqPublisher_.bind("tcp://*:" + zmqPubPortNumber_); - } - catch (zmq::error_t& error) - { - zmqPublisher_.close(); - errMsg = "Error connecting to endpoint: " + QString::fromUtf8(error.what()); - } - } + errMsg = SetFMUConnection(); + } + else if(enable && enableSendOut_) + { + errMsg = SetZMQConnection(); } else { if(zmqPublisher_.connected()) { - try - { - zmqPublisher_.close(); - } - catch (zmq::error_t& error) - { - errMsg = "Error close connecting to endpoint: " + QString::fromUtf8(error.what()); - } + errMsg = FreeZMQConnection(); + } + } + + return errMsg; +} + +QString +OsiReader::SetZMQConnection() +{ + QString errMsg; + if(!zmqPublisher_.connected()) + { + zmqPublisher_ = zmq::socket_t(zmqContext_, ZMQ_PUB); + zmqPublisher_.setsockopt(ZMQ_LINGER, 100); + try + { + zmqPublisher_.bind("tcp://*:" + pubPortNumber_); + } + catch (zmq::error_t& error) + { + zmqPublisher_.close(); + errMsg = "Error connecting to endpoint: " + QString::fromUtf8(error.what()); + } + } + + return errMsg; +} + +QString +OsiReader::FreeZMQConnection() +{ + QString errMsg; + try + { + zmqPublisher_.close(); + } + catch (zmq::error_t& error) + { + errMsg = "Error close connecting to endpoint: " + QString::fromUtf8(error.what()); + } + + return errMsg; +} + +QString +OsiReader::SetFMUConnection() +{ + QString errMsg; + if(fmu_ == nullptr) + { + if (!FMUPath_.empty()) + { + tmpPath_ = FMUPath_.substr(0, FMUPath_.find_last_of("/\\")); + + if (!initializeFMUWrapper()) + errMsg = "FMU Wrapper initialization failed!"; + + fmu_ = fmi2_import_parse_xml(fmuContext_, tmpPath_.c_str(), 0); + + if (!fmu_ && errMsg.isEmpty()) + errMsg = "Error parsing modeldescription.xml of fmu "; + + if (fmi2_import_get_fmu_kind(fmu_) == fmi2_fmu_kind_me && errMsg.isEmpty()) + errMsg = "Only Co-Simulation 2.0 is supported by this code"; + + if (!importFMU() && errMsg.isEmpty()) + errMsg = "Could not create the DLL loading mechanism (error: " + QString(fmi2_import_get_last_error(fmu_)) + ")."; + + if (!initializeFMU() && errMsg.isEmpty()) + errMsg = "FMU initialization failed:" + QString(fmi2_import_get_last_error(fmu_)); + } + else + { + errMsg = "fmu_path is empty"; } } return errMsg; } +void +OsiReader::FreeFMUConnection() +{ + fmi2_import_destroy_dllfmu(fmu_); + fmi2_import_free(fmu_); + fmi_import_free_context(fmuContext_); + fmu_ = nullptr; +} + +bool +OsiReader::initializeFMUWrapper() +{ + // TODO: config or use default values? + callbacks_.malloc = malloc; + callbacks_.calloc = calloc; + callbacks_.realloc = realloc; + callbacks_.free = free; + callbacks_.logger = fmuWrapperLogger; + if (logLevel_ == LogLevel::Warn) + { + callbacks_.log_level = jm_log_level_warning; + } + else + { + callbacks_.log_level = jm_log_level_debug; + } + callbacks_.context = 0; + + fmuContext_ = fmi_import_allocate_context(&callbacks_); + fmi_version_enu_t version = fmi_import_get_fmi_version(fmuContext_, FMUPath_.c_str(), tmpPath_.c_str()); + if (version != fmi_version_2_0_enu) + { + qDebug() << "The code only supports version 2.0"; + return false; + } + return true; +} + +bool +OsiReader::importFMU() +{ + // TODO: config or use default values? + callBackFunctions_.logger = fmi2_log_forwarding; + callBackFunctions_.allocateMemory = calloc; + callBackFunctions_.freeMemory = free; + callBackFunctions_.componentEnvironment = fmu_; + + jmStatus_ = fmi2_import_create_dllfmu(fmu_, fmi2_fmu_kind_cs, &callBackFunctions_); + if (jmStatus_ == jm_status_error) + { + return false; + } + return true; +} + +bool +OsiReader::initializeFMU() +{ + // TODO: config or use default values? + // TODO: alternative solution for start values & verify parameters for setup and initiliazation functions + // start values + fmi2_string_t instanceName = "Test CS model instance"; + + fmi2_string_t fmuLocation = ""; + fmi2_boolean_t visible = fmi2_false; + fmi2_real_t relativeTol = 1e-4; + + tStart_ = 0; + tCurrent_ = tStart_; + fmi2_boolean_t StopTimeDefined = fmi2_false; + + // Do we need it? + fmi2_string_t fmuGUID; + fmuGUID = fmi2_import_get_GUID(fmu_); + + jmStatus_ = fmi2_import_instantiate(fmu_, instanceName, fmi2_cosimulation, fmuLocation, visible); + fmiStatus_ = fmi2_import_setup_experiment(fmu_, fmi2_true, relativeTol, tStart_, StopTimeDefined, tEnd_); + fmiStatus_ = fmi2_import_enter_initialization_mode(fmu_); + fmiStatus_ = fmi2_import_exit_initialization_mode(fmu_); + + vr_[FMI_INTEGER_SENSORDATA_IN_BASELO_IDX] = FMI_INTEGER_SENSORDATA_IN_BASELO_IDX; + vr_[FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX] = FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX; + vr_[FMI_INTEGER_SENSORDATA_IN_SIZE_IDX] = FMI_INTEGER_SENSORDATA_IN_SIZE_IDX; + vr_[FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX] = FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX; + vr_[FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX] = FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX; + vr_[FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX] = FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX; + + integerVars_[FMI_INTEGER_SENSORDATA_IN_BASELO_IDX] = 0; + integerVars_[FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX] = 0; + integerVars_[FMI_INTEGER_SENSORDATA_IN_SIZE_IDX] = 0; + + integerVars_[FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX] = 0; + integerVars_[FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX] = 0; + integerVars_[FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX] = 0; + + /* Boolean Variables defined in the OSMPCNetworkProxy.h */ + // #define FMI_BOOLEAN_DUMMY_IDX 0 + // #define FMI_BOOLEAN_SENDER_IDX 1 + // #define FMI_BOOLEAN_RECEIVER_IDX 2 + fmi2_boolean_t booleanVars_[3]; + booleanVars_[0] = 0; + booleanVars_[1] = 1; + booleanVars_[2] = 0; + fmi2_status_t status1 = fmi2_import_set_boolean(fmu_, vr_, 3, booleanVars_); + + /* String Variables */ + // #define FMI_STRING_ADDRESS_IDX 0 + // #define FMI_STRING_PORT_IDX 1 + fmi2_string_t stringVars_[2]; + stringVars_[0] = "*"; +// stringVars_[0] = "127.0.0.1"; + stringVars_[1] = pubPortNumber_.c_str(); + fmi2_status_t status2 = fmi2_import_set_string(fmu_, vr_, 2, stringVars_); + + if (status1 == fmi2_status_ok && status2 == fmi2_status_ok) + return true; + else + return false; +} + +#include +static int counter = 0; +void +OsiReader::set_fmi_sensor_data_out() +{ +// currentBuffer_ = std::to_string(counter++)+'\n'; +// usleep(500000); + qDebug() << "FMU send message: " << counter++; + encode_pointer_to_integer(currentBuffer_.data(), + integerVars_[FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX], + integerVars_[FMI_INTEGER_SENSORDATA_IN_BASELO_IDX]); + integerVars_[FMI_INTEGER_SENSORDATA_IN_SIZE_IDX] = (fmi2_integer_t)currentBuffer_.length(); + + fmiStatus_ = fmi2_import_set_integer(fmu_, vr_, FMI_INTEGER_VARS, integerVars_); +} + + + From d60744402a3f9ad3d669738e9b3e9b35a8db4a9a Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Thu, 5 Apr 2018 18:35:19 +0200 Subject: [PATCH 02/11] rm test typo bugs --- src/osireader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/osireader.cpp b/src/osireader.cpp index e16328e..66fdbbf 100644 --- a/src/osireader.cpp +++ b/src/osireader.cpp @@ -708,8 +708,7 @@ OsiReader::initializeFMU() // #define FMI_STRING_ADDRESS_IDX 0 // #define FMI_STRING_PORT_IDX 1 fmi2_string_t stringVars_[2]; - stringVars_[0] = "*"; -// stringVars_[0] = "127.0.0.1"; + stringVars_[0] = "127.0.0.1"; stringVars_[1] = pubPortNumber_.c_str(); fmi2_status_t status2 = fmi2_import_set_string(fmu_, vr_, 2, stringVars_); From c5207d1342514697a616e5eca85575eef46af445 Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Thu, 19 Apr 2018 14:48:06 +0200 Subject: [PATCH 03/11] rm debug info --- open-simulation-interface | 2 +- src/osireader.cpp | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/open-simulation-interface b/open-simulation-interface index 132eb8a..ca21a73 160000 --- a/open-simulation-interface +++ b/open-simulation-interface @@ -1 +1 @@ -Subproject commit 132eb8a7727ba650939bbeeae64eba0b7d55e07e +Subproject commit ca21a731e35a96ba3f91ef6cdf4365115ec3f332 diff --git a/src/osireader.cpp b/src/osireader.cpp index 66fdbbf..84d4c77 100644 --- a/src/osireader.cpp +++ b/src/osireader.cpp @@ -718,14 +718,9 @@ OsiReader::initializeFMU() return false; } -#include -static int counter = 0; void OsiReader::set_fmi_sensor_data_out() { -// currentBuffer_ = std::to_string(counter++)+'\n'; -// usleep(500000); - qDebug() << "FMU send message: " << counter++; encode_pointer_to_integer(currentBuffer_.data(), integerVars_[FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX], integerVars_[FMI_INTEGER_SENSORDATA_IN_BASELO_IDX]); From 4ffbc8a0dc5d64e2f4b917543f2aad3f01ac9cee Mon Sep 17 00:00:00 2001 From: "Pierre R. Mai" Date: Tue, 24 Apr 2018 22:51:04 +0200 Subject: [PATCH 04/11] Minimal changes to integrate FMILib into CI builds --- CMakeLists.txt | 6 ------ Dockerfile | 5 ++++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee9d693..b8ed700 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,15 +63,9 @@ set(HEADERS include_directories( - /usr/local/include/fmi-library ${CMAKE_CURRENT_LIST_DIR}/include ) -link_directories( - /usr/local/lib/fmi-library -) - - add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} diff --git a/Dockerfile b/Dockerfile index 5fc2e48..607dcc7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,10 @@ FROM ubuntu:latest RUN mkdir -p /project -RUN apt-get update && apt-get install -y git vim unzip zip cmake gcc g++ qtbase5-dev libprotobuf-dev protobuf-compiler libzmq3-dev +RUN apt-get update && apt-get install -y git vim unzip zip cmake gcc g++ qtbase5-dev libprotobuf-dev protobuf-compiler libzmq3-dev wget +RUN mkdir -p /build +WORKDIR /build +RUN wget http://www.jmodelica.org/downloads/FMIL/FMILibrary-2.0.3-src.zip && unzip FMILibrary-2.0.3-src.zip && mkdir build-fmil && cd build-fmil && cmake -DFMILIB_INSTALL_PREFIX=/usr/local ../FMILibrary-2.0.3 && make install VOLUME [ "/project"] WORKDIR /project From d20db8ff3694e9a66a63a652dd2b9cc98f759c39 Mon Sep 17 00:00:00 2001 From: "Pierre R. Mai" Date: Tue, 24 Apr 2018 23:14:37 +0200 Subject: [PATCH 05/11] Fix OSI reference breakage --- include/osireader.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/osireader.h b/include/osireader.h index 411d310..db77211 100644 --- a/include/osireader.h +++ b/include/osireader.h @@ -8,8 +8,8 @@ #pragma once -#include -#include +#include "osi_version.pb.h" +#include "osi_sensordata.pb.h" #include From 62c0bb37d4f6835f2cf4a2cdb65dd59c0791b80d Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Tue, 15 May 2018 14:21:30 +0200 Subject: [PATCH 06/11] rm fmu hard code; change default message save threshold; display receive message time stamp; add scroll bar for the config info. --- CMakeLists.txt | 6 + include/fmureceiver.h | 32 +- include/mainwindow.h | 2 + include/osireader.h | 31 +- include/tcpreceiver.h | 2 + src/appconfig.cpp | 4 +- src/fmureceiver.cpp | 84 +- src/mainwindow.cpp | 35 +- src/mainwindow.ui | 2150 ++++++++++++++++++++++------------------- src/osireader.cpp | 103 +- src/tcpreceiver.cpp | 12 + 11 files changed, 1306 insertions(+), 1155 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8ed700..ee9d693 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,9 +63,15 @@ set(HEADERS include_directories( + /usr/local/include/fmi-library ${CMAKE_CURRENT_LIST_DIR}/include ) +link_directories( + /usr/local/lib/fmi-library +) + + add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} diff --git a/include/fmureceiver.h b/include/fmureceiver.h index 1545636..4a4aa29 100644 --- a/include/fmureceiver.h +++ b/include/fmureceiver.h @@ -23,17 +23,22 @@ extern "C" { #include } -#define FMI_INTEGER_SENSORDATA_IN_BASELO_IDX 0 -#define FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX 1 -#define FMI_INTEGER_SENSORDATA_IN_SIZE_IDX 2 -#define FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX 3 -#define FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX 4 -#define FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX 5 -#define FMI_INTEGER_LAST_IDX FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX -#define FMI_INTEGER_VARS (FMI_INTEGER_LAST_IDX + 1) - - - +/* The following names come from FMU modelDescription.in.xml */ +#define FMI_SENDER_NAME "sender" +#define FMI_RECEIVER_NAME "receiver" +#define FMI_ADDRESS_NAME "address" +#define FMI_PORT_NAME "port" + +#define FMI_DATA_OUT_BASELO_NAME "OSMPSensorDataOut.base.lo" +#define FMI_DATA_OUT_BASEHI_NAME "OSMPSensorDataOut.base.hi" +#define FMI_DATA_OUT_SIZE_NAME "OSMPSensorDataOut.size" + +/* local index defines */ +#define FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX 0 // correspond to FMI_DATA_OUT_BASELO_NAME +#define FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX 1 // correspond to FMI_DATA_OUT_BASEHI_NAME +#define FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX 2 // correspond to FMI_DATA_OUT_SIZE_NAME +#define FMI_INTEGER_LAST_OUT_IDX FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX +#define FMI_INTEGER_OUT_VARS (FMI_INTEGER_LAST_OUT_IDX + 1) class FMUReceiver: public QObject, public IMessageSource { @@ -89,11 +94,8 @@ class FMUReceiver: public QObject, public IMessageSource Debug }; LogLevel logLevel_; - std::string currentBuffer_; - - fmi2_value_reference_t vr_[FMI_INTEGER_VARS]; - fmi2_integer_t integerVars_[FMI_INTEGER_VARS]; + fmi2_value_reference_t vr_[FMI_INTEGER_OUT_VARS]; // initialize fmu wrapper specific logger, create fmi import context and check fmi version bool initializeFMUWrapper(); diff --git a/include/mainwindow.h b/include/mainwindow.h index 13efdf4..2a4f0eb 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -83,7 +83,9 @@ class MainWindow : public QMainWindow void UpdateSliderRange(int sliderRange); void UpdateSliderRange2(int sliderRange); void UpdateSliderValue(int sliderValue); + void UpdateSliderTime(int sliderValue); void UpdateSliderValue2(int sliderValue); + void UpdateSliderTime2(int sliderValue); void DisplayObjectInformation(GLObject* object); void DisplayObjectInformation2(GLObject* object); diff --git a/include/osireader.h b/include/osireader.h index db77211..9e76b90 100644 --- a/include/osireader.h +++ b/include/osireader.h @@ -8,8 +8,8 @@ #pragma once -#include "osi_version.pb.h" -#include "osi_sensordata.pb.h" +#include +#include #include @@ -24,22 +24,27 @@ #include "types.h" - extern "C" { #include #include } -#define FMI_INTEGER_SENSORDATA_IN_BASELO_IDX 0 -#define FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX 1 -#define FMI_INTEGER_SENSORDATA_IN_SIZE_IDX 2 -#define FMI_INTEGER_SENSORDATA_OUT_BASELO_IDX 3 -#define FMI_INTEGER_SENSORDATA_OUT_BASEHI_IDX 4 -#define FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX 5 -#define FMI_INTEGER_LAST_IDX FMI_INTEGER_SENSORDATA_OUT_SIZE_IDX -#define FMI_INTEGER_VARS (FMI_INTEGER_LAST_IDX + 1) +#define FMI_SENDER_NAME "sender" +#define FMI_RECEIVER_NAME "receiver" +#define FMI_ADDRESS_NAME "address" +#define FMI_PORT_NAME "port" + +#define FMI_DATA_IN_BASELO_NAME "OSMPSensorViewIn.base.lo" +#define FMI_DATA_IN_BASEHI_NAME "OSMPSensorViewIn.base.hi" +#define FMI_DATA_IN_SIZE_NAME "OSMPSensorViewIn.size" +/* local index defines */ +#define FMI_INTEGER_SENSORDATA_IN_BASELO_IDX 0 // correspond to FMI_DATA_IN_BASELO_NAME +#define FMI_INTEGER_SENSORDATA_IN_BASEHI_IDX 1 // correspond to FMI_DATA_IN_BASEHI_NAME +#define FMI_INTEGER_SENSORDATA_IN_SIZE_IDX 2 // correspond to FMI_DATA_IN_SIZE_NAME +#define FMI_INTEGER_LAST_IN_IDX FMI_INTEGER_SENSORDATA_IN_SIZE_IDX +#define FMI_INTEGER_IN_VARS (FMI_INTEGER_LAST_IN_IDX + 1) class OsiReader: public QObject, public IMessageSource @@ -96,6 +101,7 @@ class OsiReader: public QObject, public IMessageSource QString osiFileName_; QString osiHeaderName_; + uint64_t firstTimeStamp_; // std::map