-
Notifications
You must be signed in to change notification settings - Fork 253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add QoS profiles field to metadata struct and provide serialization utilities #330
Add QoS profiles field to metadata struct and provide serialization utilities #330
Conversation
@@ -33,7 +33,7 @@ struct TopicInformation | |||
|
|||
struct BagMetadata | |||
{ | |||
int version = 3; // upgrade this number when changing the content of the struct | |||
int version = 4; // upgrade this number when changing the content of the struct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it the right time to update the bag metadata? Could we delay that until the feature is built completely? What's the impact if we were to release rosbag2 just after this PR gets merged?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I was considering this, but I think that now is the time because now is when the data model actually changes. Moving forward that model will just start to hold more useful values. If we were to release this now, nothing bad would happen, it's fully backward compatible with previous metadata versions.
qos | ||
.keep_last(node["depth"].as<int>()) | ||
.history(history) | ||
.reliability(reliability) | ||
.durability(durability) | ||
.deadline(node["deadline"].as<rmw_time_t>()) | ||
.lifespan(node["lifespan"].as<rmw_time_t>()) | ||
.liveliness(liveliness) | ||
.liveliness_lease_duration(node["liveliness_lease_duration"].as<rmw_time_t>()) | ||
.avoid_ros_namespace_conventions(node["avoid_ros_namespace_conventions"].as<bool>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's a hard problem to solve, but any idea about how we could try to keep this in sync as qos gets new fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a good answer to this. My thought as of right now is just that rosbag2 needs to have a pass to support new fields if they are added, and until that time it will only support the default values for any given policy.
I'm not aware of a way to introspect fields of a struct in C++, but that doesn't mean there isn't a way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah - I thought of something we can do. It is a "change detector" like we try to avoid, but in this case of serialization method, it seems like the right thing to do. I'm adding a test that explicitly builds a rmw_qos_profile_t using {} initializer, so if new fields are added, the build will fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about it, deserialize(serialize(x)) == x
should do the trick?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're sure the qos struct will always be a POD, memcmp is an option otherwise (tread carefully as it can blow up easily)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it will. If new fields are added - when I construct the object it will use the default values for those new fields. Now when I serialize, it will write out all the fields we specified here. Then, on deserializing, it will read the fields that it knows, with the unknown fields having default values. The equality will pass and new fields will have slipped through undetected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could maybe apply something like a builder pattern which only allows to build the object if all parts are present. But I don't see a real way around updating the code base if the QoS struct gets more fields.
fd8b7fe
to
55ac449
Compare
@Karsten1987 how do you feel about the structure of this? These utilities are gating the rest of the functionality, which is started but I can't finish until this is finalized. |
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
Signed-off-by: Emerson Knapp <[email protected]>
e4587a3
to
aa55d43
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to add the QoS profile stubs in the tests now or will the interface change a bit? (I don't think it will?)
Signed-off-by: Emerson Knapp <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me.
For future PRs, I would make my life a bit easier if you could quickly summarize what part of #125 the PR is addressing. That makes it a more straightforward to get to the meat of the PR.
{ | ||
public: | ||
Rosbag2QoS() | ||
: rclcpp::QoS(0) {} // 0 history depth is always overwritten on deserializing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could also default to rclcpp::SystemsDefaultQos()
or something. But I think this doesn't really matter as far as I can understand your comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that rmw_qos_profile_system_default
is different than rmw_qos_profile_default
- system_default is dependent on the rmw implementation, and because of that I don't think it's something anybody should ever use.
But, I will instantiate this with the default profile (not system_default)
static bool decode(const Node & node, rosbag2_transport::Rosbag2QoS & qos); | ||
}; | ||
} // namespace YAML | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# pragma warning(pop) | ||
#endif | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
qos | ||
.keep_last(node["depth"].as<int>()) | ||
.history(history) | ||
.reliability(reliability) | ||
.durability(durability) | ||
.deadline(node["deadline"].as<rmw_time_t>()) | ||
.lifespan(node["lifespan"].as<rmw_time_t>()) | ||
.liveliness(liveliness) | ||
.liveliness_lease_duration(node["liveliness_lease_duration"].as<rmw_time_t>()) | ||
.avoid_ros_namespace_conventions(node["avoid_ros_namespace_conventions"].as<bool>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could maybe apply something like a builder pattern which only allows to build the object if all parts are present. But I don't see a real way around updating the code base if the QoS struct gets more fields.
: rclcpp::QoS(value) {} | ||
}; | ||
} // namespace rosbag2_transport | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Karsten for the feedback - sorry we merged before you got to it, I am feeling time pressure for the API freeze and would like to start getting to the features. I'll put up a quick PR addressing these comments And I will make sure to put a more descriptive explanation on the upcoming PRs of what part of #125 they are achieving. |
no worries. I guess I was just too slow with my review ;-) No need for an extra PR for the new lines. You might as well just put them in your next one. |
@emersonknapp Can you please point to the CI builds which have been run for this change before it was merged? This change seems to break the build on Windows: https://ci.ros2.org/job/ci_windows/9656/console#console-section-29 |
…zation utilities (#330)" This reverts commit 5810588. Signed-off-by: Emerson Knapp <[email protected]>
Argh, sorry, false sense of security from the automatic actions, I've reverted the change here #334 and will reopen this PR with a CI run on it and the windows fix |
time.sec = node["sec"].as<uint>(); | ||
time.nsec = node["nsec"].as<uint>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
time.sec = node["sec"].as<uint>(); | |
time.nsec = node["nsec"].as<uint>(); | |
time.sec = node["sec"].as<uint64_t>(); | |
time.nsec = node["nsec"].as<uint64_t>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would fix it,
…zation utilities (#330)" (#334) This reverts commit 5810588. Signed-off-by: Emerson Knapp <[email protected]>
* serialize and deserialize QoS in metadata Signed-off-by: Emerson Knapp <[email protected]>
Part of #125
But, don't use this feature anywhere yet. Next step will be to query and store the QoS profiles for recorded topics.
rosbag2_transport constructs the TopicMetadata, so that's where the serialization/deserialization will need to occur (in
recorder.cpp
/player.cpp
)