Iam currently working on simulating a pendulum. It is driven by a control force, that changes between two different methods (one for the swingup and one for the stabilize on top).. My question is how to change between these two controllers (soln1 and soln2) so that when iam above 340 Degree or below 20 Degree iam using the stabelizer and when iam not in this range iam using the swing up?
Mathematica Code:
Manipulate[
Module[{control, errorsig, energyDesired, energy, model, assm, gains,
controlForce, swingcontrolForce, soln1, soln2,
t, \[Theta], \[Theta]0, g},
g = -9.82;
assm = AffineStateSpaceModel[{m*l^2*\[Theta]''[t] + b*\[Theta]'[t] +
m*g*l*Sin[\[Theta][t]] == u[t]}, {\[Theta][t], \[Theta]'[
t]}, {u[t]}, {\[Theta][t]}, t];
gains = LQRegulatorGains[assm, {({
{2000, 0},
{0, 10}
}), {{1}}}];
errorsig[t_] = 0;
energyDesired = - g*l*m;
energy[t_] = 1/2*m*l^2*\[Theta]'[t]^2 - m*g*l*Cos[\[Theta][t]];
swingcontrolForce[t_] =
10*Sign [Derivative[1][\[Theta]][t]]*(energyDesired - energy[t]);
controlForce[t_] = (-g l m Sin[(-\[Theta][t])] +
First[First[First[gains]]] l^2 m (-\[Theta][t]) -
b (-Derivative[1][\[Theta]][t]) +
First[Last[First[gains]]] l^2 m (-Derivative[1][\[Theta]][t]))/(
l^2 m);
(*This one does not work :( *)
control[t_] :=
If[\[Theta][t] + Pi > 340 Degree ,
Return[(-g l m Sin[(-\[Theta][t])] +
First[First[First[gains]]] l^2 m (-\[Theta][t]) -
b (-Derivative[1][\[Theta]][t]) +
First[Last[
First[gains]]] l^2 m (-Derivative[1][\[Theta]][t]))/(
l^2 m)];,
Return[10*
Sign [Derivative[1][\[Theta]][
t]]*((- g*l*m) - (1/2*m*l^2*\[Theta]'[t]^2 -
m*g*l*Cos[\[Theta][t]]))];];
soln1 =
Flatten[NDSolve[{m*l^2*\[Theta]''[t] + b*\[Theta]'[t] +
m*g*l*Sin[\[Theta][t]] ==
Clip[controlForce[t], {-tl, tl}], \[Theta]'[0] ==
0, \[Theta][0] == \[Theta]e}, {\[Theta]}, {t, p - 1, p},
Method -> "StiffnessSwitching"]];
soln2 =
Flatten[NDSolve[{m*l^2*\[Theta]''[t] + b*\[Theta]'[t] +
m*g*l*Sin[\[Theta][t]] ==
Clip[swingcontrolForce[t], {-tl, tl}], \[Theta]'[0] ==
0, \[Theta][0] == \[Theta]e}, {\[Theta]}, {t, p - 1, p},
Method -> "StiffnessSwitching"]];
With[
{
y1 = \[Theta][p] + Pi /. soln1, (* Stable on top *)
y2 = \[Theta][p] + Pi /. soln2 (* Swing Up *)
},
(*If expression here? if y2 > 340 || y2 < 20 then y2=y1 ??? *)
Graphics[
{Point[{0, 0}],
Line[{{0, 0}, l {Sin[y2], -Cos[y2]}}],
Darker[Red], Disk[l {Sin[y2], -Cos[y2]}, .08]
},
PlotRange -> 1.7, ImageSize -> {300, 300}]]],
Style["start / pause / reset", Bold],
{{p , 0, "animation"}, 0, 100, .02, Trigger, DisplayAllSteps -> True,
AppearanceElements -> {"StepLeftButton", "StepRightButton",
"PlayPauseButton", "ResetButton"}},
Delimiter,
Style["pendulum parameters", Bold],
"error at start: \!\(\*SubscriptBox[\(\[Theta]\), \(e\)]\)",
{{\[Theta]e, 170 \[Degree], ""}, 0 \[Degree], 360 \[Degree],
1 \[Degree], Appearance -> "Labeled", ImageSize -> Tiny},
"length of rod: L",
{{l, 1.2, ""}, 1, 2, .1, Appearance -> "Labeled", ImageSize -> Tiny},
"mass of bob: m",
{{m, 1.0, ""}, 0.1, 2, .1, Appearance -> "Labeled",
ImageSize -> Tiny},
"Damping",
{{b, 1.0, ""}, 0, 5, Appearance -> "Labeled", ImageSize -> Tiny},
"Torque Limit",
{{tl, 4, ""}, 0, 8, Appearance -> "Labeled", ImageSize -> Tiny},
ControlPlacement -> Left, TrackedSymbols -> True, Paneled -> False,
BaseStyle -> Black, ImageMargins -> 10]
Aucun commentaire:
Enregistrer un commentaire