SlideShare a Scribd company logo
Android Sensor Fusion
Shereef Shehata
android::Fusion Class
android::Fusion Class
• Public Member Functions
Fusion ()
void init ()
void handleGyro (const vec3_t &w, float dT)
status_t handleAcc (const vec3_t &a)
status_t handleMag (const vec3_t &m)
vec4_t getAttitude () const
vec3_t getBias () const
mat33_t getRotationMatrix () const
bool hasEstimate () const
android::Fusion Class
• Private Types
ACC = 0x1
MAG = 0x2
GYRO = 0x4
enum { ACC = 0x1, MAG = 0x2, GYRO = 0x4 }
android::Fusion Class
• Private Member Functions
bool checkInitComplete (int, const vec3_t &w, float d=0)
void initFusion (const vec4_t &q0, float dT)
void checkState ()
void predict (const vec3_t &w, float dT)
void update (const vec3_t &z, const vec3_t &Bi, float sigma)
android::Fusion Class
• Static Private Member Functions
static mat34_t getF (const vec4_t &p)
android::Fusion Class
• Private Attributes
quat_t X0 Modified Rodrigues parameters
The function getAttitue() returns x0
vec3_t X1 The estimated gyro bias
The function getBias() returns x1
mat< mat33_t, 2, 2 >
P
The predicated covariance matrix is
made of 4 3x3 sub-matrices and it is
semi-definite positive.
mat< mat33_t, 2, 2 > GQGt The process noise covariance matrix
mat< mat33_t, 2, 2 > Phi
vec3_t Ba
vec3_t Bm
uint32_t mInitState
float mGyroRate
vec< vec3_t, 3 > mData
size_t mCount [3]
android::Fusion Class
Public Member Functions
Class Constructor android::Fusion::Fusion()
• Class Constructor
Fusion::Fusion() {
Phi[0][1] = 0;
Phi[1][1] = 1;
Ba.x = 0;
Ba.y = 0;
Ba.z = 1;
Bm.x = 0;
Bm.y = 1;
Bm.z = 0;
x0 = 0;
x1 = 0;
init();
}
android::Fusion::init()
• Init()
void Fusion::init() {
mInitState = 0;
mGyroRate = 0;
mCount[0] = 0;
mCount[1] = 0;
mCount[2] = 0;
mData = 0;
}
android::Fusion::handleGyro ()
• Caller Graph
• Call graph
void Fusion::handleGyro(const vec3_t& w, float dT) {
if (!checkInitComplete(GYRO, w, dT))
return;
predict(w, dT);
}
android::Fusion::handleAcc (const vec3_t& a )
• Caller graph
• Call graph
android::Fusion::handleAcc (const vec3_t& a )
status_t Fusion::handleAcc(const vec3_t& a) {
// ignore acceleration data if we're close to free-fall
if (length_squared(a) < FREE_FALL_THRESHOLD_SQ) {
return BAD_VALUE;
}
if (!checkInitComplete(ACC, a))
return BAD_VALUE;
const float l = 1/length(a);
update(a*l, Ba, accSTDEV*l);
return NO_ERROR;
}
android::Fusion::handleMag (const vec3_t& m )
• Caller graph
• Call graph
android::Fusion::handleMag (const vec3_t& m )
status_t Fusion::handleMag(const vec3_t& m) {
// the geomagnetic-field should be between 30uT and 60uT
// reject if too large to avoid spurious magnetic sources
const float magFieldSq = length_squared(m);
if (magFieldSq > MAX_VALID_MAGNETIC_FIELD_SQ) {
return BAD_VALUE;
} else if (magFieldSq < MIN_VALID_MAGNETIC_FIELD_SQ) {
// Also reject if too small since we will get ill-defined (zero mag)
// cross-products below
return BAD_VALUE;
}
if (!checkInitComplete(MAG, m))
return BAD_VALUE;
// Orthogonalize the magnetic field to the gravity field, mapping it into
// tangent to Earth.
const vec3_t up( getRotationMatrix() * Ba );
const vec3_t east( cross_product(m, up) );
// If the m and up vectors align, the cross product magnitude will
// approach 0.
// Reject this case as well to avoid div by zero problems and
// ill-conditioning below.
if (length_squared(east) < MIN_VALID_CROSS_PRODUCT_MAG_SQ) {
return BAD_VALUE;
}
// If we have created an orthogonal magnetic field successfully,
// then pass it in as the update.
vec3_t north( cross_product(up, east) );
const float l = 1 / length(north);
north *= l;
update(north, Bm, magSTDEV*l);
return NO_ERROR;
}
android::Fusion::getAttitude()
• Caller graph
vec4_t Fusion::getAttitude() const {
return x0;
}
android::Fusion::getBias()
• Caller graph
vec3_t Fusion::getBias() const {
return x1;
}
android::Fusion::getRotationMatrix ()
• Caller graph
• Call graph
android::Fusion::hasEstimate () const
• Caller graph
• Call graph
android::Fusion Class
Private Member Functions
android::Fusion::checkInitComplete()
• Caller graph
• Call graph
android::Fusion::InitFusion()
• Caller graph
• Call graph
android::Fusion::checkState()
• Caller graph
• Call graph
android::Fusion::predict()
• Caller graph
• Call graph
00372 void Fusion::predict(const vec3_t& w, float dT) {
00373 const vec4_t q = x0;
00374 const vec3_t b = x1;
00375 const vec3_t we = w - b;
00376
00377 // q(k+1) = O(we)*q(k)
00378 // --------------------
00379 //
00380 // O(w) = | cos(0.5*||w||*dT)*I33 - [psi]x psi |
00381 // | -psi' cos(0.5*||w||*dT) |
00382 //
00383 // psi = sin(0.5*||w||*dT)*w / ||w||
00384 //
00385 //
00386 // P(k+1) = Phi(k)*P(k)*Phi(k)' + G*Q(k)*G'
00387 // ----------------------------------------
00388 //
00389 // G = | -I33 0 |
00390 // | 0 I33 |
00391 //
00392 // Phi = | Phi00 Phi10 |
00393 // | 0 1 |
00394 //
00395 // Phi00 = I33
00396 // - [w]x * sin(||w||*dt)/||w||
00397 // + [w]x^2 * (1-cos(||w||*dT))/||w||^2
00398 //
00399 // Phi10 = [w]x * (1 - cos(||w||*dt))/||w||^2
00400 // - [w]x^2 * (||w||*dT - sin(||w||*dt))/||w||^3
00401 // - I33*dT
00402
00403 const mat33_t I33(1);
00404 const mat33_t I33dT(dT);
00405 const mat33_t wx(crossMatrix(we, 0));
00406 const mat33_t wx2(wx*wx);
00407 const float lwedT = length(we)*dT;
00408 const float hlwedT = 0.5f*lwedT;
00409 const float ilwe = 1/length(we);
00410 const float k0 = (1-cosf(lwedT))*(ilwe*ilwe);
00411 const float k1 = sinf(lwedT);
00412 const float k2 = cosf(hlwedT);
00413 const vec3_t psi(sinf(hlwedT)*ilwe*we);
00414 const mat33_t O33(crossMatrix(-psi, k2));
00415 mat44_t O;
00416 O[0].xyz = O33[0]; O[0].w = -psi.x;
00417 O[1].xyz = O33[1]; O[1].w = -psi.y;
00418 O[2].xyz = O33[2]; O[2].w = -psi.z;
00419 O[3].xyz = psi; O[3].w = k2;
00420
00421 Phi[0][0] = I33 - wx*(k1*ilwe) + wx2*k0;
00422 Phi[1][0] = wx*k0 - I33dT - wx2*(ilwe*ilwe*ilwe)*(lwedT-k1);
00423
00424 x0 = O*q;
00425 if (x0.w < 0)
00426 x0 = -x0;
00427
00428 P = Phi*P*transpose(Phi) + GQGt;
00429
00430 checkState();
00431 }
android::Fusion::update()
• Caller graph
• Call graph
android:: Class
Helper Functions
android::Fusion::scaleCovariance ()
scaleCovariance (
const mat<TYPE, C, R>& A,
const mat<TYPE, C, C>& P) computes the following:
• A * P * transpose(A)
android::Fusion::scaleCovariance ()
• Caller graph
template <typename TYPE, size_t C, size_t R>
static mat<TYPE, R, R> scaleCovariance(
const mat<TYPE, C, R>& A,
const mat<TYPE, C, C>& P) {
// A*P*transpose(A);
mat<TYPE, R, R> APAt;
for (size_t r=0 ; r<R ; r++) {
for (size_t j=r ; j<R ; j++) {
double apat(0);
for (size_t c=0 ; c<C ; c++) {
double v(A[c][r]*P[c][c]*0.5);
for (size_t k=c+1 ; k<C ; k++)
v += A[k][r] * P[c][k];
apat += 2 * v * A[c][j];
}
APAt[j][r] = apat;
APAt[r][j] = apat;
}
}
return APAt;
}
android::Fusion::crossMatrix ()
crossMatix (
const vec<TYPE, 3>& p,
OTHER_TYPE diag) computes the following:
• Given a value “diag” and a vector p, with components X,Y,Z, it construct a 3x3
matrix as follows:
diag Z -Y
-Z diag X
Y -X diag
android::Fusion::crossMatrix ()
• Caller graph
template <typename TYPE, typename OTHER_TYPE>
static mat<TYPE, 3, 3> crossMatrix(const vec<TYPE, 3>& p, OTHER_TYPE diag) {
mat<TYPE, 3, 3> r;
r[0][0] = diag;
r[1][1] = diag;
r[2][2] = diag;
r[0][1] = p.z;
r[1][0] =-p.z;
r[0][2] =-p.y;
r[2][0] = p.y;
r[1][2] = p.x;
r[2][1] =-p.x;
return r;
}
android::Fusion::quatToMatrix ()
quatToMatrix (const vec< TYPE, 4 > & q) computes the following:
• If the Quaternion operator qvq* (triple product quaternion) is applied to vector
v
• The equivalent matrix that produce the same result as the triple prod
• w = qvq* = Q v
android::Fusion::quatToMatrix ()
• Caller graph
template <typename TYPE>
mat<TYPE, 3, 3> quatToMatrix(const vec<TYPE, 4>& q) {
mat<TYPE, 3, 3> R;
TYPE q0(q.w);
TYPE q1(q.x);
TYPE q2(q.y);
TYPE q3(q.z);
TYPE sq_q1 = 2 * q1 * q1;
TYPE sq_q2 = 2 * q2 * q2;
TYPE sq_q3 = 2 * q3 * q3;
TYPE q1_q2 = 2 * q1 * q2;
TYPE q3_q0 = 2 * q3 * q0;
TYPE q1_q3 = 2 * q1 * q3;
TYPE q2_q0 = 2 * q2 * q0;
TYPE q2_q3 = 2 * q2 * q3;
TYPE q1_q0 = 2 * q1 * q0;
R[0][0] = 1 - sq_q2 - sq_q3;
R[0][1] = q1_q2 - q3_q0;
R[0][2] = q1_q3 + q2_q0;
R[1][0] = q1_q2 + q3_q0;
R[1][1] = 1 - sq_q1 - sq_q3;
R[1][2] = q2_q3 - q1_q0;
R[2][0] = q1_q3 - q2_q0;
R[2][1] = q2_q3 + q1_q0;
R[2][2] = 1 - sq_q1 - sq_q2;
return R;
}
gyroVAR
gyroVAR gives the measured variance of the gyro's output per Hz (or variance at 1
Hz).
• This is an "intrinsic" parameter of the gyro, which is independent of the sampling
frequency.
• static const float gyroVAR = 1e-7; // (rad/s)^2 / Hz
• The variance of gyro's output at a given sampling period can be calculated as:
variance(T) = gyroVAR / T
* The variance of the INTEGRATED OUTPUT at a given sampling period can be
calculated as:
variance_integrate_output(T) = gyroVAR * T
Standard deviations of accelerometer and magnetometer
• Standard deviation of the Accelerometer
static const float accSTDEV = 0.05f; // m/s^2 (measured 0.08 / CDD 0.05)
• Standard deviation of the Magnetometer
static const float magSTDEV = 0.5f; // uT (measured 0.7 / CDD 0.5)
Accelerometer Updates at or near freefall
• Accelerometer updates will not be performed near free fall to avoid ill-
conditioning and div by zeros.
• Threshhold:
– 10% of g, in m/s^2
– Since g is 9.8 m/s^2
– 10% of g is 0.98 m/s^2
static const float FREE_FALL_THRESHOLD = 0.981f;
static const float FREE_FALL_THRESHOLD_SQ = FREE_FALL_THRESHOLD*FREE_FALL_THRESHOLD;
• The value of g
Location
Distance from Earth's center
(m)
Value of g
(m/s2)
Earth's surface 6.38 x 106 m 9.8
Standard deviations of accelerometer
• Accelerometer Standard Deviation, accSTDEV
static const float accSTDEV = 0.05f; // m/s^2 (measured 0.08 / CDD 0.05)
• How is the standard deviation of the Accelerometer measures?
• What is CCD?
Standard deviations of magnetometer
• Accelerometer Standard Deviation, magSTDEV
• static const float magSTDEV = 0.5f; // uT (measured 0.7 / CDD 0.5)
• How is the standard deviation of the magnetometer measures?
• What is CCD?
The geomagnetic-field, MAX values
• The geomagnetic-field should be between 30uT and 60uT.
• Fields strengths greater than this likely indicate a local magnetic disturbance which
we do not want to update into the fused frame.
static const float MAX_VALID_MAGNETIC_FIELD = 100; // uT
static const float MAX_VALID_MAGNETIC_FIELD_SQ = MAX_VALID_MAGNETIC_FIELD * MAX_VALID_MAGNETIC_FIELD;
The geomagnetic-field, MIN values
• Values of the field smaller than this should be ignored in fusion to avoid ill-
conditioning.
• This state can happen with anomalous local magnetic disturbances canceling the
Earth field.
static const float MIN_VALID_MAGNETIC_FIELD = 10; // uT
static const float MIN_VALID_MAGNETIC_FIELD_SQ = MIN_VALID_MAGNETIC_FIELD * MIN_VALID_MAGNETIC_FIELD;
Cross product of two vectors, Minimum Values
• If the cross product of two vectors has magnitude squared less than this, we reject
it as invalid due to alignment of the vectors.
• This threshold is used to check for the case where the magnetic field sample is
parallel to the gravity field, which can happen in certain places due to magnetic
field disturbances.
static const float MIN_VALID_CROSS_PRODUCT_MAG = 1.0e-3;
static const float MIN_VALID_CROSS_PRODUCT_MAG_SQ = MIN_VALID_CROSS_PRODUCT_MAG * MIN_VALID_CROSS_PRODUCT_MAG;

