ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange |
1 | initial version |
Is it good practice to use the ros2 json message, ie, in a standard message like std_msgs / string, write a string with a json structure?
I would say "no".
One of the main points of using standardised messages is because they allow you to encode both syntax (ie: the exact form of data (layout, sizes of fields, etc)) and the semantics (ie: the meaning (so x
is the first element of a vector
that has its origin at frame_id
)) in a single definition.
This allows both consumers and producers of such messages to be very explicit about the information they are communicating, and allows things like decoupling in time (ie: a consumer that receives messages that were produced 2 years ago should still be able to interpret them).
Your suggestion essentially comes down to using a field of type string
and populating it with data that syntactically fits that field perfectly fine (a JSON string is still a string
), but semantically seems like a bad fit: a JSON string is not just a string
, it's (typically) actually a stringified (ie: serialised) representation of some higher order data structure (such as a list, map or even worse: arbitrary application-specific classes).
Interpretation of that string
field now has two "layers" (in contrast to the 'normal' situation where we use only appropriate msg types):
string
We could say that "special knowledge" (ie: layer 2) is always required to be able to interpret a message, but the main difference here is that by using properly typed messages the special knowledge is (at least partly) embedded in the contract that exists between the producer and consumer: it's the semantics part of the message definition. That is very powerful, as it greatly reduces coupling between the producer and consumer: very little knowledge of the internals of the producer are imported into the consumer, making things like replacing components and mixing-and-matching components to create applications a lot easier, as neither will assume (too much) about the other.
If producer A
starts putting JSON (or anything that is not actually really a plain string
) into a field, the correct interpretation of that field completely depends on consumer B
knowing that field contains JSON (and not just an arbitrary plain string). This couples A
and B
, as they both must assume their communication channel works that way, or they can't function.
Note that a similar argument can be made for all message types in the std_msgs
package: a std_msgs/String
doesn't convey much semantics, neither does publishing a temperature measurement as a std_msgs/Float64
. That is also the reason that direct usage of messages in std_msgs
is discouraged: it's always better to use a more semantically meaningful type for your topics, as that will allow consumers to reuse the contract (ie: knowledge) that comes with those message types.
2 | No.2 Revision |
Is it good practice to use the ros2 json message, ie, in a standard message like std_msgs / string, write a string with a json structure?
I would say "no".
One of the main points of using standardised messages is because as we do in ROS is that they allow you to encode both syntax (ie: the exact form of data (layout, sizes of fields, etc)) and the semantics (ie: the meaning (so x
is the first element of a vector
that has its origin at frame_id
)) in a single definition.
This allows both consumers and producers of such messages to be very explicit about the information they are communicating, and allows things like decoupling in time (ie: a consumer that receives messages that were produced 2 years ago should still be able to interpret them).
Your suggestion essentially comes down to using a field of type string
and populating it with data that syntactically fits that field perfectly fine (a JSON string is still a string
), but semantically seems like a bad fit: a JSON string is not just a string
, it's (typically) actually a stringified (ie: serialised) representation of some higher order data structure (such as a list, map or even worse: arbitrary application-specific classes).
Interpretation of that string
field now has two "layers" (in contrast to the 'normal' situation where we use only appropriate msg types):
string
We could say that "special knowledge" (ie: layer 2) is always required to be able to interpret a message, but the main difference here is that by using properly typed messages the special knowledge is (at least partly) embedded in the contract that exists between the producer and consumer: it's the semantics part of the message definition. That is very powerful, as it greatly reduces coupling between the producer and consumer: very little knowledge of the internals of the producer are imported into the consumer, making things like replacing components and mixing-and-matching components to create applications a lot easier, as neither will assume (too much) about the other.
If producer A
starts putting JSON (or anything that is not actually really a plain string
) into a field, the correct interpretation of that field completely depends on consumer B
knowing that field contains JSON (and not just an arbitrary plain string). This couples A
and B
, as they both must assume their communication channel works that way, or they can't function.
Note that a similar argument can be made for all message types in the std_msgs
package: a std_msgs/String
doesn't convey much semantics, neither does publishing a temperature measurement as a std_msgs/Float64
. That is also the reason that direct usage of messages in std_msgs
is discouraged: it's always better to use a more semantically meaningful type for your topics, as that will allow consumers to reuse the contract (ie: knowledge) that comes with those message types.
3 | No.3 Revision |
Is it good practice to use the ros2 json message, ie, in a standard message like std_msgs / string, write a string with a json structure?
I would say "no".
One of the main points of using standardised messages as we do in ROS is that they allow you to encode both syntax (ie: the exact form of data (layout, sizes of fields, etc)) and the semantics (ie: the meaning (so x
is the first element of a vector
that has its origin at frame_id
)) in a single definition.
This allows both consumers and producers of such messages to be very explicit about the information they are communicating, and allows things like decoupling in time (ie: a consumer that receives messages that were produced 2 years ago should still be able to interpret them).
Your suggestion essentially comes down to using a field of type string
and populating it with data that syntactically fits that field perfectly fine (a JSON string is still a string
), but semantically seems like a bad fit: a JSON string is not just a string
, it's (typically) actually a stringified (ie: serialised) representation of some higher order data structure (such as a list, map or even worse: arbitrary application-specific classes).
Interpretation of that string
field now has two "layers" (in contrast to the 'normal' situation where we use only appropriate msg types):
string
We could say that "special knowledge" (ie: layer 2) is always required to be able to interpret a message, but the main difference here is that by using properly typed messages the special knowledge is (at least partly) embedded in the contract that exists between the producer and consumer: it's the semantics part of the message definition. That is very powerful, as it greatly reduces coupling between the producer and consumer: very little knowledge of the internals of the producer are imported into the consumer, making things like replacing components and mixing-and-matching components to create applications a lot easier, as neither will assume (too much) about the other.
If producer A
starts putting JSON (or anything that is not actually really a plain string
) into a field, the correct interpretation of that field completely depends on consumer B
knowing that field contains JSON (and not just an arbitrary plain string). This couples A
and B
, as they both must assume their communication channel works that way, or they can't function.
To make it more explicit: even though the message definition tells me that consumer B
accepts a string
, if I send it anything but JSON, B
will fail to process the message, even though both syntax and semantics have been adhered to (but note that string
is a less-than-ideal type for this sort of communication as well, see below).
Note that a similar argument can be made for all message types in the std_msgs
package: a std_msgs/String
doesn't convey much semantics, neither does publishing a temperature measurement as a std_msgs/Float64
. That is also the reason that direct usage of messages in std_msgs
is discouraged: it's always better to use a more semantically meaningful type for your topics, as that will allow consumers to reuse the contract (ie: knowledge) that comes with those message types.