关于滑膜控制的问题。
mathematica吧
全部回复
仅看楼主
level 6
冉qx 楼主
model = CreateSystemModel[{x1'[t] == x2[t],
x2'[t] == -9.8 x1[t] + a[t],
a[t] == 9.8 x1[t] - x2[t] - Sign[x1[t] + x2[t]], x1[0] == 1,
x2[0] == 0}, t]
sim = SystemModelSimulate[model, 10,
Method -> {"RungeKutta", "StepSize" -> 0.001}]
SystemModelPlot[sim, "a", PlotRange -> {-10, 10}, Frame -> True,
GridLines -> {Range[10], Automatic}]
仿照MATLAB进行滑模控制的一个例子,按理说在t=1s之后应该出现抖振,但却没有出现,这是怎么回事?
2020年12月25日 07点12分 1
吧务
level 15
LZ最终也没去Stackexchange问,那咱们就内部解决吧,毕竟微分方程相关,我还是有点斗志的。
首先,SystemModelSimulate的结果和截图中的结果其实都不对,这个方程组的精确解其实只会在 t=1 处跳一次:
aexpr = 98/10 x1[t] - x2[t] - Sign[x1[t] + x2[t]];
solref = NDSolve[{x1'[t] == x2[t], x2'[t] == -98/10 x1[t] + aexpr, x1[0] == 1,
x2[0] == 0}, {x1, x2}, {t, 0, 10}, WorkingPrecision -> 16]
Plot[aexpr /. solref[[1]], {t, 0, 10}]
要用 NDSolve 重现振荡结果也是可以的,只要把间断检测和自适应步长关掉就行:
sol = NDSolve[{x1'[t] == x2[t], x2'[t] == -98/10 x1[t] + aexpr, x1[0] == 1,
x2[0] == 0}, {x1, x2}, {t, 0, 10},
Method -> {FixedStep, Method -> Automatic, DiscontinuityProcessing -> False}]
Plot[aexpr /. sol[[1]], {t, 0, 10}]
感觉这帖又要被审了。先吃午饭,剩下的回来再写。
2021年01月02日 04点01分 2
吧务
level 15
再说 SystemModelSimulate 为什么生成了一个完全光滑的 a 。事实上,如果你进一步检查x1和x2的求解结果,会发现 SystemModelSimulate 对这两个量的求解结果似乎并无问题:
(* solref 的定义参看2楼 *)
SystemModelPlot[sim, {"x1", "x2"}, PlotRange -> {-2, 2}]~Show~
Plot[{x1@t, x2@t} /. solref // Evaluate, {t, 0, 10}, PlotRange -> All,
PlotStyle -> Dashed, ColorFunction -> "Rainbow"]
那到底是哪不对呢?我们进一步画画Sign里面的东西:
(* "StepSize" -> 0.01 *)
nearzero = Plot[
#[t] + #
2[t] & @@ sim[{"x1", "x2"}] // Evaluate, {t, 0, 10}, PlotRange -> 0.01]
……是的,x1[t]+x2[t]大于零,进一步的实验表明,就算步长减小,x1[t]+x2[t]也始终会大于零。这似乎是RK4(经典龙格库塔)的固有性质,使用NDSolve我们可以重现此结果:
crkamat = {{1/2}, {0, 1/2}, {0, 0, 1}};
crkbvec = {1/6, 1/3, 1/3, 1/6};
crkcvec = {1/2, 1/2, 1};
ClassicalRungeKuttaCoefficients[4, p_] := N[{crkamat, crkbvec, crkcvec}, p];
aexpr = 98/10 x1[t] - x2[t] - Sign[x1[t] + x2[t]];
solrk4 = NDSolve[{x1'[t] == x2[t], x2'[t] == -98/10 x1[t] + aexpr, x1[0] == 1,
x2[0] == 0}, {x1, x2}, {t, 0, 10},
Method -> {"ExplicitRungeKutta", "DifferenceOrder" -> 4,
"Coefficients" -> ClassicalRungeKuttaCoefficients, DiscontinuityProcessing -> False},
StartingStepSize -> 0.01, InterpolationOrder -> All]
nearzero~Show~
ListLinePlot[solrk4[[1, All, -1]]["ValuesOnGrid"] // Through // Total,
DataRange -> {0, 10}, PlotRange -> 0.1, PlotStyle -> Dashed,
ColorFunction -> "Rainbow"]
至于 RK4 为什么对此方程必产生一个正误差我就不分析了。(小声:其实也不太会。)有兴趣的可以试一下。
最后,在 SystemModelSimulate 使用 Euler 法是可以产生振荡结果的:
sim = SystemModelSimulate[model, 10, Method -> {"Euler", "StepSize" -> 0.01}]
SystemModelPlot[sim, "a", AspectRatio -> 1/10, PlotRange -> {-10, 10}, Frame -> True,
Axes -> None, GridLines -> {Range@10, {0}}, GridLinesStyle -> Dashed,
PlotRangePadding -> None, FrameLabel -> {None, Style["加速度
(m/\!\(\*SuperscriptBox[\(s\), \(2\)]\))", SingleLetterItalics -> False]},
RotateLabel -> False]
2021年01月02日 05点01分 3
谢谢吧主!我用systemmodeler的Euler法同样产生了震荡。
2021年01月03日 04点01分
@冉qx 这是自然的,这俩都是 modelica 的壳。
2021年02月06日 04点02分
1