我已经使用Julia中的Euler方法实现了一个由两个二阶微分方程组成的系统。下面的代码显示了如何调用Euler方法来解决相关系统。
θ1 = 1.1900518004210798; θ2 = 0.3807445263738167
f(t, y) = [y[2], -2(y[1] - θ1) - 4y[2] + 0.5sin(3pi*t),
y[4], -2(y[3] - θ2) - 4(y[4] + abs(y[2])) + 0.5sin(3pi*t)]
y0 = [pi/2, 0, pi/6, 0]; t0 = 0; tFinal = 50; h = 0.001
res = euler(f, y0, t0, tFinal, h)
结果res
是四个数字的向量
1.18798735437173
-0.0458294959470722
0.31530569612003573
-0.049213402534541074
第一个条目是底线段与x轴的夹角,而第三个条目是两个线段彼此的夹角(见下图)。
要创建此图,我称为plot_robotarm([res[1], res[3]])
,它是根据以下代码实现的。
function plot_robotarm(thetav)
# Plots a robotarm with angles thetav
R = 1;
xv=zeros(length(thetav)+1)
yv=zeros(length(thetav)+1)
for i in 1:length(thetav)
xv[i+1]=xv[i]+R*cos(thetav[i])
yv[i+1]=yv[i]+R*sin(thetav[i])
end
# Plot with colors
opts = (:circle, 10, 1., :blue, stroke(7, 1., :red))
plt = plot(xv, yv,
marker = opts,
c = :red,
w = 5,
legend = false,
xlims = (0, 2.0),
ylims = (0, 2.0))
display(plt)
end
如何创建动画来可视化欧拉方法的连续迭代如何使机械臂(即两个线段)朝着t = 50
的最终点移动? (我不需要绘制每个迭代,只需绘制足够的动画就可以捕获机器人手臂的运动。)
答案 0 :(得分:2)
您可以使用ffmpeg和Luxor.jl的动画功能制作动画GIF。需要修改框架功能以反映程序中每个步骤的图形显示。有关更多信息,请参阅卢克索的文档。
using Luxor
using Colors
using BoundaryValueDiffEq
# constants for differential equations and movie
const g = 9.81
const L = 1.0 # pendulum length in meters
const bobd = 0.10 # pendulum bob diameter in meters
const framerate = 50.0 # intended frame rate/sec
const t0 = 0.0 # start time (s)
const tf = 2.3 # end simulation time (s)
const dtframe = 1.0/framerate # time increment per frame
const tspan = LinRange(t0, tf, Int(floor(tf*framerate))) # array of time points in animation
const bgcolor = "black" # gif background
const leaderhue = (0.80, 0.70, 0.20) # gif swing arm hue light gold
const hslcolors = [HSL(col) for col in (distinguishable_colors(
Int(floor(tf*framerate)+3),[RGB(1,1,1)])[2:end])]
const giffilename = "pendulum.gif" # output file
# differential equations copied from docs of DifferentialEquations.jl
simplependulum!(du, u, p, t) = (θ=u[1]; dθ=u[2]; du[1]=dθ; du[2]=-(g/L)*sin(θ))
bc1!(residual, u, p, t) = (residual[1] = u[div(end,2)][1] + pi/2; residual[2] = u[end][1] - pi/2)
bvp1 = TwoPointBVProblem(simplependulum!, bc1!, [pi/2,pi/2], (tspan[1],tspan[end]))
sol2 = solve(bvp1, GeneralMIRK4(), dt=dtframe)
# movie making background
backdrop(scene, framenumber) = background(bgcolor)
function frame(scene, framenumber)
u1, u2 = sol2.u[framenumber]
y, x = L*cos(u1), L*sin(u1)
sethue(leaderhue)
poly([Point(-4.0, 0.0), Point(4.0, 0.0),
Point(160.0x,160.0y)], :fill)
sethue(Colors.HSV(framenumber*4.0, 1, 1))
circle(Point(160.0x,160.0y), 160bobd, :fill)
text(string("frame $framenumber of $(scene.framerange.stop)"),
Point(0.0, -190.0),
halign=:center)
end
muv = Movie(400, 400, "Pendulum Demo", 1:length(tspan))
animate(muv, [Scene(muv, backdrop),
Scene(muv, frame, easingfunction=easeinoutcubic)],
creategif=true, pathname=giffilename)