I am currently working with mechanical rigging and has encounter a type of problem that keeps turning up again and again. I tried to solve it with inverse kinematics, but I have failed to find a way to set it up properly. I now wonder if someone knows a good solution for this problem. See the sketch below:
The two red dots can be moved freely in 2 dimensions by other parts of the mechanical rig (however, their movements will be mostly in the right/left direction). The blue bar can only move along the specified axis (think of this as a piston or a cylinder movement). The black, orange and blue bars can all rotate freely around the green joints. The orange bar is a solid bar that is connected to the blue bar with a joint somewhere between its end points (i.e. not necessarily in the middle of the orange bar).
So, in short, the movement of the blue bar is influenced by the position of the two red dots.
Also note that the rig is not symmetric and that the bars can have different lengths.
Hey, Not sure what the main drive would be but assuming its the Blue bar; Blue Bone (Parent) > Orange Rotate bone (child) > Orange Location bone (child) > 2 Black bones (children) IKs - 2 Red dot bones (children of Orange Location bone) these will be your IK Targets for the 2 Black bones. If you want the Black bones to âstretchâ, make sure to enable it. Screen shot â po st back if you have any Qs.
I think you turned it the wrong way around, sorry, my explanation might have been bad:
The main drive would be the two red dots. So I want to be able to move the red dots around and for the rig to calculate the correct position of the blue bar, not the other way around. So in you setup I would only actively move the âRed dot topâ and âRed dot botâ bones.
I havenât tried your solution, but if it solves my problem, please upload a blend file so I can test it! It is probably quicker than me trying to replicate your setup.
Note the hierarchy on the outliner. Your red dots are your IK root and IK target bones (ikRoot, ikT).
It doesnât look like you want blue to acquire any rotation from anything-- it looks like you want it to remain horizontal regardless of the position of the orange bar. Iâve done that by using a copy location constrain on the orange barâs bone, with a head/tail set to 0.5 (which, yes, can be animated.) There are other ways to do this. It has transform locks to limit its transformation to Y axis translation.
However, keep in mind that part of learning rigging is just putting the work in, and struggling to recreate things is part of that work. Thatâs an important part of how you learn.
Edit: Itâs not clear what you want blue to do. I easily could have misunderstood.
Not quite right either, but thanks for your try. When I am moving the ikT and ikRoot bones in your setup, the blue bone will still be able to move along the Y axis. It should only be able to move along the X-axis (but you are correct that is should remain horizontal, think of the blue bone as a piston rod to a cylinder) Just adding a limit location on the Y axis for the blue bone will not work, as only the blue bone will be locked to the Y-axis, the IK chain will not follow this constraint and the joint between the orange and blue bones will be broken. So the blue bone must in some way put a constrain back on the orange bone in the IK chain to force the joint between the blue and the orange bone to only move horizontally in the IK chain.
I donât have time to try it at the moment, but I wonder if you might be able to get an acceptable result using constraints instead of a rig. I used constraints for stuff like airplane ailerons and their connected cables. It keeps everything in the correct axes. Or maybe you need a combination of constraints and a rig?
I think you should demonstrate what youâre after with a better model that demonstrates the range of motion youâre after. If what you want is for the blue bone to extend from a fixed position, to the plane defined by yellow, we can do that with by shrinkwrapping/project (with project opposite enabled) to a plane parented to the bone:
But also realize that there are potential positions that donât give you a solution that youâre after, because itâs impossible without stretching (which you probably donât want, not for something that sounds mechanical.)
It also sounds like you want to drive the red dots from the position of blue somehow. What Iâve demonstrated has blue and red dots mostly independent of each other. Red are animated directly, they donât depend on blue. Itâs not clear what behavior you have in mind.
Looks like part of an eccentric rig, I did one for my traction engine, there is a video of the mechanics in the thread:
bandages is right it is best to work it out yourself as you will learn more in your attempts. I learned a lot from my trials and errors and was really proud of myself when I finally got it to work!
A spoiler:
«stretch to» «copy location» and «IK (with single chain lengths)»
If you are really stuck here is a simplified version like your example: Bones.blend (749.3 KB)
Note: you have to pose the top black bone slowly if not you can get IK solving errors. Also the piston will offset slightly due to the angle of the yellow bone, you can correct it animating the original length of the stretch bone.
DNorman:
Nice traction engine!
Yes, actually this is a part of a railway steam engine valve gear, so not so far from you have done in your model I guess. If it helps, it is the piston valve part of the Walschaertâs valve gear, the parts marked with 8, 11, 12, and 13 in the drawing on this Wiki page:
You can also see the animated gif on that page to get the idea of the movement.
There are threads on this forum showing off rigs for this kind of steam engine valve gear, but as far as I have seen they all âcheatâ by locking the movement of the top green joint to the X-axis as well. This will make the joint between the blue bone and the orange bone slide slightly along the orange bar, but it works decent as long as the movement is small and the blue bar is connected to the orange bar close to one of its endpoints. Since I have encountered other places in my rig where I have essentially the same rigging problem to solve, but where the sliding is way more noticeable, I thought it would be worth finding a better solution for it.
In the file you sent, when I move the TopBlack and BottomBlack, the green joint between the blue and the orange bones slides along the orange bone and in case the movement is too big, the connection between the blue and the orange bone will even brake. The green joint between the orange and the blue bone should always keep the same position on the orange bone.
By the way, I think the reason you get IK solving errors sometimes is because of a circular dependency IKTarget(yellow) --(parent)â> TopBlack --(IK)â>IKTarget(Black) --(parent)â>yellow(togle) --(IK)â> IKTarget(yellow)
I tried to make a better illustration of the rig showing what happens when you move the red points:
If I drive the action from the positions of points 2 (determined entirely by the lower piston) and 3 (determined entirely by the upper piston) then I can use a pair of IK to create the action.
But if you want to drive this the other way, from the positions of points 1 and 2, then as far as I can tell, it enters a class of very-hard-for-Blender problems that I call ârotate to floor.â The goal then is to derive the position of 3 from 1 and 2.
What is that position? Iâm not sure I can express it properly myself, but I find it useful to think about limited positions as limited to the intersections of shapes. One thing that is true about its location is, it lies on the intersection of a) a plane centered on the upper piston; b) a circle with thickness, centered on point 1, with a inner/outer radius equal to arm3.length ± the distance from 3 to arm3âs head; c) a circle with thickness centered on point 2, with radii equal to arm1.length ± the distance from 3 to arm1âs head. (What Iâm not sure about is if thatâs sufficient to define the position of point 3.)
Now, if you want to do that with constraints, itâs possible (to a certain level of accuracy) by shrinkwrapping to boolean/differenced meshes; itâs possible but ridiculously complicated to have a huge number of bone structures that exist solely to do your math; but your best bet is to use drivers and work at the math to figure out exactly where 3 needs to be.
Your Walschaertâs valve gear is a very similar system as my eccentric. The main difference is that the lifting system and expansion link (curved thing) is at the other end of the top drive bar, eliminating the need for the saddle on the valve piston, as the sliding occurs at the other end, where the expansion link is . Here is a better animation of the movement:
If you zoom in you can see the sliding inside the expansion link.
My setup works it just needs tweaking for the Walschaertâs gear setup and can be animated key-framing only the y axis movement of the main piston movement (bottom Bar) and the rotation of the swing coming from the expansion link. All this could be driven by the wheels rotation but you would have to make them mechanically correct.
Edit: I have changed this paragraph.
I do not now if it exists but there is a sort of crossed dependency (not full circle). The Ik targets of the Yellow and black bone do not have parental relationship with the bones that point to them. I am not sure why but it solves.
Edit2; I have removed this video from my channel as it is not a good solution and it crops up in my playlist. My definitive solution and video is in my last post. I also removed the blend file as the good one is also in my last post.
You have me thinking about modeling a train hmmmmmm
Nothing is impossible
âŠâŠ.yes I know some things are Impossible but I am a stubborn guy, lets say possible until proved otherwise. Even then, we could have a go at the devs!
Thanks for the answer. Unfortunately I have to let the points 1 and 2 drive the animation as they will both be receiving their motion from the wheels, so I will end up in the hard-to-solve class of problems.
I guess you are on to something when you are talking about positions limited by shapes. As you say: it should be possible to express the position of the point 3 in terms of the points 1 and 2 using mathematical constraints.
This got me thinking and actually I think you could express the entire problem as a Constraint Satisfaction Problem (https://en.wikipedia.org/wiki/Constraint_satisfaction_problem) in two dimensions where there are five known variables (x and y position of the points A and E, and the y position of the point C, as it is fixed) and five unknown variables (x and y of the point B and D and the x position of the point C). Then you need at least five constraints to eliminate the unknown variables, something like:
length(A, B) = some known constant
length(B, C) = some known constant
length(C, D) = some known constant
length(D, E) = some known constant
length(B, D) = some known constant
Cx < Ax (To force the solution where the C point is to the left of the A point)
Then you either use a CSP solver to solve the problem and find the correct assignment of the unknown variables given the known, or you do some math with the constraint equations and solve for Cx. This will be a little bit tricky due to the squares and square roots used in the length equations, but I think I will try to solve it once I get the time.
I guess, if you find the equation for Cx you could implement the equation as a driver in Blender to place the point C depending on the position of the points A and E. I have never used Drivers, but it should be possible to use Python expressions, so I assume it would be no problem to express the equation. Then you will have the positions of these three points and it will be trivial to add IKs to find the position of B and D. (Or solve for those in the equations as well)
I think it is doable, but it seems very tricky, so any simpler way to set it up would be appreciated.
DNorman:
Thanks for the new animation file!
It works as long as the movement of the two animated points are not to big. Is far as I could find, there are nothing that really constrains the height of the orange/yellow âcombination leverâ, so in case the movement gets too big, the drifting of the orange/yellow lever will be quite noticeable. For example, if you move to frame 40 and then rotate the TopDrive bone to 45 degrees in either direction, the yellow combination lever will clearly break free of the valve stem. But this pose should definitely be possible for a rig to find a correct solution for in my opinion!
I realized there must be a slight sliding of the radius bar in the expansion link, this was something i noticed during my own attempts to rig it, but thanks for pointing it out! One interesting problem here that the blend file you sent has not taken into consideration (for the sake of simplicity I guess) is that the movement of the âtop driveâ will not come from the lifting link by from the expansion link, and the position inside the expansion link will be determined by the length of the lifting link, which in turn has a fixed upper position determined by the rotation of the lifting arm. This is an interesting problem and I think this could be solved in some way by finding the theoretical center of the expansion link arc and let the armature motion start from there via a bone to the expansion link and then a bone for the radius bar. But here I have faced the same kind of problem again as is the reason for me starting this thread: the radius bar is part of a IK chain and its location must be constrained in a point in-between (or as in this case: on the extrapolation of a bone) two bones. So I wish there was a easy but exact and robust way to rig it.
Hey, Sorry for not getting back sooner - very busy. Keep in mind when using IK â it also has a rotation option, and there is the other solver (itasc) which may be better suited for this. https://wiki.blender.org/wiki/Source/Animation/IK
Yes, I think that is the biggest problem of my animation, the yellow leverâs pivot point floats up and down. I am still trying to find a way to fixate it. You can minimize it lifting the bones base slightly on the z axis in edit mode but I have not managed to get rid of it completely.
I will do some more experiments as I am now fascinated with this.
Well yes but that pulls the valve piston outside of the steam chest!
Yes I did not set up the whole thingâŠyet.
I have found this link, it is very exciting there is a freeware program there to design these valves, with measurements and templates! http://www.avocetconsulting.com.au/modeleng/Valve%20Gears.htm
I have installed it and will give it a good look, as accurate reference is hard to come by.
Keep us informed of your progress, I will do the same.
Have fun (the most important part!)
No, I think thatâs as simple as it gets, sorry. Yes, thatâs what Iâd recommend. (There are a few other conditions youâre going to need in order to get a proper, unique solution: A.y = B.y; E.y < A.y. And of course youâll end with solutions that are complex numbers that youâll have to discard; if all you get are complex numbers, thereâs no solution for that B and D. Assuming youâre solving for the plane, for 2D values.)
Following the links on the page I sent you for the simulation there are various different simulators. One excellent one is âThe late Charlie Dockstaderâs Simulator collectionâ which has many variants of similar gears, it is an incredible resource. here is a link to download them.
I replied to bandages by mistake and have corrected
Thanks for these resources, I will definitely take a look at them! Iâll keep you posted in case I manage to find a solution.
And good luck with your own experiments!
I gave it some initial tries, but things get ugly quite fast. I also tried to input the equations into a online equation solver, but it proved to hard for it to solve
But I still have some ideas to try out, so I might be able to solve it.
I gave up the idea to solve the system of equations. I think I know how it should be solved and it should be possible to make it work that way, but the equations gets so complicated due to the many square and square roots that the resulting equation for the position of the C point will be incredibly complicated.
Instead I found some settings in Blender for armature bones that I did not know of. Among others the possibility to lock the relative rotation of bone when solving the IK and that it is possible to have multiple bones with IK constraints in the same armature. This made me come up with a solution to both the general problem and the entire Walschaerts rig.
The idea is to approximate the X-axis locked movement by a circle with a huge radius. So the point C will essentially move along the circles circumference, but with a large enough circle the error the error can be small enough to be negligible.
So the orange bone is split into a top part (B-C) and a bottom part (C-D) with a new, really long bone attached at the C point just pointing straight down (or up). By adding an IK to that long bone targeting an empty at the tip of the bone and locking the rotation of the lower C-D bone relative to the B-C bone, the rig works as I expect. The C point will of course move up/down slightly, but the longer the helper bone is made, the smaller the error will be.
First a blend with the solution for the general problem: rigging_solution.blend (747.8 KB)
Note that the Lock IK settings is applied for the OrangeLower bone. This can be found in the Bone properties tab under Inverse Kinematics. This will make the OrangeLower boneâs rotation to be locked to the rotation of the OrangeUpper bone.
Press play to start the animation. You can adjust the cutoff by rotating the ReverseArm empty (it has a limit rotation constraint to lock the rotation within the valid range) and watch how the valve gear movement changes.
Also note that I have used my idea of driving the armature movement from the theoretical center of the expansion link as I talked about in an earlier post, it works great!
I guess this solves my problem good enough for my current needs at least. Thanks for input and ideas! Hope someone finds this useful.
Sorry I did not see your post until today.
I also came to a similar conclusion as you after watching this video:
by Locomotivist.
I did not use any empties or constraints - only bones and Ikâs.
Edit: to get the pivot point of the link sliding I created a third IK system, which points to the center of the radius of the linkâs curve that maintains and slides the pivot point in the groove of the link. You can change gear by rotating the lifting arm.
I used Charlie Dockstaderâs Simulator to synchronize the piston.
Here is a video of my results:
Here is my file: WalschaertsGear.blend (1.5 MB)
This has been a fascinating project that has had me entertained for over a week!
Best regards.