More Related Content

Viewers also liked

From sensor data_to_android_and_back
From sensor data_to_android_and_backFrom sensor data_to_android_and_back
From sensor data_to_android_and_back
Droidcon Berlin
 
Android 1.8 sensor
Android 1.8 sensorAndroid 1.8 sensor
Android 1.8 sensor
Ahsanul Karim
 
Sensor-driven indoor localization with android #bcs2
Sensor-driven indoor localization with android #bcs2Sensor-driven indoor localization with android #bcs2
Sensor-driven indoor localization with android #bcs2
Stephan Linzner
 
Andromeda: An Android Framework for Sensor-based Applications
Andromeda: An Android Framework for Sensor-based ApplicationsAndromeda: An Android Framework for Sensor-based Applications
Andromeda: An Android Framework for Sensor-based Applications
Ramon Ribeiro Rabello
 
Introduction to Android G-sensor
Introduction to Android G-sensorIntroduction to Android G-sensor
Introduction to Android G-sensor
Johnson Chou
 
Sensor fusion between car and smartphone
Sensor fusion between car and smartphoneSensor fusion between car and smartphone
Sensor fusion between car and smartphone
Gabor Paller
 
Android Development: The Basics
Android Development: The BasicsAndroid Development: The Basics
Android Development: The Basics
Mike Desjardins
 
