Skip to content

Commit

Permalink
Update to julia 1.0 (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
baggepinnen authored Mar 11, 2019
2 parents 7a5df08 + e3706c6 commit 91ff1c8
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 131 deletions.
11 changes: 8 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ os:
- linux
- osx
julia:
- 0.6
- 1.0
- 1.1
- nightly
matrix:
allow_failures:
- julia: nightly
notifications:
email: false
# uncomment the following lines to override the default test script
Expand All @@ -13,6 +18,6 @@ notifications:
# - julia -e 'Pkg.clone(pwd()); Pkg.build("DynamicMovementPrimitives"); Pkg.test("DynamicMovementPrimitives"; coverage=true)'
after_success:
# push coverage results to Coveralls
- julia -e 'cd(Pkg.dir("DynamicMovementPrimitives")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
- julia -e 'using Pkg;import ControlSystems; cd(joinpath(dirname(pathof(DynamicMovementPrimitives)), "..")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
# push coverage results to Codecov
- julia -e 'cd(Pkg.dir("DynamicMovementPrimitives")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
- julia -e 'using Pkg;import ControlSystems; cd(joinpath(dirname(pathof(DynamicMovementPrimitives)), "..")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
39 changes: 13 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# DynamicMovementPrimitives

[![DynamicMovementPrimitives](http://pkg.julialang.org/badges/DynamicMovementPrimitives_0.4.svg)](http://pkg.julialang.org/?pkg=DynamicMovementPrimitives)
[![DynamicMovementPrimitives](http://pkg.julialang.org/badges/DynamicMovementPrimitives_0.5.svg)](http://pkg.julialang.org/?pkg=DynamicMovementPrimitives)
[![DynamicMovementPrimitives](http://pkg.julialang.org/badges/DynamicMovementPrimitives_0.6.svg)](http://pkg.julialang.org/?pkg=DynamicMovementPrimitives)
[![Build Status](https://travis-ci.org/baggepinnen/DynamicMovementPrimitives.jl.svg?branch=master)](https://travis-ci.org/baggepinnen/DynamicMovementPrimitives.jl)

Expand All @@ -10,8 +8,7 @@ Provides implementations of Ijspeert et al. 2013 and of Martin Karlsson, Fredrik
## Installation

```julia
Pkg.add("DynamicMovementPrimitives")
Pkg.checkout("DynamicMovementPrimitives") # Recommended to get the latest version
using Pkg; Pkg.add("DynamicMovementPrimitives")
using DynamicMovementPrimitives
```

Expand All @@ -24,13 +21,13 @@ Nbasis = 15
αx = 1.
opts = DMPopts(Nbasis,αx,αz)

y = [zeros(10);linspace(0,2,1000); 2ones(500)]
y = [zeros(10);LinRange(0,2,1000); 2ones(500)]
T = length(y)
t = linspace(0,10,T)
t = LinRange(0,10,T)
h = t[2]-t[1] # Sample interval
y = [y 0.5y]
= centraldiff(y) /h # Differentiate position to get velocity
= centraldiff(ẏ) /h
= centraldiff(y) ./h # Differentiate position to get velocity
= centraldiff(ẏ) ./h
dmp = fit(y,ẏ,ÿ,t,opts)

tout,yout,ẏout,xout = solve(dmp,t) # Generate trajectory, see ?solve for options
Expand Down Expand Up @@ -59,34 +56,24 @@ plot(dmp2) # Requires Plots.jl, plots the trajectory from solve with default opt
plot(dmp2,true)
```

We test the performance of the 2DOF controller by implementing a custom solver. The solver `euler_disturbance` is the same as the built in solver `euler`, but between `i=500` and `i=700`, we stop the evolution of the physical system by setting `ẏa = 0`.
We test the performance of the 2DOF controller by implementing a solver callback. Between `t=2.5` and `t=4`, we stop the evolution of the physical system by setting `ẏa = 0` through `u[3] = uprev[3]`.
```julia
function euler_disturbance(time_derivative, state0, t, args...; kwargs...)
T = length(t)
n = length(state0)
res = Matrix{Float64}(T,n)
res[1,:] = state0
for i in 2:T
td = time_derivative(t[i-1],res[i-1,:])*(t[i]-t[i-1])
if 400 <= i < 600 # Hold ẏa still
td[3] = 0
end
res[i,:] = res[i-1,:] + td
end
t,res
end
import OrdinaryDiffEq
condition(u,t,integrator) = 2.5 <= t < 4
affect!(integrator) = (integrator.u[3] = integrator.uprev[3])
cb = OrdinaryDiffEq.DiscreteCallback(condition,affect!)
```

We can call the solve method with our custom solver and plot the result. It should be clear from the figures that this time, the coupled signal `yc` slows down when there is a nonzero error.
We can call the solve method with our custom callback and plot the result. It should be clear from the figures that this time, the coupled signal `yc` slows down when there is a nonzero error.
```julia
t,yc,ẏc,x,ya,ẏa,e = solve(dmp2,t, solver=euler_disturbance)
t,yc,ẏc,x,ya,ẏa,e = solve(dmp2,t, solver=OrdinaryDiffEq.Euler(), callback=cb)
plot(t,ẏc, lab="\$ẏ_c\$", c=:red, l=(:dash, 3), layout=(2,2), subplot=1)
plot!(t,yc, lab="\$y_c\$", c=:red, l=(:dash, 3), subplot=2)
plot!(t,ẏa, lab="\$ẏ_a\$", c=:blue, subplot=1)
plot!(t,ya, lab="\$y_a\$", c=:blue, subplot=2)
plot!(t,e, lab="\$e\$", c=:green, subplot=3)
plot!(t,400 .<= 1:T .< 600, lab="Disturbance", c=:green, subplot=4, fillrange=0)
t,yc,ẏc,x,ya,ẏa,e = solve(dmp2,t, solver=euler)
t,yc,ẏc,x,ya,ẏa,e = solve(dmp2,t)
plot!(t,ẏc, lab="\$ẏ_u\$", c=:black, l=(:dashdot, 3), subplot=1)
plot!(t,yc, lab="\$y_u\$", c=:black, l=(:dashdot, 3), subplot=2)
```
Expand Down
4 changes: 2 additions & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
julia 0.6.0
julia 1.0
OrdinaryDiffEq
RecipesBase 0.2.3
Requires
Requires
16 changes: 8 additions & 8 deletions src/DMP2dof.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function _acceleration(d,f, yc,ẏc,x,ya,ẏa,e,g)
ẏc,ÿc,ẏa,ÿa,ė,ẋ
end

function solve_canonical(dmp::DMP2dof, t, y0, g, solver)
function solve_canonical(dmp::DMP2dof, t, y0, g, solver; kwargs...)
T,n = size(dmp.y)
αx = dmp.opts.αx
τ = dmp.τ
Expand Down Expand Up @@ -82,13 +82,13 @@ function solve_canonical(dmp::DMP2dof, t, y0, g, solver)
end
state0 = [y0[i], dmp.ẏ[1,i], y0[i], dmp.ẏ[1,i], 0, 1.]
prob = OrdinaryDiffEq.ODEProblem(time_derivative,state0,(t[1],t[end]))
sol = OrdinaryDiffEq.solve(prob,solver,saveat=t,dt=t[2])
yc[:,i] = sol[1,:]
ẏc[:,i] = sol[2,:]
ya[:,i] = sol[3,:]
ẏa[:,i] = sol[4,:]
e[:,i] = sol[5,:]
x[:] = sol[6,:] # TODO: se till att denna är samma för alla DOF
sol = OrdinaryDiffEq.solve(prob,solver;saveat=t,dt=t[2], kwargs...)
yc[:,i] = sol(t,idxs=1)
ẏc[:,i] = sol(t,idxs=2)
ya[:,i] = sol(t,idxs=3)
ẏa[:,i] = sol(t,idxs=4)
e[:,i] = sol(t,idxs=5)
x[:] = sol(t,idxs=6) # TODO: se till att denna är samma för alla DOF
end
t,yc,ẏc,x,ya,ẏa,e
end
30 changes: 15 additions & 15 deletions src/DynamicMovementPrimitives.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module DynamicMovementPrimitives
using Requires, RecipesBase
using LinearAlgebra, RecipesBase
import OrdinaryDiffEq

export DMP, DMPopts, centraldiff,fit, solve, force, acceleration, solve_canonical, kernel_vector, plotdmp, plotdmpphase, euler
Expand Down Expand Up @@ -113,7 +113,7 @@ function fit(y,ẏ,ÿ,t,opts,g=y[end,:][:])
else # LWR
for j = 1:Nbasis
sTΓ = ξ[:,i].*Ψ[:,j]
w[j,i] = vecdot(sTΓ,ft[:,i])/vecdot(sTΓ,ξ[:,i])
w[j,i] = dot(sTΓ,ft[:,i])/dot(sTΓ,ξ[:,i])
end
end
end
Expand All @@ -124,7 +124,7 @@ function force_single(d::AbstractDMP,x::Number, i)
# ODE Point case
y0 = _1(d)
Ψ = kernel_vector(x, d.c, d.σ2)
f = vecdot(Ψ,d.w[:,i]) * x*(d.g[i]-y0[i])
f = dot(Ψ,d.w[:,i]) * x*(d.g[i]-y0[i])
end

function force_single(d::AbstractDMP,x::Number)
Expand All @@ -145,7 +145,7 @@ function force_multiple(d::AbstractDMP,x::Number, i)
# ODE Point case
y0 = _1(d)
Ψ = kernel_vector(x, d.c[:,i], d.σ2[:,i])
f = vecdot(Ψ,d.w[:,i]) * x*(d.g[i]-y0[i])
f = dot(Ψ,d.w[:,i]) * x*(d.g[i]-y0[i])
end

function force_multiple(d::AbstractDMP,x::AbstractVector)
Expand All @@ -155,7 +155,7 @@ function force_multiple(d::AbstractDMP,x::AbstractVector)
f = zeros(n)
for i = 1:n
Ψ = kernel_matrix([x[i]], d.c[:,i], d.σ2[:,i])
f[i] = vecdot(Ψ,d.w[:,i]) * x[i].*(d.g[i]-y0[i])
f[i] = dot(Ψ,d.w[:,i]) * x[i].*(d.g[i]-y0[i])
end
f
end
Expand Down Expand Up @@ -209,7 +209,7 @@ function acceleration(d::DMP, y::AbstractMatrix,ẏ::AbstractMatrix,x::AbstractV
(d.opts.αz*(d.opts.βz*(g'.-y)-d.τ*ẏ)+f)/d.τ^2
end

function solve_canonical(dmp::DMP, t, y0, g, solver)
function solve_canonical(dmp::DMP, t, y0, g, solver; kwargs...)
T,n = size(dmp.y)
αx = dmp.opts.αx
τ = dmp.τ
Expand All @@ -227,15 +227,15 @@ function solve_canonical(dmp::DMP, t, y0, g, solver)
end
state0 = [dmp.ẏ[1,i]; y0[i]; 1.]
prob = OrdinaryDiffEq.ODEProblem(time_derivative,state0,(t[1],t[end]))
sol = OrdinaryDiffEq.solve(prob,solver,saveat=t,dt=t[2])
sol = OrdinaryDiffEq.solve(prob,solver;saveat=t,dt=t[2], kwargs...)
z[:,i] = sol[1,:]
y[:,i] = sol[2,:]
x = sol[3,:] # TODO: se till att denna är samma för alla DOF
end
t,y,z,x
end

function solve_position(dmp, t, y0, g, solver)
function solve_position(dmp, t, y0, g, solver; kwargs...)
T,n = size(dmp.y)
αx = dmp.opts.αx
τ = dmp.τ
Expand All @@ -250,14 +250,14 @@ function solve_position(dmp, t, y0, g, solver)
end
state0 = [0; y0[i]]
prob = OrdinaryDiffEq.ODEProblem(time_derivative,state0,(t[1],t[end]))
sol = OrdinaryDiffEq.solve(prob,solver,saveat=t,dt=t[2])
sol = OrdinaryDiffEq.solve(prob,solver;saveat=t,dt=t[2], kwargs...)
z[:,i] = sol[1,:]
y[:,i] = sol[2,:]
end
t,y,z,y
end

function solve_time(dmp, t, y0, g, solver)
function solve_time(dmp, t, y0, g, solver; kwargs...)
T,n = size(dmp.y)
αx = dmp.opts.αx
τ = dmp.τ
Expand All @@ -272,7 +272,7 @@ function solve_time(dmp, t, y0, g, solver)
end
state0 = [0; y0[i]]
prob = OrdinaryDiffEq.ODEProblem(time_derivative,state0,(t[1],t[end]))
sol = OrdinaryDiffEq.solve(prob,solver,saveat=t,dt=t[2])
sol = OrdinaryDiffEq.solve(prob,solver;saveat=t,dt=t[2], kwargs...)
z[:,i] = sol[1,:]
y[:,i] = sol[2,:]
end
Expand All @@ -292,13 +292,13 @@ The default solver is `solver=ode54`, a faster alternative is `solver=euler`
see also `plotdmp`
"""
function solve(dmp::AbstractDMP, t = dmp.t; y0 = _1(dmp), g = dmp.g, solver=OrdinaryDiffEq.Tsit5())
function solve(dmp::AbstractDMP, t = dmp.t; y0 = _1(dmp), g = dmp.g, solver=OrdinaryDiffEq.Tsit5(), kwargs...)
if dmp.opts.sched_sig == :position
return solve_position(dmp, t, y0, g, solver)
return solve_position(dmp, t, y0, g, solver; kwargs...)
elseif dmp.opts.sched_sig == :time
return solve_time(dmp, t, y0, g, solver)
return solve_time(dmp, t, y0, g, solver; kwargs...)
end
solve_canonical(dmp, t, y0, g, solver)
solve_canonical(dmp, t, y0, g, solver; kwargs...)
end


Expand Down
2 changes: 1 addition & 1 deletion src/demo_two_link.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Nbasis = 20
opts = DMPopts(Nbasis,αx,αz, :canonical)

T = size(y,1)
t = linspace(0,T,T)
t = LinRange(0,T,T)
τ = t[end]/3
h = t[2]-t[1]
qd = centraldiff(q) / h
Expand Down
19 changes: 10 additions & 9 deletions src/two_link.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module TwoLink
using RecipesBase

export torque, forward_kin, inverse_kin, inverse_kin_up, inverse_kin_down, traj, connect_points, acceleration, time_derivative, time_derivative!, inertia,
(a::Tuple{Number,Number}, b::Tuple{Number,Number}) = (a[1]+b[1], a[2]+b[2])
Expand Down Expand Up @@ -122,7 +123,7 @@ function forward_kin(q)
p1, p
end

function forward_kin(jtraj::Matrix)
function forward_kin(jtraj::AbstractMatrix)
N = size(jtraj,2)
p = zeros(eltype(jtraj), 2, N)
for i = 1:N
Expand Down Expand Up @@ -166,7 +167,7 @@ end
`p` is of size N × 2
"""
function inverse_kin(ctraj::Matrix, dir = :up)
function inverse_kin(ctraj::AbstractMatrix, dir = :up)
if dir == :up
kin_fun = inverse_kin_up
elseif dir == :down
Expand All @@ -190,7 +191,7 @@ Move from `q0` to `q1` during total time `t` using quadratic blends.
"""
function traj(q0,q1,t)
tf = maximum(t)
V = (q1-q0)/tf * 1.5
V = (q1-q0) ./tf * 1.5
traj(q0,q1,t, V)
end

Expand Down Expand Up @@ -218,9 +219,9 @@ function traj(q0,q1,t, V)
tb = (q0 - q1 + V*tf)/V
a = V/tb

p = Array{eltype(q0)}(size(t))
pd = Array{eltype(q0)}(size(t))
pdd = Array{eltype(q0)}(size(t))
p = Array{eltype(q0)}(undef, size(t))
pd = Array{eltype(q0)}(undef, size(t))
pdd = Array{eltype(q0)}(undef, size(t))

for (i,t) = enumerate(t)
if t <= tb
Expand Down Expand Up @@ -276,12 +277,12 @@ function connect_points(points,ni)
p', pd', pdd'
end


function plotworkspace(N=1000)
@userplot Plotworkspace
@recipe function plotworkspace(p::Plotworkspace, N=1000)
q = [(2π*rand(),2π*rand()) for n in 1:N]
p = getindex.(forward_kin.(q), 2)
p1,p2 = getindex.(p,1), getindex.(p,2)
scatter(p1,p2)
seriesstyle := :scatter
p1,p2
end

Expand Down
Loading

0 comments on commit 91ff1c8

Please sign in to comment.