foreach(Pkg.add, ["IJulia", "Ipopt", "Interact", "Reactive", "JuMP", "Compose", "MacroTools"])
(x, y) - coordinates of the load (large circle)
(xctl, yctl) - coordinates of the “controlling end” of the rope, 1.7 long, tied to the load.
(xp, yp) - coordinates of a weightless point block capable of sliding along the rope.
@wire(x,y, xctl,yctl, 1.7) @wire(xp, yp, 5.0,1.0, 4.5,5.0, 6.0) @energy([w(x,y, 0,3, 1, 0.1), w(x,y, xp,yp, 5, 0.15), 0.4*y])
function myModel(xctl, yctl) m = Model() @variable(m, y >= 0) @variable(m, x) @variable(m, yp) @variable(m, xp) @wire(x,y, xctl,yctl, 1.7) @wire(xp, yp, 5.0,1.0, 4.5,5.0, 6.0) @energy([w(x,y, 0,3, 1, 0.1), w(x,y, xp,yp, 5, 0.15), 0.4*y]) status = solve(m) xval = getvalue(x) yval = getvalue(y) xpval = getvalue(xp) ypval = getvalue(yp) # print("calculate $status $xval $yval for $xctl, $yctl\n") (status, xval, yval, xpval, ypval) end
@NLconstraint(m, (x-xctl)^2+(y-yctl)^2 <= 1.7) @NLconstraint(m, sqrt((5.0-xp)^2+(1.0-yp)^2) + sqrt((4.5-xp)^2+(5.0-yp)^2) <= 6.0) @NLobjective(m, Min, 1*(sqrt(((x-0)^2 + (y - 3)^2)) - 0.1)^2 + 5*(sqrt((x - xp)^2 + (y - yp)^2) - 0.15)^2 + 0.4*y)
macro wire(x,y,x0,y0, l) v = l^2 :(@NLconstraint(m, ($x0-$x)^2+($y0-$y)^2 <= $v)) end macro wire(x,y, x0,y0, x1,y1, l) :(@NLconstraint(m, sqrt(($x0-$x)^2+($y0-$y)^2) + sqrt(($x1-$x)^2+($y1-$y)^2) <= $l)) end calcenergy(d) = MacroTools.@match d begin [t__] => :(+$(map(energy1,t)...)) v_ => energy1(v) end energy1(v) = MacroTools.@match v begin w(x1_,y1_, x2_,y2_, k_, l_) => :($k*(sqrt(($x1 - $x2)^2 + ($y1 - $y2)^2) - $l)^2) x_ => x end macro energy(v) e = calcenergy(v) :(@NLobjective(m, Min, $e)) end
xctl = slider(-2:0.01:5, label="X Control") xctlsig = signal(xctl) yctl = slider(-1:0.01:0.5, label="Y Control") yctlsig = signal(yctl)
ops = map(myModel, xctlsig, yctlsig)
xscale = 3 yscale = 3 shift = 1.5 pscale(x,y) = ((x*xscale+shift)cm, (y*yscale)cm) function l(x1,y1, x2,y2; w=0.3mm, color="black") compose(context(), linewidth(w), stroke(color), line([pscale(x1, y1), pscale(x2, y2)])) end
@manipulate for xc in xctl, yc in yctl, op in ops compose(context(), # text(150px, 220px, "m = $(op[2]) $(op[3])"), # text(150px, 200px, "p = $(op[4]) $(op[5])"), circle(pscale(op[2], op[3])..., 0.03), circle(pscale(op[4], op[5])..., 0.01), l(op[2], op[3], op[4], op[5], color="red"), l(op[2], op[3], 0, 3, color="red"), l(op[2], op[3], xc, yc), l(op[4], op[5], 5, 1), l(op[4], op[5], 4.5,5) ) end
using Interact, Reactive, JuMP, Compose, MacroTools macro wire(x,y,x0,y0, l) v = l^2 :(@NLconstraint(m, ($x0-$x)^2+($y0-$y)^2 <= $v)) end macro wire(x,y, x0,y0, x1,y1, l) :(@NLconstraint(m, sqrt(($x0-$x)^2+($y0-$y)^2) + sqrt(($x1-$x)^2+($y1-$y)^2) <= $l)) end calcenergy(d) = MacroTools.@match d begin [t__] => :(+$(map(energy1,t)...)) v_ => energy1(v) end energy1(v) = MacroTools.@match v begin w(x1_,y1_, x2_,y2_, k_, l_) => :($k*(sqrt(($x1 - $x2)^2 + ($y1 - $y2)^2) - $l)^2) x_ => x end macro energy(v) e = calcenergy(v) :(@NLobjective(m, Min, $e)) end function myModel(xctl, yctl) m = Model() @variable(m, y >= 0) @variable(m, x) @variable(m, yp) @variable(m, xp) @wire(x,y, xctl,yctl, 1.7) @wire(xp, yp, 5.0,1.0, 4.5,5.0, 6.0) @energy([w(x,y, 0,3, 1, 0.1), w(x,y, xp,yp, 5, 0.15), 0.4*y]) status = solve(m) xval = getvalue(x) yval = getvalue(y) xpval = getvalue(xp) ypval = getvalue(yp) # print("calculate $status $xval $yval for $xctl, $yctl\n") (status, xval, yval, xpval, ypval) end xctl = slider(-2:0.01:5, label="X Control") xctlsig = signal(xctl) yctl = slider(-1:0.01:0.5, label="Y Control") yctlsig = signal(yctl) ops = map(myModel, xctlsig, yctlsig) xscale = 3 yscale = 3 shift = 1.5 pscale(x,y) = ((x*xscale+shift)cm, (y*yscale)cm) function l(x1,y1, x2,y2; w=0.3mm, color="black") compose(context(), linewidth(w), stroke(color), line([pscale(x1, y1), pscale(x2, y2)])) end @manipulate for xc in xctl, yc in yctl, op in ops compose(context(), # text(150px, 220px, "m = $(op[2]) $(op[3])"), # text(150px, 200px, "p = $(op[4]) $(op[5])"), circle(pscale(op[2], op[3])..., 0.03), circle(pscale(op[4], op[5])..., 0.01), l(op[2], op[3], op[4], op[5], color="red"), l(op[2], op[3], 0, 3, color="red"), l(op[2], op[3], xc, yc), l(op[4], op[5], 5, 1), l(op[4], op[5], 4.5,5) ) end
using IJulia notebook()
. This should open in the browser " http: // localhost: 8888 / tree ". There you have to select “new” / “Julia”, copy the code in the input field and press Shift-Enter.Source: https://habr.com/ru/post/313138/
All Articles