Android accelerometer sensor tutorial
Android accelerometer sensor tutorialAndroid accelerometer sensor tutorial
Android accelerometer sensor tutorial
info_zybotech
 
Better motion control using accelerometer/gyroscope sensor fusion
Better motion control using accelerometer/gyroscope sensor fusionBetter motion control using accelerometer/gyroscope sensor fusion
Better motion control using accelerometer/gyroscope sensor fusion
Gabor Paller
 

Viewers also liked (9)

From sensor data_to_android_and_back
From sensor data_to_android_and_backFrom sensor data_to_android_and_back
From sensor data_to_android_and_back
 
Android 1.8 sensor
Android 1.8 sensorAndroid 1.8 sensor
Android 1.8 sensor
 
Sensor-driven indoor localization with android #bcs2
Sensor-driven indoor localization with android #bcs2Sensor-driven indoor localization with android #bcs2
Sensor-driven indoor localization with android #bcs2
 
Andromeda: An Android Framework for Sensor-based Applications
Andromeda: An Android Framework for Sensor-based ApplicationsAndromeda: An Android Framework for Sensor-based Applications
Andromeda: An Android Framework for Sensor-based Applications
 
Introduction to Android G-sensor
Introduction to Android G-sensorIntroduction to Android G-sensor
Introduction to Android G-sensor
 
