In [1]:
(require '[clojupyter.misc.helper :as helper])
(run! helper/add-dependencies '[[org.clojure/data.json "0.2.6"]
[net.littleredcomputer/sicmutils "0.12.0-SNAPSHOT"]
[thi.ng/geom "0.0.908"]])
(ns double-pendulum
(:refer-clojure :exclude [partial zero? + - * / ref])
(:require [sicmutils.env :refer :all]
[clojupyter.misc.display :as display]
[thi.ng.geom.viz.core :as viz]
[thi.ng.geom.svg.core :as svg]))
(defn tex [x] (-> x tex$$ display/latex))
Out[1]:
In [2]:
(defn V
[m_1 m_2 l_1 l_2 g]
(fn [[_ [theta phi] _]]
(let [y_1 (- (* l_1 (cos theta)))
y_2 (- y_1 (* l_2 (cos phi)))]
(+ (* m_1 g y_1)
(* m_2 g y_2)))))
Out[2]:
In [3]:
(defn T
[m_1 m_2 l_1 l_2 _]
(fn [[_ [theta phi] [thetadot phidot]]]
(let [v1sq (* (square l_1) (square thetadot))
v2sq (* (square l_2) (square phidot))]
(+ (* 1/2 m_1 v1sq)
(* 1/2 m_2 (+ v1sq
v2sq
(* 2 l_1 l_2 thetadot phidot (cos (- theta phi)))))))))
Out[3]:
In [4]:
(def L (- T V))
(tex ((L 'm_1 'm_2 'l_1 'l_2 'g)
(up 't
(up 'theta 'phi)
(up 'thetadot 'phidot))))
Out[4]:
In [5]:
(defn state-derivative [m_1 m_2 l_1 l_2 g]
(Lagrangian->state-derivative
(L m_1 m_2 l_1 l_2 g)))
Out[5]:
In [6]:
(def equations-of-motion
((state-derivative 'm_1 'm_2 'l_1 'l_2 'g)
(up 't
(up 'theta 'phi)
(up 'thetadot 'phidot))))
Out[6]:
In [7]:
(tex (nth equations-of-motion 2))
Out[7]:
In [8]:
(def out (atom []))
(defn observe [t [_ [theta phi]]] (swap! out conj [t theta phi]))
(tex ((evolve state-derivative 1 1 1 1 9.8)
(up 0 (up (/ pi 2) 0) (up 0 0))
observe
1/60
10
1e-6
:compile true))
Out[8]:
In [13]:
(def spec
{:x-axis (viz/linear-axis
{:domain [(first (first @out)) (first (last @out))]
:range [50 (- 985 10)]
:major 1
:pos 550})
:y-axis (viz/linear-axis
{:domain [(- Math/PI) Math/PI]
:range [550 20]
:major 1
:minor 0.2
:pos 50
:label-dist 15
:label-style {:text-anchor "end"}})
:grid {:attribs {:stroke "#caa"}
:minor-x true
:minor-y false}
:data [{:values (map #(vector (nth % 0) (nth % 1)) @out)
:attribs {:stroke "#0af" :stroke-width "2pt"}
:layout viz/svg-line-plot}
{:values (map #(vector (nth % 0) (nth % 2)) @out)
:attribs {:stroke "#f60" :stroke-width "2pt"}
:layout viz/svg-line-plot}]})
Out[13]:
In [14]:
(defn export-viz
[spec]
(->> spec
(viz/svg-plot2d-cartesian)
(svg/svg {:width 985 :height 600})
(svg/serialize)))
(-> spec
export-viz
display/make-html)
Out[14]:
In [ ]: