Why do I Receive this error: Error using odearguments ODES_LIN must return a column vector.

2 views (last 30 days)
I created an H-infinity controller for a system and am attempting implement the controller in a numerical simulation to plot the system response and control output, but receive the following error: Error using odearguments ODES_LIN must return a column vector.
Error in ode45 (line 107)
odearguments(odeIsFuncHandle,odeTreatAsMFile, solver_name, ode, tspan, y0, options, varargin);
Error in proposalGPBode (line 149)
[t,x_out] = ode45(@ODEs_lin,t_span,IC-[x_bar;0*xc0],options,const,Ap,Bp,Cp,Ac,Bc,Cc);
I've included Ap,Bp,Cp, and Dp in the code below, but just have the matrix sizes of Ac, Bc, and Dc here.
Ac: 7x7 double
Bc:7x1 double
Cc:1x7 double
Any ideas on why I am not returning a column vector?
u_bar = -b*sqrt(-1/(c*a));
x_bar = [0;b/c];
Ap=[0 b;0 -c];
Bp=[2*a*u_bar; 0];
Cp=[1 0];
Dp=0;
%% Initial conditions
xc0 = zeros(size(Ac,1),1);
IC = [0; 0.1; xc0]; % Initial state [x1; x2]
% Simulation time.
t0 = 0; % initial time (s)
t_max = 5; % final time (s)
t_div = 1001; % number of steps to divide the time series into when plotting
t_span = linspace(t0,t_max,t_div); % define simulation time
% Simulation options.
options = odeset('AbsTol',1e-5,'RelTol',1e-5); % This changes the
% integration tolerence. Smaller values of AbsTol and RelTol (e.g., 1e-12
% versus 1e-6) will give more accurate numerical integration solutions.
% Numerical solve ODE
[t,x_out] = ode45(@ODEs_lin,t_span,IC-[x_bar;0*xc0],options,const,Ap,Bp,Cp,Ac,Bc,Cc);
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Linear Differential Equation to Numerically Integrate
function [dot_x] = ODEs_lin(t,x,const,Ap,Bp,Cp,Ac,Bc,Cc)
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Calculate Control Input
delta_x1 = x(1);
delta_x2 = x(2);
delta_x=[delta_x1;delta_x2];
xc = x(3:2+size(Ac,1));
[d,n] = ExogenousSignals(t,const);
y = -Cp*delta_x - n;
delta_u=Cc*xc;
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Dynamics
dot_delta_x = Ap*delta_x + Bp*d+ Bp*delta_u;
dot_xc = Ac*xc + Bc*y;
dot_x = [dot_delta_x;dot_xc];
end
function [d,n] = ExogenousSignals(t,const)
d = sum(const.dist_amp.*sin(const.dist_freq*2*pi*t));
n = sum(const.noise_amp.*sin(const.noise_freq*2*pi*t));
end
  7 Comments
Torsten
Torsten on 17 Mar 2024
Your vector of initial conditions IC-[x_bar;0*xc0] has size 9x1. Thus dot_x must be a vector of size 9x1. But you produce a matrix of size 9x5. I don't know what's going wrong in your computations to get dot_x.
Stephen23
Stephen23 on 18 Mar 2024
Edited: Stephen23 on 18 Mar 2024
Note that you are passing extra arguments using an approach that has not been documented for twenty years. Your approach has been deprecated ever since anonymous functions were introduced in R14 exactly twenty years ago.
I strongly recommend that you parameterize your functions using the documented approaches:
For example, using an anonymous function, something like this:
fnh = @(t,x) ODEs(t,x, const,x_bar,u_bar,Cp,Ac,Bc,Cc);
[t,x_out] = ode45(fnh, t_span, IC, options);

Sign in to comment.

Answers (2)

Maureen
Maureen on 17 Mar 2024
Moved: Cris LaPierre on 18 Mar 2024
I think I figured it out. When I redefined these noise and disturbance equations, it runs. Thank you for your help!
const.dist_freq = 5*rand(2,5);
const.dist_amp = rand(2,5)/5;
const.noise_freq = 50*randn(3,5)+100;
const.noise_amp = diag([0.01;0.01;1*pi/180])*rand(3,5)/5;

Sam Chak
Sam Chak on 18 Mar 2024
It seems that you intend to generate the exogenous disturbance and noise signals as the sum of sine waves. Specifically, the disturbance signal comprises the sum of two sine waves, while the noise signal consists of the sum of three sine waves. Thus, only one noisy vector 'n' affects the output, and the matrix 'Bp' in the process plant Gp can only accommodate a single disturbance vector 'd'.
%% Settings for Exogenous Signals
num_d = 2; % number of disturbing sine waves
num_n = 3; % number of noisy sine waves
const.dist_freq = 5*rand(num_d,1);
const.dist_amp = rand(num_d,1)/5;
const.noise_freq = 50*randn(num_n,1)+100;
const.noise_amp = diag([0.01;0.01;1*pi/180])*rand(num_n,1)/5;
%% Test
t = 0:0.1:5;
[d, n] = ExogenousSignals(t, const)
d = 1×51
0 0.0929 -0.1014 0.0339 0.0498 -0.1012 0.0815 0.0115 -0.1009 0.1000 -0.0188 -0.0655 0.1002 -0.0673 -0.0235 0.1054 -0.0965 0.0049 0.0802 -0.0986 0.0511 0.0363 -0.1068 0.0901 0.0078 -0.0929 0.0967 -0.0339 -0.0500 0.1056
n = 1×51
0 0.0000 -0.0022 -0.0007 -0.0027 -0.0026 -0.0020 -0.0042 -0.0014 -0.0041 -0.0019 -0.0023 -0.0023 -0.0006 -0.0012 -0.0002 0.0012 -0.0003 0.0032 0.0005 0.0035 0.0024 0.0025 0.0037 0.0021 0.0030 0.0026 0.0011 0.0027 -0.0004
%% Function for creating Exogenous disturbance and noise
function [d, n] = ExogenousSignals(t, const)
d = sum(const.dist_amp.*sin(const.dist_freq*2*pi*t));
n = sum(const.noise_amp.*sin(const.noise_freq*2*pi*t));
end
  1 Comment
Sam Chak
Sam Chak on 18 Mar 2024
The synthesized 7th-order H-infinity () controller will generate the following trajectories for the 1st-order Integrator Plant.
%% Constants
a =-1; % Example value for the parameter alpha
b = 1; % Example value for the parameter beta
c = 1; % Example value for the parameter c
%% Process Plant
u_bar = -b*sqrt(-1/(c*a));
x_bar = [0;b/c];
Ap = [0 b;
0 -c]; % eqn 1 & 2:B
Bp = [2*a*u_bar;
0];
Cp = [1, 0];
Dp = 0;
Gp = ss(Ap, Bp, Cp, Dp);
Gp = tf(Gp)
Gp = 2 - s Continuous-time transfer function.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!