Sensor fusion between car and smartphone
Sensor fusion between car and smartphoneSensor fusion between car and smartphone
Sensor fusion between car and smartphone
 
Android Development: The Basics
Android Development: The BasicsAndroid Development: The Basics
Android Development: The Basics
 
Android accelerometer sensor tutorial
Android accelerometer sensor tutorialAndroid accelerometer sensor tutorial
Android accelerometer sensor tutorial
 
Better motion control using accelerometer/gyroscope sensor fusion
Better motion control using accelerometer/gyroscope sensor fusionBetter motion control using accelerometer/gyroscope sensor fusion
Better motion control using accelerometer/gyroscope sensor fusion
 

Similar to Fusion_Class

MOVIMIENTO_CURVILINEO_SEMANSKY.pdf
MOVIMIENTO_CURVILINEO_SEMANSKY.pdfMOVIMIENTO_CURVILINEO_SEMANSKY.pdf
MOVIMIENTO_CURVILINEO_SEMANSKY.pdf
Widmar Aguilar Gonzalez
 
Experimental Investigation of Faults in Roller Element Bearing Using Vibratio...
Experimental Investigation of Faults in Roller Element Bearing Using Vibratio...Experimental Investigation of Faults in Roller Element Bearing Using Vibratio...
Experimental Investigation of Faults in Roller Element Bearing Using Vibratio...
IRJET Journal
 
HIDRAULICA DE CANALES
HIDRAULICA DE CANALESHIDRAULICA DE CANALES
HIDRAULICA DE CANALES
Dennis Ventura Huaman
 
Paper_Flutter
Paper_FlutterPaper_Flutter
Paper_Flutter
Ram Mohan
 
Embedded Programming for Quadcopters
Embedded Programming for QuadcoptersEmbedded Programming for Quadcopters
Embedded Programming for Quadcopters
Ryan Boland
 
Comparison GUM versus GUM+1
Comparison GUM  versus GUM+1Comparison GUM  versus GUM+1
Comparison GUM versus GUM+1
Maurice Maeck
 
How to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJITHow to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJIT
Egor Bogatov
 
12
1212
Prelude to halide_public
Prelude to halide_publicPrelude to halide_public
Prelude to halide_public
Fixstars Corporation
 
Generating lisp program for assembly drawing in AutoCAD
Generating lisp program for assembly drawing in AutoCAD Generating lisp program for assembly drawing in AutoCAD
Generating lisp program for assembly drawing in AutoCAD
ISAAC SAMUEL RAJA T
 
2Part I1. Answer questions for the following graph, if .docx
2Part I1. Answer questions for the following graph, if .docx2Part I1. Answer questions for the following graph, if .docx
2Part I1. Answer questions for the following graph, if .docx
gilbertkpeters11344
 
Coscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usageCoscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usage
Wayne Tsai
 
Programming with OpenGL
Programming with OpenGLProgramming with OpenGL
Programming with OpenGL
Syed Zaid Irshad
 
CAPACITIVE SENSORS ELECTRICAL WAFER SORT
CAPACITIVE SENSORS ELECTRICAL WAFER SORTCAPACITIVE SENSORS ELECTRICAL WAFER SORT
CAPACITIVE SENSORS ELECTRICAL WAFER SORT
Massimo Garavaglia
 
Aircraft Performance and Design Project Code
Aircraft Performance and Design Project CodeAircraft Performance and Design Project Code
Aircraft Performance and Design Project Code
Elliot Farquhar
 
Design of an automotive differential with reduction ratio greater than 6
Design of an automotive differential with reduction ratio greater than 6Design of an automotive differential with reduction ratio greater than 6
Design of an automotive differential with reduction ratio greater than 6
eSAT Publishing House
 
Querying solr
Querying solrQuerying solr
Querying solr
Samuel Solís Fuentes
 
DrillBits WorkBook (1)
DrillBits WorkBook (1)DrillBits WorkBook (1)
DrillBits WorkBook (1)
Brian Avadikian
 
V8N3-6.PDF
V8N3-6.PDFV8N3-6.PDF
V8N3-6.PDF
Ram Mohan
 
Impact of Auto-tuning of Kernel Loop Transformation by using ppOpen-AT
Impact of Auto-tuning of Kernel Loop Transformation by using ppOpen-ATImpact of Auto-tuning of Kernel Loop Transformation by using ppOpen-AT
Impact of Auto-tuning of Kernel Loop Transformation by using ppOpen-AT
Takahiro Katagiri
 

Similar to Fusion_Class (20)

MOVIMIENTO_CURVILINEO_SEMANSKY.pdf
MOVIMIENTO_CURVILINEO_SEMANSKY.pdfMOVIMIENTO_CURVILINEO_SEMANSKY.pdf
MOVIMIENTO_CURVILINEO_SEMANSKY.pdf
 
Experimental Investigation of Faults in Roller Element Bearing Using Vibratio...
Experimental Investigation of Faults in Roller Element Bearing Using Vibratio...Experimental Investigation of Faults in Roller Element Bearing Using Vibratio...
Experimental Investigation of Faults in Roller Element Bearing Using Vibratio...
 
HIDRAULICA DE CANALES
HIDRAULICA DE CANALESHIDRAULICA DE CANALES
HIDRAULICA DE CANALES
 
