7
$\begingroup$

I am trying to simulate the following hybrid ode

$$ \begin{eqnarray} \dot{x}=-\left(x-a+u\right) \end{eqnarray} $$

where $u$ is given by

$$ \begin{eqnarray} u(t)=\left\{\begin{matrix} 1 & \text{if} & x-x_d>\delta\\ 0 & \text{if} &x-x_d \leq -\delta\\ u(t-dt) & \text{otherwise} \end{matrix}\right. \end{eqnarray} $$

where $a=10$, $x_d=9.5$ and moreover $u(t-dt)$ represent the value of $u$ in the last time step. $a$ and $x_d$ are known constants. I didnt know how to impliment this in mathematica.

PS: I was able to solve this with $\delta=0$. The controller simply becomes

$$ \begin{eqnarray} u(t)=\left\{\begin{matrix} 1 & if & x-x_d>0\\ 0 & if &x-x_d \leq 0\\ \end{matrix}\right. \end{eqnarray} $$

a = 10;
xd = a - 0.25
simtime = 5;
var = {x[t]} // Flatten;
varInit = var /. {t -> 0};
f = -(x[t] - a + 0.5 (1 + Sign[(x[t] - xd)]));
DAE = {Thread[D[var, t] == f], 
    Thread[varInit == Flatten[RandomReal[{1, 2}, {1, 1}]]]} // Flatten;
sol = NDSolve[DAE, var, {t, 0, simtime}, MaxSteps -> 10000000];
Plot[Evaluate[{x[t], If[x[t] > xd, 1, 0]} /. First[sol]], {t, 0, 
  simtime}, PlotStyle -> {Red, Green, Blue}, 
 PlotRange -> {{0, simtime}, {0, 12}}, AxesLabel -> {t, \[Theta]}, 
 PlotLabels -> Placed[{\[Theta][t] u[t]}, Above]]
Evaluate[{x[t]} /. First[sol] /. t -> simtime]

But I would like to implement this with a non zero $\delta$. For instance one can use a delta of $\delta=0.25$.

$\endgroup$
3
  • $\begingroup$ I tried solving it but got a NDSolve::underdet message "There are more dependent variables, {u[t],x[t]}, than equations, so the system is underdetermined"; in case my failed attempt was due to my erroneous equation setup, perhaps WhenEvent might seem useful $\endgroup$
    – user42582
    Commented Sep 17, 2018 at 13:09
  • $\begingroup$ For me, WhenEvent was giving such error. So, I started using If function. BTW, how did u approach it? How did u make the solver access its previous values? $\endgroup$
    – kosa
    Commented Sep 17, 2018 at 13:13
  • 2
    $\begingroup$ using WhenEvent; If you're certain your system is correctly specified then I suggest you play around with WhenEvent until you discover a working specification. I could be wrong, but I don't think If can be helpful in this case. $\endgroup$
    – user42582
    Commented Sep 17, 2018 at 13:28

2 Answers 2

8
$\begingroup$

It's not clear what you mean by "last time step", since NDSolve uses an adaptive step size algorithm by default, and anyhow, the details of the numerical method shouldn't get into the mathematical model.

Here's an approach using WhenEvent that might be what you're looking for:

a = 10; xd = 9.5; δ = 0.25;
tmax = 10;
sol = NDSolve[{
  x'[t] == -(x[t] - a + u[t]),
  WhenEvent[x[t] < xd - δ, u[t] -> 0],
  WhenEvent[x[t] > xd + δ, u[t] -> 1],
  x[0] == 1, u[0] == 0}, {x, u}, {t, 0, tmax}, DiscreteVariables -> {u}][[1]];

Plot[{xd - δ, xd + δ, x[t] /. sol}, {t, 0, tmax}, PlotRange -> {0, All}]
Plot[u[t] /. sol, {t, 0, tmax}]

Mathematica graphics Mathematica graphics

The first WhenEvent is triggered when x[t] crosses xd - δ from above and the second when x[t] crosses xd + δ from below.

$\endgroup$
1
  • $\begingroup$ By last time-step, I meant $u(t)=u(t^-)$. I will make this change. Thanks for the help. $\endgroup$
    – kosa
    Commented Sep 18, 2018 at 7:35
6
$\begingroup$

If you do not need greater accuracy, then you can use an explicit Euler

u[t_] := Piecewise[{{1, x[t] - xd > d}, {0, 
    x[t] - xd <= -d}, {u[t - 1], True}}]
xd = 9.5; d = .25; a = 10; h = 10^-2; T[0] = 0; x[0] = 1.5;

lst = Table[{T[i] = T[i - 1] + h, 
    x[i] = x[i - 1] - (x[i - 1] - a + u[i - 1])*h}, {i, 1, 1000}];
ListLinePlot[lst]

fig1

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.