Imu: ;--- Get Sensor Data ---
Step#1: Read Gyro &
Acc values and refer them to Zero
call AdcRead ;Calculate gyro output
;---M.Hefny
;---
Gyro = Gyro - GyroZero for Roll,Pitch & YAW
b16sub
GyroRoll, GyroRoll, GyroRollZero
b16sub
GyroPitch, GyroPitch, GyroPitchZero
b16sub
GyroYaw, GyroYaw, GyroYawZero
;---M.Hefny
;---
Acc = Acc - AccZero for X Y & Z
b16sub
AccX, AccX, AccXZero ;remove offset from Acc
b16sub
AccY, AccY, AccYZero
b16sub
AccZ, AccZ, AccZZero
;---M.Hefny
;---
AccX = AccX + AccTrimPitch
b16add
AccX, AccX, AccTrimPitch ;add trim
b16add
AccY, AccY, AccTrimRoll
Step#2: Apply
complementary filter to Acc to remove noise.
;---M.Hefny
;---
Low Pass Filter
b16ldi
Temper, 0.03 ;SF LP filter the accerellometers
;---M.Hefny
;---
AccXfilter = AccXfilter + Temper * (AccX - AccXFilter)
b16sub
Error, AccX, AccXfilter
b16mul
Error, Error, Temper
b16add
AccXfilter, AccXfilter, Error
;---M.Hefny
;---
AccYfilter = AccYfilter + Temper * (AccY - AccYFilter)
b16sub Error,
AccY, AccYfilter
b16mul
Error, Error, Temper
b16add
AccYfilter, AccYfilter, Error
;---M.Hefny
;---
AccZfilter = AccZfilter + Temper * (AccZ - AccZFilter)
b16sub
Error, AccZ, AccZfilter
b16mul
Error, Error, Temper
b16add
AccZfilter, AccZfilter, Error
Step#3: Correct Gyro-Based
calculated angles using Acc readings.
;--- calculate
tilt angle with the acc. (this approximation is good to about 20 degrees) --
b16ldi
Temp, 0.7
b16mul
AccAngleRoll, AccYfilter, Temp
b16mul
AccAnglePitch, AccXfilter, Temp
;--- Add correction data to gyro inputs based on
difference between Euler angles and acc angles ---
b16ldi
Temp, 20 ;skip correction at angles greater than +-20
b16cmp
AccAnglePitch, Temp
longbrge
im40
b16cmp
AccAngleRoll, Temp
longbrge
im40 ;M.Hefny: Skip correction
b16neg
Temp ;M.Hefny
compare -20
b16cmp
AccAnglePitch, Temp
longbrlt
im40 ;M.Hefny: Skip correction
b16cmp
AccAngleRoll, Temp
longbrlt
im40 ;M.Hefny: Skip correction
b16ldi
Temp, 60 ;skip correction if vertical acceleration is outside 0.5 to 1.5 G
b16cmp
AccZfilter, Temp
longbrge
im40 ;M.Hefny: Skip correction
b16neg
Temp
b16cmp
AccZfilter, Temp
longbrlt
im40 ;M.Hefny: Skip correction
;---- M.Hefny
;---
GyroRoll = GyroRoll + (EulerAngleRoll - AccAngleRoll) / 2;
b16sub
Temp, EulerAngleRoll, AccAngleRoll ;add
roll correction
b16fdiv
Temp, 2
b16add
GyroRoll, GyroRoll, Temp
;---- M.Hefny
;---
GyroPitch = GyroPitch + (EulerAnglePitch - AccAnglePitch) / 2;b16sub Temp,
EulerAnglePitch, AccAnglePitch ;add
pitch correction
b16fdiv
Temp, 2
b16add
GyroPitch, GyroPitch, Temp
;rvsetflagtrue flagDebugBuzzerOn
rjmp im41
im40: ;rvsetflagfalse flagDebugBuzzerOn
;----
M.Hefny
;---
im40 skipping to im40 means skipping correction.
Step#4: Calculate
Gyro-Based calculated angles.
im41:
;--- Rotate up-direction 3D vector with gyro inputs ---
call Rotate3dVector
call Lenght3dVector
call ExtractEulerAngles
;--debug
;--- Calculate Stick and Gyro ---
rvbrflagfalse
flagThrottleZero, im7 ;reset integrals if throttle closed
b16clr
IntegralRoll
b16clr
IntegralPitch
b16clr
IntegralYaw
im7:
b16fdiv
RxRoll, 4 ;Right align to the 16.4 multiply usable bit limit.
b16fdiv
RxPitch, 4
b16fdiv
RxYaw, 4
b16mul
RxRoll, RxRoll, StickScaleRoll ;scale Stick input.
b16mul
RxPitch, RxPitch, StickScalePitch
b16mul
RxYaw, RxYaw, StickScaleYaw
b16mul
RxThrottle, RxThrottle, StickScaleThrottle
;-----
Self level ----
rvbrflagtrue
flagSelflevelOn, im31 ;skip if false
rjmp
im30
im31:
;--- M.Hefny
;--- Calculate Self Leveling PID
using P only factor.
;--- Roll Axis Self-level P ---
b16neg
RxRoll
;--- M.Hefny
;---
RxRoll = RxRoll / 2
b16fdiv
RxRoll, 1
;--- M.Hefny
;---
TargetAngleRoll = (QuadRoll - StickRollAngle) /
16
b16sub
Error, EulerAngleRoll, RxRoll ;calculate
error
b16fdiv
Error, 4
;--- M.Hefny
;---
calculate P term of PID.
b16mul
Value, Error, SelflevelPgain ;Proposjonal
gain
;--- M.Hefny
;----
Limit value to SelflevelPlimit
b16mov
LimitV, SelflevelPlimit ;Proposjonal
limit
rcall limiter
;--- M.Hefny
;---
RxRoll = Limit(SelfLevelPgain * (EulerAngle-RXRoll)/16,SelflevelPlimit)/2
b16mov
RxRoll, Value
b16fdiv
RxRoll, 1
;--- Pitch Axis Self-level P ---
b16neg
RxPitch
;--- M.Hefny
;---
RxPitch = RxPitch / 2
b16fdiv
RxPitch, 1
;--- M.Hefny
;---
TargetAnglePitch = (QuadPitch - StickPitchAngle) / 16
b16sub
Error, EulerAnglePitch, RxPitch ;calculate
error
b16fdiv
Error, 4
;--- M.Hefny
;---
calculate P term of PID.
b16mul
Value, Error, SelflevelPgain ;Proposjonal
gain
;--- M.Hefny
;----
Limit value to SelflevelPlimit
b16mov
LimitV, SelflevelPlimit ;Proposjonal
limit
rcall limiter
;--- M.Hefny
;---
RxPitch = Limit(SelfLevelPgain * (EulerAngle-RXPitch)/16,SelflevelPlimit)/2
b16mov
RxPitch, Value
b16fdiv
RxPitch, 1
;--- M.Hefny
;---
EOF leveling procedure.
im30:
;--- Roll Axis PI ---
;---
M.Hefny
;---
Calculate GYRO ... Gyro is used for stabilization only.
b16sub
Error, GyroRoll, RxRoll ;calculate
error
b16fdiv
Error, 1
b16mul
Value, Error, PgainRoll ;Proposjonal
gain
b16mov
LimitV, PlimitRoll ;Proposjonal
limit
rcall limiter
b16mov
CommandRoll, Value
b16fdiv
Error, 3
b16mul
Temp, Error, IgainRoll ;Integral gain
b16add
Value, IntegralRoll, Temp
b16mov
LimitV, IlimitRoll ;Integral limit
rcall limiter
b16mov
IntegralRoll, Value
b16add
CommandRoll, CommandRoll, IntegralRoll
;--- Pitch Axis PI ---
b16sub
Error, RxPitch, GyroPitch ;calculate error
b16fdiv
Error, 1
b16mul
Value, Error, PgainPitch ;Proposjonal gain
b16mov
LimitV, PlimitPitch ;Proposjonal limit
rcall limiter
b16mov
CommandPitch, Value
b16fdiv
Error, 3
b16mul
Temp, Error, IgainPitch ;Integral gain
b16add
Value, IntegralPitch, Temp
b16mov
LimitV, IlimitPitch ;Integral limit
rcall limiter
b16mov
IntegralPitch, Value
b16add
CommandPitch, CommandPitch, IntegralPitch
;--- Yaw Axis PI ---
b16sub
Error, RxYaw, GyroYaw ;calculate error
b16fdiv
Error, 1
b16mul
Value, Error, PgainYaw ;Proposjonal gain
b16mov
LimitV, PlimitYaw ;Proposjonal limit
rcall limiter
b16mov
CommandYaw, Value
b16fdiv
Error, 3
b16mul
Temp, Error, IgainYaw ;Integral gain
b16add
Value, IntegralYaw, Temp
b16mov
LimitV, IlimitYaw ;Integral limit
rcall limiter
b16mov
IntegralYaw, Value
b16add
CommandYaw, CommandYaw, IntegralYaw
;------
ret
;--- M.Hefny
;--- Function to limit value
between high and low limits
limiter:
b16cmp
Value, LimitV ;high limit
brlt
lim5
b16mov
Value, LimitV
lim5: b16neg
LimitV ;low limit
b16cmp
Value, LimitV
brge
lim6
b16mov
Value, LimitV
lim6: ret