[JTC] Return INVALID_GOAL error code for rejected trajectories (#700)#2237
[JTC] Return INVALID_GOAL error code for rejected trajectories (#700)#2237AdvityaCode wants to merge 2 commits into
Conversation
christophfroehlich
left a comment
There was a problem hiding this comment.
Thank you for picking this.
We will have to discuss this in the next PMC meeting if the accept-and-immediately-reject pattern is something everyone is happy with.
I propose that we use tl::expected (until std::expected is available) instead of returning an empty string.
| bool validate_trajectory_msg(const trajectory_msgs::msg::JointTrajectory & trajectory) const; | ||
| /// Validate a trajectory message. Returns an empty string if valid, or a | ||
| /// human-readable error description if the trajectory should be rejected. | ||
| std::string validate_trajectory_msg( |
There was a problem hiding this comment.
what do you think of using tl-expected here? Similar to the validators in https://github.com/PickNikRobotics/generate_parameter_library?tab=readme-ov-file#custom-validator-functions
There was a problem hiding this comment.
I agree with using tl-expected! Just updated the pr: switched validate_trajectory_msg and validate_trajectory_point_field to return tl::expected<void, std::string>. The tl_expected header was already available via validate_jtc_parameters.hpp so no new dependencies were needed. Let me know your thoughts and if there's anything else you'd like changed.
2be68d8 to
acebcac
Compare
|
This PR is stale because it has been open for 45 days with no activity. Please tag a maintainer for help on completing this PR, or close it if you think it has become obsolete. |
Problem
When the Joint Trajectory Controller rejects an invalid trajectory (empty points, wrong joint names, non-monotonic timestamps, etc.), the action client receives an opaque REJECT response with no structured feedback. The only signal available to the client is a log line in the controller's terminal — which is not a viable error-handling strategy for automated systems.
This is a limitation of action protocol (tracked upstream at ros2/rclc#271): GoalResponse::REJECT provides no mechanism to set error_code or error_string on the result.
Closes #700.
Proposed Solution
This is my suggested approach — I'm open to feedback and happy to revise the implementation. It is just what I thought would be the best approach.
The workaround discussed in #699 is to always accept goals at the action protocol level, then immediately abort with a populated error_code and error_string if validation fails. I followed that direction here, but I wasn't sure on some of the design choices so please let me know if any of these should be done differently:
- Whether the controller is active (PRIMARY_STATE_INACTIVE → abort with INVALID_GOAL)
- Whether the trajectory message is valid (all existing checks → abort with INVALID_GOAL + descriptive error_string)
I wasn't certain whether changing the return type of validate_trajectory_msg to std::string was the right call, or whether an out-parameter or a separate struct would be preferred. Happy to change this if there's a style the project prefers.
Tests