+double FGAIBase::UpdateRadar(FGAIManager* manager)
+{
+ double radar_range_ft2 = fgGetDouble("/instrumentation/radar/range");
+ radar_range_ft2 *= SG_NM_TO_METER * SG_METER_TO_FEET * 1.1; // + 10%
+ radar_range_ft2 *= radar_range_ft2;
+
+ double user_latitude = manager->get_user_latitude();
+ double user_longitude = manager->get_user_longitude();
+ double lat_range = fabs(pos.lat() - user_latitude) * ft_per_deg_lat;
+ double lon_range = fabs(pos.lon() - user_longitude) * ft_per_deg_lon;
+ double range_ft2 = lat_range*lat_range + lon_range*lon_range;
+
+ //
+ // Test whether the target is within radar range.
+ //
+ in_range = (range_ft2 && (range_ft2 <= radar_range_ft2));
+ if ( in_range )
+ {
+ props->setBoolValue("radar/in-range", true);
+
+ // copy values from the AIManager
+ double user_altitude = manager->get_user_altitude();
+ double user_heading = manager->get_user_heading();
+ double user_pitch = manager->get_user_pitch();
+ double user_yaw = manager->get_user_yaw();
+ double user_speed = manager->get_user_speed();
+
+ // calculate range to target in feet and nautical miles
+ double range_ft = sqrt( range_ft2 );
+ range = range_ft / 6076.11549;
+
+ // calculate bearing to target
+ if (pos.lat() >= user_latitude) {
+ bearing = atan2(lat_range, lon_range) * SG_RADIANS_TO_DEGREES;
+ if (pos.lon() >= user_longitude) {
+ bearing = 90.0 - bearing;
+ } else {
+ bearing = 270.0 + bearing;
+ }
+ } else {
+ bearing = atan2(lon_range, lat_range) * SG_RADIANS_TO_DEGREES;
+ if (pos.lon() >= user_longitude) {
+ bearing = 180.0 - bearing;
+ } else {
+ bearing = 180.0 + bearing;
+ }
+ }
+
+ // calculate look left/right to target, without yaw correction
+ horiz_offset = bearing - user_heading;
+ if (horiz_offset > 180.0) horiz_offset -= 360.0;
+ if (horiz_offset < -180.0) horiz_offset += 360.0;
+
+ // calculate elevation to target
+ elevation = atan2( altitude * SG_METER_TO_FEET - user_altitude, range_ft )
+ * SG_RADIANS_TO_DEGREES;
+
+ // calculate look up/down to target
+ vert_offset = elevation + user_pitch;
+
+ /* this calculation needs to be fixed, but it isn't important anyway
+ // calculate range rate
+ double recip_bearing = bearing + 180.0;
+ if (recip_bearing > 360.0) recip_bearing -= 360.0;
+ double my_horiz_offset = recip_bearing - hdg;
+ if (my_horiz_offset > 180.0) my_horiz_offset -= 360.0;
+ if (my_horiz_offset < -180.0) my_horiz_offset += 360.0;
+ rdot = (-user_speed * cos( horiz_offset * SG_DEGREES_TO_RADIANS ))
+ +(-speed * 1.686 * cos( my_horiz_offset * SG_DEGREES_TO_RADIANS ));
+*/
+
+ // now correct look left/right for yaw
+ horiz_offset += user_yaw;
+
+ // calculate values for radar display
+ y_shift = range * cos( horiz_offset * SG_DEGREES_TO_RADIANS);
+ x_shift = range * sin( horiz_offset * SG_DEGREES_TO_RADIANS);
+ rotation = hdg - user_heading;
+ if (rotation < 0.0) rotation += 360.0;
+
+ }
+
+ return range_ft2;
+}
+
+SGVec3d
+FGAIBase::getCartPosAt(const SGVec3d& _off) const
+{
+ // Transform that one to the horizontal local coordinate system.
+ SGQuatd hlTrans = SGQuatd::fromLonLatDeg(pos.lon(), pos.lat());
+ // and postrotate the orientation of the AIModel wrt the horizontal
+ // local frame
+ hlTrans *= SGQuatd::fromYawPitchRollDeg(hdg, pitch, roll);
+
+ // The offset converted to the usual body fixed coordinate system
+ // rotated to the earth fiexed coordinates axis
+ SGVec3d off = hlTrans.backTransform(_off);
+
+ // Add the position offset of the AIModel to gain the earth centered position
+ SGVec3d cartPos = SGGeod::fromDegFt(pos.lon(), pos.lat(), pos.elev());
+
+ return cartPos + off;
+}
+
+/*
+ * getters and Setters
+ */
+void FGAIBase::_setLongitude( double longitude ) {
+ pos.setlon(longitude);
+}
+void FGAIBase::_setLatitude ( double latitude ) {
+ pos.setlat(latitude);
+}
+
+double FGAIBase::_getLongitude() const {
+ return pos.lon();
+}
+double FGAIBase::_getLatitude () const {
+ return pos.lat();
+}
+double FGAIBase::_getRdot() const {
+ return rdot;
+}
+double FGAIBase::_getVS_fps() const {
+ return vs*60.0;
+}
+void FGAIBase::_setVS_fps( double _vs ) {
+ vs = _vs/60.0;