Looking for an state controller for NON-linear systems

Hello, I have a non-linear state space model with some inputs and outputs and would now like to implement a state feedback (according to ACKERMANN) in SIMULINK. For this I have calculated my feedback coefficients K1, K2 and K3 with the "k=acker(A,b,p)" formula in Matlab.
Now I need a state controller. For this, there is the State Space Controller in the Matlab literature:
Can I use this for my non-linear model? I actually need a non-linear state controller. Which one can I use?
Thank you so much
-Martin
Attached my simulink project: matlab_mi.slx
Thats my model in simulink:

 Accepted Answer

Update: Since the system is nonlinear, traditional methods like Ackermann's method won't be suitable. However, you can still experiment with the suggested fundamental nonlinear state feedback control law in your Simulink model. To ensure the simulation stops when the spacecraft has safely touched down, an 'Events' function has been added.
It's important to note that this controller is conceptualized from a mathematical perspective. There are other practical engineering factors that need to be considered as well. For instance, increasing the value of the primary tuning parameter may initially cause an increase in mass, but it should gradually decrease due to fuel consumption. It wouldn't make sense for the mass to increase at the beginning.
%% Settings and Call ode45 solver
w = 0.037680; % Primary tuning parameter
tspan = [0 3000]; % simulation time
h0 = 15240; % initial descent altitude
hdot0 = -212.5; % initial descent velocity
m0 = 15264; % initial spacecraft mass
x0 = [h0, hdot0, m0];
options = odeset('RelTol', 1e-8, 'AbsTol', 1e-10, 'Events', @touchDownEventFcn);
[t, x] = ode45(@(t, x) LunarModuleEagle(t, x, w), tspan, x0, options);
%% Generate the Control Signal (mdot)
mdot = zeros(1, numel(t));
for j = 1:numel(t)
[~, mdot(j)] = LunarModuleEagle(t(j), x(j,:).', w);
end
init_u = mdot(1) % check if initial mdot ≤ 0 (cannot be > 0)
init_u = -8.1194e-05
%% Plot results
figure(1)
subplot(2,1,1)
plot(t/60, x(:,1), 'linewidth', 1.5, 'color', '#528AFA'), grid on
ylabel('h (m)', 'fontsize', 12);
title('Descent Altitude')
subplot(2,1,2)
plot(t/60, x(:,2), 'linewidth', 1.5, 'color', '#FA477A'), grid on
xlabel('t (min)', 'fontsize', 12)
ylabel('h'' (m/s)', 'fontsize', 12);
title('Rate of descent')
figure(2)
subplot(2,1,1)
plot(t/60, x(:,3), 'linewidth', 1.5, 'color', '#E7B03E'), grid on
ylabel('m (kg)', 'fontsize', 12);
title('Total Mass')
% xlim([0 0.02]) % check if mass obeys physical law
subplot(2,1,2)
plot(t/60, mdot, 'linewidth', 1.5, 'color', '#78A19B'), grid on
xlabel('t (min)', 'fontsize', 12)
ylabel('m'' (kg/s)','fontsize', 12);
title('Rate of change of Mass')
%% Fuel consumption
m = x(:,3);
m_used = m0 - m(end)
m_used = 4.9042e+03
%% Descending Equations of Motion for the Lunar Module Eagle
function [dxdt, mdot] = LunarModuleEagle(t, x, w)
% definitions
h = x(1); % state 1: descent altitude
hdot = x(2); % state 2: descent velocity
m = x(3); % state 3: spacecraft mass
% parameters
v = 3050; % not sure what to do with this?
Lg = 1.62; % lunar gravity
% state-feedback controller
wn = w;
kd = 2.5; % Secondary tuning parameter (if necessary)
Lg_Off_h = 0.21; % Off upon reaching 21 cm above surface
mdot = (m*(kd*wn*hdot + (wn^2)*h - Lg*(sign(x(1) - Lg_Off_h) + 1)/2))/v;
% mdot = -14.8018 % OP's fixed value
% ODEs
dxdt(1,1) = hdot;
dxdt(2,1) = (- v*mdot - m*Lg)/m; % m*h" = - v*m' - m*g;
dxdt(3,1) = mdot;
end
%% Stop simulation when the spacecraft has safely touched down on lunar surface
function [position,isterminal,direction] = touchDownEventFcn(t, x)
position = x(1); % The state variable that we want to be zero
isterminal = 1; % Halt integration
direction = -1; % The zero can be approached when x1 is decreasing
end

9 Comments

Hello Sam Chak! Thanks for your answer. That's what I thought: I can't use Ackermann's procedure directly. My task from my professor is to use state feedback to adjust my u so that fuel consumption is minimal.
How can I adjust my u with my altitude and speed parameters so that my mass m (including fuel) of the ferry remains maximum?
I inserted a MATLAB FUNCTION block into my model and transferred its code to a *.m file.
Thank you very much for the help!!!
Based on your latest Simulink model, it appears that you have assigned as the control variable. However, this assignment is not clearly mentioned in the original question. In my previous answer, I proposed a controller that assigned the velocity as the control variable, so the proposed controller is no longer valid.
I would advise you to validate the dynamics of the Lunar Module Eagle, particularly regarding the term . Is m/s a constant throughout the descent? If it is, the space vehicle will crash on the lunar surface at this speed. This is an important consideration to address.
Furthermore, the original control problem has now become an optimization problem. This is another technical issue that should be addressed separately once a nonlinear state-feedback controller is satisfactorily designed.
Hello Sam, I would like to use my state controller to bring the control variable u (mass change) into different states. For example, at the beginning of the descent I would like to descend without consuming fuel (fuel is the mass + weight of the ferry). Later, I switch on my engine with my manipulated variable u (v = 3050 m/s constant) in order to land gently on the moon. The u can assume different values. This allows me to compare whether it makes sense in terms of fuel to start the engine very late or right from the start. Can I develop (first of all without optimisation) a simple state feedback depending on my altitude and speed?
Enclosed is a picture of my scope with a fixed control value u, so that I land gently on the moon.
I believe you can start by developing a simple state feedback controller before diving into the optimization problem. Based on the updated Simulink model, it appears that you have assigned a fixed value for , and it seems that the spacecraft touched down after around 2 minutes. I'm not entirely sure how you achieved this without crashing the spacecraft onto the surface.
In any case, I have made some modifications to my previous answer and updated the code accordingly. I suggest deriving the control system equations and writing code that models the descent of the spacecraft. This approach will make it easier to identify any mistakes in typos, signs, or the improper usage of mathematical functions. Once the code is successfully implemented, constructing a Simulink model based on the MATLAB code will become a straightforward task.
Hey Sam, thank you very much! I have now implemented the solution in Simulink using a MATLAB Function Block and transferred my inputs and output (mdot) from SIMULINK to MATLAB.
MATLAB now calculates the feedback and I transfer the feedback (mdot) to the input m' of the model.
Unfortunately, I often get errors as feedback that my mdot array (back from MATLAB to SIMULINK) is full. What could be the reason? Here is the interface in the Function Block in Simulink:
Can you take a look and try to fix the error?
Attached my .slx simulink file and the fcn.m matlab file.
Thank you very much!!!
-Martin
It seems that there might be a slight confusion regarding the structure of the code. It appears that you may be unfamiliar with or unable to recognize the code's structure. I want to clarify that the entire code in my Answer above is actually written for solving the ODE dynamics of the Lunar descent in MATLAB, rather than for Simulink. In your original question, you inquired about a nonlinear state-feedback controller, specifically the mdot equation. In response, I provided a proposed solution and tested it on the Lunar module in MATLAB.
No need to worry, what you need to do now is to implement the mdot equation as follows:
%% Nonlinear State-feedback Controller
mdot = (m*(kd*wn*hdot + (wn^2)*h - Lg*(sign(x(1) - Lg_Off_h) + 1)/2))/v;
You can choose to implement this equation using either fundamental blocks or the MATLAB Function block, depending on your preference. If you opt for multiple fundamental blocks, please ensure that you enter the equation accurately, as it contains nested parentheses.
Hello Sam, the repatriation finally worked. I inserted mdot as a function block. Now my question: How did you come across the mdot?
The lunar descent dynamics is given by
... Eq. (1)
If we design as (this was actually my initial design)
... Eq. (2)
and substitute it into the dynamics, we get
.
Expanding it, we can cancel out the effect of lunar gravity
which compensated system dynamics can be simplified as a simple harmonic motion:
. ... Eq. (3)
However, due to the inaccuracies or oversimplifications in the descent dynamics of Eq. (1), if we implement the controller in Eq. (2), the descent altitude h (from Eq. 3) won't reach zero in finite time. The controller will keep firing the thrust, perfectly counteracting the effect of gravity until all the fuel is burned out.
One way to address this issue is by modifying Eq. (2) and disabling the "gravity canceller" term when the descent altitude is reached, allowing lunar gravity to take over. In my simulation, I let the spacecraft "drop" from 21 cm above the surface.
... Eq. (4)
Hello The variable "v" refers to the velocity of the exhaust gases with respect to the spacecraft. [m/sec]. The value of this variable must be applied while the ship has fuel, so that when has used up all the fuel, v must be worth 0 Therefore, it is necessary to have the net mass of the lunar module. After reviewing the website https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=1969-059C I have calculated that the net mass must be 4821 Kg. Below I show the code I am using:
function [dxdt, u] = LunarModuleEagle(t, x, w)
% Descending Equations of Motion for the Lunar Module Eagle
% definitions
h = x(1); % state 1: descent altitude
hdot = x(2); % state 2: descent velocity
m = x(3); % state 3: spacecraft mass
m_neta = 4821;
if (m > m_neta)
v = 3050; % velocity of the exhaust gases with respect to the spacecraft
else
v = 0;
end
Lg = 1.623; % lunar gravity [m/seg^2]
% state-feedback controller
wn = w;
kd = 2.5; % Secondary tuning parameter (if necessary)
Lg_Off_h = 0.21; % Off upon reaching 21 cm above surface
u = (m*(kd*wn*hdot + (wn^2)*h - Lg*(sign(x(1) - Lg_Off_h) + 1)/2))/v;
% u = -14.8018 % OP's fixed value
% ODEs
dxdt(1,1) = hdot;
dxdt(2,1) = (- v*u - m*Lg)/m; % m*h" = - v*m' - m*g;
dxdt(3,1) = u;
end

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!