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:
inline_formula not implemented for the central body
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 implementedSketch 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.