JsonFactory.h 8.3 KB
Newer Older
1
#pragma once
2 3

#include "ros_bridge/rapidjson/include/rapidjson/document.h"
4 5
#include "ros_bridge/include/JsonMethodes.h"
#include "MessageBaseClass.h"
6 7
#include "utilities.h"

8
#include "ros_bridge/include/MessageTraits.h"
9
#include "ros_bridge/include/MessageGroups.h"
10
#include "ros_bridge/include/GenericMessages.h"
11 12 13 14

#include "boost/type_traits.hpp"
#include "boost/type_traits/is_base_of.hpp"

15 16
namespace ROSBridge {

17 18 19
class StdHeaderPolicy;

//!
20
//! \brief The JsonFactory class is used to create ROS messages.
21
//!
22 23 24
//! The JsonFactory class is used to create \class rapidjson::Document documents containing ROS messages
//! 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.
25
template <class HeaderPolicy = StdHeaderPolicy>
Valentin Platzgummer's avatar
Valentin Platzgummer committed
26
class GenericJsonFactory : public HeaderPolicy
27
{
28
    typedef MessageBaseClass ROSMsg;
29 30
public:

Valentin Platzgummer's avatar
Valentin Platzgummer committed
31
    GenericJsonFactory() : HeaderPolicy() {}
32 33 34 35 36 37

    //!
    //! \brief Creates a \class rapidjson::Document document containing a ROS mesage from \p msg.
    //!
    //! Creates a \class rapidjson::Document document containing a ROS message from \p msg.
    //! A compile-time error will occur, if \p msg belongs to the \struct EmptyGroup or is
38 39
    //! not derived from \class MessageBaseClass.
    //! \param msg Instance of a \class MessageBaseClass subclass belonging to a ROSMessageGroup.
40 41 42
    //! \return rapidjson::Document document containing a ROS message.
    template <class T>
    rapidjson::Document *create(const T &msg){
43 44
        static_assert(boost::is_base_of<ROSMsg, T>::value, "Type of msg must be derived from MessageBaseClass.");
        static_assert(!::boost::is_same<typename T::Group, MessageGroups::EmptyGroup>::value,
45
                "msg belongs to group EmptyGroup (not allowed). Please specify Group (typedef MessageGroup Group)");
46
        //cout << T::Group::label() << endl;
47 48 49 50 51 52 53 54 55 56 57 58
        return _create(msg, Type2Type<typename T::Group>());
    }

private:

    // ===========================================================================
    // EmptyGroup and not implemented Groups
    // ===========================================================================
    template<class U, class V>
    rapidjson::Document *_create(const U &msg, Type2Type<V>){
        (void)msg;
        assert(false); // Implementation missing for group U::Group!
Valentin Platzgummer's avatar
Valentin Platzgummer committed
59
        return nullptr;
60 61 62 63 64 65
    }

    // ===========================================================================
    // Point32Group
    // ===========================================================================
    template<class U>
66 67
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::Point32Group>){
        using namespace ROSBridge;
68
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
69
        bool ret = JsonMethodes::GeometryMsgs::Point32::toJson<_Float32>(msg, *doc, doc->GetAllocator());
70 71 72 73 74 75 76 77 78 79
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // GeoPointGroup
    // ===========================================================================
    template<class U>
80 81
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::GeoPointGroup>){
        using namespace ROSBridge;
82
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
83
        bool ret = JsonMethodes::GeographicMsgs::GeoPoint::toJson(msg, *doc, doc->GetAllocator());
84 85 86 87 88 89 90 91 92 93
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // PolygonGroup
    // ===========================================================================
    template<class U>
94 95
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::PolygonGroup>){
        using namespace ROSBridge;
96
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
97
        bool ret = JsonMethodes::GeometryMsgs::Polygon::toJson(msg, *doc, doc->GetAllocator());
98 99 100 101 102 103 104 105 106 107
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // PolygonStampedGroup
    // ===========================================================================
    template<class U>
108 109 110
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::PolygonStampedGroup>){
        using namespace ROSBridge;
        using namespace ROSBridge::traits;
111 112 113 114 115 116 117
        typedef HasMemberHeader<U> HasHeader;

        return _createPolygonStamped(msg, Int2Type<HasHeader::value>());
    }

