-
Notifications
You must be signed in to change notification settings - Fork 199
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
IK solver example rig? #41
Comments
The rig from that video is hiding somewhere in here but it might be a pain to find. IK rigs can benefit from fewer constraints, since it gives the solver more paths to search for valid solutions and usually the solver won't be tasked with correcting poses that are wildly out of position. In that sense, IK rigs can actually be simpler than rigs for ragdoll dynamics. Notably, internally bepuik is just a repurposed dynamic simulation. The interface it is wrapped with is what makes it behave like an IK solver. You could do the same thing pretty easily in bepuphysics2, too, and it would would be faster and more stable. |
I've already tried creating my own IK solver a while back and ran into some problems I wasn't able to solve (mainly related to constraints), which is why I'm here. There's plenty of other IK solutions out there, but most of them don't support constraints/limits, IK trees, handles or are lacking something else.
I believe I found the model with the rig over here: https://code.google.com/archive/p/bepuik/downloads ("bepuik_autorig_example.blend"). I'm not that familiar with Blender though, maybe I'm just doing something wrong. Is there some way to export the ik rig in a text-based format, or some way to inspect the parameters in Blender? |
Dunno! I didn't write the blender plugin, just the solver bits. My guess is the easiest path is starting from the |
I've been making some progress, but I'm having some trouble understanding how the swing limit works if the two axes are not the same. Here's a very simple ball-socket constraint with a swing limit that limits the angle to 10 degrees (with the same Bone bodyBone = new Bone(body.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), 0.5f, 1.0f);
Bone headBone = new Bone(head.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), 0.5f, 1.0f);
bones.Add(new BoneRelationship(bodyBone, body));
bones.Add(new BoneRelationship(headBone, head));
joints.Add(new IKBallSocketJoint(bodyBone, headBone, headBodyBallSocketAnchor));
joints.Add(new IKSwingLimit(bodyBone, headBone, new Vector3(-1.0f,0.0f,0.0f), new Vector3(-1.0f, 0.0f, 0.0f), DegreeToRadian(10.0f)));
joints.Last().Rigidity = 999.0f; BEPUphysicsDemos.2023-04-24.16-37-58-358.mp4So far so good. This is the same example, except Bone bodyBone = new Bone(body.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), 0.5f, 1.0f);
Bone headBone = new Bone(head.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), 0.5f, 1.0f);
bones.Add(new BoneRelationship(bodyBone, body));
bones.Add(new BoneRelationship(headBone, head));
joints.Add(new IKBallSocketJoint(bodyBone, headBone, headBodyBallSocketAnchor));
joints.Add(new IKSwingLimit(bodyBone, headBone, new Vector3(-1.0f, 0.0f, 0.0f), Vector3.Normalize(new Vector3(-1.0f, 0.0f, 0.2f)), DegreeToRadian(10.0f)));
joints.Last().Rigidity = 999.0f; BEPUphysicsDemos.2023-04-24.16-38-40-710.mp4This is probably correct behavior, but I can't quite visualize what's going on here in my head. I would like to add some debug visualization aid, but I'm not quite sure what that would look like. If it's not too much to ask, do you have any tips for me? There are a few cases like this in the action figure demo, and I'm trying to understand how this configuration works exactly. For instance: //Right leg
joints.Add(new IKBallSocketJoint(bodyBone, upperRightLegBone, bodyUpperRightLegBallSocketAnchor));
joints.Add(new IKSwingLimit(bodyBone, upperRightLegBone, Vector3.Normalize(new Vector3(.3f, -1, .6f)), Vector3.Down, MathHelper.Pi * 0.6f)); |
In the end, the swing limit (both the dynamic version and So, for the hip joint, because I didn't want equal range of motion in all directions but rather more front/out, I set the axis attached to A (bodyBone) to point more in the front/out direction. Imagine a cone centered on the axis attached to A that keeps the axis attached to B within it. |
Thank you, I ended up creating a debug visualization overlay for the IK solver in my program to help visualize what's going on. In general it works just fine, but there are a few cases where the behavior is not what I would expect: In this case there is a simple IK chain with 5 bones: Hip, UpperLeg, LowerLeg, Foot, Toe.
In the first pose in the video, everything works as it should: Unfortunately in the second pose it kind of falls apart: It also becomes unstable in other configurations, though I'm not sure why: Any ideas what could cause this? I'm not sure what to look for. |
If I had to guess, the control is attempting to maintain an orientation which is incompatible with bending the leg more. Controlling only the linear degrees of freedom would test this.
I'd bet it's related to the twist limit. Twist related constraints have a singularity when the twist axes line up in reverse. v1 and bepuik didn't handle that singularity super duper gracefully, especially when combined with how it handles spring stiffness tuning. Disabling the twist limits would test this. To avoid it, swing limits pushing the configuration away from the twist limit singularity would help.
Is that all three iteration counts?
Increasing the Probably not actually necessary if other issues are resolved, though. |
Thank you for the tips, after changing the iteration values (and time step), I haven't seen any instability anymore:
It is now way too slow for a real-time simulation, but I should be able to tweak the values to find a good balance through experimentation. Unfortunately the issue where it refuses to exhaust the joint limits still remains. After some testing I've been able to narrow it down, it looks like the culprit is actually the state control: In this example there are the following constraints:
I.e. the toe and foot are fixed, and the lower and upper leg bones each have a hinge constraint. No twist limits involved. The drag control in the first half of the video behaves how you'd expect, but I don't understand the behavior of the state control. The description for it says:
As I understand it, it should just try to solve the IK in such a way that it keeps the bone's original rotation relative to its parent(?). But to me it seems like it should be able to do so, while still being able to get much closer to the effector position than it does: Am I misunderstanding the state control? As an aside, how different is the constraint system in bepuphysics2 compared to this ik system? Would it be possible to 'merge' the improvements into the ik system, without having to do large-scale rewrites and without having to take a deep dive into the intricacies of IK, or are the two too fundamentally different? |
Ah, there's the issue: it's absolute orientation, not parent relative orientation. "Controls" operate on only one target bone- if you want to maintain the relationship between two bones, you'd probably want the
They're similar in that they're both implemented with conceptually similar solvers, but it's quite different in terms of how you interact with the solver and there is no shared code. A "merge" would realistically be just "make a version of a bepuik-like API that wraps bepuphysics2." Which isn't impossible, for what it's worth- it'd probably fit in a bepuphysics2 demo. (I may do that at some point, but definitely not within a week.) |
I'm going to stick with the current implementation for now, but there's one more thing I'd like to know: I would like to replicate this behavior using bepuik: In this example, there is one control for the hand bone, and one for the elbow. The elbow control is more of a "suggestion" though, the solver always prioritizes trying to reach the control position for the hand, so moving the elbow control has no effect on the hand. I tried a similar setup with bepuik: It's just a few ball socket joints, a drag control for the elbow and a state control for the hand (no limits). Is it possible to change the behavior to mimic that of the first video? |
You can set The blender bepuik integration also did things like doing IK simulation down the bone hierarchy to the deepest defined control, while treating bones beyond that point as 'peripheral' and handled with simple FK. Plus some configuration options to change the behavior as needed. You can do things like that without needing multiple solvers running simultaneously; you can just add/remove on demand. |
The behavior you get from pinning is what I'm looking for, but of course that only works as long as the target position is actually reachable:
|
If the concern is the freakout behavior, decrease the The freakout is caused by the simulation not converging to a solution. Shortening the time step duration is the strongest stabilizer for that kind of failure, while reducing rigidity (where acceptable for the use case) simply makes the simulation easier to solve and more likely to converge. If you're concerned about the pin being movable beyond the limit of the character's reach, that's more fundamental; pins are inviolable. The state control would be necessary to avoid that (along with whatever tuning to the simulation is necessary to reach the desired stability).
Getting/setting the maximum force is an abstract property that is used to change the control's internal constraint values. For example: https://github.com/bepu/bepuphysics1/blob/master/BEPUik/DragControl.cs#L65 Also, if |
Hello!
I'm very interested in this library for the IK solver. I've checked bepuphysics v2, but it doesn't appear to include it, which is why I'm asking here.
I know there's an ik demo included with the library, but it's a very basic one. I'm curious to see what the set up looks like for a more complex humanoid IK rig, specifically like the one used in this video: https://youtu.be/lG3uKYQTVj4
I've tried replicating the behavior shown in the video, but haven't had much luck.
Is that model +rig available for download somewhere? If so, is there some way I can see how it was set up, i.e. with what kind of joints, limits, controls and parameters so I can try replicating it programmatically?
Thanks in advance!
The text was updated successfully, but these errors were encountered: