How to use ode solvers inside while/for loops for animation?

5 views (last 30 days)
It is not lucid from the documnation how to use the solution of an ODE at each step. The examples show how one can pass the entire time span which is good for some cases. However, I need to obtain the solution at each step for animation purposes. I'm using fixed ode solver (i.e. ode4).
classdef System < handle
properties
t = 0;
stepSize=0.01;
x0 = [0;0];
%Parameters:
m = 0.5; % mass (Kg)
d = 0.0023e-6; % viscous friction coefficient
L = 1; % arm length (m)
I;
g = 9.81; % acceleration due to gravity m/s^2
% PID tuning
Kp = 5;
Kd = 1.9;
Ki = 0.02;
% error
error = 0;
% control input
u=0;
x;
dx;
xVec;
dxVec;
errorVec;
idx=1;
end
methods
function obj = System()
obj.I = 1/3*obj.m*obj.L^2; % inertia seen at the rotation axis. (Kg.m^2)
obj.xVec(obj.idx) = obj.x0(1);
obj.dxVec(obj.idx) = obj.x0(2);
obj.errorVec(obj.idx) = 0;
end
function move(this)
tspan = [this.t this.t+this.stepSize];
y = ode4(@this.ODESolver, tspan, this.x0);
this.x = y(1);
this.dx = y(2);
this.t = this.t + this.stepSize;
end
function updateController(this)
Kp = this.Kp;
Kd = this.Kd;
Ki = this.Ki;
% u: joint torque
this.u = Kp*(pi/2 - this.x) + Kd*(-this.dx) + Ki*this.error;
this.error = this.error + (pi/2 - this.x);
end
function dx = ODESolver(this,t,x)
m=this.m;
g=this.g;
I=this.I;
d=this.d;
dx = zeros(2,1);
dx(1) = x(2);
dx(2) = 1/I*(this.u - d*this.dx - m*g*L*sin(this.x));
end
end
end
The main script is
clear all
clc
sys = System();
for i=1:100
sys.updateController;
sys.move;
end
I get errors at
function move(this)
tspan = [this.t this.t+this.stepSize]; % <---- I've tried to solve it with this but to no avail.
y = ode4(@this.ODESolver, tspan, this.x0); % <--- Error
this.x = y(1);
this.dx = y(2);
this.t = this.t + this.stepSize;
end
Any suggestions? Also, how can I do same scenario with ode45?

Answers (1)

Steven Lord
Steven Lord on 29 Jul 2021
If you want to plot the solution of the system of ODEs while it's being solved, use the OutputFcn option in the ODE options structure. See the ballode example for an illustration of how this is used.
If you want to plot the solution after it has been solved, either call the ODE solver with two outputs (as shown in the non-stiff van der Pol equation example on this documentation page) and possibly a tspan input with more than two elements or call it with one output that you can evaluate at specified times using deval.
  3 Comments
Steven Lord
Steven Lord on 29 Jul 2021
"If you want to plot the solution of the system of ODEs while it's being solved, use the OutputFcn option in the ODE options structure. See the ballode example for an illustration of how this is used."
The description of the OutputFcn option on the documentation page for the odeset function, which creates the ODE options structure, states in part: "The ODE solver calls the output function after each successful time step."
Bandar
Bandar on 2 Aug 2021
I've read OutputFcn. It did solve the problem paritally. The problem with OutputFcn is the fact that we don't have full control of the code. I mean if my code will do other stuff, I need to put them inside OutputFcn. For example, sending the command using tcp/ip. I couldn't find a solution where I can put ode45 inside while/for loops similar to Odeint C++ library where the stepper can perform the numerical method once at a time.

Sign in to comment.

Tags

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!