-
- // For computation of rotation speeds we just use finite differences her.
- // That is perfectly valid since this thing is not driven by accelerations
- // but by just apply discrete changes at its velocity variables.
- double old_hdg = hdg;
- double old_roll = roll;
- double old_pitch = pitch;
-
- // Update the velocity information stored in those nodes.
- double v_north = 0.51444444*speed*cos(hdg * SGD_DEGREES_TO_RADIANS);
- double v_east = 0.51444444*speed*sin(hdg * SGD_DEGREES_TO_RADIANS);
-
- double sin_lat = sin(pos.lat() * SGD_DEGREES_TO_RADIANS);
- double cos_lat = cos(pos.lat() * SGD_DEGREES_TO_RADIANS);
- double sin_lon = sin(pos.lon() * SGD_DEGREES_TO_RADIANS);
- double cos_lon = cos(pos.lon() * SGD_DEGREES_TO_RADIANS);
- double sin_roll = sin(roll * SGD_DEGREES_TO_RADIANS);
- double cos_roll = cos(roll * SGD_DEGREES_TO_RADIANS);
- double sin_pitch = sin(pitch * SGD_DEGREES_TO_RADIANS);
- double cos_pitch = cos(pitch * SGD_DEGREES_TO_RADIANS);
- double sin_hdg = sin(hdg * SGD_DEGREES_TO_RADIANS);
- double cos_hdg = cos(hdg * SGD_DEGREES_TO_RADIANS);
-
- // Transform this back the the horizontal local frame.
- sgdMat3 trans;
-
- // set up the transform matrix
- trans[0][0] = cos_pitch*cos_hdg;
- trans[0][1] = sin_roll*sin_pitch*cos_hdg - cos_roll*sin_hdg;
- trans[0][2] = cos_roll*sin_pitch*cos_hdg + sin_roll*sin_hdg;
-
- trans[1][0] = cos_pitch*sin_hdg;
- trans[1][1] = sin_roll*sin_pitch*sin_hdg + cos_roll*cos_hdg;
- trans[1][2] = cos_roll*sin_pitch*sin_hdg - sin_roll*cos_hdg;
-
- trans[2][0] = -sin_pitch;
- trans[2][1] = sin_roll*cos_pitch;
- trans[2][2] = cos_roll*cos_pitch;
-
- sgdSetVec3( vel_wrt_earth,
- - cos_lon*sin_lat*v_north - sin_lon*v_east,
- - sin_lon*sin_lat*v_north + cos_lon*v_east,
- cos_lat*v_north );
- sgGeodToCart(pos.lat() * SGD_DEGREES_TO_RADIANS,
- pos.lon() * SGD_DEGREES_TO_RADIANS,
- pos.elev(), rot_pivot_wrt_earth);
-
- // Now update the position and heading. This will compute new hdg and
- // roll values required for the rotation speed computation.
- FGAIShip::update(dt);
-
-
- //automatic turn into wind with a target wind of 25 kts otd
- if(turn_to_launch_hdg){
- TurnToLaunch();
- } else if(OutsideBox() || returning) {// check that the carrier is inside the operating box
- ReturnToBox();
- } else { //if(!returning
- TurnToBase();
- } //end if
-
- // Only change these values if we are able to compute them safely
- if (dt < DBL_MIN)
- sgdSetVec3( rot_wrt_earth, 0.0, 0.0, 0.0);
- else {
- // Compute the change of the euler angles.
- double hdg_dot = SGD_DEGREES_TO_RADIANS * (hdg-old_hdg)/dt;
- // Allways assume that the movement was done by the shorter way.
- if (hdg_dot < - SGD_DEGREES_TO_RADIANS * 180)
- hdg_dot += SGD_DEGREES_TO_RADIANS * 360;
- if (hdg_dot > SGD_DEGREES_TO_RADIANS * 180)
- hdg_dot -= SGD_DEGREES_TO_RADIANS * 360;
- double pitch_dot = SGD_DEGREES_TO_RADIANS * (pitch-old_pitch)/dt;
- // Allways assume that the movement was done by the shorter way.
- if (pitch_dot < - SGD_DEGREES_TO_RADIANS * 180)
- pitch_dot += SGD_DEGREES_TO_RADIANS * 360;
- if (pitch_dot > SGD_DEGREES_TO_RADIANS * 180)
- pitch_dot -= SGD_DEGREES_TO_RADIANS * 360;
- double roll_dot = SGD_DEGREES_TO_RADIANS * (roll-old_roll)/dt;
- // Allways assume that the movement was done by the shorter way.
- if (roll_dot < - SGD_DEGREES_TO_RADIANS * 180)
- roll_dot += SGD_DEGREES_TO_RADIANS * 360;
- if (roll_dot > SGD_DEGREES_TO_RADIANS * 180)
- roll_dot -= SGD_DEGREES_TO_RADIANS * 360;
- /*cout << "euler derivatives = "
- << roll_dot << " " << pitch_dot << " " << hdg_dot << endl;*/
-
- // Now Compute the rotation vector in the carriers coordinate frame
- // originating from the euler angle changes.
- sgdVec3 body;
- body[0] = roll_dot - hdg_dot*sin_pitch;
- body[1] = pitch_dot*cos_roll + hdg_dot*sin_roll*cos_pitch;
- body[2] = -pitch_dot*sin_roll + hdg_dot*cos_roll*cos_pitch;
-
- // Transform that back to the horizontal local frame.
- sgdVec3 hl;
- hl[0] = body[0]*trans[0][0] + body[1]*trans[0][1] + body[2]*trans[0][2];
- hl[1] = body[0]*trans[1][0] + body[1]*trans[1][1] + body[2]*trans[1][2];
- hl[2] = body[0]*trans[2][0] + body[1]*trans[2][1] + body[2]*trans[2][2];
-
- // Now we need to project out rotation components ending in speeds in y
- // direction in the hoirizontal local frame.
- hl[1] = 0;
-
- // Transform that to the earth centered frame.
- sgdSetVec3(rot_wrt_earth,
- - cos_lon*sin_lat*hl[0] - sin_lon*hl[1] - cos_lat*cos_lon*hl[2],
- - sin_lon*sin_lat*hl[0] + cos_lon*hl[1] - cos_lat*sin_lon*hl[2],
- cos_lat*hl[0] - sin_lat*hl[2]);
- }
-
- UpdateWind(dt);
- UpdateTACAN(dt);
- UpdateFlols(trans);
-} //end update
-
-bool FGAICarrier::init() {
- if (!FGAIShip::init())
- return false;
-
- // process the 3d model here
- // mark some objects solid, mark the wires ...
-
- // The model should be used for altitude computations.
- // To avoid that every detail in a carrier 3D model will end into
- // the aircraft local cache, only set the HOT traversal bit on
- // selected objects.
- ssgEntity *sel = aip.getSceneGraph();
- // Clear the HOT traversal flag
- mark_nohot(sel);
- // Selectively set that flag again for wires/cats/solid objects.
- // Attach a pointer to this carrier class to those objects.
- mark_wires(sel, wire_objects);
- mark_cat(sel, catapult_objects);
- mark_solid(sel, solid_objects);
-
- _longitude_node = fgGetNode("/position/longitude-deg", true);
- _latitude_node = fgGetNode("/position/latitude-deg", true);
- _altitude_node = fgGetNode("/position/altitude-ft", true);
- _dme_freq_node = fgGetNode("/instrumentation/dme/frequencies/selected-mhz", true);
- _surface_wind_from_deg_node =
- fgGetNode("/environment/config/boundary/entry[0]/wind-from-heading-deg", true);
- _surface_wind_speed_node =
- fgGetNode("/environment/config/boundary/entry[0]/wind-speed-kt", true);
-
-
- turn_to_launch_hdg = false;
- returning = false;
-
- initialpos = pos;
- base_course = hdg;
- base_speed = speed;
-
- return true;
-}
-
-void FGAICarrier::bind() {
- FGAIShip::bind();
-
- props->untie("velocities/true-airspeed-kt");
-
- props->tie("controls/flols/source-lights",
- SGRawValuePointer<int>(&source));
- props->tie("controls/flols/distance-m",
- SGRawValuePointer<double>(&dist));
- props->tie("controls/flols/angle-degs",
- SGRawValuePointer<double>(&angle));
- props->tie("controls/turn-to-launch-hdg",
- SGRawValuePointer<bool>(&turn_to_launch_hdg));
- props->tie("controls/in-to-wind",
- SGRawValuePointer<bool>(&turn_to_launch_hdg));
- props->tie("controls/base-course-deg",
- SGRawValuePointer<double>(&base_course));
- props->tie("controls/base-speed-kts",
- SGRawValuePointer<double>(&base_speed));
- props->tie("controls/start-pos-lat-deg",
- SGRawValuePointer<double>(&initialpos[1]));
- props->tie("controls/start-pos-long-deg",
- SGRawValuePointer<double>(&initialpos[0]));
- props->tie("velocities/speed-kts",
- SGRawValuePointer<double>(&speed));
- props->tie("environment/surface-wind-speed-true-kts",
- SGRawValuePointer<double>(&wind_speed_kts));
- props->tie("environment/surface-wind-from-true-degs",
- SGRawValuePointer<double>(&wind_from_deg));
- props->tie("environment/rel-wind-from-degs",
- SGRawValuePointer<double>(&rel_wind_from_deg));
- props->tie("environment/rel-wind-from-carrier-hdg-degs",
- SGRawValuePointer<double>(&rel_wind));
- props->tie("environment/rel-wind-speed-kts",
- SGRawValuePointer<double>(&rel_wind_speed_kts));
- props->tie("controls/flols/wave-off-lights",
- SGRawValuePointer<bool>(&wave_off_lights));
-
- props->setBoolValue("controls/flols/cut-lights", false);
- props->setBoolValue("controls/flols/wave-off-lights", false);
- props->setBoolValue("controls/flols/cond-datum-lights", true);
- props->setBoolValue("controls/crew", false);
-
- props->setStringValue("navaids/tacan/channel-ID", TACAN_channel_id.c_str());
- props->setStringValue("sign", sign.c_str());
-}
-
-void FGAICarrier::unbind() {
- FGAIShip::unbind();
-
- props->untie("velocities/true-airspeed-kt");
-
- props->untie("controls/flols/source-lights");
- props->untie("controls/flols/distance-m");
- props->untie("controls/flols/angle-degs");
- props->untie("controls/turn-to-launch-hdg");
- props->untie("velocities/speed-kts");
- props->untie("environment/wind-speed-true-kts");
- props->untie("environment/wind-from-true-degs");
- props->untie("environment/rel-wind-from-degs");
- props->untie("environment/rel-wind-speed-kts");
- props->untie("controls/flols/wave-off-lights");
-
-}