Skip to content
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

Merged
merged 15 commits into from
Mar 26, 2020

Conversation

emersonknapp
Copy link
Collaborator

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)

@@ -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
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

rosbag2_storage/include/rosbag2_storage/topic_metadata.hpp Outdated Show resolved Hide resolved
Comment on lines +58 to +67
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>());
Copy link
Contributor

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?

Copy link
Collaborator Author

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

Copy link
Collaborator Author

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.

Copy link
Contributor

@thomas-moulard thomas-moulard Mar 26, 2020

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?

Copy link
Contributor

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)

Copy link
Collaborator Author

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

Copy link
Collaborator

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.

rosbag2_transport/src/rosbag2_transport/qos.hpp Outdated Show resolved Hide resolved
rosbag2_transport/src/rosbag2_transport/recorder.cpp Outdated Show resolved Hide resolved
@emersonknapp emersonknapp force-pushed the emersonknapp/metadata-with-qos branch from fd8b7fe to 55ac449 Compare March 26, 2020 18:51
@emersonknapp
Copy link
Collaborator Author

@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 <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
@emersonknapp emersonknapp force-pushed the emersonknapp/metadata-with-qos branch from e4587a3 to aa55d43 Compare March 26, 2020 19:50
Copy link
Contributor

@piraka9011 piraka9011 left a 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 <emerson.b.knapp@gmail.com>
@emersonknapp emersonknapp merged commit 5810588 into ros2:master Mar 26, 2020
Copy link
Collaborator

@Karsten1987 Karsten1987 left a 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
Copy link
Collaborator

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.

Copy link
Collaborator Author

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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

# pragma warning(pop)
#endif


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment on lines +58 to +67
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>());
Copy link
Collaborator

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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

@emersonknapp
Copy link
Collaborator Author

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.

@Karsten1987
Copy link
Collaborator

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.

@dirk-thomas
Copy link
Member

@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

emersonknapp added a commit that referenced this pull request Mar 27, 2020
…zation utilities (#330)"

This reverts commit 5810588.

Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
@emersonknapp
Copy link
Collaborator Author

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

Comment on lines +29 to +30
time.sec = node["sec"].as<uint>();
time.nsec = node["nsec"].as<uint>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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>();

Copy link
Contributor

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,

emersonknapp added a commit that referenced this pull request Mar 27, 2020
…zation utilities (#330)" (#334)

This reverts commit 5810588.

Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
emersonknapp added a commit that referenced this pull request Mar 29, 2020
* serialize and deserialize QoS in metadata

Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants