#ifndef MESSAGES_H #define MESSAGES_H #include #include #include #include #include "ros_bridge/rapidjson/include/rapidjson/rapidjson.h" #include "ros_bridge/rapidjson/include/rapidjson/document.h" #include "utilities.h" #include "ROSMessageTraits.h" namespace ros_bridge { namespace Time { //! @brief C++ representation of std_msgs/Time class Time{ public: Time(): _secs(0), _nsecs(0) {} Time(uint32_t secs, uint32_t nsecs): _secs(secs), _nsecs(nsecs) {} uint32_t secs() const {return _secs;} uint32_t nSecs() const {return _nsecs;} void setSecs(uint32_t secs) {_secs = secs;} void setNSecs(uint32_t nsecs) {_nsecs = nsecs;} private: uint32_t _secs; uint32_t _nsecs; }; template bool toJson(const TimeType &time, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { doc.AddMember("secs", rapidjson::Value().SetUint((uint32_t)time.secs()), allocator); doc.AddMember("nsecs", rapidjson::Value().SetUint((uint32_t)time.nSecs()), allocator); return true; } } namespace Header { //! @brief C++ representation of std_msgs/Header class Header{ public: Header() : _seq(0), _stamp(Time::Time()), _frameId("") {} Header(uint32_t seq, const Time::Time &stamp, const std::string &frame_id) : _seq(seq) , _stamp(stamp) , _frameId(frame_id) {} uint32_t seq() const {return _seq;}; const Time::Time &stamp() const {return _stamp;}; const std::string &frameId() const {return _frameId;}; Time::Time &stamp() {return _stamp;}; std::string &frameId() {return _frameId;}; void setSeq (uint32_t seq) {_seq = seq;} void setStamp (const Time::Time &stamp) {_stamp = stamp;} void setFrameId (const std::string &frameId) {_frameId = frameId;} private: uint32_t _seq; Time::Time _stamp; std::string _frameId; }; template bool toJson(const HeaderType &header, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { doc.AddMember("seq", rapidjson::Value().SetUint((uint32_t)header.seq()), allocator); rapidjson::Document stamp(rapidjson::kObjectType); if (!Time::toJson(header.stamp(), doc, allocator)) return false; doc.AddMember("stamp", stamp, allocator); doc.AddMember("frame_id", rapidjson::Value().SetString(header.frameId().data(), header.frameId().length(), allocator), allocator); return true; } } namespace Point32 { using namespace ros_bridge::traits; //! @brief C++ representation of geometry_msgs/Point32. template class Point{ public: Point(FloatType x, FloatType y, FloatType z) : _x(x), _y(y), _z(z){} FloatType x() const {return _x;} FloatType y() const {return _y;} FloatType z() const {return _z;} void setX(FloatType x) {_x = x;} void setY(FloatType y) {_y = y;} void setZ(FloatType z) {_z = z;} private: FloatType _x; FloatType _y; FloatType _z; }; typedef Point<> Point64; typedef Point<_Float32> Point32; namespace det { //detail template bool toJson(const T &p, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator, Type2Type) { doc.AddMember("x", rapidjson::Value().SetFloat((FloatType)p.x()), allocator); doc.AddMember("y", rapidjson::Value().SetFloat((FloatType)p.y()), allocator); doc.AddMember("z", rapidjson::Value().SetFloat((FloatType)p.z()), allocator); return true; } template bool toJson(const T &p, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator, Type2Type) { doc.AddMember("x", rapidjson::Value().SetFloat((FloatType)p.x()), allocator); doc.AddMember("y", rapidjson::Value().SetFloat((FloatType)p.y()), allocator); doc.AddMember("z", rapidjson::Value().SetFloat((FloatType)0.0), allocator); // _point has no member z() -> add 0. return true; } } template bool toJson(const T&p, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { typedef typename Select::value, Has3Components, Has2Components>::Result Components; // Check if PointType has 2 or 3 dimensions. return det::toJson(p, doc, allocator, Type2Type()); } } namespace GeoPoint { using namespace ros_bridge::traits; //! @brief C++ representation of geographic_msgs/GeoPoint. class GeoPoint{ public: GeoPoint() : _latitude(0) , _longitude(0) , _altitude(0) {} GeoPoint(_Float64 latitude, _Float64 longitude, _Float64 altitude) : _latitude(latitude) , _longitude(longitude) , _altitude(altitude) {} _Float64 latitude() const {return _latitude;} _Float64 longitude() const {return _longitude;} _Float64 altitude() const {return _altitude;} void setLatitude (_Float64 latitude) {_latitude = latitude;} void setLongitude (_Float64 longitude) {_longitude = longitude;} void setAltitude (_Float64 altitude) {_altitude = altitude;} private: _Float64 _latitude; _Float64 _longitude; _Float64 _altitude; }; namespace det { //detail template bool toJson(const T &p, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator, Type2Type) { doc.AddMember("latitude", rapidjson::Value().SetFloat((_Float64)p.latitude()), allocator); doc.AddMember("longitude", rapidjson::Value().SetFloat((_Float64)p.longitude()), allocator); doc.AddMember("altitude", rapidjson::Value().SetFloat((_Float64)p.altitude()), allocator); return true; } template bool toJson(const T &p, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator, Type2Type) { doc.AddMember("latitudex", rapidjson::Value().SetFloat((_Float64)p.latitude()), allocator); doc.AddMember("longitude", rapidjson::Value().SetFloat((_Float64)p.longitude()), allocator); doc.AddMember("altitude", rapidjson::Value().SetFloat((_Float64)0.0), allocator); // _point has no member altitude() -> add 0. return true; } } template bool toJson(const T&p, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { typedef typename Select::value, Has3Components, Has2Components>::Result Components; // Check if PointType has 2 or 3 dimensions. return det::toJson(p, doc, allocator, Type2Type()); } } namespace Polygon { //! @brief C++ representation of geometry_msgs/Polygon template class ContainerType = std::vector> class Polygon{ typedef typename boost::remove_cv::type>::type PointType; public: Polygon(){} Polygon(const Polygon &poly) : _points(poly.points()){} const ContainerType &points() const {return _points;} ContainerType &points() {return _points;} private: ContainerType _points; }; template bool toJson(const PolygonType &poly, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { rapidjson::Value points(rapidjson::kArrayType); for(unsigned long i=0; i < (unsigned long)poly.points().size(); ++i) { rapidjson::Document point(rapidjson::kObjectType); if ( !Point32::toJson<_Float32>(poly.points()[i], point, allocator) ) return false; points.PushBack(point, allocator); } doc.AddMember("points", points, allocator); return true; } } namespace PolygonStamped { //! @brief C++ representation of geometry_msgs/PolygonStamped template class PolygonType = Polygon::Polygon, class HeaderType = Header::Header> class PolygonStamped { typedef typename boost::remove_cv::type>::type PointType; typedef PolygonType Polygon; public: PolygonStamped(){}; PolygonStamped(const HeaderType &header, Polygon &polygon) : _header(header) , _polygon(polygon) {} const HeaderType &header() const {return _header;} const Polygon &polygon() const {return _polygon;} HeaderType &header() {return _header;} Polygon &polygon() {return _polygon;} void setHeader(const HeaderType &header) {_header = header;} void setPolygon(const Polygon &polygon) { _polygon = polygon; } private: HeaderType _header; Polygon _polygon; }; template bool toJson(const PolyStamped &polyStamped, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { return toJson(polyStamped.polygon(), polyStamped.header(), doc, allocator); } template bool toJson(const PolygonType &poly, const HeaderType &h, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { rapidjson::Document header(rapidjson::kObjectType); if (!Header::toJson(h, header, allocator)) return false; rapidjson::Document polygon(rapidjson::kObjectType); if (!Polygon::toJson(poly, polygon, allocator)) return false; doc.AddMember("header", header, allocator); doc.AddMember("polygon", polygon, allocator); return true; } } namespace PolygonArray { using namespace ros_bridge::traits; //! @brief C++ representation of jsk_recognition_msgs/PolygonArray template class Polygon = Polygon::Polygon, template class ContainerType = std::vector, class HeaderType = Header::Header> class PolygonArray{ typedef typename boost::remove_cv::type>::type PointType; typedef Polygon PolygonType; public: PolygonArray(){} //! //! \brief PolygonArray //! \param header Header //! \param polygons Polygons //! \param labels Labels //! \param likelihood Header PolygonArray(const HeaderType &header, const ContainerType &polygons, const ContainerType &labels, const ContainerType<_Float32> &likelihood) : _header(header) , _polygons(polygons) , _labels(labels) , _likelihood(likelihood) {} const HeaderType &header() const {return _header;} HeaderType &header() {return _header;} const ContainerType &polygons() const {return _polygons;} ContainerType &polygons() {return _polygons;} const ContainerType &labels() const {return _labels;} ContainerType &labels() {return _labels;} const ContainerType<_Float32> &likelyhood() const {return _likelihood;} ContainerType<_Float32> &likelyhood() {return _likelihood;} void setHeader (const HeaderType &header) {_header = &header;} void setPolygons (ContainerType &polygon) { _polygons = polygon; } void setLabels (const ContainerType &labels) {_labels = labels;} void setLikelihood (const ContainerType<_Float32> &likelihood) {_likelihood = likelihood;} private: HeaderType _header; ContainerType _polygons; ContainerType _labels; ContainerType<_Float32> _likelihood; }; namespace PAdetail { //! Helper functions to generate Json entries for labels and likelihood. //! \note \p p has member \fn labels(). template void labelsToJson(const PolygonArrayType &p, rapidjson::Value &labels, rapidjson::Document::AllocatorType &allocator, Int2Type){ for(unsigned long i=0; i < (unsigned long)p.labels().size(); ++i) labels.PushBack(rapidjson::Value().SetUint(p.labels()[i]), allocator); } //! \note \p p has no member \fn labels(). template void labelsToJson(const PolygonArrayType &p, rapidjson::Value &labels, rapidjson::Document::AllocatorType &allocator, Int2Type<0>){ for(unsigned long i=0; i < (unsigned long)(p.polygons().size()); ++i) labels.PushBack(rapidjson::Value().SetUint(0), allocator); // use zero! } //! \note \p p has member \fn likelihood(). template void likelihoodToJson(const PolygonArrayType &p, rapidjson::Value &likelyhood, rapidjson::Document::AllocatorType &allocator, Int2Type){ for(unsigned long i=0; i < (unsigned long)p.likelyhood().size(); ++i) likelyhood.PushBack(rapidjson::Value().SetFloat(p.likelyhood()[i]), allocator); } //! \note \p p has no member \fn likelihood(). template void likelihoodToJson(const PolygonArrayType &p, rapidjson::Value &likelyhood, rapidjson::Document::AllocatorType &allocator, Int2Type<0>){ for(unsigned long i=0; i < (unsigned long)p.polygons().size(); ++i) likelyhood.PushBack(rapidjson::Value().SetFloat(0), allocator); // use zero! } } //! //! Create PolygonArray message from \p p. \p p contains a header. //! \param p Class implementing the PolygonArrayType interface. //! \param doc Rapidjson document used to store the PolygonArray message. //! \param allocator Allocator used by doc. Can be obtained e.g. by calling doc.getAllocator(). //! //! \note The \fn labels() and \fn likelihood() members are optinal. If any of them is missing they //! will be replaced by arrays filled with zero and size p.polygons.size(). //! //! \note If this function is called p.polygons[i] (entries implement the the PolygonStampedGroup interface) //! must contain a header. template bool toJson(const PolygonArrayType &p, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { rapidjson::Document header(rapidjson::kObjectType); if (Header::toJson(p.header(), header, allocator)) return false; doc.AddMember("header", header, allocator); rapidjson::Value polygons(rapidjson::kArrayType); for(unsigned long i=0; i < p.polygons().size(); ++i){ rapidjson::Document polygon(rapidjson::kObjectType); if (!PolygonStamped::toJson(p.polygons[i], polygon, allocator)) return false; polygons.PushBack(polygon, allocator); } doc.AddMember("polygons", polygons, allocator); rapidjson::Value labels(rapidjson::kArrayType); typedef HasMemberLabels HasLabels; PAdetail::labelsToJson(p, labels, allocator, Int2Type()); doc.AddMember("labels", labels, allocator); rapidjson::Value likelihood(rapidjson::kArrayType); typedef HasMemberLikelihood HasLikelihood; PAdetail::likelihoodToJson(p, likelihood, allocator, Int2Type()); doc.AddMember("likelihood", likelihood, allocator); return true; } //! //! Create PolygonArray message from \p p and \p h. \p p doesn't have it's own header. //! \param p Class implementing the PolygonArrayType interface. //! \param h Class implementing the HeaderType interface. //! \param doc Rapidjson document used to store the PolygonArray message. //! \param allocator Allocator used by doc. Can be obtained e.g. by calling doc.getAllocator(). //! //! \note The \fn labels() and \fn likelihood() members are optinal. If any of them is missing they //! will be replaced by arrays filled with zero and size p.polygons.size(). //! //! \note If this function is called the headers in p.polygons[i] (entries implement the the PolygonStampedGroup interface) //! are ignored. template bool toJson(const PolygonArrayType &p, const HeaderType &h, rapidjson::Document &doc, rapidjson::Document::AllocatorType &allocator) { rapidjson::Document header(rapidjson::kObjectType); if (!Header::toJson(h, header, allocator)) return false; doc.AddMember("header", header, allocator); rapidjson::Value polygons(rapidjson::kArrayType); for(unsigned long i=0; i < (unsigned long)(p.polygons().size()); ++i){ rapidjson::Document polygon(rapidjson::kObjectType); if (!PolygonStamped::toJson(p.polygons()[i], h, polygon, allocator)) return false; polygons.PushBack(polygon, allocator); } doc.AddMember("polygons", polygons, allocator); rapidjson::Value labels(rapidjson::kArrayType); typedef HasMemberLabels HasLabels; PAdetail::labelsToJson(p, labels, allocator, Int2Type()); doc.AddMember("labels", labels, allocator); rapidjson::Value likelihood(rapidjson::kArrayType); typedef HasMemberLikelihood HasLikelihood; PAdetail::likelihoodToJson(p, likelihood, allocator, Int2Type()); doc.AddMember("likelihood", likelihood, allocator); return true; } } } #endif // MESSAGES_H