UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:7_state_ekf_with_bias

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
code:7_state_ekf_with_bias [2010/01/10 00:12] – created laurencebcode:7_state_ekf_with_bias [2010/01/10 00:23] (current) laurenceb
Line 1: Line 1:
-<code matlab> 
-function quat_IMU_bias(beta,alpha,q,b) 
  
 +===== Bias tracking in Octave =====
  
 + This has been tested with three axes of accel and gyro, adding a magnetometer will give a dramatic improvement as absolute yaw determination will be possible. Interestingly this filter is still able to filter out yaw gyro bias errors if the IMU is tilted - i.e. any roll or pitch.
  
 +
 +In the first plot you can see an artiffically introduced large yaw bias being corrected reasonably well after the first few manovers. Angles are in radians.
 +
 +{{code:bigbias.png|}}
 +
 + This second test uses raw test data with a sparkfun 6DOF IMU - i.e. actual biases. The intialisation of the filter was just guesstimated, and it takes a while to settle. However the values after 40 seconds are within 15% of the bias values obtained by interpolating between the gyro outputs when the IMU was stationary between movements.
 +
 +{{code:biases.png|}}
 +
 +
 +===== GNU Octave code =====
 +
 +<code matlab>
 +function quat_IMU_bias(beta,alpha,q,b)
 %constants--------------------------------------- %constants---------------------------------------
- 
 %beta=3e-6; - gyroscope noise %beta=3e-6; - gyroscope noise
- 
 %alpha=1e-4; - accelerometer noise %alpha=1e-4; - accelerometer noise
- 
 %q=4e-2 - quaternion process noise %q=4e-2 - quaternion process noise
 %b=1e-10 - gyro bias process noise  %b=1e-10 - gyro bias process noise 
 % ^ these are sensible values % ^ these are sensible values
- 
 #gyro_null=[0.0183;0.0101;0.0063]; #gyro_null=[0.0183;0.0101;0.0063];
- 
 gyro_gain=[1/1.3096,0,0;0,1/1.41875,0;0,0,1/1.54607]; gyro_gain=[1/1.3096,0,0;0,1/1.41875,0;0,0,1/1.54607];
- 
 delta_time=0.02857; %35 Hz sampling in this data set delta_time=0.02857; %35 Hz sampling in this data set
- 
 %read in the data - each data type is in a seperate row %read in the data - each data type is in a seperate row
- 
 fp=fopen('rpy90bothways.TXT','r'); fp=fopen('rpy90bothways.TXT','r');
- 
 data=fscanf(fp,'%f    %f    %f    %f    %f    %f    %f    %f    %f    %f',[10,inf]); data=fscanf(fp,'%f    %f    %f    %f    %f    %f    %f    %f    %f    %f',[10,inf]);
- 
 fclose(fp); fclose(fp);
- 
 j=size(data); j=size(data);
- 
 j=j(1,2); j=j(1,2);
- 
 x_nav=[0;0;0]; x_nav=[0;0;0];
- 
 v_nav=[0;0;0]; v_nav=[0;0;0];
 biases=[0;0;0]; biases=[0;0;0];
- 
 %setup Kalman filter %setup Kalman filter
- 
 x=[1;0;0;0;0;0;0]; x=[1;0;0;0;0;0;0];
- 
 P=[pi^2,0,0,0,0,0,0;0,pi^2,0,0,0,0,0;0,0,pi^2,0,0,0,0;0,0,0,pi^2,0,0,0;0,0,0,0,5e-7,0,0;0,0,0,0,0,5e-7,0;0,0,0,0,0,0,5e-7]; P=[pi^2,0,0,0,0,0,0;0,pi^2,0,0,0,0,0;0,0,pi^2,0,0,0,0;0,0,0,pi^2,0,0,0;0,0,0,0,5e-7,0,0;0,0,0,0,0,5e-7,0;0,0,0,0,0,0,5e-7];
 q/=35; q/=35;
- 
 Q=[q,0,0,0,0,0,0;0,q,0,0,0,0,0;0,0,q,0,0,0,0;0,0,0,q,0,0,0;0,0,0,0,b,0,0;0,0,0,0,0,b,0;0,0,0,0,0,0,b]; Q=[q,0,0,0,0,0,0;0,q,0,0,0,0,0;0,0,q,0,0,0,0;0,0,0,q,0,0,0;0,0,0,0,b,0,0;0,0,0,0,0,b,0;0,0,0,0,0,0,b];
