How can I keep the quaternion state normalized at every step in a MATLAB S-function, not just at the output?

34 views (last 30 days)
Hello,
I am simulating the dynamics of a quadrotor using a MATLAB S-function. The attitude is represented with a quaternion. I normalize it in mdlOutputs. However, I also need the quaternion to be normalized after each integration/update step, because the internal state vector x (which contains the quaternion) is what gets fed back into the dynamics.
I'm searching for something like "mdlUpdate", but it's used for discrete states.
Can you please advice me on how should I proceed?
Thanks in advance!
  1 Comment
Sam Chak
Sam Chak on 3 Sep 2025 at 6:16
You may need to use the normalized quaternion differential equations. However, I would suggest testing the basic integration code in MATLAB using the ode45 solver before implementing it in the Simulink S-function.
Could you provide the MATLAB code for basic attitude dynamics using the normalized quaternion differential equations? You can click the "play" icon to run the code in this forum.
function dx = normAttitude(t, x)
dx = [];
end
[t, x] = ode45(@normAttitude, tspan, x0);

Sign in to comment.

Accepted Answer

Broy
Broy on 5 Sep 2025 at 4:39
Hi NY AINA HENINTSOA,
From what I understand, you are simulating a quadrotor in Simulink using a MATLAB S-Function, and you’re representing the attitude with a quaternion. Right now, you’re normalizing the quaternion in mdlOutputs, but the actual continuous state vector ‘x’ can still drift from unit length during numerical integration. Since this internal state feeds back into your dynamics, that drift can cause inaccuracies. So, your main concern is how to ensure the quaternion remains normalized after each solver integration step, especially since mdlUpdate only applies to discrete states.
There are two potential ways to enforce normalization in your S-function:
1. Normalize inside mdlDerivatives:
This ensures the input quaternion used to calculate the state derivative is always clean and normalized.
function dx = normAttitude(t, x, omega)
% Normalize quaternion
q = x(1:4) / norm(x(1:4));
% ... rest of your quaternion kinematics and dynamics
dx = ...;
end
2. Use a projection method:
This is the "cleanest" method according to Simulink’s design. You register a Projection callback in your Level-2 MATLAB S-function. The Simulink solver calls Projection after each integration step, allowing you to “project” states back onto meaningful constraints (Normalization).
function setup(block)
% ... other setup code ...
block.RegBlockMethod('Projection', @projStates);
end
function projStates(block)
% Normalize quaternion part of the state
q = block.ContStates.Data(1:4);
block.ContStates.Data(1:4) = q / norm(q);
end
Helpful Links and Resources you can refer to:
Hope this helps.

More Answers (0)

Products


Release

R2025a

Community Treasure Hunt

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

Start Hunting!