How to rig this piston-like mechanical setup?

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.

How would you rig such a thing?

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.

If you want to drive from the two red dots, use an IK, and move the root and target of the IK:

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.

Here’s a file:

rigdemo.blend (132.0 KB)

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.

Any suggestion on how to achieve this?

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:


The red arrows indicate when one of the red joints are moved. The previous poses are shown transparently in the backgrounds in figures 2., 3. and 4.

If you want to drive this the other way-- from the action of the pistons-- it’s not very tough:

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:
https://web.archive.org/web/20070520133847/http://home.new.rr.com/trumpetb/loco/rodsr.html
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 :slight_smile:
…….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!

bandages:

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! :slight_smile:

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.

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!


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.)

Can’t say I want to solve it myself though :slight_smile:

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 :laughing:
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.

Then the entire Walschaerts rig:
Walschaerts_test.blend (874.6 KB)

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.

1 Like

Interesting idea! Glad you got it working.

Sorry I did not see your post until today.
I also came to a similar conclusion as you after watching this video: https://www.youtube.com/watch?v=5AMmhKgi8qU 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.