- 
 %main loop--------------------------------------- %main loop---------------------------------------
- 
 for n=1:j; for n=1:j;
- 
     %takes vectors g and a as inputs for gyros and accels, g needs to be     %takes vectors g and a as inputs for gyros and accels, g needs to be
- 
     %premultiplied by delta time per run.     %premultiplied by delta time per run.
- 
     g=gyro_gain*data(2:4,n)*delta_time-x(5:7)-[0;0;0.001];     g=gyro_gain*data(2:4,n)*delta_time-x(5:7)-[0;0;0.001];
- 
     %get the accel vecor     %get the accel vecor
- 
     a=data(5:7,n);     a=data(5:7,n);
- 
     %a=-a for some of the sensors on the dataset;     %a=-a for some of the sensors on the dataset;
- 
     a(2)=-a(2);     a(2)=-a(2);
- 
     a(1)=-a(1);     a(1)=-a(1);
- 
     %normalise acceleration vector     %normalise acceleration vector
- 
     a=a/sqrt(a(1)^2+a(2)^2+a(3)^2);     a=a/sqrt(a(1)^2+a(2)^2+a(3)^2);
- 
     %accel sensor measurement jacobian     %accel sensor measurement jacobian
- 
     H=[2*x(3),2*x(4),2*x(1),2*x(2),0,0,0;-2*x(2),-2*x(1),2*x(4),2*x(3),0,0,0;2*x(1),-2*x(2),-2*x(3),2*x(4),0,0,0];     H=[2*x(3),2*x(4),2*x(1),2*x(2),0,0,0;-2*x(2),-2*x(1),2*x(4),2*x(3),0,0,0;2*x(1),-2*x(2),-2*x(3),2*x(4),0,0,0];
- 
     %misalignment error jacobian     %misalignment error jacobian
- 
     F=[1,-g(1)/2,-g(2)/2,-g(3)/2,x(2)/2,x(3)/2,x(4)/2;g(1)/2,1,g(3)/2,-g(2)/2,-x(1)/2,x(4)/2,-x(3)/2;g(2)/2,-g(3)/2,1,g(1)/2,-x(4)/2,-x(1)/2,x(2)/2;g(3)/2,g(2)/2,-g(1)/2,1,x(3)/2,-x(2)/2,-x(1)/2;0,0,0,0,1,0,0;0,0,0,0,0,1,0;0,0,0,0,0,0,1];     F=[1,-g(1)/2,-g(2)/2,-g(3)/2,x(2)/2,x(3)/2,x(4)/2;g(1)/2,1,g(3)/2,-g(2)/2,-x(1)/2,x(4)/2,-x(3)/2;g(2)/2,-g(3)/2,1,g(1)/2,-x(4)/2,-x(1)/2,x(2)/2;g(3)/2,g(2)/2,-g(1)/2,1,x(3)/2,-x(2)/2,-x(1)/2;0,0,0,0,1,0,0;0,0,0,0,0,1,0;0,0,0,0,0,0,1];
- 
     %input error jacobian     %input error jacobian
- 
     E=0.5*[-x(2),-x(3),-x(4);x(1),-x(4),x(3);x(4),x(1),-x(2);x(3),x(2),x(1);0,0,0;0,0,0;0,0,0];     E=0.5*[-x(2),-x(3),-x(4);x(1),-x(4),x(3);x(4),x(1),-x(2);x(3),x(2),x(1);0,0,0;0,0,0;0,0,0];
- 
     %propogate the state vector note the inclusion of 2*I     %propogate the state vector note the inclusion of 2*I
- 
     x=0.5*[2,-g(1),-g(2),-g(3),0,0,0;g(1),2,g(3),-g(2),0,0,0;g(2),-g(3),2,g(1),0,0,0;g(3),g(2),-g(1),2,0,0,0;0,0,0,0,2,0,0;0,0,0,0,0,2,0;0,0,0,0,0,0,2]*x;     x=0.5*[2,-g(1),-g(2),-g(3),0,0,0;g(1),2,g(3),-g(2),0,0,0;g(2),-g(3),2,g(1),0,0,0;g(3),g(2),-g(1),2,0,0,0;0,0,0,0,2,0,0;0,0,0,0,0,2,0;0,0,0,0,0,0,2]*x;
- 
     %normalise the quaternion     %normalise the quaternion
- 
     x(1:4)/=sqrt(x(1)^2+x(2)^2+x(3)^2+x(4)^2);     x(1:4)/=sqrt(x(1)^2+x(2)^2+x(3)^2+x(4)^2);
