From 7101ad229e1e3d7e416258697ca793865a695fd2 Mon Sep 17 00:00:00 2001 From: Valentin Platzgummer Date: Sat, 11 Jul 2020 14:06:18 +0200 Subject: [PATCH] 123 --- qgroundcontrol.pro | 6 ++- src/Wima/GeoPoint3D.h | 16 +++--- src/Wima/PolygonArray.h | 2 +- src/Wima/QtROSJsonFactory.h | 2 +- src/Wima/WimaPolygonArray.h | 4 +- src/comm/ros_bridge/include/CasePacker.h | 53 +++++++++++++++++++ src/comm/ros_bridge/include/JsonFactory.h | 31 ++++++----- src/comm/ros_bridge/include/JsonMethodes.h | 2 +- src/comm/ros_bridge/include/MessageGroups.h | 4 +- src/comm/ros_bridge/include/MessageTag.cpp | 43 +++++++++++++++ src/comm/ros_bridge/include/MessageTag.h | 24 +++++++++ .../{PackageBuffer.h => PackageQueue.h} | 7 +-- src/comm/ros_bridge/include/ROSCommunicator.h | 33 ++++++++---- src/comm/ros_bridge/src/CasePacker.cpp | 31 +++++++++-- src/comm/ros_bridge/src/CasePacker.h | 42 --------------- src/comm/ros_bridge/src/ROSCommunicator.cpp | 11 +++- 16 files changed, 218 insertions(+), 93 deletions(-) create mode 100644 src/comm/ros_bridge/include/CasePacker.h create mode 100644 src/comm/ros_bridge/include/MessageTag.cpp create mode 100644 src/comm/ros_bridge/include/MessageTag.h rename src/comm/ros_bridge/include/{PackageBuffer.h => PackageQueue.h} (90%) delete mode 100644 src/comm/ros_bridge/src/CasePacker.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index bb3f7f830..96b3a7933 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -473,12 +473,13 @@ HEADERS += \ src/Wima/testplanimetrycalculus.h \ src/Settings/WimaSettings.h \ src/QmlControls/QmlObjectVectorModel.h \ + src/comm/ros_bridge/include/CasePacker.h \ src/comm/ros_bridge/include/GenericMessages.h \ src/comm/ros_bridge/include/JsonMethodes.h \ + src/comm/ros_bridge/include/MessageTag.h \ src/comm/ros_bridge/include/MessageTraits.h \ - src/comm/ros_bridge/include/PackageBuffer.h \ + src/comm/ros_bridge/include/PackageQueue.h \ src/comm/ros_bridge/include/TypeFactory.h \ - src/comm/ros_bridge/src/CasePacker.h \ src/comm/ros_bridge/src/PackageBuffer.h \ src/comm/utilities.h SOURCES += \ @@ -487,6 +488,7 @@ SOURCES += \ src/Snake/snake_geometry.cpp \ src/Wima/GeoPoint3D.cpp \ src/Wima/PolygonArray.cc \ + src/comm/ros_bridge/include/MessageTag.cpp \ src/comm/ros_bridge/src/CasePacker.cpp \ src/comm/ros_bridge/src/ROSCommunicator.cpp \ src/Wima/WimaControllerDetail.cc \ diff --git a/src/Wima/GeoPoint3D.h b/src/Wima/GeoPoint3D.h index a45142ecd..5d47e3f1c 100644 --- a/src/Wima/GeoPoint3D.h +++ b/src/Wima/GeoPoint3D.h @@ -2,33 +2,33 @@ #include "ros_bridge/include/JsonMethodes.h" #include "ros_bridge/include/MessageBaseClass.h" -#include "ros_bridge/include/MessageGroups.h" +#include "ros_bridge/include/GenericMessages.h" #include -typedef ROSBridge::MessageBaseClass ROSMsg; -typedef ROSBridge::JsonMethodes::GeoPoint::GeoPoint ROSGeoPoint; +typedef ROSBridge::MessageBaseClass ROSMsg; +typedef ROSBridge::GenericMessages::GeographicMsgs::GeoPoint ROSGeoPoint; namespace MsgGroups = ROSBridge::MessageGroups; -class GeoPoint3D : public QObject, public ROSMsg, public ROSGeoPoint +class GeoPoint3D : public QObject, public ROSGeoPoint { Q_OBJECT public: typedef MsgGroups::GeoPointGroup Group; explicit GeoPoint3D(QObject *parent = nullptr) - : QObject(parent), ROSMsg(), ROSGeoPoint() {} + : QObject(parent), ROSGeoPoint() {} explicit GeoPoint3D(double latitude, double longitude, double altitude, QObject *parent = nullptr) - : QObject(parent), ROSMsg(), ROSGeoPoint(latitude, longitude, altitude) + : QObject(parent), ROSGeoPoint(latitude, longitude, altitude) {} explicit GeoPoint3D(const GeoPoint3D& p, QObject *parent = nullptr) - : QObject(parent), ROSMsg(), ROSGeoPoint(p.latitude(), p.longitude(), p.altitude()) + : QObject(parent), ROSGeoPoint(p.latitude(), p.longitude(), p.altitude()) {} explicit GeoPoint3D(const ROSGeoPoint& p, QObject *parent = nullptr) - : QObject(parent), ROSMsg(), ROSGeoPoint(p.latitude(), p.longitude(), p.altitude()) + : QObject(parent), ROSGeoPoint(p.latitude(), p.longitude(), p.altitude()) {} virtual GeoPoint3D *Clone() const override; diff --git a/src/Wima/PolygonArray.h b/src/Wima/PolygonArray.h index 2cad27b70..9a658169f 100644 --- a/src/Wima/PolygonArray.h +++ b/src/Wima/PolygonArray.h @@ -4,7 +4,7 @@ #include "ros_bridge/include/MessageBaseClass.h" -typedef ROSBridge::MessageBaseClass ROSMsgBase; +typedef ROSBridge::MessageBaseClass ROSMsgBase; template class ContainerType > class PolygonArray : public ROSMsgBase, public ContainerType { public: diff --git a/src/Wima/QtROSJsonFactory.h b/src/Wima/QtROSJsonFactory.h index 450959d6a..2250edaaa 100644 --- a/src/Wima/QtROSJsonFactory.h +++ b/src/Wima/QtROSJsonFactory.h @@ -2,4 +2,4 @@ #include "ros_bridge/include/JsonFactory.h" #include -typedef ROSBridge::JsonFactory QtROSJsonFactory; +typedef ROSBridge::GenericJsonFactory QtROSJsonFactory; diff --git a/src/Wima/WimaPolygonArray.h b/src/Wima/WimaPolygonArray.h index 1782e9103..f43f4ca15 100644 --- a/src/Wima/WimaPolygonArray.h +++ b/src/Wima/WimaPolygonArray.h @@ -7,7 +7,7 @@ #include #include -typedef ROSBridge::MessageBaseClass ROSMsg; +typedef ROSBridge::MessageBaseClass ROSMsg; namespace MsgGroups = ROSBridge::MessageGroups; typedef MsgGroups::EmptyGroup EmptyGroup; template class ContainerType = QVector, typename GroupType = EmptyGroup> @@ -21,7 +21,7 @@ public: , _polygons(other._polygons), _dirty(true) {} - virtual MessageBaseClass * Clone() const override{ + virtual WimaPolygonArray *Clone() const override{ return new WimaPolygonArray(*this); } diff --git a/src/comm/ros_bridge/include/CasePacker.h b/src/comm/ros_bridge/include/CasePacker.h new file mode 100644 index 000000000..203dcf0f2 --- /dev/null +++ b/src/comm/ros_bridge/include/CasePacker.h @@ -0,0 +1,53 @@ +#pragma once +#include "ros_bridge/include/MessageBaseClass.h" +#include "ros_bridge/include/MessageTag.h" +#include "ros_bridge/include/TypeFactory.h" +#include "ros_bridge/include/JsonFactory.h" + +#include +#include "rapidjson/include/rapidjson/document.h" + +namespace ROSBridge { + +class CasePacker +{ + typedef MessageTag Tag; + typedef rapidjson::Document JsonDoc; + typedef std::unique_ptr JsonDocUPtr; +public: + CasePacker(); + + template + JsonDoc *pack(const T &msg, const std::string &topic) + { + JsonDoc *docPt(_jsonFactory.create(msg)); + std::string messageType = T::Group::messageType(); + _addTag(*docPt, topic, messageType.c_str()); + return docPt; + } + + bool showTag(const JsonDoc &doc, Tag &tag); + + template + bool unpack(JsonDoc &doc, T &msg){ + _removeTag(doc); + return _typeFactory.create(doc, msg); + } + + static const char* topicKey; + static const char* messageTypeKey; + +protected: + void _addTag (JsonDoc &doc, + const std::string &topic, + const std::string &messageType); + void _removeTag (JsonDoc &doc); + bool _getTopic (const JsonDoc &doc, std::string &topic); + bool _getMessageType(const JsonDoc &doc, std::string &messageType); + +private: + TypeFactory _typeFactory; + JsonFactory _jsonFactory; +}; +} + diff --git a/src/comm/ros_bridge/include/JsonFactory.h b/src/comm/ros_bridge/include/JsonFactory.h index a6346a0b2..9dde4f6e1 100644 --- a/src/comm/ros_bridge/include/JsonFactory.h +++ b/src/comm/ros_bridge/include/JsonFactory.h @@ -23,12 +23,12 @@ class StdHeaderPolicy; //! from classes derived from \class MessageBaseClass. Each class has a group mark (typedef ... Group) which allows the //! JsonFactory to determine the ROS message type it will create. template -class JsonFactory : public HeaderPolicy +class GenericJsonFactory : public HeaderPolicy { typedef MessageBaseClass ROSMsg; public: - JsonFactory() : HeaderPolicy() {} + GenericJsonFactory() : HeaderPolicy() {} //! //! \brief Creates a \class rapidjson::Document document containing a ROS mesage from \p msg. @@ -127,7 +127,7 @@ private: template rapidjson::Document *_createPolygonStamped(const U &msg, Int2Type<0>){// U has no member header(), generate one on the fly. using namespace ROSBridge; - JsonMethodes::Header::Header header(HeaderPolicy::header(msg)); + GenericMessages::StdMsgs::Header header(HeaderPolicy::header(msg)); rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType); bool ret = JsonMethodes::GeometryMsgs::PolygonStamped::toJson(msg.polygon(), header, *doc, doc->GetAllocator()); assert(ret); @@ -152,7 +152,7 @@ private: rapidjson::Document *_createPolygonArray(const U &msg, Int2Type){ // U has member header(), use integraded header. using namespace ROSBridge; rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType); - bool ret = JsonMethodes::JSKRecognitionMsg::PolygonArray::toJson(msg, *doc, doc->GetAllocator()); + bool ret = JsonMethodes::JSKRecognitionMsgs::PolygonArray::toJson(msg, *doc, doc->GetAllocator()); assert(ret); (void)ret; @@ -163,9 +163,9 @@ private: template rapidjson::Document *_createPolygonArray(const U &msg, Int2Type<0>){// U has no member header(), generate one on the fly. using namespace ROSBridge; - JsonMethodes::Header::Header header(HeaderPolicy::header(msg)); + GenericMessages::StdMsgs::Header header(HeaderPolicy::header(msg)); rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType); - bool ret = JsonMethodes::JSKRecognitionMsg::PolygonArray::toJson(msg, header, *doc, doc->GetAllocator()); + bool ret = JsonMethodes::JSKRecognitionMsgs::PolygonArray::toJson(msg, header, *doc, doc->GetAllocator()); assert(ret); (void)ret; @@ -187,8 +187,10 @@ private: } }; -class StdHeaderPolicy{ - namespace StdMsgs = ROSBridge::GenericMessages::StdMsgs; +class StdHeaderPolicy +{ + typedef ROSBridge::GenericMessages::StdMsgs::Header Header; + typedef ROSBridge::GenericMessages::StdMsgs::Time Time; public: StdHeaderPolicy():_seq(-1){}; @@ -196,24 +198,25 @@ public: //! \brief header Returns the header belonging to msg. //! \return Returns the header belonging to msg. //! - template - StdMsgs::Header header(const T&msg) { - return StdMsgs::Header(++_seq, time(msg), "/map"); + Header header(const ROSBridge::MessageBaseClass &msg) { + return Header(++_seq, time(msg), "/map"); } //! //! \brief time Returns the current time. //! \return Returns the current time. - template - StdMsgs::Time time(const T&msg) { + Time time(const ROSBridge::MessageBaseClass &msg) { (void)msg; - return StdMsgs::Time(0,0); + return Time(0,0); } + private: long _seq; }; +typedef GenericJsonFactory<> JsonFactory; + } // end namespace ros_bridge diff --git a/src/comm/ros_bridge/include/JsonMethodes.h b/src/comm/ros_bridge/include/JsonMethodes.h index 810983ff8..03a0046b1 100644 --- a/src/comm/ros_bridge/include/JsonMethodes.h +++ b/src/comm/ros_bridge/include/JsonMethodes.h @@ -636,7 +636,7 @@ namespace Progress { progressJson.PushBack(rapidjson::Value().SetInt(std::int8_t(p.progress()[i])), allocator); } value.AddMember("progress", progressJson, allocator); - + return true; } template diff --git a/src/comm/ros_bridge/include/MessageGroups.h b/src/comm/ros_bridge/include/MessageGroups.h index 57331a3d8..0fdf84728 100644 --- a/src/comm/ros_bridge/include/MessageGroups.h +++ b/src/comm/ros_bridge/include/MessageGroups.h @@ -10,7 +10,7 @@ typedef std::string StringType; template struct MessageGroup { - static StringType messageNameFull() {return _full();} + static StringType messageType() {return _full();} template static StringType _full() {return G::label()+ "/" + _full(); } @@ -18,7 +18,7 @@ struct MessageGroup { static StringType _full() {return G::label(); } - static StringType messageNameLast() {return _last();} + static StringType messageTypeLast() {return _last();} template static StringType _last() {return _last(); } diff --git a/src/comm/ros_bridge/include/MessageTag.cpp b/src/comm/ros_bridge/include/MessageTag.cpp new file mode 100644 index 000000000..80a74d9c9 --- /dev/null +++ b/src/comm/ros_bridge/include/MessageTag.cpp @@ -0,0 +1,43 @@ +#include "MessageTag.h" + +MessageTag::MessageTag() +{ + +} + +MessageTag::MessageTag(const std::string &topic, const std::string &messageType) : + _topic(topic) + , _messagType(messageType) +{ + +} + +const std::string &MessageTag::topic() const +{ + return _topic; +} + +const std::string &MessageTag::messageType() const +{ + return _messagType; +} + +std::string &MessageTag::topic() +{ + return _topic; +} + +std::string &MessageTag::messageType() +{ + return _messagType; +} + +void MessageTag::setTopic(const std::string &topic) +{ + _topic = topic; +} + +void MessageTag::setMessageType(const std::string &messageType) +{ + _messagType = messageType; +} diff --git a/src/comm/ros_bridge/include/MessageTag.h b/src/comm/ros_bridge/include/MessageTag.h new file mode 100644 index 000000000..cc04dc6b8 --- /dev/null +++ b/src/comm/ros_bridge/include/MessageTag.h @@ -0,0 +1,24 @@ +#pragma once + +#include + + +class MessageTag { +public: + MessageTag(); + MessageTag(const std::string &topic, const std::string &messageType); + + const std::string &topic() const; + const std::string &messageType() const; + + std::string &topic(); + std::string &messageType(); + + void setTopic(const std::string &topic); + void setMessageType(const std::string &messageType); + +private: + std::string _topic; + std::string _messagType; +}; +typedef MessageTag Tag; diff --git a/src/comm/ros_bridge/include/PackageBuffer.h b/src/comm/ros_bridge/include/PackageQueue.h similarity index 90% rename from src/comm/ros_bridge/include/PackageBuffer.h rename to src/comm/ros_bridge/include/PackageQueue.h index 27ea3d03a..f4a9976a6 100644 --- a/src/comm/ros_bridge/include/PackageBuffer.h +++ b/src/comm/ros_bridge/include/PackageQueue.h @@ -5,13 +5,12 @@ #include namespace ROSBridge { -namespace Bridge { namespace lf = ::boost::lockfree; template -class PackageBuffer +class PackageQueue { public: - PackageBuffer(); + PackageQueue(); void push(T t) { buffer.push(t); @@ -41,7 +40,5 @@ private: std::function _pushCallback; }; -} // namespace Communicator - } // namespace diff --git a/src/comm/ros_bridge/include/ROSCommunicator.h b/src/comm/ros_bridge/include/ROSCommunicator.h index 61a35e96e..b87b90296 100644 --- a/src/comm/ros_bridge/include/ROSCommunicator.h +++ b/src/comm/ros_bridge/include/ROSCommunicator.h @@ -1,29 +1,44 @@ #pragma once #include "ros_bridge/rapidjson/include/rapidjson/document.h" +#include "ros_bridge/include/PackageQueue.h" +#include "ros_bridge/include/CasePacker.h" #include #include #include "boost/lockfree/queue.hpp" -#include "ros_bridge/include/ namespace ROSBridge { namespace lf = ::boost::lockfree; -class Communicator +class Communicator : protected CasePacker { - typedef std::unique_ptr UniqueJsonPtr; - typedef std::tuple MsgTopicHashPair; + typedef MessageTag Tag; + typedef rapidjson::Document JsonDoc; + typedef std::shared_ptr JsonDocShardPtr; + typedef PackageQueue Buffer; + //typedef std::tuple MsgTopicHashPair; public: - explicit Communicator() {} + explicit Communicator() : CasePacker() {} + + template + void send(T &msg, std::string &topic){ + JsonDocShardPtr docPtr(CasePacker::pack(msg, topic)); + _transmittBuffer.push(docPtr); + } - void send(UniqueJsonPtr &msg); void start(); void stop(); - virtual UniqueJsonPtr receive() = 0; + bool messagesAvailable(); + bool showMessageTag(Tag &tag); + template + void receive(T &msg){ + + } private: - lf::queue _transmittBuffer; - lf::queue _receiveBuffer; + Buffer _transmittBuffer; + Buffer _receiveBuffer; + JsonDocShardPtr _stagedMessage; // message awaiting delivery }; } diff --git a/src/comm/ros_bridge/src/CasePacker.cpp b/src/comm/ros_bridge/src/CasePacker.cpp index f75046ca3..c6fa7748c 100644 --- a/src/comm/ros_bridge/src/CasePacker.cpp +++ b/src/comm/ros_bridge/src/CasePacker.cpp @@ -1,4 +1,4 @@ -#include "CasePacker.h" +#include "ros_bridge/include/CasePacker.h" const char* ROSBridge::CasePacker::topicKey = "topic"; const char* ROSBridge::CasePacker::messageTypeKey = "messageType"; @@ -8,7 +8,16 @@ ROSBridge::CasePacker::CasePacker() } -void ROSBridge::CasePacker::_addTag(JsonDoc &doc, const char *topic, const char *messageType) +bool ROSBridge::CasePacker::showTag(const ROSBridge::CasePacker::JsonDoc &doc, Tag &tag) +{ + if( !_getTopic(doc, tag.topic()) ) + return false; + if( !_getMessageType(doc, tag.messageType()) ) + return false; + return true; +} + +void ROSBridge::CasePacker::_addTag(JsonDoc &doc, const std::string &topic, const std::string &messageType) { using namespace ROSBridge; using namespace rapidjson; @@ -16,13 +25,13 @@ void ROSBridge::CasePacker::_addTag(JsonDoc &doc, const char *topic, const char { // add topic rapidjson::Value key(CasePacker::topicKey, doc.GetAllocator()); - rapidjson::Value value(topic, doc.GetAllocator()); + rapidjson::Value value(topic.c_str(), doc.GetAllocator()); doc.AddMember(key, value, doc.GetAllocator()); } // add messageType rapidjson::Value key(CasePacker::messageTypeKey, doc.GetAllocator()); - rapidjson::Value value(messageType, doc.GetAllocator()); + rapidjson::Value value(messageType.c_str(), doc.GetAllocator()); doc.AddMember(key, value, doc.GetAllocator()); } @@ -36,4 +45,18 @@ void ROSBridge::CasePacker::_removeTag(JsonDoc &doc) doc.RemoveMember(CasePacker::messageTypeKey); } +bool ROSBridge::CasePacker::_getTopic(const ROSBridge::CasePacker::JsonDoc &doc, std::string &topic) +{ + if (!doc.HasMember(CasePacker::topicKey) || !doc[CasePacker::topicKey].IsString()) + return false; + topic = doc[CasePacker::topicKey].GetString(); + return true; +} +bool ROSBridge::CasePacker::_getMessageType(const ROSBridge::CasePacker::JsonDoc &doc, std::string &messageType) +{ + if (!doc.HasMember(CasePacker::messageTypeKey) || !doc[CasePacker::messageTypeKey].IsString()) + return false; + messageType = doc[CasePacker::messageTypeKey].GetString(); + return true; +} diff --git a/src/comm/ros_bridge/src/CasePacker.h b/src/comm/ros_bridge/src/CasePacker.h deleted file mode 100644 index 7f959db58..000000000 --- a/src/comm/ros_bridge/src/CasePacker.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include "ros_bridge/include/MessageBaseClass.h" - -#include -#include "rapidjson/include/rapidjson/document.h" - -namespace ROSBridge { - -class CasePacker -{ - typedef rapidjson::Document JsonDoc; - typedef std::unique_ptr UniqueJsonPtr; -public: - CasePacker(); - - struct MessageTag { - char *topic; - char *messagType; - }; - typedef MessageTag Tag; - - - template - void packAndSend(const T &msg, const char *topic); - - const Tag &showTag(); - - template - void unpack(T &msg); - -protected: - void _addTag(JsonDoc &doc, const char *topic, const char *messageType); - void _removeTag(JsonDoc &doc); - - static const char* topicKey; - static const char* messageTypeKey; - -private: - Tag _tag; -}; -} - diff --git a/src/comm/ros_bridge/src/ROSCommunicator.cpp b/src/comm/ros_bridge/src/ROSCommunicator.cpp index 2f335da25..acacfb7b0 100644 --- a/src/comm/ros_bridge/src/ROSCommunicator.cpp +++ b/src/comm/ros_bridge/src/ROSCommunicator.cpp @@ -1,6 +1,13 @@ #include "ros_bridge/include/ROSCommunicator.h" -void ROSBridge::Communicator::send(ROSBridge::Communicator::UniqueJsonPtr &msg) +bool ROSBridge::Communicator::messagesAvailable() { - if (!msg->HasMember("")) + return !_receiveBuffer.empty() || _stagedMessage; +} + +bool ROSBridge::Communicator::showMessageTag(ROSBridge::Communicator::Tag &tag) +{ + if (!_stagedMessage) + _stagedMessage = _receiveBuffer.pop(); + return ROSBridge::Communicator::CasePacker::showTag(*_stagedMessage.get(), tag); } -- 2.22.0