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
[Servo] Fix twist transformation #2301
Conversation
b5da5f5
to
b9fb55f
Compare
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #2301 +/- ##
==========================================
- Coverage 50.71% 50.69% -0.01%
==========================================
Files 386 386
Lines 31914 31920 +6
==========================================
- Hits 16182 16179 -3
- Misses 15732 15741 +9
☔ View full report in Codecov by Sentry. |
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.
I'll admit, I don't fully understand this logic and new parameter, so I've taken a look and commented more on the code side of things rather than the math.
Regardless, this will need some detailed documentation to make sense of it for users, because if I can't figure it out and I've been looking at servo for a few months, I'm not confident that the average user will be able to figure out easily either.
Yeah, will be updating the Servo tutorial page with a good explanation. Did not want to add it inline. |
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.
I don't understand why we would need this option at all. The PlanningSceneMonitor listens to and keeps track of all transforms (has its own transform buffer), and should probably be used instead of lookupTransform(). It also shouldn't make a difference if a frame is stationary or not just in order to transform it to the planning frame.
There is no real difference in the computation for when the command is in moving frame. So when the twist command given is expressed in the moving frame basis , we cannot use the moving frame as the Does that make sense? |
@henningkayser the basic idea is, if there's a lever arm between two poses, then an angular velocity will also cause a translational velocity. You can read all about it in #2150 |
Not sure why the "HaltForSingularity" unit test fails on Humble. |
Let's have a video chat. I feel like there is an XY communication issue going on here. |
f72311d
to
0f29f9a
Compare
Removed the complexity in favour of documentation. |
Code looks good, i'll approve after testing it. |
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.
Following @AndyZe 's need to test, I decided to test this against MoveIt Studio and found a bug...
I set the twist commands to be in the end effector frame, along a single axis, but they are leading to combined translation and rotation.
2023-08-16.16-43-04.mp4
Looking at the tf2::doTransform
code here (https://docs.ros2.org/foxy/api/tf2_geometry_msgs/namespacetf2.html), how does this work with an Eigen vector? Do you mind linking me to the code?
Behold, I found a PR by @AndyZe which says this, in fact, is translation first and rotation later! |
That helps explain my confusion. lol |
I guess the unit/integration tests still pass because we're passing all the commands in the planning frame itself, so the transform is a no-op. Would suggest making some tests that use alternative frames, e.g., the end effector, in the upcoming work we discussed offline |
BTW reverted to |
LOL, This is getting quite confusing.
I believe the documentation there is wrong. This is the equation being used in that
I think it might be because the This is And this is Also turns out, the pose resulting from the application of the twist is computed incorrectly here: https://github.com/ros-planning/moveit2/blob/a2f0183297284ed43ef5d435b4e11b414ec21876/moveit_ros/moveit_servo/src/utils/command.cpp#L236 The EDIT : Not sure about the above since the IK solver wouldn't know how to resolve the pose. EDIT 2:
So basically the command was being given in a moving frame that is not the end effector !! |
Hmm, now I too am confused. According to the code (not the comments) @ibrahiminfinite is right in that the rotation block seems to come first. Also, remember that in my example I am using a UR5e robot, not a Panda, so the actual frames used in the Panda servo config do not apply. But you're right -- this was a case where a moving frame was being used as the But then, in MoveIt Studio I get the correct results before this PR, so something else might be up. It might boil down to expectations:
How do we reconcile that some users (like myself) want the rotation-only part of the twist, whereas others (like those who reported #2150) want the actual translation+rotation portion of twisting the EE frame w.r.t. the base frame? EDIT: I guess this was the original stationary frame parameter that was in the first draft of this PR, wasn't it? The thing that differentiates whether we use equation 3.83 or 3.84? I may finally understand this, but have perhaps taken us on a big circle... |
moveit/moveit#2891 This was already reported earlier. |
I think we might be getting back to the original idea of not making any changes in code. Provide the transformation options in a header file. Point to the header file from the tutorial and an advanced user can do as they please. |
ebff3d3
to
a2f0183
Compare
Description
Fixes #2150
This was partly addressed in #2224, but the input ordering of the twist command to the
tf2::doTransform
was wrong.Since Servo used (linear, angular) and
tf2::doTransform
uses (angular, linear).Assumptions about the frames used in the context of twist commands:
planning_frame
is always stationary.