diff --git a/notebooks/Closed-loop simulation and visualization/Closed-loop simulation and visualization.ipynb b/notebooks/Closed-loop simulation and visualization/Closed-loop simulation and visualization.ipynb new file mode 100644 index 00000000..0c27dd4b --- /dev/null +++ b/notebooks/Closed-loop simulation and visualization/Closed-loop simulation and visualization.ipynb @@ -0,0 +1,265 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n", + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n", + "\u001b[?25l\u001b[2K\u001b[?25h\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n" + ] + } + ], + "source": [ + "using Pkg\n", + "Pkg.activate(@__DIR__);\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "using RigidBodyDynamics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Please note that [RigidBodySim.jl](https://github.com/JuliaRobotics/RigidBodySim.jl) now provides a more capable simulation environment." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Model definition" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll just use the double pendulum model, loaded from a URDF:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Spanning tree:\n", + "Vertex: world (root)\n", + " Vertex: upper_link, Edge: shoulder\n", + " Vertex: lower_link, Edge: elbow\n", + "No non-tree joints." + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "urdf = joinpath(dirname(pathof(RigidBodyDynamics)), \"..\", \"test\", \"urdf\", \"Acrobot.urdf\")\n", + "mechanism = parse_urdf(urdf)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Controller" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's write a simple controller that just applies $10 \\sin(t)$ at the elbow joint and adds some damping at the shoulder joint:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "simple_control! (generic function with 1 method)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "shoulder, elbow = joints(mechanism)\n", + "function simple_control!(torques::AbstractVector, t, state::MechanismState)\n", + " torques[velocity_range(state, shoulder)] .= -1 .* velocity(state, shoulder)\n", + " torques[velocity_range(state, elbow)] .= 10 * sin(t)\n", + "end" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simulation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Basic simulation can be done using the `simulate` function. We'll first create a `MechanismState` object, and set the initial joint configurations and velocities:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "state = MechanismState(mechanism)\n", + "zero_velocity!(state)\n", + "set_configuration!(state, shoulder, 0.7)\n", + "set_configuration!(state, elbow, -0.8);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can simply call `simulate`, which will return a tuple consisting of:\n", + "* simulation times (a `Vector` of numbers)\n", + "* joint configuration vectors (a `Vector` of `Vector`s)\n", + "* joint velocity vectors (a `Vector` of `Vector`s)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "final_time = 10.\n", + "ts, qs, vs = simulate(state, final_time, simple_control!; Δt = 1e-3);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For access to lower-level functionality, such as different ways of storing or visualizing the data generated during the simulation, it is advised to simply pattern match the basic `simulate` function." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Visualization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For visualization, we'll use [`MeshCatMechanisms`](https://github.com/JuliaRobotics/MeshCatMechanisms.jl), an external package based on RigidBodyDynamics.jl.\n", + "\n", + "(Note: the `#NBSKIP` comments are to skip these cells during `Pkg.test(\"RigidBodyDynamics\")`)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#NBSKIP\n", + "Pkg.activate(joinpath(@__DIR__, \"visualization\"));\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"\n", + "using MeshCatMechanisms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a `MechanismVisualizer` and open it in a new browser tab (see [`MeshCat.jl`](https://github.com/rdeits/MeshCat.jl) for other options):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#NBSKIP\n", + "mvis = MechanismVisualizer(mechanism, URDFVisuals(urdf))\n", + "open(mvis);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And animate:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#NBSKIP\n", + "MeshCatMechanisms.animate(mvis, ts, qs; realtimerate = 1.);" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.0.0", + "language": "julia", + "name": "julia-1.0" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.0.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Closed-loop simulation and visualization/Manifest.toml b/notebooks/Closed-loop simulation and visualization/Manifest.toml new file mode 100644 index 00000000..e577966e --- /dev/null +++ b/notebooks/Closed-loop simulation and visualization/Manifest.toml @@ -0,0 +1,150 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/notebooks/Closed-loop simulation and visualization/Project.toml b/notebooks/Closed-loop simulation and visualization/Project.toml new file mode 100644 index 00000000..dbd4d67d --- /dev/null +++ b/notebooks/Closed-loop simulation and visualization/Project.toml @@ -0,0 +1,2 @@ +[deps] +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/Closed-loop simulation and visualization/visualization/Manifest.toml b/notebooks/Closed-loop simulation and visualization/visualization/Manifest.toml new file mode 100644 index 00000000..fa244349 --- /dev/null +++ b/notebooks/Closed-loop simulation and visualization/visualization/Manifest.toml @@ -0,0 +1,411 @@ +[[AssetRegistry]] +deps = ["Distributed", "JSON", "Pidfile", "Pkg", "SHA", "Test"] +git-tree-sha1 = "b25e88db7944f98789130d7b503276bc34bc098e" +uuid = "bf4720bc-e11a-5d0c-854e-bdca1663c893" +version = "0.1.0" + +[[AxisAlgorithms]] +deps = ["Compat", "WoodburyMatrices"] +git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "0.3.0" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[CSSUtil]] +deps = ["Colors", "Compat", "JSON", "Measures", "Pkg", "WebIO"] +git-tree-sha1 = "ff13fd99e4dd54f56eb064815f843bc992a871a2" +uuid = "70588ee8-6100-5070-97c1-3cb50ed05fe8" +version = "0.1.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random", "Test"] +git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.7.5" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Pkg", "Printf", "Reexport", "Test"] +git-tree-sha1 = "8c89e0a9a583954eae3efcf6a531e51c02b38cee" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.4" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[CoordinateTransformations]] +deps = ["Compat", "Rotations", "StaticArrays"] +git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.5.0" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections", "REPL", "Random", "Serialization", "Test"] +git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.14.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[FileIO]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "481e4db939f005db39f7296599d0543c0744fe30" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.0.2" + +[[FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[FixedPointNumbers]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[FunctionalCollections]] +deps = ["Test"] +git-tree-sha1 = "9fdecc849480c511d7825570c20c9b64c4e5d5ed" +uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca" +version = "0.4.0" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "Pkg", "StaticArrays", "Test"] +git-tree-sha1 = "765f6d4039ba2dd37b2936235012502aafbe8bfb" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.6.2" + +[[HTTP]] +deps = ["Base64", "Dates", "Distributed", "IniFile", "MbedTLS", "Sockets", "Test"] +git-tree-sha1 = "8a0f75e8b09df01d9f1ba9ad3fbf8b4983595d20" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "0.6.14" + +[[Hiccup]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "6187bb2d5fcbb2007c39e7ac53308b0d371124bd" +uuid = "9fb69e20-1954-56bb-a84f-559cc56a8ff7" +version = "0.2.2" + +[[IniFile]] +deps = ["Test"] +git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8" +uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f" +version = "0.5.0" + +[[InteractBase]] +deps = ["Base64", "CSSUtil", "Colors", "DataStructures", "Dates", "JSExpr", "JSON", "Knockout", "Observables", "Pkg", "Random", "Test", "WebIO", "Widgets"] +git-tree-sha1 = "494156a2e3fb192210bd8404da8de1d423d48bb1" +uuid = "d3863d7c-f0c8-5437-a7b4-3ae773c01009" +version = "0.8.1" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Interpolations]] +deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] +git-tree-sha1 = "56691033f157dd1ee1d2aa042114caeefefa897b" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.10.5" + +[[IterTools]] +deps = ["Pkg", "SparseArrays", "Test"] +git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.1.1" + +[[JSExpr]] +deps = ["JSON", "MacroTools", "Observables", "Pkg", "Test", "WebIO"] +git-tree-sha1 = "e08b116ced6b7dd45cc7c2708864dc7e96727a9f" +uuid = "97c1335a-c9c5-57fe-bc5d-ec35cebe8660" +version = "0.3.1" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Pkg", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "fec8e4d433072731466d37ed0061b3ba7f70eeb9" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.19.0" + +[[Knockout]] +deps = ["JSExpr", "JSON", "Observables", "Pkg", "Test", "WebIO"] +git-tree-sha1 = "63e5e0bd2e9923191c30bb1e3d6e4d579155ddfa" +uuid = "bcebb21b-c2e3-54f8-a781-646b90f6d2cc" +version = "0.2.0" + +[[Lazy]] +deps = ["Compat", "MacroTools", "Test"] +git-tree-sha1 = "1c2c5566f0eeaaad6979c156562384458f966e6a" +uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" +version = "0.13.1" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[MbedTLS]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Random", "Sockets", "Test"] +git-tree-sha1 = "4b890362c0c2fdb14a575ce927f1f4eeac6dda9f" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "0.6.4" + +[[Measures]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "ddfd6d13e330beacdde2c80de27c1c671945e7d9" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.0" + +[[MechanismGeometries]] +deps = ["ColorTypes", "Compat", "CoordinateTransformations", "FileIO", "GeometryTypes", "LightXML", "MeshIO", "Pkg", "RigidBodyDynamics", "Rotations", "StaticArrays"] +git-tree-sha1 = "5191190f3bb652cc65297ec8122297172c6e3c80" +uuid = "931e9471-e8fb-5385-a477-07ad12718aca" +version = "0.1.1" + +[[MeshCat]] +deps = ["AssetRegistry", "BinDeps", "Colors", "Compat", "CoordinateTransformations", "DocStringExtensions", "GeometryTypes", "JSExpr", "JSON", "Libdl", "MsgPack", "Mux", "Parameters", "Pkg", "Requires", "Rotations", "StaticArrays", "WebIO"] +git-tree-sha1 = "cc9d6d14c1c7d58c56d8cf7c5c1451a5c1180660" +uuid = "283c5d60-a78f-5afe-a0af-af636b173e11" +version = "0.3.0" + +[[MeshCatMechanisms]] +deps = ["ColorTypes", "CoordinateTransformations", "DataStructures", "GeometryTypes", "InteractBase", "Interpolations", "LoopThrottle", "MechanismGeometries", "MeshCat", "Pkg", "Random", "RigidBodyDynamics", "Test"] +git-tree-sha1 = "0d700662e1aecf610cff2f6de619d5eec27b61ff" +uuid = "6ad125db-dd91-5488-b820-c1df6aab299d" +version = "0.2.0" + +[[MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] +git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.3.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[MsgPack]] +deps = ["Compat", "Random", "Test"] +git-tree-sha1 = "c44b3470fa98705f9c12cb44ec9504de3af027ad" +uuid = "99f44e22-a591-53d1-9472-aa23ef4bd671" +version = "0.2.0" + +[[Mux]] +deps = ["AssetRegistry", "Base64", "HTTP", "Hiccup", "Lazy", "Pkg", "Sockets", "Test", "WebSockets"] +git-tree-sha1 = "487feb060cdd5cc152ef4f75b3cb565c0dc4300a" +uuid = "a975b10e-0019-58db-a62f-e48ff68538c9" +version = "0.5.3" + +[[Observables]] +deps = ["Test"] +git-tree-sha1 = "752ef9b9ff1a7a6d764aee6be60cf0a5be7a21b1" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.2.2" + +[[OffsetArrays]] +deps = ["DelimitedFiles", "Test"] +git-tree-sha1 = "f8cd140824f74f2948ff8660bc2292e16d29c1b7" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "0.8.1" + +[[OrderedCollections]] +deps = ["Pkg", "Random", "Serialization", "Test"] +git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.0.2" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "Pkg", "REPL", "Test"] +git-tree-sha1 = "40f540ec96e50c0b2b9efdb11b5e4d0c63f90923" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.1" + +[[Pidfile]] +deps = ["FileWatching", "Pkg", "Test"] +git-tree-sha1 = "1ffd82728498b5071cde851bbb7abd780d4445f3" +uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" +version = "1.1.0" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Ratios]] +deps = ["Compat"] +git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.3.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Requires]] +deps = ["Test"] +git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "0.5.2" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[WebIO]] +deps = ["AssetRegistry", "Base64", "Compat", "Dates", "FunctionalCollections", "JSON", "Logging", "Observables", "Pkg", "Random", "Requires", "Sockets", "Test", "UUIDs", "Widgets"] +git-tree-sha1 = "1f70c8c7c30fd6cf95fd5d517e59a5327505a043" +uuid = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" +version = "0.4.0" + +[[WebSockets]] +deps = ["Base64", "Dates", "Distributed", "HTTP", "MbedTLS", "Pkg", "Random", "Sockets", "Test"] +git-tree-sha1 = "f23986a5f20ed2ed68b462e0fdec20d6a4468757" +uuid = "104b5d7c-a370-577a-8038-80a2059c5097" +version = "1.0.3" + +[[Widgets]] +deps = ["DataStructures", "Observables", "Pkg", "Test"] +git-tree-sha1 = "944c2f6c3b92b0689e5f46988536bee26bba4d8a" +uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" +version = "0.4.3" + +[[WoodburyMatrices]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.4.1" diff --git a/notebooks/Closed-loop simulation and visualization/visualization/Project.toml b/notebooks/Closed-loop simulation and visualization/visualization/Project.toml new file mode 100644 index 00000000..5b1f584c --- /dev/null +++ b/notebooks/Closed-loop simulation and visualization/visualization/Project.toml @@ -0,0 +1,3 @@ +[deps] +MeshCatMechanisms = "6ad125db-dd91-5488-b820-c1df6aab299d" +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/Derivatives and gradients using ForwardDiff.ipynb b/notebooks/Derivatives and gradients using ForwardDiff/Derivatives and gradients using ForwardDiff.ipynb similarity index 80% rename from notebooks/Derivatives and gradients using ForwardDiff.ipynb rename to notebooks/Derivatives and gradients using ForwardDiff/Derivatives and gradients using ForwardDiff.ipynb index af06cb44..12f8b684 100644 --- a/notebooks/Derivatives and gradients using ForwardDiff.ipynb +++ b/notebooks/Derivatives and gradients using ForwardDiff/Derivatives and gradients using ForwardDiff.ipynb @@ -11,6 +11,28 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n", + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n", + "\u001b[?25l\u001b[2K\u001b[?25h\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n" + ] + } + ], + "source": [ + "using Pkg\n", + "Pkg.activate(@__DIR__)\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, "outputs": [], "source": [ "using RigidBodyDynamics\n", @@ -37,7 +59,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -50,14 +72,13 @@ "No non-tree joints." ] }, - "execution_count": 2, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "const mechanism = parse_urdf(\"../test/urdf/Acrobot.urdf\")\n", - "mechanism" + "mechanism = parse_urdf(joinpath(dirname(pathof(RigidBodyDynamics)), \"..\", \"test\", \"urdf\", \"Acrobot.urdf\"))" ] }, { @@ -69,17 +90,17 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Momentum expressed in \"world\":\n", + "Momentum expressed in \"\":\n", "angular: [0.0801508, 1.43084, 0.159513], linear: [-0.697851, 0.0, 0.338924]" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -87,8 +108,8 @@ "source": [ "float64state = MechanismState(mechanism)\n", "rand!(float64state)\n", - "const q = configuration(float64state) # for future use\n", - "const v = velocity(float64state) # for future use\n", + "q = configuration(float64state) # for future use\n", + "v = velocity(float64state) # for future use\n", "momentum(float64state)" ] }, @@ -103,27 +124,27 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "To use `ForwardDiff.jacobian` we need to create a function that maps `v` (as a `Vector`) to momentum (as a `Vector`):" + "To use `ForwardDiff.jacobian` we'll create a function that maps `v` (as a `Vector`) to momentum (as a `Vector`):" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "mom (generic function with 1 method)" + "momentum_vec (generic function with 1 method)" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "function mom(v::AbstractVector{T}) where T\n", + "function momentum_vec(v::AbstractVector{T}) where T\n", " # create a `MechanismState` that can handle the element type of `v` (which will be some `ForwardDiff.Dual`):\n", " state = MechanismState{T}(mechanism)\n", " \n", @@ -132,7 +153,7 @@ " set_velocity!(state, v)\n", " \n", " # return momentum converted to an `SVector` (as ForwardDiff expects an `AbstractVector`)\n", - " SVector(momentum(state))\n", + " Vector(SVector(momentum(state)))\n", "end" ] }, @@ -145,22 +166,22 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\u001b[1m\u001b[32mTest Passed\u001b[39m\u001b[22m" + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "@test mom(v) == SVector(momentum(float64state))" + "@test momentum_vec(v) == SVector(momentum(float64state))" ] }, { @@ -172,7 +193,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -187,13 +208,13 @@ " 1.06794 0.628547" ] }, - "execution_count": 6, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "J = ForwardDiff.jacobian(mom, v)" + "J = ForwardDiff.jacobian(momentum_vec, v)" ] }, { @@ -205,17 +226,17 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "MomentumMatrix expressed in \"world\":\n", + "MomentumMatrix expressed in \"\":\n", "[0.252338 0.157137; 4.51855 2.25777; 0.505187 0.194443; -2.21197 -0.777771; 0.0 0.0; 1.06794 0.628547]" ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -226,16 +247,16 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\u001b[1m\u001b[32mTest Passed\u001b[39m\u001b[22m" + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -267,33 +288,33 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BenchmarkTools.Trial: \n", - " memory estimate: 46.75 KiB\n", - " allocs estimate: 703\n", + " memory estimate: 35.86 KiB\n", + " allocs estimate: 506\n", " --------------\n", - " minimum time: 106.915 μs (0.00% GC)\n", - " median time: 123.764 μs (0.00% GC)\n", - " mean time: 130.577 μs (6.15% GC)\n", - " maximum time: 4.417 ms (94.65% GC)\n", + " minimum time: 65.107 μs (0.00% GC)\n", + " median time: 76.883 μs (0.00% GC)\n", + " mean time: 83.068 μs (7.27% GC)\n", + " maximum time: 4.298 ms (95.83% GC)\n", " --------------\n", " samples: 10000\n", " evals/sample: 1" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using BenchmarkTools\n", - "@benchmark ForwardDiff.jacobian($mom, $v)" + "@benchmark ForwardDiff.jacobian($momentum_vec, $v)" ] }, { @@ -303,10 +324,12 @@ "That's not great. Note all the allocations. We can do better by making the following modifications:\n", "\n", "1. use an in-place version of the `jacobian` function, `ForwardDiff.jacobian!`\n", - "2. reimplement our `mom` function to be in-place as well\n", + "2. reimplement our `momentum_vec` function to be in-place as well\n", "3. don't create a new `MechanismState` every time\n", "\n", - "The third point is especially important; creating a `MechanismState` is expensive!" + "The third point is especially important; creating a `MechanismState` is expensive!\n", + "\n", + "Regarding the second point, we could also just stop converting momentum from a `StaticArrays.SVector` to a `Vector` to avoid allocations. However, the solution of making the function in-place also applies when the size of the output vector is not known statically (e.g., for `dynamics_bias!`)." ] }, { @@ -320,7 +343,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -329,7 +352,7 @@ "StateCache{…}(…)" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -347,7 +370,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -356,7 +379,7 @@ "MechanismState{Float32, Float64, Float64, …}(…)" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -367,16 +390,16 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\u001b[1m\u001b[32mTest Passed\u001b[39m\u001b[22m" + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" ] }, - "execution_count": 12, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -389,27 +412,27 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we'll use the `StateCache` to reimplement `mom`, making it in-place as well:" + "Now we'll use the `StateCache` to reimplement `momentum_vec`, making it in-place as well:" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "mom! (generic function with 1 method)" + "momentum_vec! (generic function with 1 method)" ] }, - "execution_count": 13, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "function mom!(out::AbstractVector, v::AbstractVector{T}) where T\n", + "function momentum_vec!(out::AbstractVector, v::AbstractVector{T}) where T\n", " # retrieve a `MechanismState` that can handle the element type of `v`:\n", " state = statecache[T]\n", " \n", @@ -432,23 +455,23 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\u001b[1m\u001b[32mTest Passed\u001b[39m\u001b[22m" + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "const out = zeros(6) # where we'll be storing our results\n", - "mom!(out, v)\n", + "momentum_vec!(out, v)\n", "@test out == SVector(momentum(float64state))" ] }, @@ -461,24 +484,24 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\u001b[1m\u001b[32mTest Passed\u001b[39m\u001b[22m" + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" ] }, - "execution_count": 15, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "const result = DiffResults.JacobianResult(out, v)\n", - "const config = ForwardDiff.JacobianConfig(mom!, out, v)\n", - "ForwardDiff.jacobian!(result, mom!, out, v, config)\n", + "const config = ForwardDiff.JacobianConfig(momentum_vec!, out, v)\n", + "ForwardDiff.jacobian!(result, momentum_vec!, out, v, config)\n", "J = DiffResults.jacobian(result)\n", "@test J ≈ Array(A) atol = 1e-12" ] @@ -492,7 +515,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -502,22 +525,22 @@ " memory estimate: 0 bytes\n", " allocs estimate: 0\n", " --------------\n", - " minimum time: 2.026 μs (0.00% GC)\n", - " median time: 2.043 μs (0.00% GC)\n", - " mean time: 2.078 μs (0.00% GC)\n", - " maximum time: 4.953 μs (0.00% GC)\n", + " minimum time: 2.783 μs (0.00% GC)\n", + " median time: 2.887 μs (0.00% GC)\n", + " mean time: 2.944 μs (0.00% GC)\n", + " maximum time: 9.286 μs (0.00% GC)\n", " --------------\n", " samples: 10000\n", " evals/sample: 9" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "@benchmark ForwardDiff.jacobian!($result, $mom!, $out, $v, $config)" + "@benchmark ForwardDiff.jacobian!($result, $momentum_vec!, $out, $v, $config)" ] }, { @@ -529,26 +552,26 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BenchmarkTools.Trial: \n", - " memory estimate: 0 bytes\n", - " allocs estimate: 0\n", + " memory estimate: 1.75 KiB\n", + " allocs estimate: 36\n", " --------------\n", - " minimum time: 696.804 ns (0.00% GC)\n", - " median time: 699.351 ns (0.00% GC)\n", - " mean time: 709.050 ns (0.00% GC)\n", - " maximum time: 1.135 μs (0.00% GC)\n", + " minimum time: 3.744 μs (0.00% GC)\n", + " median time: 4.143 μs (0.00% GC)\n", + " mean time: 4.600 μs (7.71% GC)\n", + " maximum time: 604.446 μs (98.74% GC)\n", " --------------\n", " samples: 10000\n", - " evals/sample: 148" + " evals/sample: 8" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -585,18 +608,18 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "2-element RigidBodyDynamics.CustomCollections.SegmentedVector{RigidBodyDynamics.JointID,Float64,Base.OneTo{RigidBodyDynamics.JointID},Array{Float64,1}}:\n", - " 0.0796808\n", - " -4.79883 " + "2-element SegmentedVector{JointID,Float64,Base.OneTo{JointID},Array{Float64,1}}:\n", + " 0.0796807679458064\n", + " -4.798825359977611 " ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -625,18 +648,18 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "2-element Array{ForwardDiff.Dual{Void,Float64,1},1}:\n", - " Dual{Void}(0.297288,0.312707) \n", - " Dual{Void}(0.382396,0.00790928)" + "2-element Array{ForwardDiff.Dual{Nothing,Float64,1},1}:\n", + " Dual{Nothing}(0.2972879845354616,0.3127069683360675) \n", + " Dual{Nothing}(0.3823959677906078,0.00790928339056074)" ] }, - "execution_count": 19, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -668,18 +691,18 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "2-element Array{ForwardDiff.Dual{Void,Float64,1},1}:\n", - " Dual{Void}(0.312707,0.0796808) \n", - " Dual{Void}(0.00790928,-4.79883)" + "2-element Array{ForwardDiff.Dual{Nothing,Float64,1},1}:\n", + " Dual{Nothing}(0.3127069683360675,0.0796807679458064) \n", + " Dual{Nothing}(0.00790928339056074,-4.798825359977611)" ] }, - "execution_count": 20, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -697,16 +720,16 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Dual{Void}(-21.472905435008563,4.440892098500626e-16)" + "Dual{Nothing}(-21.472905435008563,4.440892098500626e-16)" ] }, - "execution_count": 21, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -728,7 +751,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -746,7 +769,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -755,7 +778,7 @@ "-21.472905435008563" ] }, - "execution_count": 23, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -780,16 +803,16 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\u001b[1m\u001b[32mTest Passed\u001b[39m\u001b[22m" + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" ] }, - "execution_count": 24, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/Derivatives and gradients using ForwardDiff/Manifest.toml b/notebooks/Derivatives and gradients using ForwardDiff/Manifest.toml new file mode 100644 index 00000000..e3056454 --- /dev/null +++ b/notebooks/Derivatives and gradients using ForwardDiff/Manifest.toml @@ -0,0 +1,198 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[CommonSubexpressions]] +deps = ["Test"] +git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.2.0" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[DiffResults]] +deps = ["Compat", "StaticArrays"] +git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "0.0.3" + +[[DiffRules]] +deps = ["Random", "Test"] +git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "0.0.7" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Pkg", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] +git-tree-sha1 = "8425a7d4e060bc2ded32d090bce910a187d6cce7" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.9.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[NaNMath]] +deps = ["Compat"] +git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.2" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "c35c9c76008babf4d658060fc64aeb369a41e7bd" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "0.7.1" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/notebooks/Derivatives and gradients using ForwardDiff/Project.toml b/notebooks/Derivatives and gradients using ForwardDiff/Project.toml new file mode 100644 index 00000000..c8153472 --- /dev/null +++ b/notebooks/Derivatives and gradients using ForwardDiff/Project.toml @@ -0,0 +1,3 @@ +[deps] +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/Four-bar linkage - simulation and visualization.ipynb b/notebooks/Four-bar linkage/Four-bar linkage.ipynb similarity index 59% rename from notebooks/Four-bar linkage - simulation and visualization.ipynb rename to notebooks/Four-bar linkage/Four-bar linkage.ipynb index 8a4c631e..665768ce 100644 --- a/notebooks/Four-bar linkage - simulation and visualization.ipynb +++ b/notebooks/Four-bar linkage/Four-bar linkage.ipynb @@ -21,6 +21,28 @@ "# Setup" ] }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n", + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n", + "\u001b[?25l\u001b[2K\u001b[?25h\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n" + ] + } + ], + "source": [ + "using Pkg\n", + "Pkg.activate(@__DIR__)\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -30,7 +52,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -65,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -109,7 +131,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -120,7 +142,7 @@ "No non-tree joints." ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -139,7 +161,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -153,7 +175,7 @@ "No non-tree joints." ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -195,7 +217,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -210,7 +232,7 @@ "joint4, predecessor: inertia2_centroidal, successor: inertia3_centroidal" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -246,7 +268,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -256,20 +278,9 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "true" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "set_configuration!(state, joint1, 1.6707963267948966) # θ\n", "set_configuration!(state, joint2, -1.4591054166649482) # γ\n", @@ -292,7 +303,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -310,184 +321,42 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "For visualization, we'll use [`RigidBodyTreeInspector`](https://github.com/rdeits/RigidBodyTreeInspector.jl).\n", + "For visualization, we'll use [`MeshCatMechanisms`](https://github.com/JuliaRobotics/MeshCatMechanisms.jl), an external package based on RigidBodyDynamics.jl.\n", "\n", "(Note: the `#NBSKIP` comments are to skip these cells during `Pkg.test(\"RigidBodyDynamics\")`)" ] }, { "cell_type": "code", - "execution_count": 9, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - " \n", - " \n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[1m\u001b[36mINFO: \u001b[39m\u001b[22m\u001b[36mInteract.jl: using new nbwidgetsextension protocol\n", - "\u001b[39m" - ] - } - ], - "source": [ - "#NBSKIP\n", - "using RigidBodyTreeInspector" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Open the viewer application if it isn't open already:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#NBSKIP\n", - "DrakeVisualizer.any_open_windows() || (DrakeVisualizer.new_window(); sleep(1));" + "Pkg.activate(joinpath(@__DIR__, \"visualization\"));\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"\n", + "using MeshCatMechanisms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Load the mechanism's geometry into the visualizer:" + "Create a `MechanismVisualizer` for the four-bar linkage and open it in a new browser tab (see [`MeshCat.jl`](https://github.com/rdeits/MeshCat.jl) for other options):" ] }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-03-21 00:45:56.538 drake-visualizer[40259:6478725] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead. \n" - ] - } - ], + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], "source": [ "#NBSKIP\n", - "vis = DrakeVisualizer.Visualizer()[:robot1];\n", - "RigidBodyTreeInspector.setgeometry!(vis, fourbar, visual_elements(fourbar, Skeleton(inertias = false)));" + "mvis = MechanismVisualizer(fourbar, Skeleton(inertias=false))\n", + "open(mvis);" ] }, { @@ -499,12 +368,14 @@ }, { "cell_type": "code", - "execution_count": 12, - "metadata": {}, + "execution_count": null, + "metadata": { + "scrolled": false + }, "outputs": [], "source": [ "#NBSKIP\n", - "RigidBodyTreeInspector.animate(vis, fourbar, ts, qs; realtimerate = 1.);" + "MeshCatMechanisms.animate(mvis, ts, qs; realtimerate = 1.);" ] }, { diff --git a/notebooks/Four-bar linkage/Manifest.toml b/notebooks/Four-bar linkage/Manifest.toml new file mode 100644 index 00000000..e577966e --- /dev/null +++ b/notebooks/Four-bar linkage/Manifest.toml @@ -0,0 +1,150 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/notebooks/Four-bar linkage/Project.toml b/notebooks/Four-bar linkage/Project.toml new file mode 100644 index 00000000..dbd4d67d --- /dev/null +++ b/notebooks/Four-bar linkage/Project.toml @@ -0,0 +1,2 @@ +[deps] +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/fourbar.jpg b/notebooks/Four-bar linkage/fourbar.jpg similarity index 100% rename from notebooks/fourbar.jpg rename to notebooks/Four-bar linkage/fourbar.jpg diff --git a/notebooks/Four-bar linkage/visualization/Manifest.toml b/notebooks/Four-bar linkage/visualization/Manifest.toml new file mode 100644 index 00000000..fa244349 --- /dev/null +++ b/notebooks/Four-bar linkage/visualization/Manifest.toml @@ -0,0 +1,411 @@ +[[AssetRegistry]] +deps = ["Distributed", "JSON", "Pidfile", "Pkg", "SHA", "Test"] +git-tree-sha1 = "b25e88db7944f98789130d7b503276bc34bc098e" +uuid = "bf4720bc-e11a-5d0c-854e-bdca1663c893" +version = "0.1.0" + +[[AxisAlgorithms]] +deps = ["Compat", "WoodburyMatrices"] +git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "0.3.0" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[CSSUtil]] +deps = ["Colors", "Compat", "JSON", "Measures", "Pkg", "WebIO"] +git-tree-sha1 = "ff13fd99e4dd54f56eb064815f843bc992a871a2" +uuid = "70588ee8-6100-5070-97c1-3cb50ed05fe8" +version = "0.1.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random", "Test"] +git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.7.5" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Pkg", "Printf", "Reexport", "Test"] +git-tree-sha1 = "8c89e0a9a583954eae3efcf6a531e51c02b38cee" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.4" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[CoordinateTransformations]] +deps = ["Compat", "Rotations", "StaticArrays"] +git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.5.0" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections", "REPL", "Random", "Serialization", "Test"] +git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.14.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[FileIO]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "481e4db939f005db39f7296599d0543c0744fe30" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.0.2" + +[[FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[FixedPointNumbers]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[FunctionalCollections]] +deps = ["Test"] +git-tree-sha1 = "9fdecc849480c511d7825570c20c9b64c4e5d5ed" +uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca" +version = "0.4.0" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "Pkg", "StaticArrays", "Test"] +git-tree-sha1 = "765f6d4039ba2dd37b2936235012502aafbe8bfb" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.6.2" + +[[HTTP]] +deps = ["Base64", "Dates", "Distributed", "IniFile", "MbedTLS", "Sockets", "Test"] +git-tree-sha1 = "8a0f75e8b09df01d9f1ba9ad3fbf8b4983595d20" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "0.6.14" + +[[Hiccup]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "6187bb2d5fcbb2007c39e7ac53308b0d371124bd" +uuid = "9fb69e20-1954-56bb-a84f-559cc56a8ff7" +version = "0.2.2" + +[[IniFile]] +deps = ["Test"] +git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8" +uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f" +version = "0.5.0" + +[[InteractBase]] +deps = ["Base64", "CSSUtil", "Colors", "DataStructures", "Dates", "JSExpr", "JSON", "Knockout", "Observables", "Pkg", "Random", "Test", "WebIO", "Widgets"] +git-tree-sha1 = "494156a2e3fb192210bd8404da8de1d423d48bb1" +uuid = "d3863d7c-f0c8-5437-a7b4-3ae773c01009" +version = "0.8.1" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Interpolations]] +deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] +git-tree-sha1 = "56691033f157dd1ee1d2aa042114caeefefa897b" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.10.5" + +[[IterTools]] +deps = ["Pkg", "SparseArrays", "Test"] +git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.1.1" + +[[JSExpr]] +deps = ["JSON", "MacroTools", "Observables", "Pkg", "Test", "WebIO"] +git-tree-sha1 = "e08b116ced6b7dd45cc7c2708864dc7e96727a9f" +uuid = "97c1335a-c9c5-57fe-bc5d-ec35cebe8660" +version = "0.3.1" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Pkg", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "fec8e4d433072731466d37ed0061b3ba7f70eeb9" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.19.0" + +[[Knockout]] +deps = ["JSExpr", "JSON", "Observables", "Pkg", "Test", "WebIO"] +git-tree-sha1 = "63e5e0bd2e9923191c30bb1e3d6e4d579155ddfa" +uuid = "bcebb21b-c2e3-54f8-a781-646b90f6d2cc" +version = "0.2.0" + +[[Lazy]] +deps = ["Compat", "MacroTools", "Test"] +git-tree-sha1 = "1c2c5566f0eeaaad6979c156562384458f966e6a" +uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" +version = "0.13.1" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[MbedTLS]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Random", "Sockets", "Test"] +git-tree-sha1 = "4b890362c0c2fdb14a575ce927f1f4eeac6dda9f" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "0.6.4" + +[[Measures]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "ddfd6d13e330beacdde2c80de27c1c671945e7d9" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.0" + +[[MechanismGeometries]] +deps = ["ColorTypes", "Compat", "CoordinateTransformations", "FileIO", "GeometryTypes", "LightXML", "MeshIO", "Pkg", "RigidBodyDynamics", "Rotations", "StaticArrays"] +git-tree-sha1 = "5191190f3bb652cc65297ec8122297172c6e3c80" +uuid = "931e9471-e8fb-5385-a477-07ad12718aca" +version = "0.1.1" + +[[MeshCat]] +deps = ["AssetRegistry", "BinDeps", "Colors", "Compat", "CoordinateTransformations", "DocStringExtensions", "GeometryTypes", "JSExpr", "JSON", "Libdl", "MsgPack", "Mux", "Parameters", "Pkg", "Requires", "Rotations", "StaticArrays", "WebIO"] +git-tree-sha1 = "cc9d6d14c1c7d58c56d8cf7c5c1451a5c1180660" +uuid = "283c5d60-a78f-5afe-a0af-af636b173e11" +version = "0.3.0" + +[[MeshCatMechanisms]] +deps = ["ColorTypes", "CoordinateTransformations", "DataStructures", "GeometryTypes", "InteractBase", "Interpolations", "LoopThrottle", "MechanismGeometries", "MeshCat", "Pkg", "Random", "RigidBodyDynamics", "Test"] +git-tree-sha1 = "0d700662e1aecf610cff2f6de619d5eec27b61ff" +uuid = "6ad125db-dd91-5488-b820-c1df6aab299d" +version = "0.2.0" + +[[MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] +git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.3.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[MsgPack]] +deps = ["Compat", "Random", "Test"] +git-tree-sha1 = "c44b3470fa98705f9c12cb44ec9504de3af027ad" +uuid = "99f44e22-a591-53d1-9472-aa23ef4bd671" +version = "0.2.0" + +[[Mux]] +deps = ["AssetRegistry", "Base64", "HTTP", "Hiccup", "Lazy", "Pkg", "Sockets", "Test", "WebSockets"] +git-tree-sha1 = "487feb060cdd5cc152ef4f75b3cb565c0dc4300a" +uuid = "a975b10e-0019-58db-a62f-e48ff68538c9" +version = "0.5.3" + +[[Observables]] +deps = ["Test"] +git-tree-sha1 = "752ef9b9ff1a7a6d764aee6be60cf0a5be7a21b1" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.2.2" + +[[OffsetArrays]] +deps = ["DelimitedFiles", "Test"] +git-tree-sha1 = "f8cd140824f74f2948ff8660bc2292e16d29c1b7" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "0.8.1" + +[[OrderedCollections]] +deps = ["Pkg", "Random", "Serialization", "Test"] +git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.0.2" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "Pkg", "REPL", "Test"] +git-tree-sha1 = "40f540ec96e50c0b2b9efdb11b5e4d0c63f90923" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.1" + +[[Pidfile]] +deps = ["FileWatching", "Pkg", "Test"] +git-tree-sha1 = "1ffd82728498b5071cde851bbb7abd780d4445f3" +uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" +version = "1.1.0" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Ratios]] +deps = ["Compat"] +git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.3.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Requires]] +deps = ["Test"] +git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "0.5.2" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[WebIO]] +deps = ["AssetRegistry", "Base64", "Compat", "Dates", "FunctionalCollections", "JSON", "Logging", "Observables", "Pkg", "Random", "Requires", "Sockets", "Test", "UUIDs", "Widgets"] +git-tree-sha1 = "1f70c8c7c30fd6cf95fd5d517e59a5327505a043" +uuid = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" +version = "0.4.0" + +[[WebSockets]] +deps = ["Base64", "Dates", "Distributed", "HTTP", "MbedTLS", "Pkg", "Random", "Sockets", "Test"] +git-tree-sha1 = "f23986a5f20ed2ed68b462e0fdec20d6a4468757" +uuid = "104b5d7c-a370-577a-8038-80a2059c5097" +version = "1.0.3" + +[[Widgets]] +deps = ["DataStructures", "Observables", "Pkg", "Test"] +git-tree-sha1 = "944c2f6c3b92b0689e5f46988536bee26bba4d8a" +uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" +version = "0.4.3" + +[[WoodburyMatrices]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.4.1" diff --git a/notebooks/Four-bar linkage/visualization/Project.toml b/notebooks/Four-bar linkage/visualization/Project.toml new file mode 100644 index 00000000..5b1f584c --- /dev/null +++ b/notebooks/Four-bar linkage/visualization/Project.toml @@ -0,0 +1,3 @@ +[deps] +MeshCatMechanisms = "6ad125db-dd91-5488-b820-c1df6aab299d" +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/Jacobian IK and Control.ipynb b/notebooks/Jacobian IK and Control.ipynb deleted file mode 100644 index 63bbd7ee..00000000 --- a/notebooks/Jacobian IK and Control.ipynb +++ /dev/null @@ -1,908 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Jacobian Transpose Inverse Kinematics and Control\n", - "\n", - "In this notebook, we'll demonstrate an extremely simple approach for computing basic inverse kinematics (IK) and controlling the position of some point on our robot using the Jacobian transpose. \n", - "\n", - "For a brief technical introduction, see or " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "MersenneTwister(UInt32[0x0000002a], Base.dSFMT.DSFMT_state(Int32[964434469, 1073036706, 1860149520, 1073503458, 1687169063, 1073083486, -399267803, 1072983952, -909620556, 1072836235 … -293054293, 1073002412, -1300127419, 1073642642, 1917177374, -666058738, -337596527, 1830741494, 382, 0]), [1.73408, 1.63027, 1.93195, 1.91092, 1.70188, 1.39076, 1.34293, 1.09349, 1.68769, 1.49997 … 1.49857, 1.47215, 1.29587, 1.59695, 1.45917, 1.37511, 1.7363, 1.11385, 1.14541, 1.32263], 382)" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "using RigidBodyDynamics\n", - "using StaticArrays\n", - "\n", - "# Fix the random seed, so we get repeatable results\n", - "using Random\n", - "Random.seed!(42)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First we'll load our double pendulum robot from URDF:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Spanning tree:\n", - "Vertex: world (root)\n", - " Vertex: base_link, Edge: base_link_to_world\n", - " Vertex: upper_link, Edge: shoulder\n", - " Vertex: lower_link, Edge: elbow\n", - "No non-tree joints." - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "urdf = joinpath(dirname(pathof(RigidBodyDynamics)), \"..\", \"test\", \"urdf\", \"Acrobot.urdf\")\n", - "\n", - "mechanism = parse_urdf(urdf)\n", - "state = MechanismState(mechanism)\n", - "mechanism" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we choose a point on the robot to control. We'll pick the end of the second link, which is located 2m from the origin of the `lower_link` body:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Point3D in \"after_elbow\": [0.0, 0.0, -2.0]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "const body = findbody(mechanism, \"lower_link\")\n", - "const point = Point3D(default_frame(body), 0., 0, -2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's visualize the mechanism and its attached point. For visualization, we'll use [MeshCatMechanisms.jl](https://github.com/JuliaRobotics/MeshCatMechanisms.jl) with [Blink.jl](https://github.com/JunoLab/Blink.jl). \n", - "\n", - "(Note: the `#NBSKIP` comments are to skip these cells during `Pkg.test(\"RigidBodyDynamics\")`)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - " \n" - ], - "text/plain": [ - "HTML{String}(\" \\n\")" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "HTML{String}(\"\")" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "HTML{String}(\"\")" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - " \n" - ], - "text/plain": [ - "HTML{String}(\" \\n\")" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[1m\u001b[36mINFO: \u001b[39m\u001b[22m\u001b[36mLoading HttpServer methods...\n", - "\u001b[39m" - ] - } - ], - "source": [ - "#NBSKIP\n", - "using MeshCatMechanisms\n", - "using Blink" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Blink.AtomShell.Window(1, Blink.AtomShell.Electron(Process(`/home/rdeits/.julia/v0.6/Blink/deps/atom/electron /home/rdeits/.julia/v0.6/Blink/src/AtomShell/main.js port 4896`, ProcessRunning), TCPSocket(RawFD(54) active, 0 bytes waiting), Dict{String,Any}(Pair{String,Any}(\"callback\", Blink.#1))), Blink.Page(1, WebSockets.WebSocket{TCPSocket}(TCPSocket(RawFD(55) active, 0 bytes waiting), true, CONNECTED::WebSockets.ReadyState = 1), Dict{String,Any}(Pair{String,Any}(\"webio\", WebIO.#109),Pair{String,Any}(\"callback\", Blink.#1)), Future(1, 1, 1, Nullable{Any}(true))))" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#NBSKIP\n", - "# Create the visualizer\n", - "const vis = MechanismVisualizer(mechanism, URDFVisuals(urdf))\n", - "# Render our target point attached to the robot as a sphere with radius 0.07\n", - "setelement!(vis, point, 0.07)\n", - "# Open the visualizer in a new Blink window\n", - "open(vis, Window())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Inverse Kinematics\n", - "\n", - "First, let's use the point jacobian to solve a simple inverse kinematics problem. Given a target location `desired` expressed in world frame, we want to find the joint angles `q` such that the `point` attached to the robot is at the desired location. \n", - "\n", - "To do that, we'll iteratively update `q` by applying: \n", - "\n", - "\\begin{align}\n", - "\\Delta q = \\alpha \\, J_p^\\top \\, \\Delta p\n", - "\\end{align}\n", - "\n", - "where $\\alpha$ is our step size (equivalent to a learning rate in gradient descent) and $\\Delta p$ is the error in the position of our target point. " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "jacobian_transpose_ik! (generic function with 1 method)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "function jacobian_transpose_ik!(state::MechanismState,\n", - " body::RigidBody,\n", - " point::Point3D,\n", - " desired::Point3D;\n", - " α=0.1,\n", - " iterations=100)\n", - " mechanism = state.mechanism\n", - " world = root_frame(mechanism)\n", - " \n", - " # Compute the joint path from world to our target body\n", - " p = path(mechanism, root_body(mechanism), body)\n", - " # Allocate the point jacobian (we'll update this in-place later)\n", - " Jp = point_jacobian(state, p, transform(state, point, world))\n", - " \n", - " q = copy(configuration(state))\n", - " \n", - " for i in 1:iterations\n", - " # Update the position of the point\n", - " point_in_world = transform(state, point, world)\n", - " # Update the point's jacobian\n", - " point_jacobian!(Jp, state, p, point_in_world)\n", - " # Compute an update in joint coordinates using the jacobian transpose\n", - " Δq = α * Array(Jp)' * (transform(state, desired, world) - point_in_world).v\n", - " # Apply the update\n", - " q .= configuration(state) .+ Δq\n", - " set_configuration!(state, q)\n", - " end\n", - " state\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To use our IK method, we just have to set our current state and choose a desired location for the tip of the robot's arm: " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "true" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "rand!(state)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "#NBSKIP\n", - "set_configuration!(vis, configuration(state))" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "MechanismState{Float64, Float64, Float64, …}(…)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Choose a desired location. We'll move the tip of the arm to\n", - "# [0.5, 0, 2]\n", - "desired_tip_location = Point3D(root_frame(mechanism), 0.5, 0, 2)\n", - "# Run the IK, updating `state` in place\n", - "jacobian_transpose_ik!(state, body, point, desired_tip_location)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "#NBSKIP\n", - "set_configuration!(vis, configuration(state))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Point3D in \"world\": [0.488494, 0.25, 1.97828]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# We asked for our point to be close to [0.5, 0, 2], \n", - "# but since the arm cannot move in the y direction at all\n", - "# we end up near [0.5, 0.25, 2] instead\n", - "transform(state, point, root_frame(mechanism))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can try varying the target and watching the IK solution change:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "qs = typeof(configuration(state))[]\n", - "\n", - "# Vary the desired x position from -1 to 1\n", - "for x in range(-1, stop=1, length=100)\n", - " desired = Point3D(root_frame(mechanism), x, 0, 2)\n", - " jacobian_transpose_ik!(state, body, point, desired)\n", - " push!(qs, copy(configuration(state)))\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "true" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#NBSKIP\n", - "ts = collect(range(0, stop=1, length=length(qs)))\n", - "setanimation!(vis, ts, qs)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Control\n", - "\n", - "Now let's use the same principle to generate torques and actually control the robot. To make things more interesting, let's get the end of the robot's arm to trace out a circle. " - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1.0" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "circle_origin = SVector(0., 0.25, 2)\n", - "radius = 0.5\n", - "ω = 1.0 # radians per second at which the point should move in its circle" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "#NBSKIP\n", - "using MeshCat\n", - "using GeometryTypes: Point" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "MeshCat Visualizer with path /meshcat/circle" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#NBSKIP\n", - "\n", - "# Draw the circle in the viewer\n", - "θ = repeat(linspace(0, stop=2π, length=100), inner=(2,))[2:end]\n", - "cx, cy, cz = circle_origin\n", - "geometry = PointCloud(Point.(cx .+ radius .* sin.(θ), cy, cz .+ 0.5 .* cos.(θ)))\n", - "setobject!(vis[:circle], LineSegments(geometry, LineBasicMaterial()))" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "make_circle_controller (generic function with 1 method)" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# This function will take in the parameters of the circle\n", - "# and the target point and return a function we can use\n", - "# as the controller. By wrapping the construction of the \n", - "# controller in this way, we avoie any issues with accessing\n", - "# non-const global variables. \n", - "function make_circle_controller(state::MechanismState,\n", - " body::RigidBody,\n", - " point::Point3D,\n", - " circle_origin::AbstractVector,\n", - " radius,\n", - " ω)\n", - " mechanism = state.mechanism\n", - " world = root_frame(mechanism)\n", - " joint_path = path(mechanism, root_body(mechanism), body)\n", - " Jp = point_jacobian(state, joint_path, transform(state, point, root_frame(mechanism)))\n", - " v̇ = similar(velocity(state))\n", - " \n", - " function controller!(τ, t, state)\n", - " desired = Point3D(world, circle_origin .+ radius .* SVector(sin(t / ω), 0, cos(t / ω)))\n", - " point_in_world = transform_to_root(state, body) * point\n", - " point_jacobian!(Jp, state, joint_path, point_in_world)\n", - " Kp = 200\n", - " Kd = 20\n", - " Δp = desired - point_in_world\n", - " v̇ .= Kp * Array(Jp)' * Δp.v .- 20 .* velocity(state)\n", - " τ .= inverse_dynamics(state, v̇)\n", - " end\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "controller! (generic function with 1 method)" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "controller! = make_circle_controller(state, body, point, circle_origin, radius, ω)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "ts, qs, vs = simulate(state, 10, controller!);" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "true" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#NBSKIP\n", - "\n", - "# Animate the resulting trajectory\n", - "setanimation!(vis, ts, qs)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can plot the behavior of the controller. The initial state is quite far from the target, so there's some significant overshoot early in the trajectory, but the controller eventually settles into tracking the desired circular path. This controller isn't very well-tuned, and we could certainly do better with a more advanced approach, but this is still a nice demonstration of a very simple control policy. " - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Plots.GRBackend()" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#NBSKIP\n", - "\n", - "using Plots; gr()" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "-1.0\n", - "\n", - "\n", - "-0.5\n", - "\n", - "\n", - "0.0\n", - "\n", - "\n", - "0.5\n", - "\n", - "\n", - "1.0\n", - "\n", - "\n", - "1.0\n", - "\n", - "\n", - "1.5\n", - "\n", - "\n", - "2.0\n", - "\n", - "\n", - "2.5\n", - "\n", - "\n", - "3.0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "y1\n", - "\n", - "\n" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#NBSKIP\n", - "\n", - "xs = Float64[]\n", - "zs = Float64[]\n", - "for q in qs[1:100:end] # Downsample by 100 just so the plot doesn't become a huge file\n", - " set_configuration!(state, q)\n", - " p = transform(state, point, root_frame(mechanism))\n", - " push!(xs, p.v[1])\n", - " push!(zs, p.v[3])\n", - "end\n", - "\n", - "plot(xs, zs, xlim=(-1, 1), ylim=(1, 3), aspect_ratio=:equal)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Julia 1.0.0", - "language": "julia", - "name": "julia-1.0" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/Jacobian IK and Control/Jacobian IK and Control.ipynb b/notebooks/Jacobian IK and Control/Jacobian IK and Control.ipynb new file mode 100644 index 00000000..7532f3c1 --- /dev/null +++ b/notebooks/Jacobian IK and Control/Jacobian IK and Control.ipynb @@ -0,0 +1,884 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Jacobian Transpose Inverse Kinematics and Control\n", + "\n", + "In this notebook, we'll demonstrate an extremely simple approach for computing basic inverse kinematics (IK) and controlling the position of some point on our robot using the Jacobian transpose. \n", + "\n", + "For a brief technical introduction, see or " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n", + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n", + "\u001b[?25l\u001b[2K\u001b[?25h\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n" + ] + } + ], + "source": [ + "using Pkg\n", + "Pkg.activate(@__DIR__)\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "using RigidBodyDynamics\n", + "using StaticArrays\n", + "\n", + "# Fix the random seed, so we get repeatable results\n", + "using Random\n", + "Random.seed!(42);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we'll load our double pendulum robot from URDF:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Spanning tree:\n", + "Vertex: world (root)\n", + " Vertex: upper_link, Edge: shoulder\n", + " Vertex: lower_link, Edge: elbow\n", + "No non-tree joints." + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "urdf = joinpath(dirname(pathof(RigidBodyDynamics)), \"..\", \"test\", \"urdf\", \"Acrobot.urdf\")\n", + "mechanism = parse_urdf(urdf)\n", + "state = MechanismState(mechanism)\n", + "mechanism" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we choose a point on the robot to control. We'll pick the end of the second link, which is located 2m from the origin of the `lower_link` body:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Point3D in \"after_elbow\": [0.0, 0.0, -2.0]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "body = findbody(mechanism, \"lower_link\")\n", + "point = Point3D(default_frame(body), 0., 0, -2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's visualize the mechanism and its attached point. For visualization, we'll use [MeshCatMechanisms.jl](https://github.com/JuliaRobotics/MeshCatMechanisms.jl) with [Blink.jl](https://github.com/JunoLab/Blink.jl). \n", + "\n", + "(Note: the `#NBSKIP` comments are to skip these cells during `Pkg.test(\"RigidBodyDynamics\")`)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n", + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n", + "\u001b[?25l\u001b[2K\u001b[?25h\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n" + ] + }, + { + "data": { + "text/html": [ + " \n" + ], + "text/plain": [ + "HTML{String}(\" \\n\")" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "HTML{String}(\"\")" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "HTML{String}(\"\")" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " \n" + ], + "text/plain": [ + "HTML{String}(\" \\n\")" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#NBSKIP\n", + "using Pkg\n", + "Pkg.activate(joinpath(@__DIR__, \"visualization\"))\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"\n", + "using MeshCatMechanisms, Blink\n", + "Blink.AtomShell.isinstalled() || Blink.AtomShell.install();" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "#NBSKIP\n", + "# Create the visualizer\n", + "vis = MechanismVisualizer(mechanism, URDFVisuals(urdf))\n", + "# Render our target point attached to the robot as a sphere with radius 0.07\n", + "setelement!(vis, point, 0.07)\n", + "# Open the visualizer in a new Blink window\n", + "open(vis, Window());" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inverse Kinematics\n", + "\n", + "First, let's use the point jacobian to solve a simple inverse kinematics problem. Given a target location `desired` expressed in world frame, we want to find the joint angles `q` such that the `point` attached to the robot is at the desired location. \n", + "\n", + "To do that, we'll iteratively update `q` by applying: \n", + "\n", + "\\begin{align}\n", + "\\Delta q = \\alpha \\, J_p^\\top \\, \\Delta p\n", + "\\end{align}\n", + "\n", + "where $\\alpha$ is our step size (equivalent to a learning rate in gradient descent) and $\\Delta p$ is the error in the position of our target point. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "jacobian_transpose_ik! (generic function with 1 method)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "function jacobian_transpose_ik!(state::MechanismState,\n", + " body::RigidBody,\n", + " point::Point3D,\n", + " desired::Point3D;\n", + " α=0.1,\n", + " iterations=100)\n", + " mechanism = state.mechanism\n", + " world = root_frame(mechanism)\n", + " \n", + " # Compute the joint path from world to our target body\n", + " p = path(mechanism, root_body(mechanism), body)\n", + " # Allocate the point jacobian (we'll update this in-place later)\n", + " Jp = point_jacobian(state, p, transform(state, point, world))\n", + " \n", + " q = copy(configuration(state))\n", + " \n", + " for i in 1:iterations\n", + " # Update the position of the point\n", + " point_in_world = transform(state, point, world)\n", + " # Update the point's jacobian\n", + " point_jacobian!(Jp, state, p, point_in_world)\n", + " # Compute an update in joint coordinates using the jacobian transpose\n", + " Δq = α * Array(Jp)' * (transform(state, desired, world) - point_in_world).v\n", + " # Apply the update\n", + " q .= configuration(state) .+ Δq\n", + " set_configuration!(state, q)\n", + " end\n", + " state\n", + "end" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To use our IK method, we just have to set our current state and choose a desired location for the tip of the robot's arm: " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "rand!(state)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "#NBSKIP\n", + "set_configuration!(vis, configuration(state))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "MechanismState{Float64, Float64, Float64, …}(…)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Choose a desired location. We'll move the tip of the arm to\n", + "# [0.5, 0, 2]\n", + "desired_tip_location = Point3D(root_frame(mechanism), 0.5, 0, 2)\n", + "# Run the IK, updating `state` in place\n", + "jacobian_transpose_ik!(state, body, point, desired_tip_location)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#NBSKIP\n", + "set_configuration!(vis, configuration(state))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Point3D in \"\": [0.49993, 0.25, 1.969]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# We asked for our point to be close to [0.5, 0, 2], \n", + "# but since the arm cannot move in the y direction at all\n", + "# we end up near [0.5, 0.25, 2] instead\n", + "transform(state, point, root_frame(mechanism))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can try varying the target and watching the IK solution change:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "qs = typeof(configuration(state))[]\n", + "\n", + "# Vary the desired x position from -1 to 1\n", + "for x in range(-1, stop=1, length=100)\n", + " desired = Point3D(root_frame(mechanism), x, 0, 2)\n", + " jacobian_transpose_ik!(state, body, point, desired)\n", + " push!(qs, copy(configuration(state)))\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "┌ Warning: `getindex(itp::AbstractInterpolation{T, N}, i::Vararg{Number, N}) where {T, N}` is deprecated, use `itp(i...)` instead.\n", + "│ caller = #setanimation!#4(::Int64, ::Bool, ::Int64, ::Function, ::MechanismVisualizer{MechanismState{Float64,Float64,Float64,TypeSortedCollections.TypeSortedCollection{Tuple{Array{Joint{Float64,Revolute{Float64}},1}},1}},MeshCat.Visualizer}, ::Array{Float64,1}, ::Array{SegmentedVector{JointID,Float64,Base.OneTo{JointID},Array{Float64,1}},1}) at animate.jl:46\n", + "└ @ MeshCatMechanisms /home/twan/.julia/packages/MeshCatMechanisms/AHOtT/src/animate.jl:46\n" + ] + } + ], + "source": [ + "#NBSKIP\n", + "ts = collect(range(0, stop=1, length=length(qs)))\n", + "setanimation!(vis, ts, qs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Control\n", + "\n", + "Now let's use the same principle to generate torques and actually control the robot. To make things more interesting, let's get the end of the robot's arm to trace out a circle. " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.0" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "circle_origin = SVector(0., 0.25, 2)\n", + "radius = 0.5\n", + "ω = 1.0 # radians per second at which the point should move in its circle" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "#NBSKIP\n", + "using MeshCat\n", + "using GeometryTypes: Point" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "MeshCat Visualizer with path /meshcat/circle" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#NBSKIP\n", + "\n", + "# Draw the circle in the viewer\n", + "θ = repeat(range(0, stop=2π, length=100), inner=(2,))[2:end]\n", + "cx, cy, cz = circle_origin\n", + "geometry = PointCloud(Point.(cx .+ radius .* sin.(θ), cy, cz .+ 0.5 .* cos.(θ)))\n", + "setobject!(vis[:circle], LineSegments(geometry, LineBasicMaterial()))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "make_circle_controller (generic function with 1 method)" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# This function will take in the parameters of the circle\n", + "# and the target point and return a function we can use\n", + "# as the controller. By wrapping the construction of the \n", + "# controller in this way, we avoid any issues with accessing\n", + "# non-const global variables. \n", + "function make_circle_controller(state::MechanismState,\n", + " body::RigidBody,\n", + " point::Point3D,\n", + " circle_origin::AbstractVector,\n", + " radius,\n", + " ω)\n", + " mechanism = state.mechanism\n", + " world = root_frame(mechanism)\n", + " joint_path = path(mechanism, root_body(mechanism), body)\n", + " Jp = point_jacobian(state, joint_path, transform(state, point, root_frame(mechanism)))\n", + " v̇ = similar(velocity(state))\n", + " \n", + " function controller!(τ, t, state)\n", + " desired = Point3D(world, circle_origin .+ radius .* SVector(sin(t / ω), 0, cos(t / ω)))\n", + " point_in_world = transform_to_root(state, body) * point\n", + " point_jacobian!(Jp, state, joint_path, point_in_world)\n", + " Kp = 200\n", + " Kd = 20\n", + " Δp = desired - point_in_world\n", + " v̇ .= Kp * Array(Jp)' * Δp.v .- 20 .* velocity(state)\n", + " τ .= inverse_dynamics(state, v̇)\n", + " end\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "controller! (generic function with 1 method)" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "controller! = make_circle_controller(state, body, point, circle_origin, radius, ω)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "ts, qs, vs = simulate(state, 10, controller!);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Animate the resulting trajectory:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "#NBSKIP\n", + "setanimation!(vis, ts, qs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can plot the behavior of the controller. The initial state is quite far from the target, so there's some significant overshoot early in the trajectory, but the controller eventually settles into tracking the desired circular path. This controller isn't very well-tuned, and we could certainly do better with a more advanced approach, but this is still a nice demonstration of a very simple control policy. " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Plots.GRBackend()" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#NBSKIP\n", + "using Plots; gr()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "-1.0\n", + "\n", + "\n", + "-0.5\n", + "\n", + "\n", + "0.0\n", + "\n", + "\n", + "0.5\n", + "\n", + "\n", + "1.0\n", + "\n", + "\n", + "1.0\n", + "\n", + "\n", + "1.5\n", + "\n", + "\n", + "2.0\n", + "\n", + "\n", + "2.5\n", + "\n", + "\n", + "3.0\n", + "\n", + "\n", + "\n" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#NBSKIP\n", + "xs = Float64[]\n", + "zs = Float64[]\n", + "for q in qs[1:100:end] # Downsample by 100 just so the plot doesn't become a huge file\n", + " set_configuration!(state, q)\n", + " p = transform(state, point, root_frame(mechanism))\n", + " push!(xs, p.v[1])\n", + " push!(zs, p.v[3])\n", + "end\n", + "\n", + "plot(xs, zs, xlim=(-1, 1), ylim=(1, 3), aspect_ratio=:equal, legend=nothing)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.0.0", + "language": "julia", + "name": "julia-1.0" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.0.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Jacobian IK and Control/Manifest.toml b/notebooks/Jacobian IK and Control/Manifest.toml new file mode 100644 index 00000000..e577966e --- /dev/null +++ b/notebooks/Jacobian IK and Control/Manifest.toml @@ -0,0 +1,150 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/notebooks/Jacobian IK and Control/Project.toml b/notebooks/Jacobian IK and Control/Project.toml new file mode 100644 index 00000000..dbd4d67d --- /dev/null +++ b/notebooks/Jacobian IK and Control/Project.toml @@ -0,0 +1,2 @@ +[deps] +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/Jacobian IK and Control/visualization/Manifest.toml b/notebooks/Jacobian IK and Control/visualization/Manifest.toml new file mode 100644 index 00000000..80d07ff3 --- /dev/null +++ b/notebooks/Jacobian IK and Control/visualization/Manifest.toml @@ -0,0 +1,495 @@ +[[AssetRegistry]] +deps = ["Distributed", "JSON", "Pidfile", "Pkg", "SHA", "Test"] +git-tree-sha1 = "b25e88db7944f98789130d7b503276bc34bc098e" +uuid = "bf4720bc-e11a-5d0c-854e-bdca1663c893" +version = "0.1.0" + +[[AxisAlgorithms]] +deps = ["Compat", "WoodburyMatrices"] +git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "0.3.0" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[Blink]] +deps = ["Base64", "BinDeps", "Distributed", "JSExpr", "JSON", "Lazy", "Libdl", "Logging", "MacroTools", "Mustache", "Mux", "Pkg", "Reexport", "Sockets", "Test", "WebIO", "WebSockets"] +git-tree-sha1 = "74096d749a7d58e2798abfc087fc6a2e36df0a75" +uuid = "ad839575-38b3-5650-b840-f874b8c74a25" +version = "0.8.1" + +[[CSSUtil]] +deps = ["Colors", "Compat", "JSON", "Measures", "Pkg", "WebIO"] +git-tree-sha1 = "ff13fd99e4dd54f56eb064815f843bc992a871a2" +uuid = "70588ee8-6100-5070-97c1-3cb50ed05fe8" +version = "0.1.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random", "Test"] +git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.7.5" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Pkg", "Printf", "Reexport", "Test"] +git-tree-sha1 = "8c89e0a9a583954eae3efcf6a531e51c02b38cee" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.4" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[Contour]] +deps = ["LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.5.1" + +[[CoordinateTransformations]] +deps = ["Compat", "Rotations", "StaticArrays"] +git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.5.0" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections", "REPL", "Random", "Serialization", "Test"] +git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.14.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[FileIO]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "481e4db939f005db39f7296599d0543c0744fe30" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.0.2" + +[[FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[FixedPointNumbers]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[FunctionalCollections]] +deps = ["Test"] +git-tree-sha1 = "9fdecc849480c511d7825570c20c9b64c4e5d5ed" +uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca" +version = "0.4.0" + +[[GR]] +deps = ["Base64", "DelimitedFiles", "Pkg", "Random", "Serialization", "Sockets", "Test"] +git-tree-sha1 = "0437921cbf8ee555ab7a2a3115c1d0907289e816" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.34.1" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "Pkg", "StaticArrays", "Test"] +git-tree-sha1 = "765f6d4039ba2dd37b2936235012502aafbe8bfb" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.6.2" + +[[HTTP]] +deps = ["Base64", "Dates", "Distributed", "IniFile", "MbedTLS", "Sockets", "Test"] +git-tree-sha1 = "8a0f75e8b09df01d9f1ba9ad3fbf8b4983595d20" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "0.6.14" + +[[Hiccup]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "6187bb2d5fcbb2007c39e7ac53308b0d371124bd" +uuid = "9fb69e20-1954-56bb-a84f-559cc56a8ff7" +version = "0.2.2" + +[[IniFile]] +deps = ["Test"] +git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8" +uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f" +version = "0.5.0" + +[[InteractBase]] +deps = ["Base64", "CSSUtil", "Colors", "DataStructures", "Dates", "JSExpr", "JSON", "Knockout", "Observables", "Pkg", "Random", "Test", "WebIO", "Widgets"] +git-tree-sha1 = "494156a2e3fb192210bd8404da8de1d423d48bb1" +uuid = "d3863d7c-f0c8-5437-a7b4-3ae773c01009" +version = "0.8.1" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Interpolations]] +deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] +git-tree-sha1 = "56691033f157dd1ee1d2aa042114caeefefa897b" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.10.5" + +[[IterTools]] +deps = ["Pkg", "SparseArrays", "Test"] +git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.1.1" + +[[JSExpr]] +deps = ["JSON", "MacroTools", "Observables", "Pkg", "Test", "WebIO"] +git-tree-sha1 = "e08b116ced6b7dd45cc7c2708864dc7e96727a9f" +uuid = "97c1335a-c9c5-57fe-bc5d-ec35cebe8660" +version = "0.3.1" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Pkg", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "fec8e4d433072731466d37ed0061b3ba7f70eeb9" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.19.0" + +[[Knockout]] +deps = ["JSExpr", "JSON", "Observables", "Pkg", "Test", "WebIO"] +git-tree-sha1 = "63e5e0bd2e9923191c30bb1e3d6e4d579155ddfa" +uuid = "bcebb21b-c2e3-54f8-a781-646b90f6d2cc" +version = "0.2.0" + +[[Lazy]] +deps = ["Compat", "MacroTools", "Test"] +git-tree-sha1 = "1c2c5566f0eeaaad6979c156562384458f966e6a" +uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" +version = "0.13.1" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[MbedTLS]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Random", "Sockets", "Test"] +git-tree-sha1 = "4b890362c0c2fdb14a575ce927f1f4eeac6dda9f" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "0.6.4" + +[[Measures]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "ddfd6d13e330beacdde2c80de27c1c671945e7d9" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.0" + +[[MechanismGeometries]] +deps = ["ColorTypes", "Compat", "CoordinateTransformations", "FileIO", "GeometryTypes", "LightXML", "MeshIO", "Pkg", "RigidBodyDynamics", "Rotations", "StaticArrays"] +git-tree-sha1 = "5191190f3bb652cc65297ec8122297172c6e3c80" +uuid = "931e9471-e8fb-5385-a477-07ad12718aca" +version = "0.1.1" + +[[MeshCat]] +deps = ["AssetRegistry", "BinDeps", "Colors", "Compat", "CoordinateTransformations", "DocStringExtensions", "GeometryTypes", "JSExpr", "JSON", "Libdl", "MsgPack", "Mux", "Parameters", "Pkg", "Requires", "Rotations", "StaticArrays", "WebIO"] +git-tree-sha1 = "cc9d6d14c1c7d58c56d8cf7c5c1451a5c1180660" +uuid = "283c5d60-a78f-5afe-a0af-af636b173e11" +version = "0.3.0" + +[[MeshCatMechanisms]] +deps = ["ColorTypes", "CoordinateTransformations", "DataStructures", "GeometryTypes", "InteractBase", "Interpolations", "LoopThrottle", "MechanismGeometries", "MeshCat", "Pkg", "Random", "RigidBodyDynamics", "Test"] +git-tree-sha1 = "0d700662e1aecf610cff2f6de619d5eec27b61ff" +uuid = "6ad125db-dd91-5488-b820-c1df6aab299d" +version = "0.2.0" + +[[MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] +git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.3.1" + +[[Missings]] +deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] +git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "0.3.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[MsgPack]] +deps = ["Compat", "Random", "Test"] +git-tree-sha1 = "c44b3470fa98705f9c12cb44ec9504de3af027ad" +uuid = "99f44e22-a591-53d1-9472-aa23ef4bd671" +version = "0.2.0" + +[[Mustache]] +deps = ["Pkg", "Tables", "Test"] +git-tree-sha1 = "1cee2f530502aa2357724e7b19af3239b2e7f6b7" +uuid = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" +version = "0.5.5" + +[[Mux]] +deps = ["AssetRegistry", "Base64", "HTTP", "Hiccup", "Lazy", "Pkg", "Sockets", "Test", "WebSockets"] +git-tree-sha1 = "487feb060cdd5cc152ef4f75b3cb565c0dc4300a" +uuid = "a975b10e-0019-58db-a62f-e48ff68538c9" +version = "0.5.3" + +[[NaNMath]] +deps = ["Compat"] +git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.2" + +[[Observables]] +deps = ["Test"] +git-tree-sha1 = "752ef9b9ff1a7a6d764aee6be60cf0a5be7a21b1" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.2.2" + +[[OffsetArrays]] +deps = ["DelimitedFiles", "Test"] +git-tree-sha1 = "f8cd140824f74f2948ff8660bc2292e16d29c1b7" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "0.8.1" + +[[OrderedCollections]] +deps = ["Pkg", "Random", "Serialization", "Test"] +git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.0.2" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "Pkg", "REPL", "Test"] +git-tree-sha1 = "40f540ec96e50c0b2b9efdb11b5e4d0c63f90923" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.1" + +[[Pidfile]] +deps = ["FileWatching", "Pkg", "Test"] +git-tree-sha1 = "1ffd82728498b5071cde851bbb7abd780d4445f3" +uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" +version = "1.1.0" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[PlotThemes]] +deps = ["PlotUtils", "Requires", "Test"] +git-tree-sha1 = "f3afd2d58e1f6ac9be2cea46e4a9083ccc1d990b" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "0.3.0" + +[[PlotUtils]] +deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] +git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "0.5.5" + +[[Plots]] +deps = ["Base64", "Contour", "Dates", "FixedPointNumbers", "GR", "JSON", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "Printf", "Random", "RecipesBase", "Reexport", "Requires", "Showoff", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "Test", "UUIDs"] +git-tree-sha1 = "83f387a4989ab60dfb0bb3f52f3907a14acc1588" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "0.20.6" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Ratios]] +deps = ["Compat"] +git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.3.0" + +[[RecipesBase]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "0.6.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Requires]] +deps = ["Test"] +git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "0.5.2" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Showoff]] +deps = ["Compat", "Pkg"] +git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "0.2.1" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SortingAlgorithms]] +deps = ["DataStructures", "Random", "Test"] +git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "0.3.1" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[StatsBase]] +deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "723193a13e8078cec6dcd0b8fe245c8bfd81690e" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.25.0" + +[[Tables]] +deps = ["Pkg", "Requires", "Test"] +git-tree-sha1 = "7b7e95a34c2c2504f1403aa9005399e239f461b9" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "0.1.9" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[WebIO]] +deps = ["AssetRegistry", "Base64", "Compat", "Dates", "FunctionalCollections", "JSON", "Logging", "Observables", "Pkg", "Random", "Requires", "Sockets", "Test", "UUIDs", "Widgets"] +git-tree-sha1 = "1f70c8c7c30fd6cf95fd5d517e59a5327505a043" +uuid = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" +version = "0.4.0" + +[[WebSockets]] +deps = ["Base64", "Dates", "Distributed", "HTTP", "MbedTLS", "Pkg", "Random", "Sockets", "Test"] +git-tree-sha1 = "f23986a5f20ed2ed68b462e0fdec20d6a4468757" +uuid = "104b5d7c-a370-577a-8038-80a2059c5097" +version = "1.0.3" + +[[Widgets]] +deps = ["DataStructures", "Observables", "Pkg", "Test"] +git-tree-sha1 = "944c2f6c3b92b0689e5f46988536bee26bba4d8a" +uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" +version = "0.4.3" + +[[WoodburyMatrices]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.4.1" diff --git a/notebooks/Jacobian IK and Control/visualization/Project.toml b/notebooks/Jacobian IK and Control/visualization/Project.toml new file mode 100644 index 00000000..3629bfae --- /dev/null +++ b/notebooks/Jacobian IK and Control/visualization/Project.toml @@ -0,0 +1,8 @@ +[deps] +Blink = "ad839575-38b3-5650-b840-f874b8c74a25" +GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +MeshCat = "283c5d60-a78f-5afe-a0af-af636b173e11" +MeshCatMechanisms = "6ad125db-dd91-5488-b820-c1df6aab299d" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/Quickstart - double pendulum/Manifest.toml b/notebooks/Quickstart - double pendulum/Manifest.toml new file mode 100644 index 00000000..e577966e --- /dev/null +++ b/notebooks/Quickstart - double pendulum/Manifest.toml @@ -0,0 +1,150 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/notebooks/Quickstart - double pendulum/Project.toml b/notebooks/Quickstart - double pendulum/Project.toml new file mode 100644 index 00000000..dbd4d67d --- /dev/null +++ b/notebooks/Quickstart - double pendulum/Project.toml @@ -0,0 +1,2 @@ +[deps] +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/Quickstart - double pendulum.ipynb b/notebooks/Quickstart - double pendulum/Quickstart - double pendulum.ipynb similarity index 90% rename from notebooks/Quickstart - double pendulum.ipynb rename to notebooks/Quickstart - double pendulum/Quickstart - double pendulum.ipynb index 36c174ca..5a57f114 100644 --- a/notebooks/Quickstart - double pendulum.ipynb +++ b/notebooks/Quickstart - double pendulum/Quickstart - double pendulum.ipynb @@ -18,6 +18,28 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n", + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n", + "\u001b[?25l\u001b[2K\u001b[?25h\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n" + ] + } + ], + "source": [ + "using Pkg\n", + "Pkg.activate(@__DIR__);\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, "outputs": [], "source": [ "using RigidBodyDynamics\n", @@ -38,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -49,7 +71,7 @@ "No non-tree joints." ] }, - "execution_count": 2, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -71,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -84,7 +106,7 @@ "[0.0 0.0 0.0; 0.0 0.333 0.0; 0.0 0.0 0.0]" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -114,7 +136,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -123,7 +145,7 @@ "RigidBody: \"upper_link\"" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -141,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -150,7 +172,7 @@ "Joint \"shoulder\": Revolute joint with axis [0.0, 1.0, 0.0]" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -168,7 +190,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -178,7 +200,7 @@ "rotation: 0.0 rad about [1.0, 0.0, 0.0], translation: [0.0, 0.0, 0.0]" ] }, - "execution_count": 6, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -196,7 +218,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -208,7 +230,7 @@ "No non-tree joints." ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -233,7 +255,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -246,7 +268,7 @@ "No non-tree joints." ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -279,7 +301,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -287,20 +309,19 @@ "text/plain": [ "Spanning tree:\n", "Vertex: world (root)\n", - " Vertex: base_link, Edge: base_link_to_world\n", - " Vertex: upper_link, Edge: shoulder\n", - " Vertex: lower_link, Edge: elbow\n", + " Vertex: upper_link, Edge: shoulder\n", + " Vertex: lower_link, Edge: elbow\n", "No non-tree joints." ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "filename = \"../test/urdf/Acrobot.urdf\"\n", - "parse_urdf(filename)" + "urdf = joinpath(dirname(pathof(RigidBodyDynamics)), \"..\", \"test\", \"urdf\", \"Acrobot.urdf\")\n", + "parse_urdf(urdf)" ] }, { @@ -319,7 +340,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -328,7 +349,7 @@ "MechanismState{Float64, Float64, Float64, …}(…)" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -346,7 +367,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -365,20 +386,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "true" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "setdirty!(state)" ] @@ -392,18 +402,18 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "2-element RigidBodyDynamics.CustomCollections.SegmentedVector{RigidBodyDynamics.JointID,Float64,Base.OneTo{RigidBodyDynamics.JointID},Array{Float64,1}}:\n", + "2-element SegmentedVector{JointID,Float64,Base.OneTo{JointID},Array{Float64,1}}:\n", " 0.3\n", " 0.4" ] }, - "execution_count": 13, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -414,18 +424,18 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "2-element RigidBodyDynamics.CustomCollections.SegmentedVector{RigidBodyDynamics.JointID,Float64,Base.OneTo{RigidBodyDynamics.JointID},Array{Float64,1}}:\n", + "2-element SegmentedVector{JointID,Float64,Base.OneTo{JointID},Array{Float64,1}}:\n", " 1.0\n", " 2.0" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -450,7 +460,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -459,7 +469,7 @@ "Point3D in \"world\": [-0.29552, 0.0, -0.955336]" ] }, - "execution_count": 15, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -484,17 +494,17 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Transform3D from \"after_elbow\" to \"world\":\n", - "rotation: 0.7000000000000001 rad about [0.0, 1.0, 0.0], translation: [-0.29552, 0.0, -0.955336]" + "rotation: 0.7000000000000001 rad about [7.08918e-63, 1.0, 0.0], translation: [-0.29552, 0.0, -0.955336]" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -512,17 +522,17 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Transform3D from \"after_elbow\" to \"after_shoulder\":\n", - "rotation: 0.39999999999999997 rad about [0.0, 1.0, 0.0], translation: [0.0, 0.0, -1.0]" + "rotation: 0.39999999999999997 rad about [1.22357e-62, 1.0, 0.0], translation: [0.0, 0.0, -1.0]" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -540,7 +550,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -549,7 +559,7 @@ "Point3D in \"world\": [-0.382695, 0.0, -0.907713]" ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -574,7 +584,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -585,7 +595,7 @@ " 0.79353 0.333 " ] }, - "execution_count": 19, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -610,18 +620,18 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "2-element RigidBodyDynamics.CustomCollections.SegmentedVector{RigidBodyDynamics.JointID,Float64,Base.OneTo{RigidBodyDynamics.JointID},Array{Float64,1}}:\n", - " 10.1249 \n", - " 4.81413" + "2-element SegmentedVector{JointID,Float64,Base.OneTo{JointID},Array{Float64,1}}:\n", + " 10.124916215693656\n", + " 4.814127424056646" ] }, - "execution_count": 20, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -649,7 +659,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -660,7 +670,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "`simulate` returns a vector of times (`ts`) and associated joint configurations (`qs`) and velocities (`vs`). You can of course plot the trajectories using your favorite plotting package (see e.g. [Plots.jl](https://github.com/JuliaPlots/Plots.jl)). The [RigidBodyTreeInspector](https://github.com/rdeits/RigidBodyTreeInspector.jl) package can also be used for 3D animation of the double pendulum in action." + "`simulate` returns a vector of times (`ts`) and associated joint configurations (`qs`) and velocities (`vs`). You can of course plot the trajectories using your favorite plotting package (see e.g. [Plots.jl](https://github.com/JuliaPlots/Plots.jl)). The [MeshCatMechanisms](https://github.com/JuliaRobotics/MeshCatMechanisms.jl) or [RigidBodyTreeInspector](https://github.com/rdeits/RigidBodyTreeInspector.jl) packages can also be used for 3D animation of the double pendulum in action." ] }, { diff --git a/notebooks/Rigorous error bounds using IntervalArithmetic/Manifest.toml b/notebooks/Rigorous error bounds using IntervalArithmetic/Manifest.toml new file mode 100644 index 00000000..862f6589 --- /dev/null +++ b/notebooks/Rigorous error bounds using IntervalArithmetic/Manifest.toml @@ -0,0 +1,186 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[CRlibm]] +deps = ["Libdl", "Test"] +git-tree-sha1 = "8ed645bb81cf6bb24e0dec6431ec5a0db1d6d005" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "0.7.0" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[ErrorfreeArithmetic]] +deps = ["Test"] +git-tree-sha1 = "071677938ef6e8f2a51ec0fedf5c312af88e26dc" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.2.1" + +[[FastRounding]] +deps = ["ErrorfreeArithmetic", "Pkg", "Test"] +git-tree-sha1 = "224175e213fd4fe112db3eea05d66b308dc2bf6b" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.2.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Pkg", "RecipesBase", "SetRounding", "StaticArrays", "Test"] +git-tree-sha1 = "9ce05b28f218d833aedbed0a53ca35948275f336" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.15.0" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[RecipesBase]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "0.6.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SetRounding]] +deps = ["Test"] +git-tree-sha1 = "faca28c7937138d560ede5bfef2076d0cdf3584b" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.0" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/notebooks/Rigorous error bounds using IntervalArithmetic/Project.toml b/notebooks/Rigorous error bounds using IntervalArithmetic/Project.toml new file mode 100644 index 00000000..4f5e21e2 --- /dev/null +++ b/notebooks/Rigorous error bounds using IntervalArithmetic/Project.toml @@ -0,0 +1,3 @@ +[deps] +IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" diff --git a/notebooks/Rigorous error bounds using IntervalArithmetic.ipynb b/notebooks/Rigorous error bounds using IntervalArithmetic/Rigorous error bounds using IntervalArithmetic.ipynb similarity index 86% rename from notebooks/Rigorous error bounds using IntervalArithmetic.ipynb rename to notebooks/Rigorous error bounds using IntervalArithmetic/Rigorous error bounds using IntervalArithmetic.ipynb index 5aa66f4b..05a5dc90 100644 --- a/notebooks/Rigorous error bounds using IntervalArithmetic.ipynb +++ b/notebooks/Rigorous error bounds using IntervalArithmetic/Rigorous error bounds using IntervalArithmetic.ipynb @@ -7,6 +7,37 @@ "# Floating-point error" ] }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n", + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n", + "\u001b[?25l\u001b[2K\u001b[?25h\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n", + "\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m IntervalArithmetic\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "┌ Info: Precompiling IntervalArithmetic [d1acc4aa-44c8-5952-acd4-ba5d80a2a253]\n", + "└ @ Base loading.jl:1186\n" + ] + } + ], + "source": [ + "using Pkg\n", + "Pkg.activate(@__DIR__)\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -16,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -25,7 +56,7 @@ "2.220446049250313e-16" ] }, - "execution_count": 1, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -43,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -59,7 +90,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -68,7 +99,7 @@ "[1, 2]" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -79,14 +110,14 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "IntervalArithmetic.Interval{Float64}\n", + "Interval{Float64}\n", " lo: Float64 1.0\n", " hi: Float64 2.0\n" ] @@ -105,7 +136,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -114,7 +145,7 @@ "[2, 4]" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -125,7 +156,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -134,7 +165,7 @@ "[0.84147, 1]" ] }, - "execution_count": 6, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -152,7 +183,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -160,7 +191,7 @@ "output_type": "stream", "text": [ "i.lo === i.hi = false\n", - "IntervalArithmetic.Interval{Float64}\n", + "Interval{Float64}\n", " lo: Float64 2.9\n", " hi: Float64 2.9000000000000004\n" ] @@ -181,7 +212,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -189,7 +220,7 @@ "output_type": "stream", "text": [ "i.lo === i.hi = true\n", - "IntervalArithmetic.Interval{Float64}\n", + "Interval{Float64}\n", " lo: Float64 2.9\n", " hi: Float64 2.9\n" ] @@ -210,7 +241,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -219,7 +250,7 @@ "[-6.66134e-16, 2.22045e-16]" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -237,16 +268,16 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\u001b[1m\u001b[32mTest Passed\u001b[39m\u001b[22m" + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -272,7 +303,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -288,16 +319,16 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "MechanismState{IntervalArithmetic.Interval{Float64}, IntervalArithmetic.Interval{Float64}, IntervalArithmetic.Interval{Float64}, …}(…)" + "MechanismState{Interval{Float64}, Interval{Float64}, Interval{Float64}, …}(…)" ] }, - "execution_count": 12, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -317,7 +348,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -335,18 +366,18 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "2×2 Symmetric{IntervalArithmetic.Interval{Float64},Array{IntervalArithmetic.Interval{Float64},2}}:\n", + "2×2 LinearAlgebra.Symmetric{Interval{Float64},Array{Interval{Float64},2}}:\n", " [1.8307, 1.83071] [0.913853, 0.913854]\n", " [0.913853, 0.913854] [1.32999, 1.33001] " ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -364,7 +395,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -375,7 +406,7 @@ " 5.10703e-15 6.66134e-15" ] }, - "execution_count": 15, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -386,16 +417,16 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\u001b[1m\u001b[32mTest Passed\u001b[39m\u001b[22m" + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -420,7 +451,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -437,16 +468,16 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Point3D in \"world\": IntervalArithmetic.Interval{Float64}[[-0.770193, -0.630851], [0.199999, 0.200001], [0.0167304, 0.163822]]" + "Point3D in \"\": Interval{Float64}[[-0.770193, -0.630851], [0.199999, 0.200001], [0.0167304, 0.163822]]" ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/Simulation and visualization with a controller in the loop.ipynb b/notebooks/Simulation and visualization with a controller in the loop.ipynb deleted file mode 100644 index d9e7eb0b..00000000 --- a/notebooks/Simulation and visualization with a controller in the loop.ipynb +++ /dev/null @@ -1,385 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "using RigidBodyDynamics" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Please note that [RigidBodySim.jl](https://github.com/JuliaRobotics/RigidBodySim.jl) now provides a more capable simulation environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Model definition" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll just use the double pendulum model, loaded from a URDF:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Spanning tree:\n", - "Vertex: world (root)\n", - " Vertex: upper_link, Edge: shoulder\n", - " Vertex: lower_link, Edge: elbow\n", - "No non-tree joints." - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "urdf = joinpath(dirname(pathof(RigidBodyDynamics)), \"..\", \"test\", \"urdf\", \"Acrobot.urdf\")\n", - "mechanism = parse_urdf(urdf)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Controller" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's write a simple controller that just applies $10 \\sin(t)$ at the elbow joint and adds some damping at the shoulder joint:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "simple_control! (generic function with 1 method)" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "shoulder, elbow = joints(mechanism)\n", - "function simple_control!(torques::AbstractVector, t, state::MechanismState)\n", - " torques[velocity_range(state, shoulder)] .= -1 .* velocity(state, shoulder)\n", - " torques[velocity_range(state, elbow)] .= 10 * sin(t)\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Simulation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Basic simulation can be done using the `simulate` function. We'll first create a `MechanismState` object, and set the initial joint configurations and velocities:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "state = MechanismState(mechanism)\n", - "zero_velocity!(state)\n", - "set_configuration!(state, shoulder, 0.7)\n", - "set_configuration!(state, elbow, -0.8);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can simply call `simulate`, which will return a tuple consisting of:\n", - "* simulation times (a `Vector` of numbers)\n", - "* joint configuration vectors (a `Vector` of `Vector`s)\n", - "* joint velocity vectors (a `Vector` of `Vector`s)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "final_time = 10.\n", - "ts, qs, vs = simulate(state, final_time, simple_control!; Δt = 1e-3);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For access to lower-level functionality, such as different ways of storing or visualizing the data generated during the simulation, it is advised to simply pattern match the basic `simulate` function." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Visualization" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For visualization, we'll use [`RigidBodyTreeInspector`](https://github.com/rdeits/RigidBodyTreeInspector.jl).\n", - "\n", - "(Note: the `#NBSKIP` comments are to skip these cells during `Pkg.test(\"RigidBodyDynamics\")`)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - " \n", - " \n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[1m\u001b[36mINFO: \u001b[39m\u001b[22m\u001b[36mInteract.jl: using new nbwidgetsextension protocol\n", - "\u001b[39m" - ] - } - ], - "source": [ - "#NBSKIP\n", - "using RigidBodyTreeInspector" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Open the viewer application if it isn't open already:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "#NBSKIP\n", - "DrakeVisualizer.any_open_windows() || (DrakeVisualizer.new_window(); sleep(1));" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Load the mechanism's geometry into the visualizer:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-03-21 00:54:37.807 drake-visualizer[40350:6483186] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead. \n" - ] - } - ], - "source": [ - "#NBSKIP\n", - "geometries = visual_elements(mechanism, URDFVisuals(urdf))\n", - "vis = Visualizer(mechanism, geometries);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And animate:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "#NBSKIP\n", - "RigidBodyTreeInspector.animate(vis, mechanism, ts, qs; realtimerate = 1.);" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Julia 1.0.0", - "language": "julia", - "name": "julia-1.0" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/Symbolic double pendulum/Manifest.toml b/notebooks/Symbolic double pendulum/Manifest.toml new file mode 100644 index 00000000..c67a7d85 --- /dev/null +++ b/notebooks/Symbolic double pendulum/Manifest.toml @@ -0,0 +1,211 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "9930c1a6cd49d9fcd7218df6be417e6ae4f1468a" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.2" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2d9e14d19bad3f9ad5cc5e4cffabc3cfa59de825" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.3.0" + +[[Conda]] +deps = ["Compat", "JSON", "VersionParsing"] +git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" +uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" +version = "1.1.1" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Pkg", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "fec8e4d433072731466d37ed0061b3ba7f70eeb9" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.19.0" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LightXML]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "aeec7a341652d47bc773475a42952fa78eccd7cc" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.8.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LoopThrottle]] +deps = ["Compat"] +git-tree-sha1 = "90a056cc8261d47828b5ee05b3a166d691660628" +uuid = "39f5be34-8529-5463-bac7-bf6867c840a3" +version = "0.0.3" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[PyCall]] +deps = ["Compat", "Conda", "MacroTools", "Statistics", "VersionParsing"] +git-tree-sha1 = "ce4681263f41d98b3faf6107b28284bf8b866f5f" +uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" +version = "1.18.5" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[RecipesBase]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "0.6.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[RigidBodyDynamics]] +deps = ["DocStringExtensions", "LightXML", "LinearAlgebra", "LoopThrottle", "Profile", "Random", "Reexport", "Rotations", "SparseArrays", "StaticArrays", "Test", "TypeSortedCollections"] +path = "../.." +uuid = "366cf18f-59d5-5db9-a4de-86a9f6786172" +version = "1.0.2+" + +[[Rotations]] +deps = ["LinearAlgebra", "Pkg", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "c35c9c76008babf4d658060fc64aeb369a41e7bd" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "0.7.1" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "d432c79bef174a830304f8601427a4357dfdbfb7" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.8.3" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[SymPy]] +deps = ["LinearAlgebra", "Pkg", "PyCall", "RecipesBase", "SpecialFunctions", "Test"] +git-tree-sha1 = "340900f24c2db3cef3122b6d96466be48b8f980e" +pinned = true +uuid = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" +version = "0.8.0" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TypeSortedCollections]] +deps = ["Pkg", "Test"] +git-tree-sha1 = "bc360a93d6f2f45e1313875964853f745890f143" +uuid = "94a5cd58-49a0-5741-bd07-fa4f4be8babf" +version = "1.0.0" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[VersionParsing]] +deps = ["Compat"] +git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.1.3" diff --git a/notebooks/Symbolic double pendulum/Project.toml b/notebooks/Symbolic double pendulum/Project.toml new file mode 100644 index 00000000..ea02cb3e --- /dev/null +++ b/notebooks/Symbolic double pendulum/Project.toml @@ -0,0 +1,4 @@ +[deps] +RigidBodyDynamics = "366cf18f-59d5-5db9-a4de-86a9f6786172" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" diff --git a/notebooks/Symbolic double pendulum.ipynb b/notebooks/Symbolic double pendulum/Symbolic double pendulum.ipynb similarity index 74% rename from notebooks/Symbolic double pendulum.ipynb rename to notebooks/Symbolic double pendulum/Symbolic double pendulum.ipynb index 87bc770e..24d20793 100644 --- a/notebooks/Symbolic double pendulum.ipynb +++ b/notebooks/Symbolic double pendulum/Symbolic double pendulum.ipynb @@ -11,6 +11,28 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n", + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n", + "\u001b[?25l\u001b[2K\u001b[?25h\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n" + ] + } + ], + "source": [ + "using Pkg\n", + "Pkg.activate(@__DIR__)\n", + "pkg\"instantiate\"\n", + "pkg\"precompile\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, "outputs": [], "source": [ "using RigidBodyDynamics\n", @@ -32,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -41,11 +63,11 @@ "\\begin{bmatrix}m_{1}&m_{2}&I_{1}&I_{2}&l_{1}&l_{2}&c_{1}&c_{2}&g\\end{bmatrix}" ], "text/plain": [ - "1×9 RowVector{SymPy.Sym,Array{SymPy.Sym,1}}:\n", + "1×9 LinearAlgebra.Transpose{Sym,Array{Sym,1}}:\n", " m_1 m_2 I_1 I_2 l_1 l_2 c_1 c_2 g" ] }, - "execution_count": 2, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -69,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -82,7 +104,7 @@ "No non-tree joints." ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -94,14 +116,14 @@ "world = root_body(double_pendulum) # the fixed 'world' rigid body\n", "\n", "# Attach the first (upper) link to the world via a revolute joint named 'shoulder'\n", - "inertia1 = SpatialInertia(CartesianFrame3D(\"upper_link\"), I_1 * axis * axis', m_1 * SVector(zero(T), zero(T), c_1), m_1)\n", + "inertia1 = SpatialInertia(CartesianFrame3D(\"upper_link\"), I_1 * axis * transpose(axis), m_1 * SVector(zero(T), zero(T), c_1), m_1)\n", "body1 = RigidBody(inertia1)\n", "joint1 = Joint(\"shoulder\", Revolute(axis))\n", - "joint1_to_world = one(Transform3D{T}, frame_before(joint1), default_frame(world))\n", - "attach!(double_pendulum, world, body1, joint1, joint_pose = joint1_to_world)\n", + "joint1_to_world = one(Transform3D{T}, frame_before(joint1), default_frame(world));\n", + "attach!(double_pendulum, world, body1, joint1, joint_pose = joint1_to_world);\n", "\n", "# Attach the second (lower) link to the world via a revolute joint named 'elbow'\n", - "inertia2 = SpatialInertia(CartesianFrame3D(\"lower_link\"), I_2 * axis * axis', m_2 * SVector(zero(T), zero(T), c_2), m_2)\n", + "inertia2 = SpatialInertia(CartesianFrame3D(\"lower_link\"), I_2 * axis * transpose(axis), m_2 * SVector(zero(T), zero(T), c_2), m_2)\n", "body2 = RigidBody(inertia2)\n", "joint2 = Joint(\"elbow\", Revolute(axis))\n", "joint2_to_body1 = Transform3D(frame_before(joint2), default_frame(body1), SVector(zero(T), zero(T), l_1))\n", @@ -119,7 +141,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -128,54 +150,28 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "\\begin{bmatrix}q_{1}\\\\q_{2}\\end{bmatrix}" - ], - "text/plain": [ - "2-element Array{SymPy.Sym,1}:\n", - " q_1\n", - " q_2" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Set the joint configuration vector of the MechanismState to a new vector of symbolic variables\n", - "configuration(x) .= [symbols(\"q_$i\", real = true) for i = 1 : num_positions(x)]" + "q = configuration(x)\n", + "for i in eachindex(q)\n", + " q[i] = symbols(\"q_$i\", real = true)\n", + "end" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "\\begin{bmatrix}v_{1}\\\\v_{2}\\end{bmatrix}" - ], - "text/plain": [ - "2-element Array{SymPy.Sym,1}:\n", - " v_1\n", - " v_2" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Set the joint velocity vector of the MechanismState to a new vector of symbolic variables\n", - "velocity(x) .= [symbols(\"v_$i\", real = true) for i = 1 : num_positions(x)]" + "v = velocity(x)\n", + "for i in eachindex(v)\n", + " v[i] = symbols(\"v_$i\", real = true)\n", + "end" ] }, { @@ -187,7 +183,16 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "Base.sincos(x::Sym) = (sin(x), cos(x)) # FIXME: https://github.com/JuliaPy/SymPy.jl/issues/245" + ] + }, + { + "cell_type": "code", + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -196,12 +201,12 @@ "\\begin{bmatrix}I_{1} + I_{2} + 2 c_{2} l_{1} m_{2} \\cos{\\left (q_{2} \\right )} + l_{1}^{2} m_{2}&I_{2} + c_{2} l_{1} m_{2} \\cos{\\left (q_{2} \\right )}\\\\I_{2} + c_{2} l_{1} m_{2} \\cos{\\left (q_{2} \\right )}&I_{2}\\end{bmatrix}" ], "text/plain": [ - "2×2 Symmetric{SymPy.Sym,Array{SymPy.Sym,2}}:\n", + "2×2 LinearAlgebra.Symmetric{Sym,Array{Sym,2}}:\n", " I_1 + I_2 + 2*c_2*l_1*m_2*cos(q_2) + l_1^2*m_2 I_2 + c_2*l_1*m_2*cos(q_2)\n", " I_2 + c_2*l_1*m_2*cos(q_2) I_2" ] }, - "execution_count": 7, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -215,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": { "scrolled": false }, @@ -223,21 +228,21 @@ { "data": { "text/latex": [ - "$$\\frac{I_{1} v_{1}^{2}}{2} + \\frac{I_{2} v_{1}^{2}}{2} + I_{2} v_{1} v_{2} + \\frac{I_{2} v_{2}^{2}}{2} + c_{2} l_{1} m_{2} v_{1}^{2} \\cos{\\left (q_{2} \\right )} + c_{2} l_{1} m_{2} v_{1} v_{2} \\cos{\\left (q_{2} \\right )} + \\frac{l_{1}^{2} m_{2}}{2} v_{1}^{2}$$" + "$$\\frac{I_{1} v_{1}^{2}}{2} + \\frac{I_{2} v_{1}^{2}}{2} + I_{2} v_{1} v_{2} + \\frac{I_{2} v_{2}^{2}}{2} + c_{2} l_{1} m_{2} v_{1}^{2} \\cos{\\left (q_{2} \\right )} + c_{2} l_{1} m_{2} v_{1} v_{2} \\cos{\\left (q_{2} \\right )} + \\frac{l_{1}^{2} m_{2} v_{1}^{2}}{2}$$" ], "text/plain": [ - " 2 2 2 \n", - "I_1*v_1 I_2*v_1 I_2*v_2 2 \n", - "-------- + -------- + I_2*v_1*v_2 + -------- + c_2*l_1*m_2*v_1 *cos(q_2) + c_2\n", - " 2 2 2 \n", + " 2 2 2 \n", + "I₁⋅v₁ I₂⋅v₁ I₂⋅v₂ 2 \n", + "────── + ────── + I₂⋅v₁⋅v₂ + ────── + c₂⋅l₁⋅m₂⋅v₁ ⋅cos(q₂) + c₂⋅l₁⋅m₂⋅v₁⋅v₂⋅co\n", + " 2 2 2 \n", "\n", - " 2 2\n", - " l_1 *m_2*v_1 \n", - "*l_1*m_2*v_1*v_2*cos(q_2) + -------------\n", - " 2 " + " 2 2\n", + " l₁ ⋅m₂⋅v₁ \n", + "s(q₂) + ──────────\n", + " 2 " ] }, - "execution_count": 8, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -249,7 +254,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -258,10 +263,10 @@ "$$- g \\left(c_{1} m_{1} \\cos{\\left (q_{1} \\right )} + c_{2} m_{2} \\cos{\\left (q_{1} + q_{2} \\right )} + l_{1} m_{2} \\cos{\\left (q_{1} \\right )}\\right)$$" ], "text/plain": [ - "-g*(c_1*m_1*cos(q_1) + c_2*m_2*cos(q_1 + q_2) + l_1*m_2*cos(q_1))" + "-g⋅(c₁⋅m₁⋅cos(q₁) + c₂⋅m₂⋅cos(q₁ + q₂) + l₁⋅m₂⋅cos(q₁))" ] }, - "execution_count": 9, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -270,6 +275,13 @@ "# Potential energy\n", "simplify(gravitational_potential_energy(x))" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/src/spatial/common.jl b/src/spatial/common.jl index 05229553..14e65d5e 100644 --- a/src/spatial/common.jl +++ b/src/spatial/common.jl @@ -14,7 +14,7 @@ for SpatialVector in (:Twist, :SpatialAcceleration, :Momentum, :Wrench) StaticArrays.SVector{6}(v::$SpatialVector{X}) where {X} = SVector{6, X}(v) StaticArrays.SVector(v::$SpatialVector) = SVector{6}(v) StaticArrays.SArray(v::$SpatialVector) = SVector(v) - Base.convert(::Type{SA}, v::$SpatialVector) where {SA} = SA(v) + Base.convert(::Type{SA}, v::$SpatialVector) where {SA <: SArray} = SA(v) function Base.Array(v::$SpatialVector) Base.depwarn("Array(v) has been deprecated. Please use SVector(v) instead.", :Array) diff --git a/test/test_notebooks.jl b/test/test_notebooks.jl index 88ed5bae..f7236f14 100644 --- a/test/test_notebooks.jl +++ b/test/test_notebooks.jl @@ -1,20 +1,23 @@ -@testset "example notebooks" begin +let notebookdir = joinpath(@__DIR__, "..", "notebooks") - excludes = String[] - push!(excludes, joinpath(notebookdir, "Rigorous error bounds using IntervalArithmetic.ipynb")) - push!(excludes, joinpath(notebookdir, "Symbolic double pendulum.ipynb")) - for file in readdir(notebookdir) - path = joinpath(notebookdir, file) - path in excludes && continue - name, ext = splitext(file) - lowercase(ext) == ".ipynb" || continue - - @eval module $(gensym()) # Each notebook is run in its own module. - using Test - using NBInclude - @testset "$($name)" begin - @nbinclude($path; regex = r"^((?!\#NBSKIP).)*$"s) # Use #NBSKIP in a cell to skip it during tests. + excludedirs = [".ipynb_checkpoints"] + excludefiles = String[] + # push!(excludefiles, "Rigorous error bounds using IntervalArithmetic.ipynb") + for (root, dir, files) in walkdir(notebookdir) + basename(root) in excludedirs && continue + for file in files + file in excludefiles && continue + name, ext = splitext(file) + lowercase(ext) == ".ipynb" || continue + path = joinpath(root, file) + @eval module $(gensym()) # Each notebook is run in its own module. + using Test + using NBInclude + @testset "Notebook: $($name)" begin + # Note: use #NBSKIP in a cell to skip it during tests. + @nbinclude($path; regex = r"^((?!\#NBSKIP).)*$"s) + end + end # module end - end # module end end