mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-04 20:51:35 +08:00
matlab: Add derivation of observation Jacobians used by the terrain estimator
This commit is contained in:
@@ -0,0 +1,91 @@
|
|||||||
|
% IMPORTANT - This script requires the Matlab symbolic toolbox
|
||||||
|
% Derivation of EKF equations for estimation of terrain height offset
|
||||||
|
% Author: Paul Riseborough
|
||||||
|
% Last Modified: 20 June 2017
|
||||||
|
|
||||||
|
% State vector:
|
||||||
|
|
||||||
|
% terrain vertical position (ptd)
|
||||||
|
|
||||||
|
% Observations:
|
||||||
|
|
||||||
|
% line of sight (LOS) angular rate measurements (rel to sensor frame)
|
||||||
|
% from a downwards looking optical flow sensor measured in rad/sec about
|
||||||
|
% the X and Y sensor axes. These rates are motion compensated.
|
||||||
|
|
||||||
|
% A positive LOS X rate is a RH rotation of the image about the X sensor
|
||||||
|
% axis, and is produced by either a positive ground relative velocity in
|
||||||
|
% the direction of the Y axis.
|
||||||
|
|
||||||
|
% A positive LOS Y rate is a RH rotation of the image about the Y sensor
|
||||||
|
% axis, and is produced by either a negative ground relative velocity in
|
||||||
|
% the direction of the X axis.
|
||||||
|
|
||||||
|
% Range measurement aligned with the Z body axis (flat earth model assumed)
|
||||||
|
|
||||||
|
% Time varying parameters:
|
||||||
|
|
||||||
|
% quaternion parameters defining the rotation from navigation to body axes
|
||||||
|
% NED flight vehicle velocities
|
||||||
|
% vehicle vertical position
|
||||||
|
|
||||||
|
clear all;
|
||||||
|
|
||||||
|
%% define symbolic variables and constants
|
||||||
|
syms vel_x vel_y vel_z real % NED velocity : m/sec
|
||||||
|
syms R_OPT real % variance of LOS angular rate mesurements : (rad/sec)^2
|
||||||
|
syms R_RNG real % variance of range finder measurement : m^2
|
||||||
|
syms stateNoiseVar real % state process noise variance
|
||||||
|
syms pd real % position of vehicle in down axis : (m)
|
||||||
|
syms ptd real % position of terrain in down axis : (m)
|
||||||
|
syms q0 q1 q2 q3 real % quaternions defining attitude of body axes relative to local NED
|
||||||
|
syms Popt real % state variance
|
||||||
|
nStates = 1;
|
||||||
|
|
||||||
|
|
||||||
|
%% derive Jacobians for fusion of optical flow measurements
|
||||||
|
syms vel_x vel_y vel_z real % NED velocity : m/sec
|
||||||
|
syms pd real % position of vehicle in down axis : (m)
|
||||||
|
syms ptd real % position of terrain in down axis : (m)
|
||||||
|
syms q0 q1 q2 q3 real % quaternions defining attitude of body axes relative to local NED
|
||||||
|
|
||||||
|
% derive the body to nav direction cosine matrix
|
||||||
|
Tbn = Quat2Tbn([q0,q1,q2,q3]);
|
||||||
|
|
||||||
|
% calculate relative velocity in sensor frame
|
||||||
|
relVelSensor = transpose(Tbn)*[vel_x;vel_y;vel_z];
|
||||||
|
|
||||||
|
% calculate range to centre of flow sensor fov assuming flat earth
|
||||||
|
range = ((ptd - pd)/Tbn(3,3));
|
||||||
|
|
||||||
|
% divide velocity by range to get predicted motion compensated flow rates
|
||||||
|
optRateX = relVelSensor(2)/range;
|
||||||
|
optRateY = -relVelSensor(1)/range;
|
||||||
|
|
||||||
|
% calculate the observation jacobians
|
||||||
|
H_OPTX = jacobian(optRateX,ptd);
|
||||||
|
H_OPTY = jacobian(optRateY,ptd);
|
||||||
|
H_OPT = [H_OPTX;H_OPTY];
|
||||||
|
ccode(H_OPT,'file','H_OPT.c');
|
||||||
|
fix_c_code('H_OPT.c');
|
||||||
|
|
||||||
|
clear all;
|
||||||
|
reset(symengine)
|
||||||
|
|
||||||
|
%% derive Jacobian for fusion of range finder measurements
|
||||||
|
syms vel_x vel_y vel_z real % NED velocity : m/sec
|
||||||
|
syms R_RNG real % variance of range finder measurement : m^2
|
||||||
|
syms pd real % position of vehicle in down axis : (m)
|
||||||
|
syms ptd real % position of terrain in down axis : (m)
|
||||||
|
syms q0 q1 q2 q3 real % quaternions defining attitude of body axes relative to local NED
|
||||||
|
|
||||||
|
% derive the body to nav direction cosine matrix
|
||||||
|
Tbn = Quat2Tbn([q0,q1,q2,q3]);
|
||||||
|
|
||||||
|
% calculate range assuming flat earth
|
||||||
|
range = ((ptd - pd)/Tbn(3,3));
|
||||||
|
|
||||||
|
% calculate range observation Jacobian
|
||||||
|
H_RNG = jacobian(range,ptd); % measurement Jacobian
|
||||||
|
ccode(H_RNG,'file','H_RNG.c');
|
||||||
|
fix_c_code('H_RNG.c');
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
t2 = q0*q0;
|
||||||
|
t3 = q1*q1;
|
||||||
|
t4 = q2*q2;
|
||||||
|
t5 = q3*q3;
|
||||||
|
t6 = pd-ptd;
|
||||||
|
t7 = 1.0/(t6*t6);
|
||||||
|
t8 = q0*q3*2.0;
|
||||||
|
t9 = t2-t3-t4+t5;
|
||||||
|
A0[0][0] = -t7*t9*(vel_z*(q0*q1*2.0+q2*q3*2.0)+vel_y*(t2-t3+t4-t5)-vel_x*(t8-q1*q2*2.0));
|
||||||
|
A0[1][0] = t7*t9*(-vel_z*(q0*q2*2.0-q1*q3*2.0)+vel_x*(t2+t3-t4-t5)+vel_y*(t8+q1*q2*2.0));
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
A0[0][0] = 1.0/(q0*q0-q1*q1-q2*q2+q3*q3);
|
||||||
Reference in New Issue
Block a user