Paper_Flutter
Paper_FlutterPaper_Flutter
Paper_Flutter
 
Embedded Programming for Quadcopters
Embedded Programming for QuadcoptersEmbedded Programming for Quadcopters
Embedded Programming for Quadcopters
 
Comparison GUM versus GUM+1
Comparison GUM  versus GUM+1Comparison GUM  versus GUM+1
Comparison GUM versus GUM+1
 
How to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJITHow to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJIT
 
12
1212
12
 
Prelude to halide_public
Prelude to halide_publicPrelude to halide_public
Prelude to halide_public
 
Generating lisp program for assembly drawing in AutoCAD
Generating lisp program for assembly drawing in AutoCAD Generating lisp program for assembly drawing in AutoCAD
Generating lisp program for assembly drawing in AutoCAD
 
2Part I1. Answer questions for the following graph, if .docx
2Part I1. Answer questions for the following graph, if .docx2Part I1. Answer questions for the following graph, if .docx
2Part I1. Answer questions for the following graph, if .docx
 
Coscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usageCoscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usage
 
Programming with OpenGL
Programming with OpenGLProgramming with OpenGL
Programming with OpenGL
 
CAPACITIVE SENSORS ELECTRICAL WAFER SORT
CAPACITIVE SENSORS ELECTRICAL WAFER SORTCAPACITIVE SENSORS ELECTRICAL WAFER SORT
CAPACITIVE SENSORS ELECTRICAL WAFER SORT
 
Aircraft Performance and Design Project Code
Aircraft Performance and Design Project CodeAircraft Performance and Design Project Code
Aircraft Performance and Design Project Code
 
Design of an automotive differential with reduction ratio greater than 6
Design of an automotive differential with reduction ratio greater than 6Design of an automotive differential with reduction ratio greater than 6
Design of an automotive differential with reduction ratio greater than 6
 
Querying solr
Querying solrQuerying solr
Querying solr
 
DrillBits WorkBook (1)
DrillBits WorkBook (1)DrillBits WorkBook (1)
DrillBits WorkBook (1)
 
V8N3-6.PDF
V8N3-6.PDFV8N3-6.PDF
V8N3-6.PDF
 
Impact of Auto-tuning of Kernel Loop Transformation by using ppOpen-AT
Impact of Auto-tuning of Kernel Loop Transformation by using ppOpen-ATImpact of Auto-tuning of Kernel Loop Transformation by using ppOpen-AT
Impact of Auto-tuning of Kernel Loop Transformation by using ppOpen-AT
 

More from Shereef Shehata

Windows_Scaling_2X_Speedup
Windows_Scaling_2X_SpeedupWindows_Scaling_2X_Speedup
Windows_Scaling_2X_Speedup
Shereef Shehata
 
2D_block_scaling_Software
2D_block_scaling_Software2D_block_scaling_Software
2D_block_scaling_Software
Shereef Shehata
 
2D_BLIT_software_Blackness
2D_BLIT_software_Blackness2D_BLIT_software_Blackness
2D_BLIT_software_Blackness
Shereef Shehata
 
CIECAM02_Color_Management
CIECAM02_Color_ManagementCIECAM02_Color_Management
CIECAM02_Color_Management
Shereef Shehata
 
Deblocking_Filter_v2
Deblocking_Filter_v2Deblocking_Filter_v2
Deblocking_Filter_v2
Shereef Shehata
 
log_algorithm
log_algorithmlog_algorithm
log_algorithm
Shereef Shehata
 
Temporal_video_noise_reduction
Temporal_video_noise_reductionTemporal_video_noise_reduction
Temporal_video_noise_reduction
Shereef Shehata
 
Shereef_Color_Processing
Shereef_Color_ProcessingShereef_Color_Processing
Shereef_Color_Processing
Shereef Shehata
 
Inertial_Sensors
Inertial_SensorsInertial_Sensors
Inertial_Sensors
Shereef Shehata
 
magentometers
magentometersmagentometers
magentometers
Shereef Shehata
 
Shereef_MP3_decoder
Shereef_MP3_decoderShereef_MP3_decoder
Shereef_MP3_decoder
Shereef Shehata
 
Gyroscope_sensors
Gyroscope_sensorsGyroscope_sensors
Gyroscope_sensors
Shereef Shehata
 
2DCompsitionEngine
2DCompsitionEngine2DCompsitionEngine
2DCompsitionEngine
Shereef Shehata
 
Block_Scaler_Control
Block_Scaler_ControlBlock_Scaler_Control
Block_Scaler_Control
Shereef Shehata
 
2D_BitBlt_Scale
2D_BitBlt_Scale2D_BitBlt_Scale
2D_BitBlt_Scale
Shereef Shehata
 
xvYCC_RGB
xvYCC_RGBxvYCC_RGB
xvYCC_RGB
Shereef Shehata
 
The_Mismatch_Noise_Cancellation_Architecture
The_Mismatch_Noise_Cancellation_ArchitectureThe_Mismatch_Noise_Cancellation_Architecture
The_Mismatch_Noise_Cancellation_Architecture
Shereef Shehata
 
Architectural_Synthesis_for_DSP_Structured_Datapaths
Architectural_Synthesis_for_DSP_Structured_DatapathsArchitectural_Synthesis_for_DSP_Structured_Datapaths
Architectural_Synthesis_for_DSP_Structured_Datapaths
Shereef Shehata
 
High_Level_Synthesis_of_DSP_Archiectures_Targeting_FPGAs
High_Level_Synthesis_of_DSP_Archiectures_Targeting_FPGAsHigh_Level_Synthesis_of_DSP_Archiectures_Targeting_FPGAs
High_Level_Synthesis_of_DSP_Archiectures_Targeting_FPGAs
Shereef Shehata
 

More from Shereef Shehata (19)

Windows_Scaling_2X_Speedup
Windows_Scaling_2X_SpeedupWindows_Scaling_2X_Speedup
Windows_Scaling_2X_Speedup
 
2D_block_scaling_Software
2D_block_scaling_Software2D_block_scaling_Software
2D_block_scaling_Software
 
2D_BLIT_software_Blackness
2D_BLIT_software_Blackness2D_BLIT_software_Blackness
2D_BLIT_software_Blackness
 
CIECAM02_Color_Management
CIECAM02_Color_ManagementCIECAM02_Color_Management
CIECAM02_Color_Management
 
Deblocking_Filter_v2
Deblocking_Filter_v2Deblocking_Filter_v2
Deblocking_Filter_v2
 
log_algorithm
log_algorithmlog_algorithm
log_algorithm
 
Temporal_video_noise_reduction
Temporal_video_noise_reductionTemporal_video_noise_reduction
Temporal_video_noise_reduction
 
Shereef_Color_Processing
Shereef_Color_ProcessingShereef_Color_Processing
Shereef_Color_Processing
 
Inertial_Sensors
Inertial_SensorsInertial_Sensors
Inertial_Sensors
 
magentometers
magentometersmagentometers
magentometers
 
Shereef_MP3_decoder
Shereef_MP3_decoderShereef_MP3_decoder
Shereef_MP3_decoder
 
Gyroscope_sensors
Gyroscope_sensorsGyroscope_sensors
Gyroscope_sensors
 
2DCompsitionEngine
2DCompsitionEngine2DCompsitionEngine
2DCompsitionEngine
 
Block_Scaler_Control
Block_Scaler_ControlBlock_Scaler_Control
Block_Scaler_Control
 
2D_BitBlt_Scale
2D_BitBlt_Scale2D_BitBlt_Scale
2D_BitBlt_Scale
 
xvYCC_RGB
xvYCC_RGBxvYCC_RGB
xvYCC_RGB
 
The_Mismatch_Noise_Cancellation_Architecture
The_Mismatch_Noise_Cancellation_ArchitectureThe_Mismatch_Noise_Cancellation_Architecture
The_Mismatch_Noise_Cancellation_Architecture
 
Architectural_Synthesis_for_DSP_Structured_Datapaths
Architectural_Synthesis_for_DSP_Structured_DatapathsArchitectural_Synthesis_for_DSP_Structured_Datapaths
Architectural_Synthesis_for_DSP_Structured_Datapaths
 
High_Level_Synthesis_of_DSP_Archiectures_Targeting_FPGAs
High_Level_Synthesis_of_DSP_Archiectures_Targeting_FPGAsHigh_Level_Synthesis_of_DSP_Archiectures_Targeting_FPGAs
High_Level_Synthesis_of_DSP_Archiectures_Targeting_FPGAs
 

