Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
ODEs taking variables below 0

Subject: ODEs taking variables below 0

From: Matthew

Date: 28 Mar, 2013 13:38:06

Message: 1 of 5

I have a problem with ODEs taking variables below 0 or some limit. This occurs with multiple things like positions, pressures and volumes.

For example, a piston head should stop when it hits the end, say its called xend = 1m. z(3) is the position of the piston, while dz(3) is the change in position, which is the velocity, va.

I have a piece of code which says that if the piston head is at xend, then dz(3) is 0 if its going to push it further past xend. However this code doesn't work if say z(3) is at 0.99 and then dz(3) is 0.02, in this case it does not register that it will go beyond xend. The code is listed at the bottom.

I have tried making statements like the one below but they don't seem to work, maybe i have some syntax wrong. The one below is just a simple version of what would be required for example.

if z(3) + dz(3) >= xend
   z(3) = xend;
dz(3) = 0;
else
dz(3) = va;
end

Below is an example of my current code:

if abs(z(3)) >= xend
    if sign(z(3)) > 0
        if dz(3) >= 0
            dz(3) = 0;
        else
            dz(3) = va;
        end
    else
        if dz(3) <= 0
            dz(3) = 0;
        else
            dz(3) = va;
        end
    end
    z(3) = sign(z(3)) * xend;
else
    dz(3) = va;
end

Subject: ODEs taking variables below 0

From: Steven_Lord

Date: 28 Mar, 2013 14:05:00

Message: 2 of 5



"Matthew " <s0700340@sms.ed.ac.uk> wrote in message
news:kj1h3u$ge$1@newscl01ah.mathworks.com...
> I have a problem with ODEs taking variables below 0 or some limit. This
> occurs with multiple things like positions, pressures and volumes.
>
> For example, a piston head should stop when it hits the end, say its
> called xend = 1m. z(3) is the position of the piston, while dz(3) is the
> change in position, which is the velocity, va.
>
> I have a piece of code which says that if the piston head is at xend, then
> dz(3) is 0 if its going to push it further past xend. However this code
> doesn't work if say z(3) is at 0.99 and then dz(3) is 0.02, in this case
> it does not register that it will go beyond xend. The code is listed at
> the bottom.
>
> I have tried making statements like the one below but they don't seem to
> work, maybe i have some syntax wrong. The one below is just a simple
> version of what would be required for example.

Either use an Events function or set the ODE option NonNegative using
ODESET.

http://www.mathworks.co.uk/help/matlab/ref/odeset.html

If you're just worried about the ODE solver returning values less than 0,
the NonNegative option will do what you need. If there are events (like the
piston reaching its upper limit, not the lower limit) to which you need to
react use an Events function. For one example of how to use an Events
function, see the example BALLODE.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: ODEs taking variables below 0

From: Matthew

Date: 28 Mar, 2013 14:52:05

Message: 3 of 5

Thanks, the nonnegative odeset command is perfect for the pressures and volumes. I have been looking at the events literature and the BALLODE example but I don't really understand what is going on.

How do i say if my ODE dx = u goes above abs(xend) then sign(x) * xend?

Thanks.

Subject: ODEs taking variables below 0

From: Matthew

Date: 28 Mar, 2013 16:51:22

Message: 4 of 5

I have my event stopping at the right place but it wont just cap the variable and continue.

Heres what I have:

function [value,isterminal,direction] = events(t, z,design)
value = [xend - z(3); (xend + z(3)];
isterminal = [0; 1];
direction = [0; 0];
end

I don't understand what direction does? Terminal simply stops the integration if its a 1 and lets its keep on running if its a 0. I want it to stop integrating if its going past that.

Subject: ODEs taking variables below 0

From: Richard Crozier

Date: 28 Mar, 2013 20:10:07

Message: 5 of 5

"Matthew" wrote in message <kj1sea$ab6$1@newscl01ah.mathworks.com>...
> I have my event stopping at the right place but it wont just cap the variable and continue.
>
> Heres what I have:
>
> function [value,isterminal,direction] = events(t, z,design)
> value = [xend - z(3); (xend + z(3)];
> isterminal = [0; 1];
> direction = [0; 0];
> end
>
> I don't understand what direction does? Terminal simply stops the integration if its a 1 and lets its keep on running if its a 0. I want it to stop integrating if its going past that.


The direction lets you specify whether the function was increasing when it crossed the threshold or decreasing, or if it doesn't matter.

if direction is zero it will always raise an event when crossing the threshold

if direction is +1 it will only create an event if the threshold is crossed from below (i.e. the function is increasing)

if direction is -1 it will only create an event if the threshold is crossed from above (i.e. the function is decreasing)

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us