    template<class U, int k>
    rapidjson::Document *_createPolygonStamped(const U &msg, Int2Type<k>){ // U has member header(), use integraded header.
118
        using namespace ROSBridge;
119
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
120
        bool ret = JsonMethodes::GeometryMsgs::PolygonStamped::toJson(msg, *doc, doc->GetAllocator());
121 122 123 124 125 126 127 128 129
        assert(ret);
        (void)ret;

        return doc;

    }

    template<class U>
    rapidjson::Document *_createPolygonStamped(const U &msg, Int2Type<0>){// U has no member header(), generate one on the fly.
130
        using namespace ROSBridge;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
131
        GenericMessages::StdMsgs::Header header(HeaderPolicy::header(msg));
132
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
133
        bool ret = JsonMethodes::GeometryMsgs::PolygonStamped::toJson(msg.polygon(), header, *doc, doc->GetAllocator());
134 135 136 137 138 139 140 141 142 143
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // PolygonArrayGroup
    // ===========================================================================
    template<class U>
144 145 146
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::PolygonArrayGroup>){
        using namespace ROSBridge;
        using namespace ROSBridge::traits;
147 148 149 150 151 152 153
        typedef HasMemberHeader<U> HasHeader;

        return _createPolygonArray(msg, Int2Type<HasHeader::value>());
    }

    template<class U, int k>
    rapidjson::Document *_createPolygonArray(const U &msg, Int2Type<k>){ // U has member header(), use integraded header.
154
        using namespace ROSBridge;
155
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
156
        bool ret = JsonMethodes::JSKRecognitionMsgs::PolygonArray::toJson(msg, *doc, doc->GetAllocator());
157 158 159 160 161 162 163 164 165
        assert(ret);
        (void)ret;

        return doc;

    }

    template<class U>
    rapidjson::Document *_createPolygonArray(const U &msg, Int2Type<0>){// U has no member header(), generate one on the fly.
166
        using namespace ROSBridge;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
167
        GenericMessages::StdMsgs::Header header(HeaderPolicy::header(msg));
168
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
169
        bool ret = JsonMethodes::JSKRecognitionMsgs::PolygonArray::toJson(msg, header, *doc, doc->GetAllocator());
170 171 172 173 174 175
        assert(ret);
        (void)ret;

        return doc;
    }

176 177 178 179 180 181 182 183 184 185
    // ===========================================================================
    // ProgressGroup
    // ===========================================================================
    template<class U>
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::ProgressGroup>){
        using namespace ROSBridge;
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
        bool ret = JsonMethodes::NemoMsgs::Progress::toJson(msg, *doc, doc->GetAllocator());
        assert(ret);
        (void)ret;
186

187 188
        return doc;
    }
189 190
};

Valentin Platzgummer's avatar
Valentin Platzgummer committed
191 192 193 194
class StdHeaderPolicy
{
    typedef ROSBridge::GenericMessages::StdMsgs::Header Header;
    typedef ROSBridge::GenericMessages::StdMsgs::Time Time;
195
public:
Valentin Platzgummer's avatar
Valentin Platzgummer committed
196
    StdHeaderPolicy():_seq(-1){}
197 198 199 200

    //!
    //! \brief header Returns the header belonging to msg.
    //! \return Returns the header belonging to msg.
Valentin Platzgummer's avatar
Valentin Platzgummer committed
201 202 203
    template<class T>
    Header header(const T &msg) {
        return Header(std::uint32_t(++_seq), time(msg), "/map");
204 205 206 207 208
    }


    //!
    //! \brief time Returns the current time.
Valentin Platzgummer's avatar
Valentin Platzgummer committed
209 210 211
    //! \return Returns the current time.    
    template<class T>
    Time time(const T &msg) {
212
        (void)msg;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
213
        return Time(0,0);
214
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
215

216 217 218 219
private:
    long _seq;
};

Valentin Platzgummer's avatar
Valentin Platzgummer committed
220 221
typedef GenericJsonFactory<> JsonFactory;

222 223 224
} // end namespace ros_bridge