{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "fig.canvas.width = '7in'\n", "fig.canvas.height= '5in'\n", "\n", "# if I hide the header here, I get a libpng error\n", "# fig.canvas.header_visible = False\n", "\n", "ax.plot([1,2,3], [4,5,3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# hiding after rendering works\n", "fig.canvas.header_visible = False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# hiding together with calls to toolbar options, work.\n", "fig, ax = plt.subplots()\n", "fig.canvas.width = '7in'\n", "fig.canvas.height= '5in'\n", "\n", "fig.canvas.toolbar_visible = False\n", "fig.canvas.header_visible = False\n", "\n", "ax.plot([1,2,3], [4,5,3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# When using the `widget` backend from ipympl,\n", "# fig.canvas is a proper Jupyter interactive widget, which can be embedded in\n", "# an ipywidgets layout. See https://ipywidgets.readthedocs.io/en/stable/examples/Layout%20Templates.html\n", "\n", "# One can bound figure attributes to other widget values.\n", "from ipywidgets import AppLayout, FloatSlider\n", "\n", "plt.ioff()\n", "\n", "slider = FloatSlider(\n", " orientation='horizontal',\n", " description='Factor:',\n", " value=1.0,\n", " min=0.02,\n", " max=2.0\n", ")\n", "\n", "slider.layout.margin = '0px 30% 0px 30%'\n", "slider.layout.width = '40%'\n", "\n", "fig = plt.figure()\n", "fig.canvas.header_visible = False\n", "fig.canvas.layout.min_height = '400px'\n", "plt.title('Plotting: y=sin({} * x)'.format(slider.value))\n", "\n", "x = np.linspace(0, 20, 500)\n", "\n", "lines = plt.plot(x, np.sin(slider.value * x))\n", "\n", "def update_lines(change):\n", " plt.title('Plotting: y=sin({} * x)'.format(change.new))\n", " lines[0].set_data(x, np.sin(change.new * x))\n", " fig.canvas.draw()\n", " fig.canvas.flush_events()\n", "\n", "slider.observe(update_lines, names='value')\n", "\n", "AppLayout(\n", " center=fig.canvas,\n", " footer=slider,\n", " pane_heights=[0, 6, 1]\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "from matplotlib.patches import Shadow\n", "\n", "# make a square figure and axes\n", "fig = plt.figure(figsize=(6, 6))\n", "ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])\n", "\n", "labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'\n", "fracs = [15, 30, 45, 10]\n", "\n", "explode = (0, 0.05, 0, 0)\n", "\n", "# We want to draw the shadow for each pie but we will not use \"shadow\"\n", "# option as it does'n save the references to the shadow patches.\n", "pies = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%')\n", "\n", "for w in pies[0]:\n", " # set the id with the label.\n", " w.set_gid(w.get_label())\n", "\n", " # we don't want to draw the edge of the pie\n", " w.set_edgecolor(\"none\")\n", "\n", "for w in pies[0]:\n", " # create shadow patch\n", " s = Shadow(w, -0.01, -0.01)\n", " s.set_gid(w.get_gid() + \"_shadow\")\n", " s.set_zorder(w.get_zorder() - 0.1)\n", " ax.add_patch(s)\n", "\n", "\n", "# save\n", "from io import BytesIO\n", "f = BytesIO()\n", "plt.savefig(f, format=\"svg\")\n", "\n", "import xml.etree.cElementTree as ET\n", "\n", "\n", "# filter definition for shadow using a gaussian blur\n", "# and lightening effect.\n", "# The lightening filter is copied from http://www.w3.org/TR/SVG/filters.html\n", "\n", "# I tested it with Inkscape and Firefox3. \"Gaussian blur\" is supported\n", "# in both, but the lightening effect only in the Inkscape. Also note\n", "# that, Inkscape's exporting also may not support it.\n", "\n", "filter_def = \"\"\"\n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\"\"\"\n", "\n", "\n", "tree, xmlid = ET.XMLID(f.getvalue())\n", "\n", "# insert the filter definition in the svg dom tree.\n", "tree.insert(0, ET.XML(filter_def))\n", "\n", "for i, pie_name in enumerate(labels):\n", " pie = xmlid[pie_name]\n", " pie.set(\"filter\", 'url(#MyFilter)')\n", "\n", " shadow = xmlid[pie_name + \"_shadow\"]\n", " shadow.set(\"filter\", 'url(#dropshadow)')\n", "\n", "fn = \"svg_filter_pie.svg\"\n", "print(\"Saving '%s'\" % fn)\n", "ET.ElementTree(tree).write(fn)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget\n", "import ipywidgets as widgets\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "# set up plot\n", "fig, ax = plt.subplots(figsize=(6, 4))\n", "ax.set_ylim([-4, 4])\n", "ax.grid(True)\n", " \n", "# generate x values\n", "x = np.linspace(0, 2 * np.pi, 100)\n", " \n", " \n", "def my_sine(x, w, amp, phi):\n", " \"\"\"\n", " Return a sine for x with angular frequeny w and amplitude amp.\n", " \"\"\"\n", " return amp*np.sin(w * (x-phi))\n", " \n", " \n", "@widgets.interact(w=(0, 10, 1), amp=(0, 4, .1), phi=(0, 2*np.pi+0.01, 0.01))\n", "def update(w = 1.0, amp=1, phi=0):\n", " \"\"\"Remove old lines from plot and plot new one\"\"\"\n", " [l.remove() for l in ax.lines]\n", " ax.plot(x, my_sine(x, w, amp, phi), color='C0')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import time\n", "import pylab as pl\n", "from IPython import display\n", "for i in range(10):\n", " pl.plot(pl.randn(100))\n", " display.clear_output(wait=True)\n", " display.display(pl.gcf())\n", " time.sleep(1.0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install drawsvg" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import drawSvg as draw" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from IPython.display import SVG, display" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "d = draw.Drawing(200, 200, origin='center')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "c = draw.Circle(0, 0, 20, fill='red')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "d.append(c)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "c0 = d.allElements()[0]" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'cx': 0, 'cy': 0, 'r': 30, 'fill': 'red'}" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c0.args" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "c0.args={'cx': 0, 'cy': 0, 'r': 25, 'fill': 'red'}" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "r = draw.Rectangle(5,5,5,3,fill='blue')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "d.append(r)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'x': 25, 'y': 25, 'width': 25, 'height': 10, 'fill': 'blue'}" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.args" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "r.args={'x': 25, 'y': 25, 'width': 25, 'height': 20, 'fill': 'blue'}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip3 install hyperbolic" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "\n", "require.undef('drawingview');\n", "\n", "define('drawingview', ['@jupyter-widgets/base'], function(widgets) {\n", " var DrawingView = widgets.DOMWidgetView.extend({\n", " render: function() {\n", " this.container = document.createElement('a');\n", " this.image_changed();\n", " this.container.appendChild(this.svg_view);\n", " this.el.appendChild(this.container);\n", " this.model.on('change:_image', this.image_changed, this);\n", " this.model.on('change:_mousemove_blocked', this.block_changed,\n", " this);\n", " this.model.on('change:frame_delay', this.delay_changed,\n", " this);\n", " this.model.on('change:_frame_blocked', this.delay_changed,\n", " this);\n", " this.model.on('change:disable', this.delay_changed,\n", " this);\n", " this.delay_changed();\n", " },\n", " image_changed: function() {\n", " this.container.innerHTML = this.model.get('_image');\n", " this.svg_view = this.container.getElementsByTagName('svg')[0];\n", " this.cursor_point = this.svg_view.createSVGPoint();\n", " this.register_events();\n", " },\n", " last_move: null,\n", " last_mousemove_blocked: null,\n", " last_timer: null,\n", " block_changed: function() {\n", " var widget = this;\n", " window.setTimeout(function() {\n", " if (widget.model.get('_mousemove_blocked')\n", " != widget.last_mousemove_blocked && widget.last_move) {\n", " widget.send_mouse_event('mousemove', widget.last_move);\n", " }\n", " }, 0);\n", " },\n", " send_mouse_event: function(name, e) {\n", " this.last_move = null;\n", " if (this.model.get('disable')) {\n", " return;\n", " }\n", "\n", " this.cursor_point.x = e.clientX;\n", " this.cursor_point.y = e.clientY;\n", " var svg_pt = this.cursor_point.matrixTransform(\n", " this.svg_view.getScreenCTM().inverse());\n", "\n", " this.send({\n", " name: name,\n", " x: svg_pt.x,\n", " y: -svg_pt.y,\n", " type: e.type,\n", " button: e.button,\n", " buttons: e.buttons,\n", " shiftKey: e.shiftKey,\n", " altKey: e.altKey,\n", " ctrlKey: e.ctrlKey,\n", " metaKey: e.metaKey,\n", " clientX: e.clientX,\n", " clientY: e.clientY,\n", " movementX: e.movementX,\n", " movementY: e.movementY,\n", " timeStamp: e.timeStamp,\n", " targetId: e.target ? e.target.id : null,\n", " currentTargetId: e.currentTarget ? e.currentTarget.id : null,\n", " relatedTargetId: e.relatedTarget ? e.relatedTarget.id : null,\n", " });\n", " },\n", " delay_changed: function() {\n", " var widget = this;\n", " window.clearTimeout(widget.last_timer);\n", " if (widget.model.get('disable')) {\n", " return;\n", " }\n", " var delay = widget.model.get('frame_delay');\n", " if (delay > 0) {\n", " widget.last_timer = window.setTimeout(function() {\n", " widget.send_timed_event('timed');\n", " }, delay);\n", " }\n", " },\n", " send_timed_event: function(name) {\n", " if (this.model.get('disable')) {\n", " return;\n", " }\n", "\n", " this.send({\n", " name: name,\n", " });\n", " },\n", " register_events: function() {\n", " var widget = this;\n", " this.svg_view.addEventListener('mousedown', function(e) {\n", " e.preventDefault();\n", " widget.send_mouse_event('mousedown', e);\n", " });\n", " this.svg_view.addEventListener('mousemove', function(e) {\n", " e.preventDefault();\n", " if (widget.model.get('_mousemove_blocked')\n", " == widget.last_mousemove_blocked) {\n", " widget.last_move = e;\n", " } else {\n", " widget.send_mouse_event('mousemove', e);\n", " }\n", " });\n", " this.svg_view.addEventListener('mouseup', function(e) {\n", " e.preventDefault();\n", " widget.send_mouse_event('mouseup', e);\n", " });\n", " }\n", " });\n", "\n", " return {\n", " DrawingView: DrawingView\n", " };\n", "});\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "334798dc0fde4ed692ac15851a340d8c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DrawingWidget()" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import drawSvg as draw\n", "from drawSvg.widgets import DrawingWidget\n", "import hyperbolic.poincare.shapes as hyper # pip3 install hyperbolic\n", "\n", "# Create drawing\n", "d = draw.Drawing(2, 2, origin='center')\n", "d.setRenderSize(500)\n", "d.append(draw.Circle(0, 0, 1, fill='orange'))\n", "group = draw.Group()\n", "d.append(group)\n", "\n", "# Update the drawing based on user input\n", "click_list = []\n", "def redraw(points):\n", " group.children.clear()\n", " for x1, y1 in points:\n", " for x2, y2 in points:\n", " if (x1, y1) == (x2, y2): continue\n", " p1 = hyper.Point.fromEuclid(x1, y1)\n", " p2 = hyper.Point.fromEuclid(x2, y2)\n", " if p1.distanceTo(p2) <= 2:\n", " line = hyper.Line.fromPoints(*p1, *p2, segment=True)\n", " group.draw(line, hwidth=0.2, fill='white')\n", " for x, y in points:\n", " p = hyper.Point.fromEuclid(x, y)\n", " group.draw(hyper.Circle.fromCenterRadius(p, 0.1),\n", " fill='green')\n", "redraw(click_list)\n", "\n", "# Create interactive widget and register mouse events\n", "widget = DrawingWidget(d)\n", "@widget.mousedown\n", "def mousedown(widget, x, y, info):\n", " if (x**2 + y**2) ** 0.5 + 1e-5 < 1:\n", " click_list.append((x, y))\n", " redraw(click_list)\n", " widget.refresh()\n", "@widget.mousemove\n", "def mousemove(widget, x, y, info):\n", " if (x**2 + y**2) ** 0.5 + 1e-5 < 1:\n", " redraw(click_list + [(x, y)])\n", " widget.refresh()\n", "widget" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](fourbar.png)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting sympy\n", " Downloading sympy-1.6.1-py3-none-any.whl (5.8 MB)\n", "Collecting mpmath>=0.19\n", " Downloading mpmath-1.1.0.tar.gz (512 kB)\n", "Building wheels for collected packages: mpmath\n", " Building wheel for mpmath (setup.py): started\n", " Building wheel for mpmath (setup.py): finished with status 'done'\n", " Created wheel for mpmath: filename=mpmath-1.1.0-py3-none-any.whl size=532244 sha256=4e5fd83b126d38807ebed2bc066be78eae9d4a5264f3e44ea762409275b7379d\n", " Stored in directory: c:\\users\\gilbe\\appdata\\local\\pip\\cache\\wheels\\29\\2c\\1c\\d2e4580cde2743b0aef389e936ac21a2db92921ddbca53faa1\n", "Successfully built mpmath\n", "Installing collected packages: mpmath, sympy\n", "Successfully installed mpmath-1.1.0 sympy-1.6.1\n" ] } ], "source": [ "!pip install sympy" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting pydy\n", " Downloading pydy-0.5.0.tar.gz (5.3 MB)\n", "Requirement already satisfied: numpy>=1.11.0 in c:\\users\\gilbe\\documents\\github\\venv\\lib\\site-packages (from pydy) (1.19.1)\n", "Requirement already satisfied: scipy>=0.17.1 in c:\\users\\gilbe\\documents\\github\\venv\\lib\\site-packages (from pydy) (1.5.2)\n", "Requirement already satisfied: sympy>=0.7.6.1 in c:\\users\\gilbe\\documents\\github\\venv\\lib\\site-packages (from pydy) (1.6.1)\n", "Requirement already satisfied: PyWin32>=219 in c:\\users\\gilbe\\documents\\github\\venv\\lib\\site-packages (from pydy) (228)\n", "Requirement already satisfied: mpmath>=0.19 in c:\\users\\gilbe\\documents\\github\\venv\\lib\\site-packages (from sympy>=0.7.6.1->pydy) (1.1.0)\n", "Building wheels for collected packages: pydy\n", " Building wheel for pydy (setup.py): started\n", " Building wheel for pydy (setup.py): finished with status 'done'\n", " Created wheel for pydy: filename=pydy-0.5.0-py3-none-any.whl size=5224788 sha256=121e8cf7827b9c20546840213cacedee58a91a2eafd3e9da3649a2b567811e5f\n", " Stored in directory: c:\\users\\gilbe\\appdata\\local\\pip\\cache\\wheels\\42\\81\\0a\\71f8f9716851b780cf1195f766cadf606041c1ac2a6767dc3a\n", "Successfully built pydy\n", "Installing collected packages: pydy\n", "Successfully installed pydy-0.5.0\n" ] } ], "source": [ "!pip install pydy" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from __future__ import print_function, division\n", "from sympy.physics.mechanics import *\n", "from sympy.physics.vector import time_derivative\n", "from sympy import symbols\n", "from numpy import array, linspace, rad2deg, deg2rad\n", "from scipy.integrate import odeint\n", "from pydy.codegen.ode_function_generators import generate_ode_function\n", "# number of links in the mechanism\n", "n = 3\n", "# generalized speeds and coordinates\n", "theta = dynamicsymbols('theta:{}'.format(n))\n", "theta_d = dynamicsymbols('theta:{}'.format(n), 1)\n", "omega = dynamicsymbols('omega:{}'.format(n))\n", "omega_d = dynamicsymbols('omega:{}'.format(n), 1)\n", "# the extra symbol thanks to n+1 stands for the distance\n", "# between the grounding joints\n", "length_bars = symbols('L_B:{}'.format(n+1))\n", "g = symbols('g') # gravity" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# reference frames\n", "inertial_frame = ReferenceFrame('I')\n", "bar0_frame = inertial_frame.orientnew('B0', 'Axis', (theta[0],\n", " inertial_frame.z))\n", "bar1_frame = inertial_frame.orientnew('B1', 'Axis', (theta[1],\n", " inertial_frame.z))\n", "bar2_frame = inertial_frame.orientnew('B2', 'Body', [0, 0, theta[2]],\n", " 'XYZ')\n", "# angular velocities\n", "bar0_frame.set_ang_vel(inertial_frame, omega[0]*inertial_frame.z)\n", "bar1_frame.set_ang_vel(inertial_frame, omega[1]*inertial_frame.z)\n", "bar2_frame.set_ang_vel(inertial_frame, omega[2]*inertial_frame.z)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# joints\n", "joint0 = Point('j0')\n", "joint1 = joint0.locatenew('j1', length_bars[0] * bar0_frame.x)\n", "joint2 = joint1.locatenew('j2', length_bars[1] * bar1_frame.x)\n", "joint3 = joint2.locatenew('j3', -length_bars[2] * bar2_frame.x)\n", "# cm positions\n", "bar0_cm = joint0.locatenew('b0cm', length_bars[0]/2 * bar0_frame.x)\n", "bar1_cm = joint1.locatenew('b1cm', length_bars[1]/2 * bar1_frame.x)\n", "bar2_cm = joint3.locatenew('b2cm', length_bars[2]/2 * bar2_frame.x)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle L_{B0} \\omega_{0}\\mathbf{\\hat{b0}_y} + L_{B1} \\omega_{1}\\mathbf{\\hat{b1}_y} - \\frac{L_{B2} \\omega_{2}}{2}\\mathbf{\\hat{b2}_y}$" ], "text/plain": [ "L_B0*omega0*B0.y + L_B1*omega1*B1.y - L_B2*omega2/2*B2.y" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# velocity of the grounding joints is 0\n", "joint0.set_vel(inertial_frame, 0)\n", "joint3.set_vel(inertial_frame, 0)\n", "# velocity if the remaining joints\n", "joint1.v2pt_theory(joint0, inertial_frame, bar0_frame)\n", "joint2.v2pt_theory(joint1, inertial_frame, bar1_frame)\n", "# velocity if centres of mass\n", "bar0_cm.v2pt_theory(joint0, inertial_frame, bar0_frame)\n", "bar1_cm.v2pt_theory(joint1, inertial_frame, bar1_frame)\n", "bar2_cm.v2pt_theory(joint2, inertial_frame, bar2_frame) " ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# configuration constraint\n", "zero = joint3.pos_from(joint0) + length_bars[3] * inertial_frame.x\n", "f_c = [zero & inertial_frame.x, zero & inertial_frame.y]\n", "# velocity constraint\n", "dzero = time_derivative(zero, inertial_frame)\n", "f_v = [dzero & inertial_frame.x, dzero & inertial_frame.y] " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# mass and inertia\n", "mass_bars = symbols('m_B:{}'.format(n))\n", "inertia_bars = symbols('I_B:{}'.format(n))\n", "# inertia(frame, ixx=0, iyy=0, izz, ixy=0, iyz=0, izx=0)\n", "bar0_indyad = inertia(bar0_frame, 0, 0, inertia_bars[0])\n", "bar1_indyad = inertia(bar1_frame, 0, 0, inertia_bars[1])\n", "bar2_indyad = inertia(bar2_frame, 0, 0, inertia_bars[2])\n", "bar0_inertia = (bar0_indyad, bar0_cm)\n", "bar1_inertia = (bar1_indyad, bar1_cm)\n", "bar2_inertia = (bar2_indyad, bar2_cm)\n", "# bodies\n", "bar0 = RigidBody('Bar 0', bar0_cm, bar0_frame, mass_bars[0],\n", " bar0_inertia)\n", "bar1 = RigidBody('Bar 1', bar1_cm, bar0_frame, mass_bars[1],\n", " bar1_inertia)\n", "bar2 = RigidBody('Bar 1', bar2_cm, bar0_frame, mass_bars[2],\n", " bar2_inertia)\n", "bodies = [bar0, bar1, bar2] " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "# forces\n", "bar0_force = (bar0_cm, -mass_bars[0] * g * inertial_frame.y)\n", "bar1_force = (bar1_cm, -mass_bars[1] * g * inertial_frame.y)\n", "bar2_force = (bar2_cm, -mass_bars[2] * g * inertial_frame.y)\n", "loads = [bar0_force, bar1_force, bar2_force] " ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "# kinematic differential equations\n", "KDE = [theta_d[0] - omega[0], theta_d[1] - omega[1],\n", " theta_d[2] - omega[2]]\n", "# Kanes Method\n", "kane = KanesMethod(inertial_frame, q_ind=[theta[0]],\n", " u_ind=[omega[0]],\n", " q_dependent=[theta[1],theta[2]],\n", " u_dependent=[omega[1],omega[2]],\n", " configuration_constraints=f_c,\n", " velocity_constraints=f_v,\n", " kd_eqs=KDE)\n", "fr, frstar = kane.kanes_equations(bodies, loads) " ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (, line 39)", "output_type": "error", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m39\u001b[0m\n\u001b[1;33m y = odeint(right_hand_side, x0, t, args= (constants, numerical_constants))\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" ] } ], "source": [ "# list of constants\n", "constants = [g,\n", " mass_bars[0],\n", " mass_bars[1],\n", " mass_bars[2],\n", " length_bars[0],\n", " length_bars[1],\n", " length_bars[2],\n", " length_bars[3],\n", " inertia_bars[0],\n", " inertia_bars[1],\n", " inertia_bars[2]]\n", "kdd = kane.kindiffdict()\n", "mass_matrix = kane.mass_matrix_full.subs(kdd)\n", "forcing_vector = kane.forcing_full.subs(kdd)\n", "right_hand_side = generate_ode_function(forcing_vector,\n", " theta, omega, constants, mass_matrix=mass_matrix)\n", "# list of numerical values\n", "numerical_constants = [9.81,\n", " 2.0,\n", "5.0,\n", "4.0,\n", " 2.0,\n", "5.0,\n", "5.0,\n", "4.0,\n", "1.0,\n", "1.0,\n", "1.0]\n", "# inital conditions\n", "x0 = array([deg2rad(135), deg2rad(41.3340), deg2rad(109.3884), 0.0,\n", " 0.0, 0.0])\n", "# timeframe\n", "frames_per_sec = 100\n", "final_time = 20.0\n", "t = linspace(0.0, final_time, int(final_time * frames_per_sec)\n", "# integration\n", "\n", "y = odeint(right_hand_side, x0, t, args= (constants, numerical_constants))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }