if (!s.empty())
wire_objects.push_back(s);
}
-
+
props = scFileNode->getChildren("catapult");
for (it = props.begin(); it != props.end(); ++it) {
std::string s = (*it)->getStringValue();
// but by just apply discrete changes at its velocity variables.
// Update the velocity information stored in those nodes.
// Transform that one to the horizontal local coordinate system.
- SGQuatd ec2hl = SGQuatd::fromLonLatDeg(pos.lon(), pos.lat());
+ SGQuatd ec2hl = SGQuatd::fromLonLat(pos);
// The orientation of the carrier wrt the horizontal local frame
SGQuatd hl2body = SGQuatd::fromYawPitchRollDeg(hdg, pitch, roll);
// and postrotate the orientation of the AIModel wrt the horizontal
// local frame
SGQuatd ec2body = ec2hl*hl2body;
// The cartesian position of the carrier in the wgs84 world
- SGVec3d cartPos = SGGeod::fromDegFt(pos.lon(), pos.lat(), pos.elev());
+ SGVec3d cartPos = SGVec3d::fromGeod(pos);
// Store for later use by the groundcache
rot_pivot_wrt_earth = cartPos;
// Now here is the finite difference ...
// Transform that one to the horizontal local coordinate system.
- SGQuatd ec2hlNew = SGQuatd::fromLonLatDeg(pos.lon(), pos.lat());
+ SGQuatd ec2hlNew = SGQuatd::fromLonLat(pos);
// compute the new orientation
SGQuatd hl2bodyNew = SGQuatd::fromYawPitchRollDeg(hdg, pitch, roll);
// The rotation difference
UpdateWind(dt);
UpdateElevator(dt, transition_time);
-
+ UpdateJBD(dt, jbd_transition_time);
// For the flols reuse some computations done above ...
// The position of the eyepoint - at least near that ...
_longitude_node = fgGetNode("/position/longitude-deg", true);
_latitude_node = fgGetNode("/position/latitude-deg", true);
_altitude_node = fgGetNode("/position/altitude-ft", true);
- // _elevator_node = fgGetNode("/controls/elevators", true);
+
+ _launchbar_state_node = fgGetNode("/gear/launchbar/state", true);
_surface_wind_from_deg_node =
fgGetNode("/environment/config/boundary/entry[0]/wind-from-heading-deg", true);
turn_to_launch_hdg = false;
returning = false;
- initialpos = pos;
+ mOpBoxPos = pos;
base_course = hdg;
base_speed = speed;
- step = 0;
pos_norm = 0;
elevators = false;
transition_time = 150;
time_constant = 0.005;
-
+ jbd_pos_norm = raw_jbd_pos_norm = 0;
+ jbd = false ;
+ jbd_transition_time = 3;
+ jbd_time_constant = 0.1;
return true;
}
props->tie("controls/base-speed-kts",
SGRawValuePointer<double>(&base_speed));
props->tie("controls/start-pos-lat-deg",
- SGRawValuePointer<double>(&initialpos[1]));
+ SGRawValueMethods<SGGeod,double>(pos, &SGGeod::getLatitudeDeg));
props->tie("controls/start-pos-long-deg",
- SGRawValuePointer<double>(&initialpos[0]));
+ SGRawValueMethods<SGGeod,double>(pos, &SGGeod::getLongitudeDeg));
props->tie("velocities/speed-kts",
SGRawValuePointer<double>(&speed));
props->tie("environment/surface-wind-speed-true-kts",
SGRawValuePointer<double>(&transition_time));
props->tie("controls/elevators-time-constant",
SGRawValuePointer<double>(&time_constant));
+ props->tie("controls/jbd",
+ SGRawValuePointer<bool>(&jbd));
+ props->tie("surface-positions/jbd-pos-norm",
+ SGRawValuePointer<double>(&jbd_pos_norm));
+ props->tie("controls/jbd-trans-time-s",
+ SGRawValuePointer<double>(&jbd_transition_time));
+ props->tie("controls/jbd-time-constant",
+ SGRawValuePointer<double>(&jbd_time_constant));
props->setBoolValue("controls/flols/cut-lights", false);
props->setBoolValue("controls/flols/wave-off-lights", false);
props->untie("surface-positions/elevators-pos-norm");
props->untie("controls/elevators-trans-time-secs");
props->untie("controls/elevators-time-constant");
+ props->untie("controls/jbd");
+ props->untie("surface-positions/jbd-pos-norm");
+ props->untie("controls/jbd-trans-time-s");
+ props->untie("controls/jbd-time-constant");
+
}
if ((*it).name == id || id.empty()) {
ParkPosition ppos = *it;
SGVec3d cartPos = getCartPosAt(ppos.offset);
- geodPos = cartPos;
+ geodPos = SGGeod::fromCart(cartPos);
hdng = hdg + ppos.heading_deg;
double shdng = sin(ppos.heading_deg * SGD_DEGREES_TO_RADIANS);
double chdng = cos(ppos.heading_deg * SGD_DEGREES_TO_RADIANS);
// care for transforms ...
short v[2];
l->getLine(0, v, v+1 );
- sgVec3 ends[2];
+ SGVec3f ends[2];
for (int k=0; k<2; ++k)
- sgCopyVec3( ends[k], l->getVertex( v[k] ) );
+ sgCopyVec3( ends[k].sg(), l->getVertex( v[k] ) );
// When the 1 end is behind the 0 end, swap the coordinates.
if (ends[0][0] < ends[1][0]) {
- sgCopyVec3( l->getVertex( v[0] ), ends[1] );
- sgCopyVec3( l->getVertex( v[1] ), ends[0] );
+ sgCopyVec3( l->getVertex( v[0] ), ends[1].sg() );
+ sgCopyVec3( l->getVertex( v[1] ), ends[0].sg() );
}
found = true;
}
void FGAICarrier::ReturnToBox(){
double course, distance, az2;
- //get the carrier position
- carrierpos = pos;
-
- //cout << "lat: " << carrierpos[1] << " lon: " << carrierpos[0] << endl;
-
//calculate the bearing and range of the initial position from the carrier
- geo_inverse_wgs_84(carrierpos[2],
- carrierpos[1],
- carrierpos[0],
- initialpos[1],
- initialpos[0],
- &course, &az2, &distance);
+ geo_inverse_wgs_84(pos, mOpBoxPos, &course, &az2, &distance);
distance *= SG_METER_TO_NM;
return false;
}
- if (initialpos[1] >= 0) { //northern hemisphere
- if (pos[1] >= initialpos[1] + max_lat)
+ if (mOpBoxPos.getLatitudeDeg() >= 0) { //northern hemisphere
+ if (pos.getLatitudeDeg() >= mOpBoxPos.getLatitudeDeg() + max_lat)
return true;
- if (pos[1] <= initialpos[1] - min_lat)
+ if (pos.getLatitudeDeg() <= mOpBoxPos.getLatitudeDeg() - min_lat)
return true;
} else { //southern hemisphere
- if (pos[1] <= initialpos[1] - max_lat)
+ if (pos.getLatitudeDeg() <= mOpBoxPos.getLatitudeDeg() - max_lat)
return true;
- if (pos[1] >= initialpos[1] + min_lat)
+ if (pos.getLatitudeDeg() >= mOpBoxPos.getLatitudeDeg() + min_lat)
return true;
}
- if (initialpos[0] >=0) { //eastern hemisphere
- if (pos[0] >= initialpos[0] + max_long)
+ if (mOpBoxPos.getLongitudeDeg() >=0) { //eastern hemisphere
+ if (pos.getLongitudeDeg() >= mOpBoxPos.getLongitudeDeg() + max_long)
return true;
- if (pos[0] <= initialpos[0] - min_long)
+ if (pos.getLongitudeDeg() <= mOpBoxPos.getLongitudeDeg() - min_long)
return true;
} else { //western hemisphere
- if (pos[0] <= initialpos[0] - max_long)
+ if (pos.getLongitudeDeg() <= mOpBoxPos.getLongitudeDeg() - max_long)
return true;
- if (pos[0] >= initialpos[0] + min_long)
+ if (pos.getLongitudeDeg() >= mOpBoxPos.getLongitudeDeg() + min_long)
return true;
}
void FGAICarrier::UpdateElevator(double dt, double transition_time) {
+ double step = 0;
+
if ((elevators && pos_norm >= 1 ) || (!elevators && pos_norm <= 0 ))
return;
// move the elevators
if ( elevators ) {
- step += dt/transition_time;
+ step = dt/transition_time;
if ( step > 1 )
step = 1;
-
} else {
- step -= dt/transition_time;
- if ( step < 0 )
- step = 0;
+ step = -dt/transition_time;
+ if ( step < -1 )
+ step = -1;
}
// assume a linear relationship
- raw_pos_norm = step;
+ raw_pos_norm += step;
+
+ //low pass filter
+ pos_norm = (raw_pos_norm * time_constant) + (pos_norm * (1 - time_constant));
+
+ //sanitise the output
if (raw_pos_norm >= 1) {
raw_pos_norm = 1;
} else if (raw_pos_norm <= 0) {
raw_pos_norm = 0;
}
+ return;
+
+} // end UpdateElevator
+
+void FGAICarrier::UpdateJBD(double dt, double jbd_transition_time) {
+
+ string launchbar_state = _launchbar_state_node->getStringValue();
+ double step = 0;
+
+ if (launchbar_state == "Engaged"){
+ jbd = true;
+ } else {
+ jbd = false;
+ }
+
+ if (( jbd && jbd_pos_norm >= 1 ) || ( !jbd && jbd_pos_norm <= 0 )){
+ return;
+ }
+
+ // move the jbds
+ if ( jbd ) {
+ step = dt/jbd_transition_time;
+ if ( step > 1 )
+ step = 1;
+ } else {
+ step = -dt/jbd_transition_time;
+ if ( step < -1 )
+ step = -1;
+ }
+
+ // assume a linear relationship
+ raw_jbd_pos_norm += step;
//low pass filter
- pos_norm = (raw_pos_norm * time_constant) + (pos_norm * (1 - time_constant));
+ jbd_pos_norm = (raw_jbd_pos_norm * jbd_time_constant) + (jbd_pos_norm * (1 - jbd_time_constant));
+
+ //sanitise the output
+ if (jbd_pos_norm >= 1) {
+ jbd_pos_norm = 1;
+ } else if (jbd_pos_norm <= 0) {
+ jbd_pos_norm = 0;
+ }
+
return;
-} // end UpdateElevator
+} // end UpdateJBD
int FGAICarrierHardware::unique_id = 1;