ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Ok, I tried to do this. But I haven't been successful yet.

Here is what I did:

class ByteArrayMessage 
{
public:
    ByteArrayMessage(const uint8_t *buffer, uint32_t length, std::string dataType, std::string md5sum, std::string messageDefinition) 
        : __serialized_length(length),
          m_dataType(dataType),
          m_md5sum(md5sum),
          m_messageDefinition(messageDefinition),
          buffer_(buffer), length_(length)
    {}

    const std::string __getDataType() const {   return m_dataType;  }
    const std::string __getMD5Sum() const   {   return m_md5sum;    }
    const std::string __getMessageDefinition() const    {   return m_messageDefinition; }

    uint32_t serializationLength() const    {   return __serialized_length; }
    uint8_t *serialize(uint8_t *write_ptr, uint32_t seq);

    const uint8_t byte(size_t i) {  return buffer_[i];  }
    uint32_t length() { return length_; }

    uint32_t __serialized_length;

private:
    std::string m_dataType;
    std::string m_md5sum;
    std::string m_messageDefinition;

    const uint8_t *buffer_;
    uint32_t length_;
};

namespace serialization {
template<typename T>
struct Serializer {
  template<typename Stream>
  inline static void write(Stream& stream, T t) 
  {
    for (size_t i = 0; i < t.length(); i++) 
    {
      stream.next(t.byte(i));
    }
  }

  inline static uint32_t serializedLength(const ByteArrayMessage &msg) 
  {
    return msg.length();
  }      
};
}  //namespace serialization

I created the new class ByteArrayMessage and the Serializer you proposed.

I also had to add the functions __get*(), *serialize(), serializationLength() since they are requested by publisher.publish() as well. It seems that ByteArrayMessage should be derived from ros::Message. True?

Well the above mentioned is my current version. I get the following compiling error message:

 40%] Building CXX object CMakeFiles/simple_opc_client.dir/ros/src/generic_publisher.o
In file included from /home/fxm/git/cob3_intern/cob_sandbox/generic_topic_opc_client/ros/src/generic_publisher.cpp:2:0:
/home/fxm/git/cob3_intern/cob_sandbox/generic_topic_opc_client//ros/include/generic_topic_opc_client/byte_array_message.h:64:29: warning: type qualifiers ignored on function return type
In file included from /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/publisher.h:34:0,
                 from /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/node_handle.h:32,
                 from /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/ros.h:45,
                 from /home/fxm/git/cob3_intern/cob_sandbox/generic_topic_opc_client//ros/include/generic_topic_opc_client/generic_publisher.h:7,
                 from /home/fxm/git/cob3_intern/cob_sandbox/generic_topic_opc_client/ros/src/generic_publisher.cpp:1:
/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_serialization/include/ros/serialization.h: In static member function ‘static void ros::serialization::Serializer<T>::write(Stream&, typename boost::call_traits<T>::param_type) [with Stream = ros::serialization::OStream, T = ByteArrayMessage, typename boost::call_traits<T>::param_type = const ByteArrayMessage&]’:
/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_serialization/include/ros/serialization.h:152:3:   instantiated from ‘void ros::serialization::serialize(Stream&, const T&) [with T = ByteArrayMessage, Stream = ros::serialization::OStream]’
/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_serialization/include/ros/serialization.h:812:3:   instantiated from ‘ros::SerializedMessage ros::serialization::serializeMessage(const M&) [with M = ByteArrayMessage]’
/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/publisher.h:115:5:   instantiated from ‘void ros::Publisher::publish(const M&) const [with M = ByteArrayMessage]’
/home/fxm/git/cob3_intern/cob_sandbox/generic_topic_opc_client/ros/src/generic_publisher.cpp:108:41:   instantiated from here
/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_serialization/include/ros/serialization.h:124:5: error: passing ‘const ByteArrayMessage’ as ‘this’ argument of ‘uint8_t* ByteArrayMessage::serialize(uint8_t*, uint32_t)’ discards qualifiers
make[3]: *** [CMakeFiles/simple_opc_client.dir/ros/src/generic_publisher.o] Error 1

And here is how I am currently using it:

ros::AdvertiseOptions opts("/generic_topic_opc_client"+m_genericRosTopic.TopicName, 10, m_genericRosTopic.MD5Sum, m_genericRosTopic.MessageDataType, m_genericRosTopic.MessageDefinition);
m_genericRosTopic_publisher = n.advertise(opts);

UaVariant testValue((OpcUa_Variant*) m_genericRosTopic.SerializedMessagePtr);
ROS_INFO("** UaVariant: %s", testValue.toString().toUtf8());
UaByteArray testArray;
testValue.toByteArray(testArray);
//ROS_INFO("** UaByteArray: %s", testArray.toHex(true).toUtf8());

ros::serialization::IStream i_stream((u_int8_t*) testArray.data(), m_genericRosTopic.SerializedMessageSize);

ByteArrayMessage msg(i_stream.getData(), i_stream.getLength(), m_genericRosTopic.MessageDataType, m_genericRosTopic.MD5Sum, m_genericRosTopic.MessageDefinition);

m_genericRosTopic_publisher.publish(msg);

For clarification:

  • testArray and thus i_stream contains a message that I serialized using ros::serialization (it's NOT of the type SerializedMessage)

  • the struct m_genericRosTopic provides all information about the message that has been serialized (TopicName, DataType, MessageDefinition, MD5Sum)