I am trying to solve a system with seven differential equations. And I am having a hard time grapsing the ode45 solver.
These are the equations:
ω2_dot = -0.75 ω1 ω3
ω1_dot = 0.75 ω2 ω3 + 0.2
ω3_dot = 0
q1_dot = 1/2(ω1q4 + ω2q3 - ω3q2)
q2_dot = 1/2(ω2q4 + ω3q1 - ω1q3)
q3_dot = 1/2(ω3q4 + ω1q2 - ω2q2)
q4_dot = -1/2(ω1q1 + ω2q2 + ω3q3)
The initial values are listed in the inital_val
in the same order. Here is what I have so far:
inital_val = [1 -1 2 0 0 0 1];
timespan = [0:0.05:3.95];
[result t] = ode45(@soe,timespan,inital_val);
function [results,t]=soe(inital_val, timespan)
omega1_dot = -0.75*omega2*omega3;
omega2_dot = 0.75*omega2*omega3+0.2;
omega3_dot = 0;
q1_dot = (1/2)*(q4*omega1+omega2*q3-omega3*q2);
q2_dot = (1/2)*(q4*omega2+omega3*q1-omega1*q3);
q3_dot = (1/2)*(q4*omega3+omega1*q2-omega2*q2);
q4_dot = (1/2)*(q1*omega1+q2*omega2+q3*omega3);
results = [omega1 omega2 omega3 q1 q2 q3 q4];
end
However, it gives me this error message, which makes sense but I then don't know how to fix it:
Unrecognized function or variable 'omega2'.
Error in ode45_part>soe (line 10)
omega1_dot = -0.75*omega2*omega3;
Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
Error in ode45_part (line 7)
[result t] = ode45(@soe,timespan,inital_val);
Any help would be much appreciated
There are two fundamental problems with your code. First problem is you don't have the correct signature of the derivative function needed for use with ode45( ). Second problem is that blindly integrating quaternion elements this way will lead to non-unit quaternions. I don't know of an easy way to enforce this restriction when using ode45( ).
Let's tackle the easy problem first, the derivative function signature. Also your use of variables inside this function isn't correct. It needs to be like this:
function dy = soe(t,y) % Required signature is (time,state_vector)
% Pick off the named variables from the state vector y
omega1 = y(1);
omega2 = y(2);
omega3 = y(3);
q1 = y(4);
q2 = y(5);
q3 = y(6);
q4 = y(7);
% Calculate the variable derivatives
omega1_dot = -0.75*omega2*omega3; % IS THIS A TYPO? Should it be omega1*omega3?
omega2_dot = 0.75*omega2*omega3+0.2;
omega3_dot = 0;
q1_dot = (1/2)*(q4*omega1+omega2*q3-omega3*q2);
q2_dot = (1/2)*(q4*omega2+omega3*q1-omega1*q3);
q3_dot = (1/2)*(q4*omega3+omega1*q2-omega2*q2);
q4_dot = (1/2)*(q1*omega1+q2*omega2+q3*omega3);
% Group variable derivatives into a single column vector
dy = [omega1dot; omega2dot; omega3dot; q1_dot; q2_dot; q3_dot; q4_dot];
end
Also your angular rate initial values seem completely unreasonable for a rotation problem. They will be interpreted as [1 -1 2] radians/second. I suspect you wanted degrees/second for this, so you will need to scale down those values.
The second problem, that of keeping the quaternion elements forming a unit quaternion, is not going to be easy to overcome using ode45( ). All of the little integration errors will creep in driving the quaternion magnitude away from 1. Any subsequent use of this quaternion in your other code will have problems because of this. My only advice in this is to maybe abandon ode45( ) altogether and write your own custom integrator (e.g., RK4) so that at each step you can re-normalize the quaternion elements.