/*************************************************************************** TITLE: gear ---------------------------------------------------------------------------- FUNCTION: Landing gear model for example simulation ---------------------------------------------------------------------------- MODULE STATUS: developmental ---------------------------------------------------------------------------- GENEALOGY: Created 931012 by E. B. Jackson ---------------------------------------------------------------------------- DESIGNED BY: E. B. Jackson CODED BY: E. B. Jackson MAINTAINED BY: E. B. Jackson ---------------------------------------------------------------------------- MODIFICATION HISTORY: DATE PURPOSE BY 931218 Added navion.h header to allow connection with aileron displacement for nosewheel steering. EBJ 940511 Connected nosewheel to rudder pedal; adjusted gain. CURRENT RCS HEADER: $Header$ $Log$ Revision 1.14 2000/04/10 18:09:41 curt David Megginson made a few (mostly minor) mods to the LaRCsim files, and it's now possible to choose the LaRCsim model at runtime, as in fgfs --aircraft=c172 or fgfs --aircraft=uiuc --aircraft-dir=Aircraft-uiuc/Boeing747 I did this so that I could play with the UIUC stuff without losing Tony's C172 with its flaps, etc. I did my best to respect the design of the LaRCsim code by staying in C, making only minimal changes, and not introducing any dependencies on the rest of FlightGear. The modified files are attached. Revision 1.13 1999/12/13 20:43:41 curt Updates from Tony. ---------------------------------------------------------------------------- REFERENCES: ---------------------------------------------------------------------------- CALLED BY: ---------------------------------------------------------------------------- CALLS TO: ---------------------------------------------------------------------------- INPUTS: ---------------------------------------------------------------------------- OUTPUTS: --------------------------------------------------------------------------*/ #include #include "ls_types.h" #include "ls_constants.h" #include "ls_generic.h" #include "ls_cockpit.h" #define HEIGHT_AGL_WHEEL d_wheel_rwy_local_v[2] static sub3( DATA v1[], DATA v2[], DATA result[] ) { result[0] = v1[0] - v2[0]; result[1] = v1[1] - v2[1]; result[2] = v1[2] - v2[2]; } static add3( DATA v1[], DATA v2[], DATA result[] ) { result[0] = v1[0] + v2[0]; result[1] = v1[1] + v2[1]; result[2] = v1[2] + v2[2]; } static cross3( DATA v1[], DATA v2[], DATA result[] ) { result[0] = v1[1]*v2[2] - v1[2]*v2[1]; result[1] = v1[2]*v2[0] - v1[0]*v2[2]; result[2] = v1[0]*v2[1] - v1[1]*v2[0]; } static multtrans3x3by3( DATA m[][3], DATA v[], DATA result[] ) { result[0] = m[0][0]*v[0] + m[1][0]*v[1] + m[2][0]*v[2]; result[1] = m[0][1]*v[0] + m[1][1]*v[1] + m[2][1]*v[2]; result[2] = m[0][2]*v[0] + m[1][2]*v[1] + m[2][2]*v[2]; } static mult3x3by3( DATA m[][3], DATA v[], DATA result[] ) { result[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; result[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; result[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; } static clear3( DATA v[] ) { v[0] = 0.; v[1] = 0.; v[2] = 0.; } c172_gear() { char rcsid[] = "$Id$"; #define NUM_WHEELS 4 char gear_strings[NUM_WHEELS][12]={"nose","right main", "left main", "tail skid"}; /* * Aircraft specific initializations and data goes here */ static int num_wheels = NUM_WHEELS; /* number of wheels */ static DATA d_wheel_rp_body_v[NUM_WHEELS][3] = /* X, Y, Z locations,full extension */ { { 3.91, 0., 6.67 }, /*nose*/ /* in feet */ { -1.47, 3.58, 6.71 }, /*right main*/ { -1.47, -3.58, 6.71 }, /*left main*/ { -15.67, 0, 2.42 } /*tail skid */ }; static DATA gear_travel[NUM_WHEELS] = /*in Z-axis*/ { -0.5, 2.5, 2.5, 0}; static DATA spring_constant[NUM_WHEELS] = /* springiness, lbs/ft */ { 1200., 900., 900., 10000. }; static DATA spring_damping[NUM_WHEELS] = /* damping, lbs/ft/sec */ { 200., 300., 300., 400. }; static DATA percent_brake[NUM_WHEELS] = /* percent applied braking */ { 0., 0., 0., 0. }; /* 0 = none, 1 = full */ static DATA caster_angle_rad[NUM_WHEELS] = /* steerable tires - in */ { 0., 0., 0., 0}; /* radians, +CW */ /* * End of aircraft specific code */ /* * Constants & coefficients for tyres on tarmac - ref [1] */ /* skid function looks like: * * mu ^ * | * max_mu | + * | /| * sliding_mu | / +------ * | / * | / * +--+------------------------> * | | | sideward V * 0 bkout skid * V V */ static int it_rolls[NUM_WHEELS] = { 1,1,1,0}; static DATA sliding_mu[NUM_WHEELS] = { 0.5, 0.5, 0.5, 0.3}; static DATA rolling_mu[NUM_WHEELS] = { 0.01, 0.01, 0.01, 0.0}; static DATA max_brake_mu[NUM_WHEELS] ={ 0.0, 0.6, 0.6, 0.0}; static DATA max_mu = 0.8; static DATA bkout_v = 0.1; static DATA skid_v = 1.0; /* * Local data variables */ DATA d_wheel_cg_body_v[3]; /* wheel offset from cg, X-Y-Z */ DATA d_wheel_cg_local_v[3]; /* wheel offset from cg, N-E-D */ DATA d_wheel_rwy_local_v[3]; /* wheel offset from rwy, N-E-U */ DATA v_wheel_cg_local_v[3]; /*wheel velocity rel to cg N-E-D*/ DATA v_wheel_body_v[3]; /* wheel velocity, X-Y-Z */ DATA v_wheel_local_v[3]; /* wheel velocity, N-E-D */ DATA f_wheel_local_v[3]; /* wheel reaction force, N-E-D */ DATA altitude_local_v[3]; /*altitude vector in local (N-E-D) i.e. (0,0,h)*/ DATA altitude_body_v[3]; /*altitude vector in body (X,Y,Z)*/ DATA temp3a[3], temp3b[3], tempF[3], tempM[3]; DATA reaction_normal_force; /* wheel normal (to rwy) force */ DATA cos_wheel_hdg_angle, sin_wheel_hdg_angle; /* temp storage */ DATA v_wheel_forward, v_wheel_sideward, abs_v_wheel_sideward; DATA forward_mu, sideward_mu; /* friction coefficients */ DATA beta_mu; /* breakout friction slope */ DATA forward_wheel_force, sideward_wheel_force; int i; /* per wheel loop counter */ /* * Execution starts here */ beta_mu = max_mu/(skid_v-bkout_v); clear3( F_gear_v ); /* Initialize sum of forces... */ clear3( M_gear_v ); /* ...and moments */ /* * Put aircraft specific executable code here */ percent_brake[1] = Brake_pct; /* replace with cockpit brake handle connection code */ percent_brake[2] = percent_brake[1]; caster_angle_rad[0] = 0.52*Rudder_pedal; for (i=0;i 0.) reaction_normal_force = 0.; /* to prevent damping component from swamping spring component */ /* Calculate friction coefficients */ if(it_rolls[i]) { forward_mu = (max_brake_mu[i] - rolling_mu[i])*percent_brake[i] + rolling_mu[i]; abs_v_wheel_sideward = sqrt(v_wheel_sideward*v_wheel_sideward); sideward_mu = sliding_mu[i]; if (abs_v_wheel_sideward < skid_v) sideward_mu = (abs_v_wheel_sideward - bkout_v)*beta_mu; if (abs_v_wheel_sideward < bkout_v) sideward_mu = 0.; } else { forward_mu=sliding_mu[i]; sideward_mu=sliding_mu[i]; } /* Calculate foreward and sideward reaction forces */ forward_wheel_force = forward_mu*reaction_normal_force; sideward_wheel_force = sideward_mu*reaction_normal_force; if(v_wheel_forward < 0.) forward_wheel_force = -forward_wheel_force; if(v_wheel_sideward < 0.) sideward_wheel_force = -sideward_wheel_force; /* printf("\tFfwdgear: %g Fsidegear: %g\n",forward_wheel_force,sideward_wheel_force); */ /* Rotate into local (N-E-D) axes */ f_wheel_local_v[0] = forward_wheel_force*cos_wheel_hdg_angle - sideward_wheel_force*sin_wheel_hdg_angle; f_wheel_local_v[1] = forward_wheel_force*sin_wheel_hdg_angle + sideward_wheel_force*cos_wheel_hdg_angle; f_wheel_local_v[2] = reaction_normal_force; /* Convert reaction force from local (N-E-D) axes to body (X-Y-Z) */ mult3x3by3( T_local_to_body_m, f_wheel_local_v, tempF ); /* Calculate moments from force and offsets in body axes */ cross3( d_wheel_cg_body_v, tempF, tempM ); /* Sum forces and moments across all wheels */ add3( tempF, F_gear_v, F_gear_v ); add3( tempM, M_gear_v, M_gear_v ); } /* printf("\tN: %g,dZrwy: %g dZdotrwy: %g\n",reaction_normal_force,HEIGHT_AGL_WHEEL,v_wheel_cg_local_v[2]); */ /*printf("\tFxgear: %g Fygear: %g, Fzgear: %g\n",F_X_gear,F_Y_gear,F_Z_gear); printf("\tMgear: %g, Lgear: %g, Ngear: %g\n\n",M_m_gear,M_l_gear,M_n_gear); */ } }