123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- ###############################################################################
- ## $Id: copilot-dual-control.nas,v 1.5 2010/01/02 09:49:31 vmmeazza Exp $
- ##
- ## Nasal for copilot for dual control over the multiplayer network.
- ##
- ## Copyright (C) 2007 - 2009 Anders Gidenstam (anders(at)gidenstam.org)
- ## This file is licensed under the GPL license version 2 or later.
- ##
- ###############################################################################
- # Renaming (almost :)
- var DCT = dual_control_tools;
- var ADC = aircraft_dual_control;
- # NOTE: By loading the aircraft specific dual control module
- # as <aircraft_dual_control> this file is generic.
- # The aircraft specific modul must set the variables
- # pilot_type and copilot_type to the name (with full path) of
- # main 3d model XML for the pilot and copilot aircraft.
- # This module should be loades under the name dual_control.
- # Allow aircraft to override the copilot view name. Deprecated.
- if (!contains(ADC, "copilot_view")) {
- ADC.copilot_view = "Copilot View";
- }
- # Properties for position and orientation of local aircraft.
- var l_lat = "/position/latitude-deg";
- var l_lon = "/position/longitude-deg";
- var l_alt = "/position/altitude-ft";
- var l_heading = "/orientation/heading-deg";
- var l_pitch = "/orientation/pitch-deg";
- var l_roll = "/orientation/roll-deg";
- var l_rudder = "/controls/flight/rudder";
- var l_aileron = "/controls/flight/aileron";
- var l_elevator = "/controls/flight/elevator";
- # Replicate remote state.
- var r_airspeed = "velocities/true-airspeed-kt";
- var l_airspeed = "/velocities/airspeed-kt";
- var vertspeed = "velocities/vertical-speed-fps";
- # Default external views to slave to the MP pilot.
- var views = {};
- views["Helicopter View"] = 2;
- views["Chase View"] = 3;
- views["Tower View"] = 0;
- views["Fly-By View"] = 1;
- views["Chase View Without Yaw"] = 1;
- ######################################################################
- # Connect to new pilot
- var process_data = 0;
- var connect = func (pilot) {
- print("Trying connect pilot to copilot (copilot-dual-control.nas)");
- # Set external view eye and target paths.
- foreach (var vn; keys(views)) {
- var view_cfg = "/sim/view[" ~ view.indexof(vn) ~ "]/config";
- setprop(view_cfg ~ "/at-model", 0);
- if (views[vn] > 0) {
- setprop(view_cfg ~ "/eye-lat-deg-path",
- pilot.getNode(DCT.lat_mpp).getPath());
- setprop(view_cfg ~ "/eye-lon-deg-path",
- pilot.getNode(DCT.lon_mpp).getPath());
- setprop(view_cfg ~ "/eye-alt-ft-path",
- pilot.getNode(DCT.alt_mpp).getPath());
- }
- if (views[vn] > 1) {
- setprop(view_cfg ~ "/eye-heading-deg-path",
- pilot.getNode(DCT.heading_mpp).getPath());
- }
- if (views[vn] > 2) {
- setprop(view_cfg ~ "/eye-pitch-deg-path",
- pilot.getNode(DCT.pitch_mpp).getPath());
- setprop(view_cfg ~ "/eye-roll-deg-path",
- pilot.getNode(DCT.roll_mpp).getPath());
- }
- setprop(view_cfg ~ "/target-lat-deg-path",
- pilot.getNode(DCT.lat_mpp).getPath());
- setprop(view_cfg ~ "/target-lon-deg-path",
- pilot.getNode(DCT.lon_mpp).getPath());
- setprop(view_cfg ~ "/target-alt-ft-path",
- pilot.getNode(DCT.alt_mpp).getPath());
- setprop(view_cfg ~ "/target-heading-deg-path",
- pilot.getNode(DCT.heading_mpp).getPath());
- setprop(view_cfg ~ "/target-pitch-deg-path",
- pilot.getNode(DCT.pitch_mpp).getPath());
- setprop(view_cfg ~ "/target-roll-deg-path",
- pilot.getNode(DCT.roll_mpp).getPath());
- }
- # Tweak MP/AI filters
- pilot.getNode("controls/allow-extrapolation").setBoolValue(1);
- pilot.getNode("controls/lag-adjust-system-speed").setValue(5.0);
- # Set up property aliases
- # Set up property mappings.
- process_data =
- [
- # Map /postition/*
- DCT.Translator.new
- (pilot.getNode(DCT.lat_mpp),
- props.globals.getNode(l_lat)),
- DCT.Translator.new
- (pilot.getNode(DCT.lon_mpp),
- props.globals.getNode(l_lon)),
- DCT.Translator.new
- (pilot.getNode(DCT.alt_mpp),
- props.globals.getNode(l_alt)),
- # Map /orientation/*
- DCT.Translator.new
- (pilot.getNode(DCT.heading_mpp),
- props.globals.getNode(l_heading)),
- DCT.Translator.new
- (pilot.getNode(DCT.pitch_mpp),
- props.globals.getNode(l_pitch)),
- DCT.Translator.new
- (pilot.getNode(DCT.roll_mpp),
- props.globals.getNode(l_roll)),
- # Map /velocities/*
- DCT.Translator.new
- (pilot.getNode(r_airspeed),
- props.globals.getNode(l_airspeed)),
- DCT.Translator.new
- (pilot.getNode(vertspeed),
- props.globals.getNode(vertspeed)),
- ] ~ ADC.copilot_connect_pilot(pilot);
- print("Dual control ... connected to pilot.");
- setprop("/sim/messages/copilot", "Welcome aboard. I'm your pilot !");
- }
- var disconnect = func {
- # Reset external view eye and target paths.
- foreach (var vn; keys(views)) {
- var view_cfg = "/sim/view[" ~ view.indexof(vn) ~ "]/config";
-
- if (views[vn] > 0) {
- setprop(view_cfg ~ "/eye-lat-deg-path",
- "/position/latitude-deg");
- setprop(view_cfg ~ "/eye-lon-deg-path",
- "/position/longitude-deg");
- setprop(view_cfg ~ "/eye-alt-ft-path",
- "/position/altitude-ft");
- }
- if (views[vn] > 1) {
- setprop(view_cfg ~ "/eye-heading-deg-path",
- "/orientation/heading-deg");
- }
- if (views[vn] > 2) {
- setprop(view_cfg ~ "/eye-pitch-deg-path",
- "/orientation/pitch-deg");
- setprop(view_cfg ~ "/eye-roll-deg-path",
- "/orientation/roll-deg");
- }
- setprop(view_cfg ~ "/target-lat-deg-path",
- "/sim/viewer/target/latitude-deg");
- setprop(view_cfg ~ "/target-lon-deg-path",
- "/sim/viewer/target/longitude-deg");
- setprop(view_cfg ~ "/target-alt-ft-path",
- "/sim/viewer/target/altitude-ft");
- setprop(view_cfg ~ "/target-heading-deg-path",
- "/sim/viewer/target/heading-deg");
- setprop(view_cfg ~ "/target-pitch-deg-path",
- "/sim/viewer/target/pitch-deg");
- setprop(view_cfg ~ "/target-roll-deg-path",
- "/sim/viewer/target/roll-deg");
- }
- }
- ######################################################################
- # Main loop singleton class.
- var main = {
- init : func {
- me.loopid = 0;
- me.active = 0;
- setlistener("/ai/models/model-added", func {
- settimer(func { me.activate(); }, 2);
- });
- print("Copilot dual control ... initialized");
- settimer(func { me.activate(); }, 5);
- },
- reset : func {
- me.active = 0;
- me.loopid += 1;
- me._loop_(me.loopid);
- },
- activate : func {
- if (!me.active) {
- me.reset();
- }
- },
- update : func {
- var mpplayers =
- props.globals.getNode("/ai/models").getChildren("multiplayer");
- var r_callsign = getprop("/sim/remote/pilot-callsign");
- foreach (var pilot; mpplayers) {
- if ((pilot.getChild("valid").getValue()) and
- (pilot.getChild("callsign") != nil) and
- (pilot.getChild("callsign").getValue() == r_callsign)) {
- if (me.active == 0) {
- # Note: sim/model/path contains the model XML file.
- if ((pilot.getNode("sim/model/path") != nil) and
- (pilot.getNode("sim/model/path").getValue() ==
- ADC.pilot_type)) {
- me.active = 1;
- connect(pilot);
- } else {
- print("Dual control ... pilot rejected - wrong aircraft type.");
- me.loopid += 1;
- return;
- }
- }
- # Mess with the MP filters. Highly experimental.
- if (pilot.getNode("controls/lag-time-offset") != nil) {
- var v = pilot.getNode("controls/lag-time-offset").getValue();
- #pilot.getNode("controls/lag-time-offset").setValue(0.99 * v);
- }
- foreach (var w; process_data) {
- w.update();
- }
- return;
- }
- }
- # The pilot player is not around. Idle loop.
- if (me.active) {
- print("Dual control ... disconnected from pilot.");
- disconnect();
- ADC.copilot_disconnect_pilot();
- }
- me.active = 0;
- me.loopid += 1;
- },
- _loop_ : func(id) {
- id == me.loopid or return;
- me.update();
- settimer(func { me._loop_(id); }, 0);
- }
- };
- ###############################################################################
- # Initialization.
- var last_view = 0;
- setlistener("/sim/signals/fdm-initialized", func {
- main.init();
- });
|