示例#1
0
// initialize actuator property nodes 
static void bind_act_nodes() {
    act_timestamp_node = fgGetNode("/actuators/actuator/time-stamp", true);
    act_aileron_node = fgGetNode("/actuators/actuator/channel", 0, true);
    act_elevator_node = fgGetNode("/actuators/actuator/channel", 1, true);
    act_throttle_node = fgGetNode("/actuators/actuator/channel", 2, true);
    act_rudder_node = fgGetNode("/actuators/actuator/channel", 3, true);
    act_channel5_node = fgGetNode("/actuators/actuator/channel", 4, true);
    act_channel6_node = fgGetNode("/actuators/actuator/channel", 5, true);
    act_channel7_node = fgGetNode("/actuators/actuator/channel", 6, true);
    act_channel8_node = fgGetNode("/actuators/actuator/channel", 7, true);
}
示例#2
0
void AirData_close() {
    // traverse configured modules
    SGPropertyNode *toplevel = fgGetNode("/config/sensors/air-data-group", true);
    for ( int i = 0; i < toplevel->nChildren(); ++i ) {
	SGPropertyNode *section = toplevel->getChild(i);
	string name = section->getName();
	if ( name == "airdata" ) {
	    string source = section->getChild("source", 0, true)->getStringValue();
	    string basename = "/sensors/";
	    basename += section->getDisplayName();
	    // printf("i = %d  name = %s source = %s %s\n",
	    //	   i, name.c_str(), source.c_str(), basename.c_str());
	    if ( source == "null" ) {
		// do nothing
	    } else if ( source == "fgfs" ) {
		// nop
	    } else if ( source == "ardupilot" ) {
		// nop
#ifdef ENABLE_MNAV_SENSOR
	    } else if ( source == "mnav" ) {
		// nop
#endif
	    } else {
		printf("Unknown air data source = '%s' in config file\n",
		       source.c_str());
	    }
	}
    }
}
示例#3
0
void Actuators_close() {
    // traverse configured modules
    SGPropertyNode *toplevel = fgGetNode("/config/actuators", true);
    for ( int i = 0; i < toplevel->nChildren(); ++i ) {
	SGPropertyNode *section = toplevel->getChild(i);
	string name = section->getName();
	if ( name == "actuator" ) {
	    string module = section->getChild("module", 0, true)->getStringValue();
	    bool enabled = section->getChild("enable", 0, true)->getBoolValue();
	    if ( !enabled ) {
		continue;
	    }
	    if ( module == "null" ) {
		// do nothing
	    } else if ( module == "ardupilot" ) {
		ardupilot_close();
	    } else if ( module == "fgfs" ) {
		fgfs_act_close();
#ifdef ENABLE_MNAV_SENSOR
	    } else if ( module == "mnav" ) {
		// do nothing
#endif // ENABLE_MNAV_SENSOR
	    } else {
		printf("Unknown actuator = '%s' in config file\n",
		       module.c_str());
	    }
	}
    }
}
示例#4
0
// initialize mnav gps output property nodes 
static void bind_airdata_output( string rootname ) {
    // "/sensors/air-data"
    outputroot = fgGetNode( rootname.c_str(), true );
    airdata_timestamp_node = outputroot->getChild("time-stamp", 0, true);
    airdata_altitude_node = outputroot->getChild("altitude-m", 0, true);
    airdata_airspeed_node = outputroot->getChild("airspeed-kt", 0, true);
}
示例#5
0
// initialize mnav gps output property nodes 
static void bind_gps_output( string rootname ) {
    outputroot = fgGetNode( rootname.c_str(), true );
    gps_timestamp_node = outputroot->getChild("time-stamp", 0, true);
    gps_lat_node = outputroot->getChild("latitude-deg", 0, true);
    gps_lon_node = outputroot->getChild("longitude-deg", 0, true);
    gps_alt_node = outputroot->getChild("altitude-m", 0, true);
    gps_ve_node = outputroot->getChild("ve-ms", 0, true);
    gps_vn_node = outputroot->getChild("vn-ms", 0, true);
    gps_vd_node = outputroot->getChild("vd-ms", 0, true);
    gps_unix_sec_node = outputroot->getChild("unix-time-sec", 0, true);
}
示例#6
0
// initialize mnav imu output property nodes 
static void bind_imu_output( string rootname ) {
    outputroot = fgGetNode( rootname.c_str(), true );
    imu_timestamp_node = outputroot->getChild("time-stamp", 0, true);
    imu_p_node = outputroot->getChild("p-rad_sec", 0, true);
    imu_q_node = outputroot->getChild("q-rad_sec", 0, true);
    imu_r_node = outputroot->getChild("r-rad_sec", 0, true);
    imu_ax_node = outputroot->getChild("ax-mps_sec", 0, true);
    imu_ay_node = outputroot->getChild("ay-mps_sec", 0, true);
    imu_az_node = outputroot->getChild("az-mps_sec", 0, true);
    imu_hx_node = outputroot->getChild("hx", 0, true);
    imu_hy_node = outputroot->getChild("hy", 0, true);
    imu_hz_node = outputroot->getChild("hz", 0, true);
}
示例#7
0
bool health_init() {
    loadavg_init();
    //sgbatmon_init();

    ap_roll = fgGetNode("/autopilot/internal/target-roll-deg", true);
    ap_hdg = fgGetNode( "/autopilot/settings/true-heading-deg", true );
    ap_pitch = fgGetNode( "/autopilot/settings/target-pitch-deg", true );
    ap_climb = fgGetNode("/autopilot/internal/target-climb-rate-fps", true);
    ap_altitude = fgGetNode( "/autopilot/settings/target-altitude-ft", true );
    ground_ref = fgGetNode( "/position/ground-altitude-pressure-m", true );
    ap_agl = fgGetNode( "/autopilot/settings/target-agl-ft", true );

    // set initial values
    healthpacket.command_sequence = 0;
    healthpacket.target_waypoint = 0;

    return true;
}
示例#8
0
void control_init() {
    // initialize the autopilot class and build the structures from the
    // configuration file values
    ap.init();
    ap.build();

    // initialize the flight control output property nodes
    aileron_out_node = fgGetNode("/controls/flight/aileron", true);
    elevator_out_node = fgGetNode("/controls/flight/elevator", true);
    throttle_out_node = fgGetNode("/engines/engine[0]/throttle", true);
    rudder_out_node = fgGetNode("/controls/flight/rudder", true);

    ap_target = fgGetNode("/autopilot/settings/target-roll-deg", true);

    elevon_mix = fgGetNode("/config/autopilot/elevon-mixing", true);
}
示例#9
0
bool loadavg_init() {
    system_load_avg = fgGetNode("/status/system-load-avg", true);

    return true;
}
示例#10
0
void Actuator_init() {
    debug6a.set_name("debug6a act update and output");
    debug6b.set_name("debug6b act console logging");

    // bind properties
    output_aileron_node = fgGetNode("/controls/flight/aileron", true);
    output_elevator_node = fgGetNode("/controls/flight/elevator", true);
    output_elevator_damp_node = fgGetNode("/controls/flight/elevator-damp", true);
    output_throttle_node = fgGetNode("/controls/engine/throttle", true);
    output_rudder_node = fgGetNode("/controls/flight/rudder", true);

    act_elevon_mix_node = fgGetNode("/config/actuators/elevon-mixing", true);
    agl_alt_ft_node = fgGetNode("/position/altitude-agl-ft", true);

    act_timestamp_node = fgGetNode("/actuators/actuator/time-stamp", true);
    act_aileron_node = fgGetNode("/actuators/actuator/channel", 0, true);
    act_elevator_node = fgGetNode("/actuators/actuator/channel", 1, true);
    act_throttle_node = fgGetNode("/actuators/actuator/channel", 2, true);
    act_rudder_node = fgGetNode("/actuators/actuator/channel", 3, true);
    act_channel5_node = fgGetNode("/actuators/actuator/channel", 4, true);
    act_channel6_node = fgGetNode("/actuators/actuator/channel", 5, true);
    act_channel7_node = fgGetNode("/actuators/actuator/channel", 6, true);
    act_channel8_node = fgGetNode("/actuators/actuator/channel", 7, true);

    // initialize comm nodes
    act_console_skip = fgGetNode("/config/remote-link/actuator-skip", true);
    act_logging_skip = fgGetNode("/config/logging/actuator-skip", true);

    // throttle safety
    throttle_safety_prop_node
	= fgGetNode("/config/actuators/throttle-safety/prop", true);
    if ( (string)throttle_safety_prop_node->getStringValue() != (string)"" ) {
	throttle_safety_val_node
	    = fgGetNode(throttle_safety_prop_node->getStringValue(), true);
    }
    throttle_safety_min_node
	= fgGetNode("/config/actuators/throttle-safety/min-value", true);

    // master autopilot switch
    ap_master_switch_node = fgGetNode("/autopilot/master-switch", true);
    fcs_mode_node = fgGetNode("/config/fcs/mode", true);

    // default to ap on unless pilot inputs turn it off (so we can run
    // with no pilot inputs connected)
    ap_master_switch_node->setBoolValue( true );

    // traverse configured modules
    SGPropertyNode *toplevel = fgGetNode("/config/actuators", true);
    for ( int i = 0; i < toplevel->nChildren(); ++i ) {
	SGPropertyNode *section = toplevel->getChild(i);
	string name = section->getName();
	if ( name == "actuator" ) {
	    string module = section->getChild("module", 0, true)->getStringValue();
	    bool enabled = section->getChild("enable", 0, true)->getBoolValue();
	    if ( !enabled ) {
		continue;
	    }
	    printf("i = %d  name = %s module = %s\n",
	    	   i, name.c_str(), module.c_str());

	    if ( module == "null" ) {
		// do nothing
	    } else if ( module == "ardupilot" ) {
		ardupilot_init( section );
	    } else if ( module == "fgfs" ) {
		fgfs_act_init( section );
#ifdef ENABLE_MNAV_SENSOR
	    } else if ( module == "mnav" ) {
		mnav_act_init();
#endif // ENABLE_MNAV_SENSOR
	    } else {
		printf("Unknown actuator = '%s' in config file\n",
		       module.c_str());
	    }
	}
    }
}
示例#11
0
bool Actuator_update() {
    debug6a.start();

    // time stamp for logging
    act_timestamp_node->setDoubleValue( get_Time() );
    if ( ap_master_switch_node->getBoolValue() ) {
	set_actuator_values_ap();
    } else {
	set_actuator_values_pilot();
    }

    // traverse configured modules
    SGPropertyNode *toplevel = fgGetNode("/config/actuators", true);
    for ( int i = 0; i < toplevel->nChildren(); ++i ) {
	SGPropertyNode *section = toplevel->getChild(i);
	string name = section->getName();
	if ( name == "actuator" ) {
	    string module = section->getChild("module", 0, true)->getStringValue();
	    bool enabled = section->getChild("enable", 0, true)->getBoolValue();
	    if ( !enabled ) {
		continue;
	    }
	    if ( module == "null" ) {
		// do nothing
	    } else if ( module == "ardupilot" ) {
		ardupilot_update();
	    } else if ( module == "fgfs" ) {
		fgfs_act_update();
#ifdef ENABLE_MNAV_SENSOR
	    } else if ( module == "mnav" ) {
		mnav_send_short_servo_cmd( /* &servo_out */ );
#endif // ENABLE_MNAV_SENSOR
	    } else {
		printf("Unknown actuator = '%s' in config file\n",
		       module.c_str());
	    }
	}
    }

    debug6a.stop();

    debug6b.start();

    if ( remote_link_on || log_to_file ) {
	// actuators

	uint8_t buf[256];
	int size = packetizer->packetize_actuator( buf );

	if ( remote_link_on ) {
	    remote_link_actuator( buf, size, act_console_skip->getIntValue() );
	}

	if ( log_to_file ) {
	    log_actuator( buf, size, act_logging_skip->getIntValue() );
	}
    }

    debug6b.stop();

    return true;
}
示例#12
0
void AirData_init() {
    debug2b1.set_name("debug2b1 airdata update");
    debug2b2.set_name("debug2b2 airdata console link");

    // initialize air data property nodes
    airdata_timestamp_node = fgGetNode("/sensors/air-data/time-stamp", true);
    airdata_altitude_node = fgGetNode("/sensors/air-data/altitude-m", true);
    airdata_airspeed_node = fgGetNode("/sensors/air-data/airspeed-kt", true);

    // input property nodes
    filter_timestamp_node = fgGetNode("/filters/filter/time-stamp", true);
    filter_alt_node = fgGetNode("/position/altitude-m", true);

    // filtered/computed output property nodes
    altitude_filt_node = fgGetNode("/position/altitude-pressure-m", true);
    airspeed_filt_node = fgGetNode("/velocity/airspeed-kt", true);

    true_alt_ft_node = fgGetNode("/position/altitude-true-combined-ft",true);
    agl_alt_ft_node = fgGetNode("/position/altitude-pressure-agl-ft", true);

    pressure_error_m_node
	= fgGetNode("/position/pressure-error-m", true);
    vert_fps_node
	= fgGetNode("/velocity/pressure-vertical-speed-fps",true);
    forward_accel_node = fgGetNode("/acceleration/airspeed-ktps",true);
    ground_alt_press_m_node
        = fgGetNode("/position/ground-altitude-pressure-m", true);

    // initialize comm nodes
    airdata_console_skip = fgGetNode("/config/remote-link/airdata-skip", true);
    airdata_logging_skip = fgGetNode("/config/logging/airdata-skip", true);

    // traverse configured modules
    SGPropertyNode *toplevel = fgGetNode("/config/sensors/air-data-group", true);
    for ( int i = 0; i < toplevel->nChildren(); ++i ) {
	SGPropertyNode *section = toplevel->getChild(i);
	string name = section->getName();
	if ( name == "air-data" ) {
	    string source = section->getChild("source", 0, true)->getStringValue();
	    bool enabled = section->getChild("enable", 0, true)->getBoolValue();
	    if ( !enabled ) {
		continue;
	    }
	    string basename = "/sensors/";
	    basename += section->getDisplayName();
	    printf("i = %d  name = %s source = %s %s\n",
		   i, name.c_str(), source.c_str(), basename.c_str());
	    if ( source == "null" ) {
		// do nothing
	    } else if ( source == "ardupilot" ) {
		ardupilot_airdata_init( basename );
	    } else if ( source == "fgfs" ) {
		fgfs_airdata_init( basename );
#ifdef ENABLE_MNAV_SENSOR
	    } else if ( source == "mnav" ) {
		mnav_airdata_init( basename );
#endif // ENABLE_MNAV_SENSOR
	    } else {
		printf("Unknown air data source = '%s' in config file\n",
		       source.c_str());
	    }
	}
    }
}
示例#13
0
static void bind_properties() {
    ap_master_switch_node = fgGetNode("/autopilot/master-switch", true);
    fcs_mode_node = fgGetNode("/config/fcs/mode", true);
    // ap_heading_mode_node = fgGetNode("/autopilot/heading-mode", true);
    // ap_roll_mode_node = fgGetNode("/autopilot/roll-mode", true);
    // ap_yaw_mode_node = fgGetNode("/autopilot/yaw-mode", true);
    // ap_altitude_mode_node = fgGetNode("/autopilot/altitude-mode", true);
    // ap_speed_mode_node = fgGetNode("/autopilot/speed-mode", true);
    // ap_pitch_mode_node = fgGetNode("/autopilot/pitch-mode", true);

    heading_lock_node = fgGetNode("/autopilot/locks/heading", true);
    roll_lock_node = fgGetNode("/autopilot/locks/roll", true);
    yaw_lock_node = fgGetNode("/autopilot/locks/yaw", true);
    altitude_lock_node = fgGetNode("/autopilot/locks/altitude", true);
    speed_lock_node = fgGetNode("/autopilot/locks/speed", true);
    pitch_lock_node = fgGetNode("/autopilot/locks/pitch", true);
    pointing_lock_node = fgGetNode("/autopilot/locks/pointing", true);

    lookat_mode_node = fgGetNode("/pointing/lookat-mode", true);
    ned_n_node = fgGetNode("/pointing/vector/north", true);
    ned_e_node = fgGetNode("/pointing/vector/east", true);
    ned_d_node = fgGetNode("/pointing/vector/down", true);

    roll_deg_node = fgGetNode("/orientation/roll-deg", true);
    pitch_deg_node = fgGetNode("/orientation/pitch-deg", true);
    cur_speed_node = fgGetNode("/velocity/airspeed-kt", true);
    initial_speed_node = fgGetNode("/config/fcs/initial-speed-kt", true);
    target_roll_deg_node
	= fgGetNode("/autopilot/settings/target-roll-deg", true);
    target_pitch_base_deg_node
	= fgGetNode("/autopilot/settings/target-pitch-base-deg", true);
    target_speed_node = fgGetNode("/autopilot/settings/target-speed-kt", true);
}
示例#14
0
bool AirData_update() {
    debug2b1.start();

    air_prof.start();

    bool fresh_data = false;

    // traverse configured modules
    SGPropertyNode *toplevel = fgGetNode("/config/sensors/air-data-group", true);
    for ( int i = 0; i < toplevel->nChildren(); ++i ) {
	SGPropertyNode *section = toplevel->getChild(i);
	string name = section->getName();
	if ( name == "air-data" ) {
	    string source = section->getChild("source", 0, true)->getStringValue();
	    bool enabled = section->getChild("enable", 0, true)->getBoolValue();
	    if ( !enabled ) {
		continue;
	    }
	    string basename = "/sensors/";
	    basename += section->getDisplayName();
	    // printf("i = %d  name = %s source = %s %s\n",
	    //	   i, name.c_str(), source.c_str(), basename.c_str());
	    if ( source == "null" ) {
		// do nothing
	    } else if ( source == "ardupilot" ) {
		fresh_data = ardupilot_airdata_update();
	    } else if ( source == "fgfs" ) {
		fresh_data = fgfs_airdata_update();
#ifdef ENABLE_MNAV_SENSOR
	    } else if ( source == "mnav" ) {
		fresh_data = mnav_get_airdata();
#endif // ENABLE_MNAV_SENSOR
	    } else {
		printf("Unknown air data source = '%s' in config file\n",
		       source.c_str());
	    }
	}
    }

    debug2b1.stop();
    debug2b2.start();

    if ( fresh_data ) {
	update_pressure_helpers();

	if ( remote_link_on || log_to_file ) {
	    uint8_t buf[256];
	    int size = packetizer->packetize_airdata( buf );

	    if ( remote_link_on ) {
		// printf("sending filter packet\n");
		remote_link_airdata( buf, size,
				      airdata_console_skip->getIntValue() );
	    }

	    if ( log_to_file ) {
		log_airdata( buf, size, airdata_logging_skip->getIntValue() );
	    }
	}
    }

    debug2b2.stop();

    air_prof.stop();

    return fresh_data;
}
示例#15
0
static void init_props() {
    props_inited = true;

    // initialize imu property nodes
    imu_timestamp_node = fgGetNode("/sensors/imu/time-stamp");
    imu_p_node = fgGetNode("/sensors/imu/p-rad_sec", true);
    imu_q_node = fgGetNode("/sensors/imu/q-rad_sec", true);
    imu_r_node = fgGetNode("/sensors/imu/r-rad_sec", true);
    imu_ax_node = fgGetNode("/sensors/imu/ax-mps_sec", true);
    imu_ay_node = fgGetNode("/sensors/imu/ay-mps_sec", true);
    imu_az_node = fgGetNode("/sensors/imu/az-mps_sec", true);
    imu_hx_node = fgGetNode("/sensors/imu/hx", true);
    imu_hy_node = fgGetNode("/sensors/imu/hy", true);
    imu_hz_node = fgGetNode("/sensors/imu/hz", true);

    // initialize air data nodes
    airdata_altitude_node = fgGetNode("/sensors/air-data/altitude-m", true);
    airdata_airspeed_node = fgGetNode("/sensors/air-data/airspeed-kt", true);

    // initialize gps property nodes
    gps_timestamp_node = fgGetNode("/sensors/gps/time-stamp", true);
    gps_lat_node = fgGetNode("/sensors/gps/latitude-deg", true);
    gps_lon_node = fgGetNode("/sensors/gps/longitude-deg", true);
    gps_alt_node = fgGetNode("/sensors/gps/altitude-m", true);
    gps_ve_node = fgGetNode("/sensors/gps/ve-ms", true);
    gps_vn_node = fgGetNode("/sensors/gps/vn-ms", true);
    gps_vd_node = fgGetNode("/sensors/gps/vd-ms", true);
    gps_track_node = fgGetNode("/sensors/gps/groundtrack-deg", true);
    gps_unix_sec_node = fgGetNode("/sensors/gps/unix-time-sec", true);

    // initialize filter property nodes 
    filter_theta_node = fgGetNode("/orientation/pitch-deg", true);
    filter_phi_node = fgGetNode("/orientation/roll-deg", true);
    filter_psi_node = fgGetNode("/orientation/heading-deg", true);
    filter_lat_node = fgGetNode("/position/latitude-deg", true);
    filter_lon_node = fgGetNode("/position/longitude-deg", true);
    filter_alt_node = fgGetNode("/position/altitude-m", true);
    filter_vn_node = fgGetNode("/velocity/vn-ms", true);
    filter_ve_node = fgGetNode("/velocity/ve-ms", true);
    filter_vd_node = fgGetNode("/velocity/vd-ms", true);
    filter_status_node = fgGetNode("/health/navigation", true);

    // initialize actuator property nodes
    act_aileron_node = fgGetNode("/actuators/actuator/channel", 0, true);
    act_elevator_node = fgGetNode("/actuators/actuator/channel", 1, true);
    act_throttle_node = fgGetNode("/actuators/actuator/channel", 2, true);
    act_rudder_node = fgGetNode("/actuators/actuator/channel", 3, true);
    act_channel5_node = fgGetNode("/actuators/actuator/channel", 4, true);

    // initialize pilot property nodes
    pilot_aileron_node = fgGetNode("/sensors/pilot/aileron", true);
    pilot_elevator_node = fgGetNode("/sensors/pilot/elevator", true);
    pilot_throttle_node = fgGetNode("/sensors/pilot/throttle", true);
    pilot_rudder_node = fgGetNode("/sensors/pilot/rudder", true);
    pilot_channel5_node = fgGetNode("/sensors/pilot/manual", true);

    // initialize health/status property nodes
    link_seq_num = fgGetNode("/status/remote-link-sequence-num", true);
    target_waypoint = fgGetNode( "/autopilot/route-mgr/target-waypoint-idx",
				 true );
    system_load_avg = fgGetNode("/status/system-load-avg", true);
}
void uiuc_gear()
{
  
  /*
   * Aircraft specific initializations and data goes here
   */
  
  static DATA percent_brake[MAX_GEAR] =	    /* percent applied braking */
  { 0.,  0.,  0., 0.,
    0.,  0.,  0., 0.,
    0.,  0.,  0., 0.,
    0.,  0.,  0., 0. };			    /* 0 = none, 1 = full */
  static DATA caster_angle_rad[MAX_GEAR] =	    /* steerable tires - in */
  { 0., 0., 0., 0.,
    0., 0., 0., 0.,
    0., 0., 0., 0.,
    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[MAX_GEAR] =
  { 1, 1, 1, 0,
    0, 0, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0 };	
  static DATA sliding_mu[MAX_GEAR] =
  { 0.5, 0.5, 0.5, 0.3,
    0.3, 0.3, 0.3, 0.3,
    0.3, 0.3, 0.3, 0.3,
    0.3, 0.3, 0.3, 0.3 };	
  static DATA max_brake_mu[MAX_GEAR] =
  { 0.0, 0.6, 0.6, 0.0,
    0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 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];
  // DATA temp3b[3];
  DATA tempF[3];
  DATA 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[0];
  percent_brake[2] = Brake_pct[1];
  
  caster_angle_rad[0] =
    (0.01 + 0.04 * (1 - V_calibrated_kts / 130)) * Rudder_pedal;
  
  
  for (i=0;i<MAX_GEAR;i++)	    /* Loop for each wheel */
    {
      // Execute only if the gear has been defined
      if (!gear_model[i]) 
	{
	  // do nothing
	  continue;
	}       
      else
	{
	  
	  /*========================================*/
	  /* Calculate wheel position w.r.t. runway */
	  /*========================================*/
	  
	  /* printf("\thgcg: %g, theta: %g,phi: %g\n",D_cg_above_rwy,Theta*RAD_TO_DEG,Phi*RAD_TO_DEG); */
	  
	  /* First calculate wheel location w.r.t. cg in body (X-Y-Z) axes... */
	  
	  sub3( D_gear_v[i], D_cg_rp_body_v, d_wheel_cg_body_v );
	  
	  /* then converting to local (North-East-Down) axes... */
	  
	  multtrans3x3by3( T_local_to_body_m,  d_wheel_cg_body_v, d_wheel_cg_local_v );
	  
	  
	  /* Runway axes correction - third element is Altitude, not (-)Z... */
	  
	  d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* since altitude = -Z */
	  
	  /* Add wheel offset to cg location in local axes */
	  
	  add3( d_wheel_cg_local_v, D_cg_rwy_local_v, d_wheel_rwy_local_v );
	  
	  /* remove Runway axes correction so right hand rule applies */
	  
	  d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* now Z positive down */
	  
	  /*============================*/
	  /* Calculate wheel velocities */
	  /*============================*/
	  
	  /* contribution due to angular rates */
	  
	  cross3( Omega_body_v, d_wheel_cg_body_v, temp3a );
	  
	  /* transform into local axes */
	  
	  multtrans3x3by3( T_local_to_body_m, temp3a,v_wheel_cg_local_v );
	  
	  /* plus contribution due to cg velocities */
	  
	  add3( v_wheel_cg_local_v, V_local_rel_ground_v, v_wheel_local_v );
	  
	  clear3(f_wheel_local_v);
	  reaction_normal_force=0;
#if 0
	  static const SGPropertyNode * gear_wow
	    = fgGetNode("/gear/gear[0]/wow", false);
	  static const SGPropertyNode * gear_wow1
	    = fgGetNode("/gear/gear[1]/wow", false);
	  static const SGPropertyNode * gear_wow2
	    = fgGetNode("/gear/gear[2]/wow", false);
#endif
	  fgSetBool("/gear/gear[0]/wow", false);
	  fgSetBool("/gear/gear[1]/wow", false);
	  fgSetBool("/gear/gear[2]/wow", false);
	  if( HEIGHT_AGL_WHEEL < 0. ) 
	    /*the wheel is underground -- which implies ground contact 
	      so calculate reaction forces */ 
	    {
	      //set the property - weight on wheels
	      //  	  if (i==0) 
	      //  	    {
	      //  	      fgSetBool("/gear/gear[0]/wow", true);
	      //  	    }
	      //	  if (i==1) 
	      //	    {
	      //	      fgSetBool("/gear/gear[1]/wow", true);
	      //	    }
	      //  	  if (i==2) 
	      //  	    {
	      //  	      fgSetBool("/gear/gear[2]/wow", true);
	      //  	    }
	      
	      /*===========================================*/
	      /* Calculate forces & moments for this wheel */
	      /*===========================================*/
	      
	      /* Add any anticipation, or frame lead/prediction, here... */
	      
		    		/* no lead used at present */
	      
	      /* Calculate sideward and forward velocities of the wheel 
		 in the runway plane					*/
	      
	      cos_wheel_hdg_angle = cos(caster_angle_rad[i] + Psi);
	      sin_wheel_hdg_angle = sin(caster_angle_rad[i] + Psi);
	      
	      v_wheel_forward  = v_wheel_local_v[0]*cos_wheel_hdg_angle
		+ v_wheel_local_v[1]*sin_wheel_hdg_angle;
	      v_wheel_sideward = v_wheel_local_v[1]*cos_wheel_hdg_angle
		- v_wheel_local_v[0]*sin_wheel_hdg_angle;
	      
	      
	      /* Calculate normal load force (simple spring constant) */
	      
	      reaction_normal_force = 0.;
	      
	      reaction_normal_force = kgear[i]*d_wheel_rwy_local_v[2]
		- v_wheel_local_v[2]*cgear[i];
	      /* printf("\treaction_normal_force: %g\n",reaction_normal_force); */
	      
	      if (reaction_normal_force > 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] - muGear[i])*percent_brake[i] + muGear[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 */
	      if (tempF[0] != 0.0 || tempF[1] != 0.0 || tempF[2] != 0.0) {
		fgSetBool("/gear/gear[1]/wow", true);
	      }
	      
	      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); */
      
      
    }
}
示例#17
0
void control_update(short flight_mode)
{
    // make a quick exit if we are disabled
    if ( !autopilot_active ) {
      return;
    }

    // reset the autopilot if requested
    if ( autopilot_reinit ) {
      control_reset();
      autopilot_reinit = false;
    }

    // optional: use channel #6 to change the autopilot target value
    // double min_value = -35.0;
    // double max_value = 35.0;
    // double tgt_value = (max_value - min_value) *
    //   ((double)servo_in.chn[5] / 65535.0) + min_value;
    // ap_target->setFloatValue( tgt_value );

    // update the autopilot stages
    ap.update( 0.04 );	// dt = 1/25

    /* printf("%.2f %.2f\n", aileron_out_node->getFloatValue(),
              elevator_out_node->getFloatValue()); */
    static SGPropertyNode *vert_speed_fps
        = fgGetNode("/velocities/vertical-speed-fps", true);
    static SGPropertyNode *true_alt
        = fgGetNode("/position/altitude-ft", true);
    /* printf("%.1f %.2f %.2f\n",
           true_alt->getFloatValue(),
           vert_speed_fps->getFloatValue(),
           elevator_out_node->getFloatValue()); */

    // initialize the servo command array to central values so we don't
    // inherit junk
    for ( int i = 0; i < 8; ++i ) {
        servo_out.chn[i] = 32768;
    }

    if ( elevon_mix->getBoolValue() ) {
        // elevon mixing mode

        //aileron
        servo_out.chn[0] = 32768
            + (int16_t)(aileron_out_node->getFloatValue() * 32768)
            + (int16_t)(elevator_out_node->getFloatValue() * 32768);

        //elevator
        servo_out.chn[1] = 32768
            + (int16_t)(aileron_out_node->getFloatValue() * 32768)
            - (int16_t)(elevator_out_node->getFloatValue() * 32768);
    } else {
        // conventional airframe mode

        //aileron
        servo_out.chn[0] = 32768
            + (int16_t)(aileron_out_node->getFloatValue() * 32768);

        //elevator
        servo_out.chn[1] = 32768
            + (int16_t)(elevator_out_node->getFloatValue() * 32768);
    }

    //throttle
    servo_out.chn[2] = 32768
        + (uint16_t)(throttle_out_node->getFloatValue() * 32768);

    // rudder
    servo_out.chn[3] = 32768
        + (int16_t)(rudder_out_node->getFloatValue() * 32768);

    // time stamp the packet for logging
    servo_out.time = get_Time();

    // send commanded servo positions to the MNAV
    send_short_servo_cmd();
}