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

Revision history [back]

I think you cannot (and probably should not) publish different message types on a single topic. ShapeShifter can subscribe using a wildcard on the md5 sum and message type. However, it is not possible to advertise using a wildcard. That means for advertising a topic you need to specify a valid message type and md5 sum and once advertised, these values cannot change anymore.

There are several ways to work around this problem:

  • Create a compound message that contains all different message type that you might want to publish and fill only these. An example is the move_arm action.

  • Use one topic for each type.

  • Create a generic message that only contains a message type and a byte array. Encode the message to the byte array for sending and decode it again when receiving it to get the correct data type.

You didn't say which error you actually get. I think assume the problem is that you cannot (and probably should not) pass a SerializedMessage to publisher which actually expects something that can be serialized into a SerializedMessage. To publish different message types on a single topic. ShapeShifter can subscribe using a wildcard on the md5 sum and message type. However, it is not possible to advertise using a wildcard. That means for advertising a topic a message, you need to specify a valid implement a Serializer struct, specialized on your data type as explained here. For just a pure byte array, the implementation should be pretty trivial, something like the following:

class Foo {
 public:
  Foo(const char *buffer, size_t length) 
      : buffer_(buffer), length_(length) {}
  const char byte(size_t i) { 
    return buffer[i]; 
   }
   size_t length() {
     return length_;
   }
  private:
   const char *buffer_;
   size_t length_;
};

namespace serialization {
template<>
struct Serializer<Foo> {
  template<typename Stream, typename T>
  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 Foo &foo) {
    return foo.length();
  }      
};
}  //namespace serialization

Note that the code doesn't implement any code for deserializing the message type and md5 sum and once advertised, these values cannot change anymore.which is (hopefully) not necessary for publishing messages.

There are several ways to work around this problem:

  • Create a compound message that contains all different message type that you might want to publish and fill only these. An example is the move_arm action.

  • Use one topic for each type.

  • Create a generic message that only contains a message type and a byte array. Encode the message to the byte array for sending and decode it again when receiving it to get the correct data type.