/* stick.c */ #ifdef WE_HAVE_SQRT #include #else #include "fisqrt.h" #endif #include "matrix.h" #include "stick.h" #include "dcm.h" #include "uart.h" #include "timer.h" #include "trig.h" #include "motor.h" #include "status.h" #include "watchdog.h" #include "log.h" #define TWO_PI 6.28318531f #define PI 3.14159265f #define MIN_X 8720 #define MAX_X 23800 #define CENTRE_X 16260 #define MIN_Y 8720 #define MAX_Y 23800 #define CENTRE_Y 16260 #define MIN_Z 8720 #define MAX_Z 23800 #define CENTRE_Z 16300 #define MIN_THR 9720 #define MAX_THR 23750 #define MIN_REAL_THR 8720 #define CENTRE_ZONE 100 /* With new TX firmware, CPPM: * x y thr z * centre: 16260, 16258, 16000, 16300 * min: 8720, 8718, 8720, 8722 * max: 23790, 23817, 23750, 23803 */ /* Full scale is a roll/pitch angle of 30 degrees from the vertical */ #define SCALE_X (TWO_PI*30.0/360.0 / (MAX_X-CENTRE_X)) #define SCALE_Y (TWO_PI*30.0/360.0 / (MAX_Y-CENTRE_Y)) /* Full scale is a complete rotation in one second */ #define SCALE_Z (TWO_PI / (MAX_Z-CENTRE_Z)) /* 0 is min throttle, 1 is max throttle */ #define SCALE_THROTTLE (1.0f/(MAX_THR - MIN_THR)) float stick_yaw = 0.0f; unsigned int stick_counter; void stick_update(float x, float y, float z) { float tz = delta_t * z; stick_yaw += tz; if (stick_yaw <= -PI) stick_yaw += TWO_PI; if (stick_yaw > PI) stick_yaw -= TWO_PI; #if 0 z = stick_yaw; #endif x = sine(x); y = sine(y); #if 0 z = 1.0/fisqrt(1-x*x-y*y); #endif dcm_attitude_error(x, y, z); } #ifdef STICK_DEBUG_CALIBRATE void stick_debug_calibrate() { unsigned int t1 = timer_input(0); unsigned int t2 = timer_input(1); unsigned int t3 = timer_input(2); unsigned int t4 = timer_input(3); putstr("S:("); putint(t1); putstr(","); putint(t2); putstr(","); putint(t3); putstr(","); putint(t4); putstr(")\r\n"); } #endif void stick_input(void) { float x, y, z, throttle; unsigned int xi, yi, zi, throttlei; if (timer_allvalid()) { xi = timer_input(0); yi = timer_input(1); throttlei = timer_input(2); zi = timer_input(3); log_put_uint16(xi); log_put_uint16(yi); log_put_uint16(throttlei); log_put_uint16(zi); x = xi; y = yi; throttle = throttlei; z = zi; #ifdef STICK_DEBUG_CALIBRATE if ((stick_counter % 100) == 0) stick_debug_calibrate(); #endif if (!status_armed()) { if ((throttle < MIN_THR) && (x > (CENTRE_X - CENTRE_ZONE)) && (x < (CENTRE_X + CENTRE_ZONE)) && (y > (CENTRE_Y - CENTRE_ZONE)) && (y < (CENTRE_Y + CENTRE_ZONE)) && (z > (CENTRE_Z - CENTRE_ZONE)) && (z < (CENTRE_Z + CENTRE_ZONE))) status_set_ready(STATUS_MODULE_STICK, TRUE); else status_set_ready(STATUS_MODULE_STICK,FALSE); } x -= CENTRE_X; y -= CENTRE_Y; z -= CENTRE_Z; x = x * SCALE_X; y = y * SCALE_Y; z = z * SCALE_Z; throttle = (throttle - MIN_THR) * SCALE_THROTTLE; if (throttle < 0.0) throttle = 0.0; } else { x = 0.0f; y = 0.0f; z = 0.0f; throttle = 0.0f; status_set_ready(STATUS_MODULE_STICK,FALSE); } motor_set_throttle(throttle); watchdog_kick(WATCHDOG_STICK); /* So the controls are back to front. Let's fix that. */ x = -x; y = -y; z = -z; #if 0 if ((stick_counter % 100) == 0) { putstr("["); putint_s((int)(z * 10000)); putstr("] "); } #endif #if 1 stick_update(x, y, z); #else if ((stick_counter % 100) == 0) stick_update(x, y, z); #endif /* if ((stick_counter & 3) == 0) stick_send_packet(); */ stick_counter++; }