Exercise 1.19: Two-bar linkage

Double pendulum, sort of, except the whole thing can fly around the plane.

The system description is:

(require '[sicmutils.env :refer :all])

The two-bar linkage shown in figure 1.3 is constrained to move in the plane. It is composed of three small massive bodies interconnected by two massless rigid rods in a uniform gravitational field with vertical acceleration g. The rods are pinned to the central body by a hinge that allows the linkage to fold. The system is arranged so that the hinge is completely free: the members can go through all configurations without collision. Formulate a Lagrangian that describes the system and find the Lagrange equations of motion. Use the computer to do this, because the equations are rather big.

This is new. Now we have multiple bodies:

We can handle this by treating our coordinate space as having new dimensions for, say, inline_formula not implemented, inline_formula not implemented, inline_formula not implemented, inline_formula not implemented. The fact that multiple coordinates refer to the same particle doesn't matter for the Lagrangian. But it's a confusing API.

Without any constraints, we have six degrees of freedom. inline_formula not implemented for each particle. With the constraints we have:

  1. inline_formula not implemented for the central body

  2. inline_formula not implemented and inline_formula not implemented for the angles off center.

(Sketch these out on the picture for the final version.)

formula not implemented

Sketch out why this makes sense. Each angle is positive CCW for consistency, since they can swing all the way around.

Write the coordinate transformation in scheme.

(defn double-linkage->rect [l1 l2]
  (fn [[_ [theta phi x2 y2]]]
    (up (+ x2 (* l1 (sin theta)))
        (- y2 (* l1 (cos theta)))
        x2
        y2
        (+ x2 (* l2 (sin phi)))
        (- y2 (* l2 (cos phi))))))

Next, the Lagrangian given rectangular coordinates, assuming no constraints. Remember, we have a uniform gravitational field pointing down; this means that each of the components has a potential dragging on it.

(defn L-double-linkage-rect [m1 m2 m3 U]
  (fn [[_ q [vx1 vy1 vx2 vy2 vx3 vy3]]]
    (- (+ (* m1 (+ (square vx1)
                   (square vy1)))
          (* m2 (+ (square vx2)
                   (square vy2)))
          (* m3 (+ (square vx3)
                   (square vy3))))
       (U q))))

And the composition:

(defn L-double-linkage [l1 l2 m1 m2 m3 U]
  (compose (L-double-linkage-rect m1 m2 m3 U)
           (F->C (double-linkage->rect l1 l2))))

Gravitational potential:

(defn U-gravity [g m1 m2 m3]
  (fn [[_ y1 _ y2 _ y3]]
    (* g (+ (* m1 y1)
            (* m2 y2)
            (* m3 y3)))))
(let [local (up 't
                (up 'theta 'phi 'x_2 'y_2)
                (up 'thetadot 'phidot 'xdot_2 'ydot_2))
      U (U-gravity 'g 'm_1 'm_2 'm_3)]
  ((L-double-linkage 'l_1 'l_2 'm_1 'm_2 'm_3 U) local))

Lagrange equations of motion:

(let [U (U-gravity 'g 'm_1 'm_2 'm_3)
      L (L-double-linkage 'l_1 'l_2 'm_1 'm_2 'm_3 U)
      theta (literal-function 'theta)
      phi (literal-function 'phi)
      x2 (literal-function 'x_2)
      y2 (literal-function 'y_2)]
  (((Lagrange-equations L) (up theta phi x2 y2))
   't))

Kill some clear factors:

(let [U (U-gravity 'g 'm_1 'm_2 'm_3)
      L (L-double-linkage 'l_1 'l_2 'm_1 'm_2 'm_3 U)
      theta (literal-function 'theta)
      phi (literal-function 'phi)
      x2 (literal-function 'x_2)
      y2 (literal-function 'y_2)
      eqs (((Lagrange-equations L) (up theta phi x2 y2))
           't)]
  (up (/ (ref eqs 0) 'l_1 'm_1)
      (/ (ref eqs 1) 'l_2 'm_3)
      (/ (ref eqs 2) 2)
      (ref eqs 3)))

This was not as gnarly as the previous problem. Perhaps I did something wrong there. We'll see when we get animation.

Runtimes (1)