-
Notifications
You must be signed in to change notification settings - Fork 911
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
Ensure latched messages are updated on every split #2261
base: noetic-devel
Are you sure you want to change the base?
Conversation
I am running into issues caused by this, which strongly limits the viability of @mjcarroll |
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.
Suggested a change, but even without it, merging what is here is better than keeping a broken implementation around.
@@ -347,7 +347,11 @@ void Recorder::doQueue(const ros::MessageEvent<topic_tools::ShapeShifter const>& | |||
ros::M_string::const_iterator it2 = out.connection_header->find("callerid"); | |||
if (it2 != out.connection_header->end()) | |||
{ | |||
latched_msgs_.insert({{subscriber->getTopic(), it2->second}, out}); | |||
auto const result = latched_msgs_.insert({{subscriber->getTopic(), it2->second}, out}); |
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.
auto const result = latched_msgs_.insert({{subscriber->getTopic(), it2->second}, out}); | |
latched_msgs_[{subscriber->getTopic(), it2->second}] = out; |
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.
The []
operator does exactly what's expected here, in case the key doesn't exist in the map, it will be created and when it does exist, it will be updated.
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 for the suggestion - the []
operator is indeed cleaner since it removes the need for the extra manual check (in lines 351-354).
I'll try to update it shortly (I don't have the test environment handy anymore).
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.
@AndreasNagel I tried your suggestion and unfortunately it fails to build:
error: no matching function for call to ‘rosbag::OutgoingMessage::OutgoingMessage()’
I believe this is due to the behavior of the []
operator when a key is not found in the map. From the docs:
If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value.
When a key is missing, the []
operator tries to create an OutgoingMessage
object with an empty constructor that does not exist: OutgoingMessage()
. (The object seems to only have one constructor that requires 4 arguments.)
I didn't find an easy way to go around this without creating an empty constructor for OutgoingMessage
- I'd prefer to avoid introducing a change like that.
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.
Good point, I missed that OutgoingMessage
doesn't have a default constructor. I agree, there's no point in creating one just to use the []
operator. There's insert_or_assign in c++17, but nothing with equivalent functionality in c++14, so what you have there is probably as good as it gets. Still hoping, that this change will get merged one day.
Behavior has changed after #2351 |
Summary
This fixes an issue with #1850 - latched messages from the same publisher are not updated in the
Recorder
.Steps to Reproduce
rosrun rosbag record -a --repeat-latched --duration 10 --split
rostopic echo -b <last_split>.bag chatter
Expected behavior
The first message in the last split is the value of the latched topic when the split was started (e.g.,
data: "18"
).Actual behavior
The first message in the last split is the value of the latched topic when the
rosbag record
was run (e.g.,data: "0"
).Implications
This behavior causes issues when recording latched topics that are not often updated. If the
rosbag record
is a long-running process, the latched topic values in some splits may be several hours old (if the publisher does not send an update within the split time frame).Cause
Latched messages are stored as a
std::map<std::pair<std::string, std::string>, OutgoingMessage>
, where the key is a pair of strings (topic and publisher name) and the value is the latched message.When updating the
latched_msgs_
map, thestd::map::insert()
function is used. This behaves as expected when the key does not yet exist in the map. However, if the key exists, the old value is not updated:This effectively means that the first value (latched message) that was inserted into the map will persist across the whole
rosbag record
.Solution
Check for insertion success and assign value manually if required (see commit).