- 
     %propogate the covarience, can also use P+=, and subtract identity from F     %propogate the covarience, can also use P+=, and subtract identity from F
- 
     P=F*P*F'+E*E'*beta+Q;     P=F*P*F'+E*E'*beta+Q;
- 
     %find the residual     %find the residual
- 
     y=a-[2*(x(2)*x(4)+x(1)*x(3));2*(x(3)*x(4)-x(1)*x(2));x(1)^2-x(2)^2-x(3)^2+x(4)^2];     y=a-[2*(x(2)*x(4)+x(1)*x(3));2*(x(3)*x(4)-x(1)*x(2));x(1)^2-x(2)^2-x(3)^2+x(4)^2];
     fflush(stdout);     fflush(stdout);
- 
     %alpha is accel noise     %alpha is accel noise
- 
     S=H*P*H'+alpha*[1,0,0;0,1,0;0,0,1];     S=H*P*H'+alpha*[1,0,0;0,1,0;0,0,1];
- 
     %find gain     %find gain
- 
     K=P*H'*S^(-1);     K=P*H'*S^(-1);
- 
     %state update     %state update
- 
     x=x+(K*y);     x=x+(K*y);
- 
     %covariance update     %covariance update
- 
     P=P-K*H*P;     P=P-K*H*P;
- 
     %normalise quaternion     %normalise quaternion
- 
     x(1:4)/=sqrt(x(1)^2+x(2)^2+x(3)^2+x(4)^2);     x(1:4)/=sqrt(x(1)^2+x(2)^2+x(3)^2+x(4)^2);
     %work out the roll pitch and yaw (these are NOT EULER ANGLES)     %work out the roll pitch and yaw (these are NOT EULER ANGLES)
Line 129: Line 89:
  p_x=-p_x;  p_x=-p_x;
     endif     endif
- 
     yaw(n)=asin(norm(cross(trans_x,[p_x;0;p_z])));%asin the lenght to get the rotation angle     yaw(n)=asin(norm(cross(trans_x,[p_x;0;p_z])));%asin the lenght to get the rotation angle
- 
     if trans_x(2)<0 %account for ambiguity in sign caused by taking norm - check sign of y co-ord of transformed x     if trans_x(2)<0 %account for ambiguity in sign caused by taking norm - check sign of y co-ord of transformed x
  yaw(n)=-yaw(n);  yaw(n)=-yaw(n);
     endif     endif
     if trans_x(1)<   %mapping of x onto x is negative     if trans_x(1)<   %mapping of x onto x is negative
- 
         yaw(n)=pi-yaw(n);               %account for the ambiguity in asin         yaw(n)=pi-yaw(n);               %account for the ambiguity in asin
  if(yaw(n)>pi) %stay in range +-pi  if(yaw(n)>pi) %stay in range +-pi
  yaw(n)-=2*pi;  yaw(n)-=2*pi;
  endif  endif
- 
     endif     endif
- 
     if z_z<0 %this if for the case where we are inverted - the body z axis is in -ive z direction so reverse yaw     if z_z<0 %this if for the case where we are inverted - the body z axis is in -ive z direction so reverse yaw
- 
         yaw(n)=-yaw(n);         yaw(n)=-yaw(n);
- 
     endif     endif
     biases=[biases,x(5:7)/delta_time];     biases=[biases,x(5:7)/delta_time];
- 
 endfor endfor
- 
 plot(data(1,1:j),roll(1:j),"r",data(1,1:j),pitch(1:j),"g",data(1,1:j),yaw(1:j),"b"); plot(data(1,1:j),roll(1:j),"r",data(1,1:j),pitch(1:j),"g",data(1,1:j),yaw(1:j),"b");
- 
 h = legend('Roll','Pitch','Yaw',3); h = legend('Roll','Pitch','Yaw',3);
- 
 set(h,'Interpreter','none'); set(h,'Interpreter','none');
- 
 #plot(data(1,1:j),biases(1,1:j),"r",data(1,1:j),biases(2,1:j),"g",data(1,1:j),biases(3,1:j),"b"); #plot(data(1,1:j),biases(1,1:j),"r",data(1,1:j),biases(2,1:j),"g",data(1,1:j),biases(3,1:j),"b");
 endfunction endfunction
 </code> </code>
code/7_state_ekf_with_bias.1263082325.txt.gz · Last modified: 2010/01/10 00:12 by laurenceb

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki