From a44e33bdafdf1300facb2147f8a1634aa9ec19c5 Mon Sep 17 00:00:00 2001 From: Tim Trueman Date: Fri, 30 Dec 2011 08:54:45 -0800 Subject: [PATCH] Working on getting cpress working --- .gitignore | 3 + autopilot.py | 59 ++++ dcm.py | 802 +++++++++++++++++++++++++++++++++++++++++++++++++++ ekf.py | 85 ++++-- fgo.py | 4 +- shumai.py | 49 ++-- vgo.py | 2 +- 7 files changed, 956 insertions(+), 48 deletions(-) create mode 100644 .gitignore create mode 100644 autopilot.py create mode 100644 dcm.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c06bc88 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.log +*.csv +*.sql diff --git a/autopilot.py b/autopilot.py new file mode 100644 index 0000000..5bb3b52 --- /dev/null +++ b/autopilot.py @@ -0,0 +1,59 @@ +from truthdata import TruthData +from math import degrees, radians, atan +from display import Display +from utils import GRAVITY + +TD = TruthData() +display = Display() + +class Autopilot: + + def __init__(self): + self.pitch_cmd = 10.0 + self.roll_cmd = 0.0 + self.hdg_cmd = 0.0 + self.xplane_gain = 1 / 45.0 + + def condition_heading(self, heading): + heading_error = self.hdg_cmd - heading + if heading > 180: # never goes <180 from GPS + heading = heading - 360 + heading_error = self.hdg_cmd - heading + if self.hdg_cmd - heading > 180: + heading_error = (self.hdg_cmd - heading) - 360; + if self.hdg_cmd - heading < -180: + heading_error = (self.hdg_cmd - heading) + 360; + # display.register_scalars({"heading_error": heading_error,}) + heading_error = min(30, max(-30, heading_error)) + return heading_error + + def heading_hold(self): + kp_psi = 0.75 + trim_airspeed = 45.0 + kp_deweight = 0.1 + hdg_deweight = (trim_airspeed / TD.SPEEDOVERGROUND) * kp_deweight + hdg_deweight = min(1.6, max(0.6, hdg_deweight)) + kp_psi_dot = 0.333 + psi_dot_cmd = self.condition_heading(degrees(TD.HEADING)) * kp_psi_dot + psi_dot_cmd = min(6, max(-6, psi_dot_cmd)) + psi_dot_cmd = radians(psi_dot_cmd) + self.roll_cmd = atan(psi_dot_cmd * (TD.SPEEDOVERGROUND * 1.68780986) / 32.2) + self.roll_cmd = min(30, max(-30, degrees(self.roll_cmd))) + # display.register_scalars({"roll_cmd": self.roll_cmd,"psi_dot_cmd": degrees(psi_dot_cmd),"hdg_deweight": hdg_deweight}, "Autopilot debugging") + # display.register_scalars({"roll_cmd": self.roll_cmd,"psi_dot_cmd": degrees(psi_dot_cmd),}) + # self.roll_cmd = kp_psi * hdg_deweight * self.condition_heading(degrees(TD.HEADING)) + return self.roll_cmd + + def pitch_hold(self): + kp_theta = 0.0 + self.ele_cmd = kp_theta * (self.pitch_cmd - degrees(TD.PITCH)) * self.xplane_gain + return self.ele_cmd + + def roll_hold(self): + kp_phi = 1.0 + self.ail_cmd = kp_phi * (self.roll_cmd - degrees(TD.ROLL)) * self.xplane_gain + #display.register_scalars({"ail_cmd": self.ail_cmd,"wtf": self.roll_cmd - degrees(TD.ROLL),"roll_cmd":self.roll_cmd, "td_roll":degrees(TD.ROLL)}, "Autopilot debugging") + return self.ail_cmd + + def throttle(self): + return 0.4 diff --git a/dcm.py b/dcm.py new file mode 100644 index 0000000..86de18c --- /dev/null +++ b/dcm.py @@ -0,0 +1,802 @@ +from math import * + +''' +Alternate algorithms (VGO, DCM, EKF Euler angles versus quaternions) could provide a gut check / fall-back option as a fail-safe... + +This didn't get very far. + +DCM - Bill Premerlani & Paul Bizard / DIY Drones +Inputs: + gyros (rad/s) + accelerometers (m/s^2) + GPS vx vy horizontal speed (m/s) + GPS course over ground (rad) + GPS speeed Ve (m/s) +Outputs + y0[0 1 2] euler angels (rad) + y1[0 1 2] + y2[0 1 2] + y3[0 1 2] +''' + +class DCM: + + def __init__(self): + self.psi = 0.0 + self.theta = 0.023865 + self.phi = 0.0 + psi = self.psi + theta = self.theta + phi = self.phi + self.R[0,0] = cos(theta) * cos(psi) + self.R[0,1] = cos(theta) * sin(psi) + self.R[0,2] = -sin(theta) + self.R[1,0] = (sin(phi) * sin(theta) * cos(psi)) - (cos(phi) * sin(psi)) + self.R[1,1] = (sin(phi) *sin(theta) * sin(psi)) + (cos(phi) * cos(psi)) + self.R[1,2] = sin(phi) * cos(theta) + self.R[2,0] = (cos(phi) * sin(theta) * cos(psi)) + (sin(phi) * sin(psi)) + self.R[2,1] = (cos(phi) * sin(theta) * sin(psi)) - (sin(phi) * cos(psi)) + self.R[2,2] = cos(phi) * cos(theta) + self.rup = matrix("1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0") + self.integral = matrix("0.0 0.0 0.0") + self.Rfilter0 = R[0,0] + self.Rfilter3 = R[1,0] + self.yaw_flag = 0.0 + self.GPSspeed = matrix("26.66 26.66") + self.omega = matrix("0.0 0.0 0.0") + + def model_outputs(self): + self.psi = atan2(self.R[1,0],self.R[0,0]) + self.theta = -asin(self.R[2,0]) + self.phi = atan2(self.R[2,1],self.R[2,2]) + return {"psi": self.psi, + "theta": self.theta, + "phi": self.phi,} + + def model_update(self, dt): + omega_correction = matrix("%f %f %f" % omega_correction_p_acc, omega_correction_p_gps, omega_correction_integral) + self.omega += omega_correction + self.theta_hat = omega * dt + self.rup[0,0] + + +# /*============================================================================*/ +# /* SFUNCTION NUMERICAL CONTROLLER */ +# /*============================================================================*/ +# /* Authors: Bill PREMERLANI & Paul BIZARD / DIY Drones */ +# /* Date : February 2009 */ +# /*============================================================================*/ +# /* INPUTS */ +# /* ------ */ +# /* u0[0 1 2] Gyrometers p q r rad/s */ +# /* u1[0 1 2] Accelerometers x y z m/s^2 */ +# /* u2[0 1] GPS vx vy horizontal speed m/s */ +# /* u3[0] GPS Khi course over ground rad */ +# /* u4[0] GPS speed Ve m/s */ +# /*============================================================================*/ +# /* OUTPUTS */ +# /* ------- */ +# /* y0[0 1 2] Euler angles rad */ +# /* y1[0 1 2] */ +# /* y2[0 1 2] */ +# /* y3[0 1 2] */ +# /*============================================================================*/ +# /* DCM matrix estimation */ +# /* R marix = transformation from body frame to earth frame */ +# /* */ +# /* 1st column is x body vector expressed in earth frame */ +# /* 2nd... y */ +# /* 3rd... z */ +# /* */ +# /* 1st row is x earth vector expressed in body frame */ +# /* 2nd row y */ +# /* 3rd row z */ +# /* */ +# /* x front */ +# /* y right wing */ +# /* z down */ +# /*============================================================================*/ + +# #define S_FUNCTION_NAME R +# #define S_FUNCTION_LEVEL 2 +# #define NUM_INPUTS 5 +# #define INPUT_0_WIDTH 3 +# #define INPUT_1_WIDTH 3 +# #define INPUT_2_WIDTH 2 +# #define INPUT_3_WIDTH 1 +# #define INPUT_4_WIDTH 1 +# #define INPUT_0_FEEDTHROUGH 1 +# #define INPUT_1_FEEDTHROUGH 1 +# #define INPUT_2_FEEDTHROUGH 1 +# #define INPUT_3_FEEDTHROUGH 1 +# #define INPUT_4_FEEDTHROUGH 1 +# #define NUM_OUTPUTS 6 +# #define OUTPUT_0_WIDTH 3 +# #define OUTPUT_1_WIDTH 3 +# #define OUTPUT_2_WIDTH 3 +# #define OUTPUT_3_WIDTH 3 +# #define OUTPUT_4_WIDTH 3 +# #define OUTPUT_5_WIDTH 3 +# #define NPARAMS 0 +# #define SAMPLE_TIME_0 0.025 +# #define SAMPLE_TIME_1 1. +# #define NUM_DISC_STATES 0 +# #define DISC_STATES_IC [0] +# #define NUM_CONT_STATES 0 +# #define CONT_STATES_IC [0] +# #define SFUNWIZ_GENERATE_TLC 1 +# #define SOURCEFILES "" +# #define PANELINDEX 5 +# #define SFUNWIZ_REVISION 1.0 +# +# #define DT25 0.025 // 25ms sample time +# #define GPSFILT 0.012422 // x body filter coefficient = 1-exp(-DT25/2s) +# +# #define KPPitchRoll 0.012 // Pitch-Roll correction proportional gain +# #define KIPitchRoll 0.00002 // Pitch-Roll correction integral gain +# #define KPYaw 0.3 // Yaw correction proportional gain +# #define KIYaw 0.0001 // Yaw correction integral gain +# +# #define R2D 57.295779 // Radians to degrees +# #define D2R 0.0174532 // Degrees to radians +# +# #define PARAM_DEF0(S) ssGetSFcnParam(S, 0) +# +# #define MDL_CHECK_PARAMETERS +# #if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE) +# /*----------------------------------------------------------------------------*/ +# static void mdlCheckParameters(SimStruct *S) +# /*----------------------------------------------------------------------------*/ +# { +# unsigned short int i; +# bool validParam = false; +# +# +# /* All parameters must be scalar */ +# for (i=0;i