Studying the Walschaerts linkage, I think I see a path that my scheme can support. So let’s see if we can inch into it.

A fundamental limitation of my linkage scheme, at least at present, is that Components have exactly one parent, and at most one target or other constraint. The parent must supply two fixed points, and a child component works from those to decide where it is. So a linkage is built from one or more roots outward. In real locomotive linkages, there seem to be components that have no fixed parent. Instead, they seem to have constraints like “one end is at distance d1 from this point and the other end distance d2 from this other point”. I am pretty sure that that definition is under-constrained. The linkages seem then to have a third aspect: “and this other point lies on the line segment from a to b”.

I do not know how to solve that kind of constraint set. (Yet.)1 Whether it’s my advanced age or the complexity of the calculation involved, I’ve not (yet) been able to sort out that general case. I think I could approximate a solution, iterate to a solution, but that’s really not suitable for what I’m trying to do.

However, I think there is good news. The Walschaerts linkage shown on the Steam Locomotive Valve Gear page seems to be showing me that the component I’m worried about has fixed constraints. The one I have in mind is the uppermost blue line in the Walschaerts diagram. I think the point in the middle is attached to what I call a Bell Crank, and the point at the left end is a fixed distance from the point at the end of the green line, which itself is fixed. So my ArcRod should be able to extend from the Bell Crank to that point, and then I’m sure I can come up with an ArcRod kind of thing that extends off to the right as shown. That will give me the top of the red rod on the right, and the bottom of it seems to me to be another ArcRod kind of connection to the green line, whose other end is known as the end of the lower long red rod.

So my plan over the next few sessions is to change my sample diagram (or create a new one) that copies the Walschaerts diagram from that page, and to work through the necessary additions. I believe that it will all come down to solutions that we already have, or that can readily be worked out.

As a first step, I’m going to draw a grid over the W diagram and use that to set up my new sample. And as a first step for that, I’ve added a grid to the sample.

x_max = 16
y_max = 12
for ix in range(1, x_max):
    for iy in range(1, y_max):
        canvas.create_line(0, iy, x_max, iy, 
            fill="black", width=1)
        canvas.create_line(ix, 0, ix, y_max, 
            fill="black", width=1)

That gives me this, which is actually rather nice, looks kind of official:

linkage diagram with large grid

Now, I think I’ll extract the current linkage setup code to a function and then we’ll be in a position to write the new one without losing the old demo.

To my dismay PyCharm doesn’t do a great job of extracting in this case, but I think I can sort it.

To my continued dismay, there’s a global wheel that is known to my creation code and the animation code. This is what happens when your sample graphics is just there to be looked at, not intended to be good production code. I’ll deal with that later, or never. I have the extracted function and now let’s start on the new linkage.

With this much done:

def w_linkage(linkage):
    global wheel
    bell_pos = vector(6.5, 1.8)
    linkage.add(
        FixedPoint(vector(1.75, 3.5)),
        wheel := Wheel(),
        crank1 := Crank(radius=1, lead_degrees=0),
        ConRod(length=8,piston_angle = 0)
    )
    linkage.parent = wheel
    linkage.add(
        crank_2 := Crank(radius = 0.5, lead_degrees = -90),
        ArcRod(length=4.5, target_position=bell_pos,
               target_radius= 1.5, target_angle = 0)
    )

    linkage.add(
        bell1 := BellCrank(center=bell_pos,
                           input_radius=1.5,
                           output_radius=0.5,
                           angle=0),
    )

We get this much picture:

The jerking about in the video isn’t in the program, it is in my hasty editing of the video file. That’ll have to do for now: I have Covid and Flu shots scheduled, so I need to suit up.

See you next time for more thrilling lines and circles!



  1. As a mental trick, whenever I catch myself saying that I can’t do something, I try to remember to add “yet”, reminding me that in most cases, with enough time and effort, I probably can. It helps me not close the door on things that I’d like to do but can’t … yet.