Hier der Teil, der das Self-Level erledigt (aus imu.asm):
Und hier die Umrechnung der Vektoren in Winkel (aus trigonometry.asm):
Code:
;----- Self level ----
rvbrflagtrue flagSelflevelOn, im31 ;skip if false
rjmp im30
im31:
;--- Roll Axis Self-level P ---
b16neg RxRoll
b16fdiv RxRoll, 1
b16sub Error, EulerAngleRoll, RxRoll ;calculate error
b16fdiv Error, 4
b16mul Value, Error, SelflevelPgain ;Proposjonal gain
b16mov LimitV, SelflevelPlimit ;Proposjonal limit
rcall limiter
b16mov RxRoll, Value
b16fdiv RxRoll, 1
;--- Pitch Axis Self-level P ---
b16neg RxPitch
b16fdiv RxPitch, 1
b16sub Error, EulerAnglePitch, RxPitch ;calculate error
b16fdiv Error, 4
b16mul Value, Error, SelflevelPgain ;Proposjonal gain
b16mov LimitV, SelflevelPlimit ;Proposjonal limit
rcall limiter
b16mov RxPitch, Value
b16fdiv RxPitch, 1
im30:
Und hier die Umrechnung der Vektoren in Winkel (aus trigonometry.asm):
Code:
ExtractEulerAngles:
b824mov TempD, VectorX
rcall ext2
b16mov EulerAngleRoll, Angle
b824mov TempD, VectorY
rcall ext2
b16mov EulerAnglePitch, Angle
ret
ext2: ;b824mul TempA, TempD, TempD ;approximation of a quarter circle (lol :-)
b824ldi TempB, 90 ;convert to degrees (0 to 90)
b824mul TempA, TempD, TempB
b824load TempA
rcall transfer824168
b16store Angle
; b824load VectorZ ;mirror on X/Y plane (90 to 180)
; tst xh
; brpl ext3
; b16ldi Temp, 180
; b16sub Angle, Temp, Angle
;ext3:
; b824load TempD ;mirror on the Z axis (0 to -180)
; tst xh
; brpl ext1
; b16ldi Temp, -1
; b16mul Angle, Angle, Temp
;ext1:
ret