Improve failure info in MessageFilter and TransformListener#130
Improve failure info in MessageFilter and TransformListener#130
Conversation
add error message when source or target frames are nonexistent
tfoote
left a comment
There was a problem hiding this comment.
Thanks for adding these improvements to the debugging. I found one bug and two places where I'd rather have small well scoped helper functions rather than just increasing the complexity of the processing methods.
| @@ -861,7 +868,7 @@ bool BufferCore::canTransform(const std::string& target_frame, const TimePoint& | |||
| if (warnFrameId("canTransform argument fixed_frame", fixed_frame)) | |||
There was a problem hiding this comment.
There appear to be more instances of warnFrameId that could pass through the error message instead of just printing to console.
| CompactFrameID source_id = lookupFrameNumber(source_frame); | ||
| CompactFrameID target_id, source_id; | ||
|
|
||
| try { |
There was a problem hiding this comment.
This logic could be worked inside of warnFrameId instead of replacing it. Then it could be reused elsewhere. The prototype would need to be extended with the error_msg pointer.
There was a problem hiding this comment.
That sounds like a great idea for a followup PR by someone who is more comfortable than I with this code
There was a problem hiding this comment.
This logic is creating the warnings, throwing an exception then immediately catching the exception and then pulling the string out of it. This is in one of the potentially highest throughput and consequently desired to be lowest latency sections of code. We don't want to be doing that.
If we add the third check of non-existant frame to warnFrameId it will have full coverage of the cases for validateFrameId's cases. And right now warnFrameId only outputs to console. In some cases like can_transform where we have an error string that we can populate if it's set. We should add that same capability to warnFrameId by adding the error_msg argument and then it can simply be added as an additional argument. And the behavior can be to either populate that error_msg if it's present, otherwise do the current behavior and send a warning to the console.
This will be an overloaded function and the current prototype can be updated to simply call the new version with the error_msg set to null to get the same behavior.
| RCLCPP_INFO(node_logging_->get_logger(), "[%s] Drop message: frame '%s' at time %.3f for reason(%d)", | ||
| __func__, frame_id.c_str(), stamp.seconds(), reason); | ||
|
|
||
| std::string reason_string; |
There was a problem hiding this comment.
This logic would be great for a helper function that converts the enum to string to keep the complexity of the functions lower. It then could also have a small unit test to ensure coverage too.
There was a problem hiding this comment.
This function exists just for logging. It's appropriate to convert the enum here. Also, I have no idea what the enums actually mean beyond what their names say.
There was a problem hiding this comment.
Just because it's used for logging doesn't mean it shouldn't have coverage and follow best practices.
The code would be much more readable if the whole case block was just a function std::string get_failure_reason_string(const FilterFailureReason& reason)
That then is invoked in the RCLCPP_INFO element instead of reason_string.c_str() it would be get_failure_reason_string(reason).c_str() And this method stays 5 lines long with no branchpoints.
And a unit test can be written for the static function that exercises all 3 cases and provides full coverage of that function.
This is just cleaning up the structure of the code to avoid building up technical debt.
|
I'm sorry. I can't really iterate on this. I don't understand the code well at all, and it's been 3 weeks since I had a tenuous grasp on how it works :-( |
|
@tfoote could you please either accept or reject this PR as-is? It’s clear this code needs lots of love, and I don’t intend to increase the scope of this PR |
tfoote
left a comment
There was a problem hiding this comment.
As it stands this is valuable but needs a little bit of refactoring to be a cleaner implementation. If you or anyone has time to update it that would be appreciated, right now I don't have time to clean this up myself.
| RCLCPP_INFO(node_logging_->get_logger(), "[%s] Drop message: frame '%s' at time %.3f for reason(%d)", | ||
| __func__, frame_id.c_str(), stamp.seconds(), reason); | ||
|
|
||
| std::string reason_string; |
There was a problem hiding this comment.
Just because it's used for logging doesn't mean it shouldn't have coverage and follow best practices.
The code would be much more readable if the whole case block was just a function std::string get_failure_reason_string(const FilterFailureReason& reason)
That then is invoked in the RCLCPP_INFO element instead of reason_string.c_str() it would be get_failure_reason_string(reason).c_str() And this method stays 5 lines long with no branchpoints.
And a unit test can be written for the static function that exercises all 3 cases and provides full coverage of that function.
This is just cleaning up the structure of the code to avoid building up technical debt.
| CompactFrameID source_id = lookupFrameNumber(source_frame); | ||
| CompactFrameID target_id, source_id; | ||
|
|
||
| try { |
There was a problem hiding this comment.
This logic is creating the warnings, throwing an exception then immediately catching the exception and then pulling the string out of it. This is in one of the potentially highest throughput and consequently desired to be lowest latency sections of code. We don't want to be doing that.
If we add the third check of non-existant frame to warnFrameId it will have full coverage of the cases for validateFrameId's cases. And right now warnFrameId only outputs to console. In some cases like can_transform where we have an error string that we can populate if it's set. We should add that same capability to warnFrameId by adding the error_msg argument and then it can simply be added as an additional argument. And the behavior can be to either populate that error_msg if it's present, otherwise do the current behavior and send a warning to the console.
This will be an overloaded function and the current prototype can be updated to simply call the new version with the error_msg set to null to get the same behavior.
|
@tfoote I am planning to continue out this PR over the next week, thanks for the above feedback, that informs the direction. |
|
Thank you so much for taking this over, @emersonknapp!!! |
fix #118