-
Notifications
You must be signed in to change notification settings - Fork 35
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
[3D] Solutions involving local hinges may exhibit discontinuities #2
Comments
+1 to fix this issue. I've used the calico library to handle the IK for a robotic arm but found that certain effector targets would cause undesirable "snapping" of the bones that causes huge stresses on the mechanicals. I've so far mitigated the problem somewhat with judicious choices of constraints--but this is non-optimal since doing so effectively removes possible solutions for the IK problems in exchange for reducing the likelihood of snapping through a constraint. By the way, great job on this library. It is very useful. |
I'd love to fix this issue, I truly would - but I have other projects that need completing at the moment, sorry. But that's part of why I open-sourced this, so other people can contribute if they'd like ;-) In fact, there's a guy working on providing proper (i.e. true to the FABRIK research paper) four-quarter constraints to the library for inclusion in Unreal Engine 4, and the results of that work could flow back into this if it all comes to fruition. Even without that, it might be possible to avoid the 'pull-through' / "snapping" by not accepting solutions where, say, the angle of the basebone between solutions has moved more than a given amount. However, you would then end up in a joint-lock 'you-can't-get-there-from-here' situation, but it wouldn't stress the arm as much. I'm glad you like the library - I've never seen it actually move a robotic arm, would love to see any pics/video or such if you'd be willing to share! Cheers! |
Here's a video. Not very good one, but you can kind of see where I'm going with this. The end is a sort of joke: the arm follows a macro to pull its own power and commits suicide. Enjoy. |
Haha, that's great! Thanks for sharing! =D |
Hi all. It's been a while. I got some time during the holidays to control a Braccio robot arm using the Caliko library, although in 2D only at this time. |
That's very cool - seems to be working like a charm! =D |
I wish I had read this issue before implementing the constraints part of this implementation in another language and bumping my head against the wall, trying to figure out why my local hinges weren't working properly. |
jvdnbus, do you mean you re-implemented FABRIK and found yourself with the same discontinuity problem? Or you transcoded Caliko to another language? Depending on your use-case, you may find that alternate methods (of which there are a few) to generate orthonormal basis axes may help you out. Take a look at the Mat3f class and the "createRotationMatrix" method (and commented out alternatives). I'd be happy to work with you to try to fix the issue, but it's not something I'm really keen about taking on by myself. |
Easiest solution to stop snapping: only allow a maximum of x-degree (like 2 degrees) from where it currently is per frame. For example, if it WANTS to snap 80 degrees? Only let it have 2 degrees from the current angle - but in the direction of the 80 degree snap. This could probably be done by simply changing a return statement to: return clamp(-maxSnapDegs, maxSnapDegs) Whether that's just for end effector (likely) or for all bones in the chain (less likely) I don't know - it would require some testing to see how it responds. |
I transcoded the base code to Lua. I was having issues with the createRotationMatrix method, indeed. I noticed the snapping behavior sometimes but I'm fairly certain in my use case I can post process the angles like you said. Secondly, I'm not sure if this is related to this issue but when creating consecutive bones with local hinges like pictured here, the algorithm is unable to create a relative rotation vector that is perpendicular to the reference axis.
All joints are hinges and they are all positioned 0 on the z axis and should rotate around the z axis. This makes the 2nd and 3rd bone go straight down the y axis ( dir {0,-1,0} ). I'm unable to get the right parameters for j2 as it states the angle between rot and ref axis is either 0 or 180 degrees. |
Did you try any of the alternate methods to generate orthonormal axes? Worst case - if you're getting bad results from PURE directions then fuzz them by +/- 0.0001 or so. Give me a setup that doesn't work and I'll take a look at it. |
"The algorithm is unable to create a relative rotation vector that is perpendicular to the reference axis." The algorithm isn't the problem - my implementation of it might be. |
I have not yet tried any alternate methods. Here's a crude test: caliko test |
I'll get back to you within a week. Have you tried FIK? It's Caliko but in JavaScript. |
You have a rotation axis and a reference axis comprised of FOUR Vec3s. WTF? I'm sorry, but this library was not designed to work in four-dimensional space. You're on your own. |
Haha, no, those are simply different axes for each bone, still 3d! I figured that way I could try different setups more easily. |
I was able to get it working using "OLD VERSION 1.3.4 and earlier" of createRotationMatrix. The plane vector gave a zero vector with the newer version. |
Cool. Sorry for being a bit scattered in the replies above, I might have had a few too many shandies that night (as evidenced by the fact that I completely forgot that this part of the issue thread ever happened - oops). Yeah, the v1.3.5 createRotationMatrix() method was knacked under some circumstances and would return an illegal 3x3 rotation matrix - it got fixed in the v1.3.8 release after prompting from this issue, when really I should have got on top of it from this one. My bad - glad you got it sorted, anyhow =D |
@alansley hello, thanks for library) I'm trying to use it for human body inverse kinematic. I have similar problem with local hinge discontinuity. I would like to fix problem with
Is my understanding correct? Can you give ideas on using new approach with quanternions, what else should be considered in algorithm to change? |
I think you'd only need a single Quaternion to describe the rotation of a FabrikBone3D.
I'm not quite sure I understand what you mean. When creating each bone, rather than giving it just a start and end position (which would get you the pitch and yaw) you'd also want to specify the roll. Essentially rather than With the join restrictions you'd probably end up doing a lot of Quaternion-to-Euler conversion (and back) unless you take the joint restrictions in Euler angles and then convert them to some kind of`Quaternion that describes the degree of restriction relative to whatever you've specified (e.g., global space, or local space previous bone). You'd also need to import a math library that provides Quaternions, or write the bits and pieces you need and add them to the custom math classes that come with Caliko. I definitely think it can be done, but I don't have the time or inclination to do it - if you have a go maybe just start small. You could write the world's simplest Quaternion class and have a pretend/text-based setup with 2 bones, then try restricting the end-effector bone about the base-bone using Quaternions some small amount / with some easy to intuit values (although you'll likely have to go to/from Eulers as just looking at Quaternions (as raw values) doesn't really intuit which way they're pointing (at least to me). If you can get some simple setup working like that, then you've got proof of concept and could have a go at integrating them into Caliko proper, if you wanted. |
IK solutions when using local hinges, especially with references constraints, exhibit discontinuities in the solutions. This isn't necessarily to say that the solutions are bad - they aren't - but that they can 'snap' from one side of a constraint to another, which may have knock-on effects on other bones in the same chain, resulting in 'jumps' in the chain's solution.
The issue may also be exacerbated by the fact that bone directions are not kept in quaternions (which would enable smooth 'closest-path-to' interpolation [i.e. lerp] from one vector to another) - they are held as plain start and end points, from which a direction is determined and used for the generation of axes. However, a single directional vector does not contain enough information to allow for the generation of 100% consistent perpendicular axes, as when the direction of the bone is the same as the what is used for the 'up' vector when generating an orthonormal basis, an alternate vector must be used which may also add to the 'jump' in chain configuration.
Resolving this issue with code to avoid snapping through constraints would introduce a form of joint-lock where you can't get there from here, which is undesirable - but storing bone directions either in quaternions or along with their own per-bone Model matrix could mitigate orthonormal axis generation issues which I believe add to the observed discontinuities in the solutions to chains involving local hinges.
I've thought out the basis of a comparative investigation of local-hinge algorithm modifications, and I would love to complete it in 2016 - but it depends on what interest there is in this library, as it forms only the very first research artefact of my PhD through publication, and I have only 17 months left to publish another five papers. For perspective, this library took me 18 months to write.
The text was updated successfully, but these errors were encountered: