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

End-state deviates from goal state #532

Merged
merged 8 commits into from
Feb 25, 2024

Conversation

captain-yoshi
Copy link
Contributor

This fixes #531 but may not fix the actual problem, e.g. it may be the planner that silently fails or something else in the framework.

I just validate the last trajectory waypoint with the goal in the ConnectStage. If there is a deviation, the solution is marked as failed and a comment is set. I'm pretty sure you can optimize some of the code ;)


On a side note, I had to make sure that the joints where compared correctly (-pi = pi). Currently, when comparing joint position in the Connect::compatible method, this is not checked. You might reject some valid solutions, e.g the IK solver gives some joint positions in a negative defined angle versus the RobotState who may have a positive defined angle.

Solution 1 et 3 are valid but not 2 and 4.

image

If not within the threshold, mark solution as a failure and set comment.
Copy link

codecov bot commented Feb 21, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 59.09%. Comparing base (7638e5f) to head (8f8f08b).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #532      +/-   ##
==========================================
+ Coverage   58.99%   59.09%   +0.11%     
==========================================
  Files          90       90              
  Lines        8497     8504       +7     
==========================================
+ Hits         5012     5025      +13     
+ Misses       3485     3479       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@rhaschke rhaschke left a comment

Choose a reason for hiding this comment

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

Reading your solution to #531, I think that this is not related to incompatible start and end states: What you check is that the end-state actually reaches the goal state.
I think, your issue is a duplicate of #485, which was caused by a bug in MoveIt2.
Are you using MoveIt1 or MoveIt2? If you were using MoveIt1, it would be great if you could setup a failing unittest for your issue. Then, I can search for the underlying problem instead of applying cosmetic corrections 😉

if (jm->getType() == robot_state::JointModel::REVOLUTE)
min_distance = angles::shortest_angular_distance(positions_last_waypoint[i], positions_goal[i]);
else
min_distance = positions_last_waypoint[i], positions_goal[i];
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess you want to compute the joint difference:

Suggested change
min_distance = positions_last_waypoint[i], positions_goal[i];
min_distance = std::abs(positions_last_waypoint[i] - positions_goal[i]);

ROS_DEBUG_STREAM_NAMED("Connect",
"angular deviation: " << min_distance << " between trajectory last waypoint and goal.");

if (std::abs(min_distance) > 1e-4) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The magic number 1e-4 should be configurable, e.g. via a stage property.

@captain-yoshi captain-yoshi changed the title Validate connect stage deviation from end trajectory to goal End-state deviates from goal state Feb 23, 2024
@captain-yoshi
Copy link
Contributor Author

What you check is that the end-state actually reaches the goal state.

Yes ! Changed the title.

This fixes #531 but may not fix the actual problem, e.g. it may be the planner that silently fails or something else in the framework.

Just found the culprit. Even though LIN Pilz receives a JointConstraint, it will compute the FK to compute the goal pose. Currently the LIN planner only plans from a cartesian goal. Will create an issue in MoveIt.

Not tested but I'm pretty sure I could recreate the problem by changing the demo pick and place and replacing this line with the LIN Pilz planner. Or would you prefer a unit-test in MoveIt ?

For testing this PR, is there a way to fake a planner response that would offset the goal state outside the threshold limits ?

@captain-yoshi
Copy link
Contributor Author

To replicate this error, just use this mtc fork captain-yoshi/moveit_task_constructor/tree/trigger-error-532 and start the pick & place demo. This includes the validation in this PR.

You should see that it's failing and that for some solution the end-state does not match the goal-state.

image

@captain-yoshi
Copy link
Contributor Author

captain-yoshi commented Feb 23, 2024

After reading more on the Pilz LIN planner, it generates linear Cartesian trajectory between goal and start poses.

The solution would be to feed the joint constraint goal instead of redoing an IK.


EDIT
The IK is invoked on each sample of the cartesian path. Because the end goal IK can be different from the one supplied, one cannot use a Pilz LIN in a Connect stage.

Well you can use it, but it will only work for IK's who succeeded (in the ComputeIK stage) on their first attempt because the seed is wrt. the start state ?

@rhaschke
Copy link
Contributor

Yes, the Pilz planner performs linear interpolation in Cartesian space. If you want to perform linear interpolation in joint space, there is the JointInterpolationPlanner in MTC available for this.

Not tested but I'm pretty sure I could recreate the problem by changing the demo pick and place and replacing this line with the LIN Pilz planner. Or would you prefer a unit-test in MoveIt ?

So you claim, that the Pilz planner generates incomplete trajectories, which are considered to be valid by MTC?
Please create a unit test in MTC triggering exactly this issue. Thanks.

For testing this PR, is there a way to fake a planner response that would offset the goal state outside the threshold limits?

Why would you like to do so? If a planner behaves like that, this planner is buggy and should get fixed.

Copy link
Contributor

@rhaschke rhaschke left a comment

Choose a reason for hiding this comment

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

I see the need for this PR. Some planners, like Pilz or MTC's Cartesian interpolation, may not reach the exact goal state, although the Cartesian poses match.
See the comment below to address before merging.

double min_distance;
for (std::size_t i = 0; i < num; ++i) {
if (jm->getType() == robot_state::JointModel::REVOLUTE)
min_distance = angles::shortest_angular_distance(positions_last_waypoint[i], positions_goal[i]);
Copy link
Contributor

Choose a reason for hiding this comment

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

You must not use angles::shortest_angular_distance here, as we need to reach the exact goal state - subsequent stages rely on this fact!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hum... I'm pretty sure it removed valid solutions... Will investigate more and report back soon.

Copy link
Contributor

Choose a reason for hiding this comment

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

We cannot accept equality up to multiples to 360°. The goal state needs to be reached exactly. Otherwise subsequent stages will run into trouble because they relied on a different start state.

@captain-yoshi
Copy link
Contributor Author

captain-yoshi commented Feb 25, 2024

I see the need for this PR. Some planners, like Pilz or MTC's Cartesian interpolation, may not reach the exact goal state, although the Cartesian poses match.

Exactly ! This is necessary to be able to use such planners, which does not respect the goal joint constraint. Furthermore, it can catch errors in other planners, e.g. #485. Finally, it guards against the move_group/ExecuteTaskSolutionCapability which seems to shoot the hole trajectory without doing any validation against the end state and the start state of sub-trajectories.

@rhaschke
Copy link
Contributor

it guards against the move_group/ExecuteTaskSolutionCapability which seems to shoot the hole trajectory without doing any validation against the end state and the start state of sub-trajectories.

The discontinuity doesn't happen between the end-state and start-state of to consecutive trajectories but between the next-to-last and last state of the Connect trajectories. Thus, MoveIt's task execution cannot guard against this discontinuity.

@rhaschke
Copy link
Contributor

I pushed a simplifying commit, using RobotState::distance() to compute the joint-space distance between the two states. No need to reimplement the wheel ;-)

Copy link
Contributor

@rhaschke rhaschke left a comment

Choose a reason for hiding this comment

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

I also added a unit test now. For me, this is ready to merge. @captain-yoshi, any objections to my changes?

@captain-yoshi
Copy link
Contributor Author

All good on my end :) Great optimization by the way 🥇

@rhaschke rhaschke merged commit 5720b83 into moveit:master Feb 25, 2024
8 checks passed
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.

Connect stage: incompatible end and start state marked as valid
2 participants