Fusion_Class

  • 2.
  • 4. android::Fusion Class • Public Member Functions Fusion () void init () void handleGyro (const vec3_t &w, float dT) status_t handleAcc (const vec3_t &a) status_t handleMag (const vec3_t &m) vec4_t getAttitude () const vec3_t getBias () const mat33_t getRotationMatrix () const bool hasEstimate () const
  • 5. android::Fusion Class • Private Types ACC = 0x1 MAG = 0x2 GYRO = 0x4 enum { ACC = 0x1, MAG = 0x2, GYRO = 0x4 }
  • 6. android::Fusion Class • Private Member Functions bool checkInitComplete (int, const vec3_t &w, float d=0) void initFusion (const vec4_t &q0, float dT) void checkState () void predict (const vec3_t &w, float dT) void update (const vec3_t &z, const vec3_t &Bi, float sigma)
  • 7. android::Fusion Class • Static Private Member Functions static mat34_t getF (const vec4_t &p)
  • 8. android::Fusion Class • Private Attributes quat_t X0 Modified Rodrigues parameters The function getAttitue() returns x0 vec3_t X1 The estimated gyro bias The function getBias() returns x1 mat< mat33_t, 2, 2 > P The predicated covariance matrix is made of 4 3x3 sub-matrices and it is semi-definite positive. mat< mat33_t, 2, 2 > GQGt The process noise covariance matrix mat< mat33_t, 2, 2 > Phi vec3_t Ba vec3_t Bm uint32_t mInitState float mGyroRate vec< vec3_t, 3 > mData size_t mCount [3]
  • 10. Class Constructor android::Fusion::Fusion() • Class Constructor Fusion::Fusion() { Phi[0][1] = 0; Phi[1][1] = 1; Ba.x = 0; Ba.y = 0; Ba.z = 1; Bm.x = 0; Bm.y = 1; Bm.z = 0; x0 = 0; x1 = 0; init(); }
  • 11. android::Fusion::init() • Init() void Fusion::init() { mInitState = 0; mGyroRate = 0; mCount[0] = 0; mCount[1] = 0; mCount[2] = 0; mData = 0; }
  • 12. android::Fusion::handleGyro () • Caller Graph • Call graph void Fusion::handleGyro(const vec3_t& w, float dT) { if (!checkInitComplete(GYRO, w, dT)) return; predict(w, dT); }
  • 13. android::Fusion::handleAcc (const vec3_t& a ) • Caller graph • Call graph
  • 14. android::Fusion::handleAcc (const vec3_t& a ) status_t Fusion::handleAcc(const vec3_t& a) { // ignore acceleration data if we're close to free-fall if (length_squared(a) < FREE_FALL_THRESHOLD_SQ) { return BAD_VALUE; } if (!checkInitComplete(ACC, a)) return BAD_VALUE; const float l = 1/length(a); update(a*l, Ba, accSTDEV*l); return NO_ERROR; }
  • 15. android::Fusion::handleMag (const vec3_t& m ) • Caller graph • Call graph
  • 16. android::Fusion::handleMag (const vec3_t& m ) status_t Fusion::handleMag(const vec3_t& m) { // the geomagnetic-field should be between 30uT and 60uT // reject if too large to avoid spurious magnetic sources const float magFieldSq = length_squared(m); if (magFieldSq > MAX_VALID_MAGNETIC_FIELD_SQ) { return BAD_VALUE; } else if (magFieldSq < MIN_VALID_MAGNETIC_FIELD_SQ) { // Also reject if too small since we will get ill-defined (zero mag) // cross-products below return BAD_VALUE; } if (!checkInitComplete(MAG, m)) return BAD_VALUE; // Orthogonalize the magnetic field to the gravity field, mapping it into // tangent to Earth. const vec3_t up( getRotationMatrix() * Ba ); const vec3_t east( cross_product(m, up) ); // If the m and up vectors align, the cross product magnitude will // approach 0. // Reject this case as well to avoid div by zero problems and // ill-conditioning below. if (length_squared(east) < MIN_VALID_CROSS_PRODUCT_MAG_SQ) { return BAD_VALUE; } // If we have created an orthogonal magnetic field successfully, // then pass it in as the update. vec3_t north( cross_product(up, east) ); const float l = 1 / length(north); north *= l; update(north, Bm, magSTDEV*l); return NO_ERROR; }
  • 17. android::Fusion::getAttitude() • Caller graph vec4_t Fusion::getAttitude() const { return x0; }
  • 18. android::Fusion::getBias() • Caller graph vec3_t Fusion::getBias() const { return x1; }
  • 20. android::Fusion::hasEstimate () const • Caller graph • Call graph
  • 26. 00372 void Fusion::predict(const vec3_t& w, float dT) { 00373 const vec4_t q = x0; 00374 const vec3_t b = x1; 00375 const vec3_t we = w - b; 00376 00377 // q(k+1) = O(we)*q(k) 00378 // -------------------- 00379 // 00380 // O(w) = | cos(0.5*||w||*dT)*I33 - [psi]x psi | 00381 // | -psi' cos(0.5*||w||*dT) | 00382 // 00383 // psi = sin(0.5*||w||*dT)*w / ||w|| 00384 // 00385 // 00386 // P(k+1) = Phi(k)*P(k)*Phi(k)' + G*Q(k)*G' 00387 // ---------------------------------------- 00388 // 00389 // G = | -I33 0 | 00390 // | 0 I33 | 00391 // 00392 // Phi = | Phi00 Phi10 | 00393 // | 0 1 | 00394 // 00395 // Phi00 = I33 00396 // - [w]x * sin(||w||*dt)/||w|| 00397 // + [w]x^2 * (1-cos(||w||*dT))/||w||^2 00398 // 00399 // Phi10 = [w]x * (1 - cos(||w||*dt))/||w||^2 00400 // - [w]x^2 * (||w||*dT - sin(||w||*dt))/||w||^3 00401 // - I33*dT 00402 00403 const mat33_t I33(1); 00404 const mat33_t I33dT(dT); 00405 const mat33_t wx(crossMatrix(we, 0)); 00406 const mat33_t wx2(wx*wx); 00407 const float lwedT = length(we)*dT; 00408 const float hlwedT = 0.5f*lwedT; 00409 const float ilwe = 1/length(we); 00410 const float k0 = (1-cosf(lwedT))*(ilwe*ilwe); 00411 const float k1 = sinf(lwedT); 00412 const float k2 = cosf(hlwedT); 00413 const vec3_t psi(sinf(hlwedT)*ilwe*we); 00414 const mat33_t O33(crossMatrix(-psi, k2)); 00415 mat44_t O; 00416 O[0].xyz = O33[0]; O[0].w = -psi.x; 00417 O[1].xyz = O33[1]; O[1].w = -psi.y; 00418 O[2].xyz = O33[2]; O[2].w = -psi.z; 00419 O[3].xyz = psi; O[3].w = k2; 00420 00421 Phi[0][0] = I33 - wx*(k1*ilwe) + wx2*k0; 00422 Phi[1][0] = wx*k0 - I33dT - wx2*(ilwe*ilwe*ilwe)*(lwedT-k1); 00423 00424 x0 = O*q; 00425 if (x0.w < 0) 00426 x0 = -x0; 00427 00428 P = Phi*P*transpose(Phi) + GQGt; 00429 00430 checkState(); 00431 }
  • 29. android::Fusion::scaleCovariance () scaleCovariance ( const mat<TYPE, C, R>& A, const mat<TYPE, C, C>& P) computes the following: • A * P * transpose(A)
  • 30. android::Fusion::scaleCovariance () • Caller graph template <typename TYPE, size_t C, size_t R> static mat<TYPE, R, R> scaleCovariance( const mat<TYPE, C, R>& A, const mat<TYPE, C, C>& P) { // A*P*transpose(A); mat<TYPE, R, R> APAt; for (size_t r=0 ; r<R ; r++) { for (size_t j=r ; j<R ; j++) { double apat(0); for (size_t c=0 ; c<C ; c++) { double v(A[c][r]*P[c][c]*0.5); for (size_t k=c+1 ; k<C ; k++) v += A[k][r] * P[c][k]; apat += 2 * v * A[c][j]; } APAt[j][r] = apat; APAt[r][j] = apat; } } return APAt; }
  • 31. android::Fusion::crossMatrix () crossMatix ( const vec<TYPE, 3>& p, OTHER_TYPE diag) computes the following: • Given a value “diag” and a vector p, with components X,Y,Z, it construct a 3x3 matrix as follows: diag Z -Y -Z diag X Y -X diag
  • 32. android::Fusion::crossMatrix () • Caller graph template <typename TYPE, typename OTHER_TYPE> static mat<TYPE, 3, 3> crossMatrix(const vec<TYPE, 3>& p, OTHER_TYPE diag) { mat<TYPE, 3, 3> r; r[0][0] = diag; r[1][1] = diag; r[2][2] = diag; r[0][1] = p.z; r[1][0] =-p.z; r[0][2] =-p.y; r[2][0] = p.y; r[1][2] = p.x; r[2][1] =-p.x; return r; }
  • 33. android::Fusion::quatToMatrix () quatToMatrix (const vec< TYPE, 4 > & q) computes the following: • If the Quaternion operator qvq* (triple product quaternion) is applied to vector v • The equivalent matrix that produce the same result as the triple prod • w = qvq* = Q v
  • 34. android::Fusion::quatToMatrix () • Caller graph template <typename TYPE> mat<TYPE, 3, 3> quatToMatrix(const vec<TYPE, 4>& q) { mat<TYPE, 3, 3> R; TYPE q0(q.w); TYPE q1(q.x); TYPE q2(q.y); TYPE q3(q.z); TYPE sq_q1 = 2 * q1 * q1; TYPE sq_q2 = 2 * q2 * q2; TYPE sq_q3 = 2 * q3 * q3; TYPE q1_q2 = 2 * q1 * q2; TYPE q3_q0 = 2 * q3 * q0; TYPE q1_q3 = 2 * q1 * q3; TYPE q2_q0 = 2 * q2 * q0; TYPE q2_q3 = 2 * q2 * q3; TYPE q1_q0 = 2 * q1 * q0; R[0][0] = 1 - sq_q2 - sq_q3; R[0][1] = q1_q2 - q3_q0; R[0][2] = q1_q3 + q2_q0; R[1][0] = q1_q2 + q3_q0; R[1][1] = 1 - sq_q1 - sq_q3; R[1][2] = q2_q3 - q1_q0; R[2][0] = q1_q3 - q2_q0; R[2][1] = q2_q3 + q1_q0; R[2][2] = 1 - sq_q1 - sq_q2; return R; }
  • 35. gyroVAR gyroVAR gives the measured variance of the gyro's output per Hz (or variance at 1 Hz). • This is an "intrinsic" parameter of the gyro, which is independent of the sampling frequency. • static const float gyroVAR = 1e-7; // (rad/s)^2 / Hz • The variance of gyro's output at a given sampling period can be calculated as: variance(T) = gyroVAR / T * The variance of the INTEGRATED OUTPUT at a given sampling period can be calculated as: variance_integrate_output(T) = gyroVAR * T
  • 36. Standard deviations of accelerometer and magnetometer • Standard deviation of the Accelerometer static const float accSTDEV = 0.05f; // m/s^2 (measured 0.08 / CDD 0.05) • Standard deviation of the Magnetometer static const float magSTDEV = 0.5f; // uT (measured 0.7 / CDD 0.5)
  • 37. Accelerometer Updates at or near freefall • Accelerometer updates will not be performed near free fall to avoid ill- conditioning and div by zeros. • Threshhold: – 10% of g, in m/s^2 – Since g is 9.8 m/s^2 – 10% of g is 0.98 m/s^2 static const float FREE_FALL_THRESHOLD = 0.981f; static const float FREE_FALL_THRESHOLD_SQ = FREE_FALL_THRESHOLD*FREE_FALL_THRESHOLD; • The value of g Location Distance from Earth's center (m) Value of g (m/s2) Earth's surface 6.38 x 106 m 9.8
  • 38. Standard deviations of accelerometer • Accelerometer Standard Deviation, accSTDEV static const float accSTDEV = 0.05f; // m/s^2 (measured 0.08 / CDD 0.05) • How is the standard deviation of the Accelerometer measures? • What is CCD?
  • 39. Standard deviations of magnetometer • Accelerometer Standard Deviation, magSTDEV • static const float magSTDEV = 0.5f; // uT (measured 0.7 / CDD 0.5) • How is the standard deviation of the magnetometer measures? • What is CCD?
  • 40. The geomagnetic-field, MAX values • The geomagnetic-field should be between 30uT and 60uT. • Fields strengths greater than this likely indicate a local magnetic disturbance which we do not want to update into the fused frame. static const float MAX_VALID_MAGNETIC_FIELD = 100; // uT static const float MAX_VALID_MAGNETIC_FIELD_SQ = MAX_VALID_MAGNETIC_FIELD * MAX_VALID_MAGNETIC_FIELD;
  • 41. The geomagnetic-field, MIN values • Values of the field smaller than this should be ignored in fusion to avoid ill- conditioning. • This state can happen with anomalous local magnetic disturbances canceling the Earth field. static const float MIN_VALID_MAGNETIC_FIELD = 10; // uT static const float MIN_VALID_MAGNETIC_FIELD_SQ = MIN_VALID_MAGNETIC_FIELD * MIN_VALID_MAGNETIC_FIELD;
  • 42. Cross product of two vectors, Minimum Values • If the cross product of two vectors has magnitude squared less than this, we reject it as invalid due to alignment of the vectors. • This threshold is used to check for the case where the magnetic field sample is parallel to the gravity field, which can happen in certain places due to magnetic field disturbances. static const float MIN_VALID_CROSS_PRODUCT_MAG = 1.0e-3; static const float MIN_VALID_CROSS_PRODUCT_MAG_SQ = MIN_VALID_CROSS_PRODUCT_MAG * MIN_VALID_CROSS_PRODUCT_MAG;