{
"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",
""
],
"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": [
""
]
},
{
"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
}