2004-09-22 08:47:05 +00:00
|
|
|
// FGAIBase.hxx - abstract base class for AI objects
|
2003-11-28 15:48:05 +00:00
|
|
|
// Written by David Culp, started Nov 2003, based on
|
|
|
|
// David Luff's FGAIEntity class.
|
2010-08-29 00:08:50 +01:00
|
|
|
// - davidculp2@comcast.net
|
2003-11-28 15:48:05 +00:00
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
2006-02-21 01:16:04 +00:00
|
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2003-11-28 15:48:05 +00:00
|
|
|
|
|
|
|
#ifndef _FG_AIBASE_HXX
|
|
|
|
#define _FG_AIBASE_HXX
|
|
|
|
|
2004-01-22 21:13:47 +00:00
|
|
|
#include <string>
|
2014-02-23 11:51:21 -08:00
|
|
|
#include <osg/ref_ptr>
|
2013-03-28 16:49:52 +00:00
|
|
|
|
2003-12-21 20:12:55 +00:00
|
|
|
#include <simgear/constants.h>
|
2003-11-28 15:48:05 +00:00
|
|
|
#include <simgear/scene/model/placement.hxx>
|
2005-02-10 09:01:51 +00:00
|
|
|
#include <simgear/misc/sg_path.hxx>
|
2006-10-30 16:31:45 +00:00
|
|
|
#include <simgear/structure/SGSharedPtr.hxx>
|
2006-02-11 13:16:56 +00:00
|
|
|
#include <simgear/structure/SGReferenced.hxx>
|
2012-03-04 15:30:08 +01:00
|
|
|
#include <simgear/props/tiedpropertylist.hxx>
|
2010-09-27 23:50:44 +01:00
|
|
|
#include <simgear/sg_inlines.h>
|
|
|
|
|
|
|
|
#include <simgear/math/sg_geodesy.hxx>
|
|
|
|
|
2014-02-23 11:51:21 -08:00
|
|
|
namespace osg { class PagedLOD; }
|
|
|
|
|
2012-08-27 20:51:16 +02:00
|
|
|
namespace simgear {
|
|
|
|
class BVHMaterial;
|
|
|
|
}
|
David Culp:
Here's a new batch of AI code which includes a working radar instrument.
I put the radar calculations into the existing AIAircraft class. It was
easier that way, and it can always be migrated out later if we have to.
Every tenth sim cycle the AIManager makes a copy of the current user state
information. When the AIAircraft updates it uses this information to
calculate the radar numbers. It calculates:
1) bearing from user to target
2) range to target in nautical miles
3) "horizontal offset" to target. This is the angle from the nose to the
target, in degrees, from -180 to 180. This will be useful later for a HUD.
4) elevation, in degrees (vertical angle from user's position to target
position)
5) vertical offset, in degrees (this is elevation corrected for user's pitch)
6) rdot (range rate in knots, note: not working yet, so I commented it out)
and three items used by the radar instrument to place the "blip"
7) y_shift, in nautical miles
8) x_shift, in nautical miles
9) rotation, in degrees
The radar instrument uses the above three items, and applies a scale factor to
the x-shift and y-shift in order to match the instrument's scale. Changing
the display scale can be done entirely in the XML code for the instrument.
Right now it's set up only to display a 40 mile scale.
The radar is an AWACS view, which is not very realistic, but it is useful and
demonstrates the technology. With just a little more work I can get a HUD
marker. All I need to do there is make a bank angle adjustment to the
current values.
2004-02-27 10:20:17 +00:00
|
|
|
class FGAIManager;
|
2004-09-07 09:53:23 +00:00
|
|
|
class FGAIFlightPlan;
|
2011-11-20 15:05:37 +01:00
|
|
|
class FGFX;
|
2012-03-04 15:30:08 +01:00
|
|
|
class FGAIModelData; // defined below
|
2011-11-25 13:39:10 +01:00
|
|
|
|
2004-09-07 09:53:23 +00:00
|
|
|
|
2010-06-16 06:57:47 +02:00
|
|
|
class FGAIBase : public SGReferenced {
|
2003-11-28 15:48:05 +00:00
|
|
|
|
|
|
|
public:
|
2006-02-11 13:16:56 +00:00
|
|
|
enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic,
|
2010-08-14 13:39:30 +01:00
|
|
|
otRocket, otStorm, otThermal, otStatic, otWingman, otGroundVehicle,
|
|
|
|
otEscort, otMultiplayer,
|
2012-03-04 15:30:08 +01:00
|
|
|
MAX_OBJECTS }; // Needs to be last!!!
|
2003-11-28 15:48:05 +00:00
|
|
|
|
2011-06-25 20:44:44 +02:00
|
|
|
FGAIBase(object_type ot, bool enableHot);
|
2003-11-28 15:48:05 +00:00
|
|
|
virtual ~FGAIBase();
|
2003-12-21 20:12:55 +00:00
|
|
|
|
2006-02-11 13:16:56 +00:00
|
|
|
virtual void readFromScenario(SGPropertyNode* scFileNode);
|
David Culp:
I added some things to the AI stuff to improve the AIThermal processing.
Before, all the thermals were processed in order, and the last one overwrote
the prior one. Now, only the data from the nearest thermal is kept. This
way a tile can be populated with many thermals, and (as long as they have the
same diameter) the one nearest the airplane correctly takes effect. This
will make us ready for the next step, "auto-thermaling", where FlightGear's
tile manager can cover a tile with thermals, and set the thermal strength
based on land-use type.
I moved the enumerated object_type to the base class. When an AI object is
created it now sets the _otype variable in the base class. This lets the AI
manager find out what kind of AI object it is dealing with, using the base
pointer. I also added a function isa() to the base class, so the manager can
process objects differently based on their type.
The AI manager now sends AIThermal processing to a different function, where
only the data from the nearest thermal is kept. After the manager processes
all the AI objects, then the results from the nearest thermal are applied to
wind-from-down.
2004-03-07 12:08:46 +00:00
|
|
|
|
2007-01-13 09:04:07 +00:00
|
|
|
virtual bool init(bool search_in_AI_path=false);
|
2014-02-23 11:51:21 -08:00
|
|
|
virtual void initModel();
|
2006-02-11 13:16:56 +00:00
|
|
|
virtual void update(double dt);
|
2003-12-21 20:12:55 +00:00
|
|
|
virtual void bind();
|
|
|
|
virtual void unbind();
|
2007-02-26 11:47:04 +00:00
|
|
|
virtual void reinit() {}
|
2003-11-28 15:48:05 +00:00
|
|
|
|
2011-10-03 12:01:58 +02:00
|
|
|
void updateLOD();
|
2014-09-21 22:08:57 +02:00
|
|
|
void updateInterior();
|
2006-03-04 12:49:30 +00:00
|
|
|
void setManager(FGAIManager* mgr, SGPropertyNode* p);
|
2003-11-28 15:48:05 +00:00
|
|
|
void setPath( const char* model );
|
2013-03-28 16:49:52 +00:00
|
|
|
void setSMPath( const std::string& p );
|
|
|
|
void setCallSign(const std::string& );
|
2003-11-28 15:48:05 +00:00
|
|
|
void setSpeed( double speed_KTAS );
|
|
|
|
void setAltitude( double altitude_ft );
|
2010-09-10 23:51:25 +01:00
|
|
|
void setAltitudeAGL( double altitude_agl_ft );
|
2003-11-28 15:48:05 +00:00
|
|
|
void setHeading( double heading );
|
2003-12-21 22:16:57 +00:00
|
|
|
void setLatitude( double latitude );
|
|
|
|
void setLongitude( double longitude );
|
2004-02-23 20:55:07 +00:00
|
|
|
void setBank( double bank );
|
2006-02-09 12:29:05 +00:00
|
|
|
void setPitch( double newpitch );
|
2004-11-16 09:33:21 +00:00
|
|
|
void setRadius ( double radius );
|
2004-11-30 12:34:11 +00:00
|
|
|
void setXoffset( double x_offset );
|
|
|
|
void setYoffset( double y_offset );
|
|
|
|
void setZoffset( double z_offset );
|
2008-02-15 11:06:27 +00:00
|
|
|
void setPitchoffset( double x_offset );
|
|
|
|
void setRolloffset( double y_offset );
|
|
|
|
void setYawoffset( double z_offset );
|
2007-03-30 22:51:52 +00:00
|
|
|
void setServiceable ( bool serviceable );
|
|
|
|
void setDie( bool die );
|
2007-06-07 16:30:26 +00:00
|
|
|
void setCollisionData( bool i, double lat, double lon, double elev );
|
|
|
|
void setImpactData( bool d );
|
|
|
|
void setImpactLat( double lat );
|
|
|
|
void setImpactLon( double lon );
|
|
|
|
void setImpactElev( double e );
|
2013-03-28 16:49:52 +00:00
|
|
|
void setParentName(const std::string& p);
|
|
|
|
void setName(const std::string& n);
|
2010-09-27 23:50:44 +01:00
|
|
|
void setMaxSpeed(double kts);
|
|
|
|
|
|
|
|
void calcRangeBearing(double lat, double lon, double lat2, double lon2,
|
|
|
|
double &range, double &bearing) const;
|
|
|
|
double calcRelBearingDeg(double bearing, double heading);
|
|
|
|
double calcTrueBearingDeg(double bearing, double heading);
|
|
|
|
double calcRecipBearingDeg(double bearing);
|
|
|
|
|
2010-09-09 21:38:49 +01:00
|
|
|
bool setParentNode();
|
2004-11-30 12:34:11 +00:00
|
|
|
|
2005-10-15 14:55:51 +00:00
|
|
|
int getID() const;
|
2007-06-07 16:30:26 +00:00
|
|
|
int _getSubID() const;
|
2003-12-21 20:12:55 +00:00
|
|
|
|
|
|
|
bool getDie();
|
2017-09-21 18:37:14 +01:00
|
|
|
bool isValid() const;
|
|
|
|
|
|
|
|
void setFlightPlan(std::unique_ptr<FGAIFlightPlan> f);
|
2017-09-08 22:31:22 +01:00
|
|
|
|
|
|
|
SGGeod getGeodPos() const;
|
2017-09-24 18:13:15 +02:00
|
|
|
void setGeodPos(const SGGeod& pos);
|
|
|
|
|
2006-02-19 17:28:31 +00:00
|
|
|
SGVec3d getCartPosAt(const SGVec3d& off) const;
|
2007-01-13 09:04:07 +00:00
|
|
|
SGVec3d getCartPos() const;
|
2009-08-10 05:21:44 +00:00
|
|
|
|
|
|
|
bool getGroundElevationM(const SGGeod& pos, double& elev,
|
2012-08-27 20:51:16 +02:00
|
|
|
const simgear::BVHMaterial** material) const;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2010-09-10 23:51:25 +01:00
|
|
|
|
2007-01-13 09:04:07 +00:00
|
|
|
double _getCartPosX() const;
|
|
|
|
double _getCartPosY() const;
|
|
|
|
double _getCartPosZ() const;
|
2013-03-28 16:49:52 +00:00
|
|
|
|
2017-09-08 22:31:22 +01:00
|
|
|
osg::PagedLOD* getSceneBranch() const;
|
2013-03-28 16:49:52 +00:00
|
|
|
protected:
|
|
|
|
double _elevation_m;
|
|
|
|
|
2014-09-21 22:08:57 +02:00
|
|
|
double _maxRangeInterior;
|
Mathias Frhlich:
I have introduced the posibility to start directly on the carrier.
With that patch you will have a --carrrier=id argument where id can either be
the pennant number configured in the nimitz scenario or the carriers name
also configured in the carriers scenario.
Additionaly you can use --parkpos=id to select different positions on the
carrier. They are also configured in the scenario file.
That includes the switch of the whole FGInterface class to make use of the
groundcache.
That means that an aircraft no longer uses the current elevation value from
the scenery class. It rather has its own local cache of the aircrafts
environment which is setup in the common_init method of FGInterface and
updated either manually by calling
FGInterface::get_groundlevel_m(lat, lon, alt_m);
or implicitly by calling the above method in the
FGInterface::_updateGeo*Position(lat, lon, alt);
methods.
A call get_groundlevel_m rebuilds the groundcache if the request is outside
the range of the cache.
Note that for the real usage of the groundcache including the correct
information about the movement of objects and the velocity information, you
still need to set up the groundcache in the usual way like YASim and JSBSim
currently does.
If you use the native interface, you will get only static objects correctly.
But for FDM's only using one single ground level for a whole step this is IMO
sufficient.
The AIManager gets a way to return the location of a object which is placed
wrt an AI Object. At the moment it only honours AICarriers for that.
That method is a static one, which loads the scenario file for that reason and
throws it away afterwards. This looked like the aprioriate way, because the
AIManager is initialized much later in flightgears bootstrap, and I did not
find an easy way to reorder that for my needs. Since this additional load is
very small and does only happen if such a relative location is required, I
think that this is ok.
Note that moving on the carrier will only work correctly for JSBSim and YASim,
but you should now be able to start and move on every not itself moving
object with any FDM.
2005-07-03 09:39:14 +00:00
|
|
|
|
2008-02-15 11:06:27 +00:00
|
|
|
double _x_offset;
|
|
|
|
double _y_offset;
|
|
|
|
double _z_offset;
|
2013-03-28 16:49:52 +00:00
|
|
|
|
2008-02-15 11:06:27 +00:00
|
|
|
double _pitch_offset;
|
|
|
|
double _roll_offset;
|
|
|
|
double _yaw_offset;
|
2013-03-28 16:49:52 +00:00
|
|
|
|
2010-09-27 23:50:44 +01:00
|
|
|
double _max_speed;
|
2013-03-28 16:49:52 +00:00
|
|
|
|
|
|
|
std::string _path;
|
|
|
|
std::string _callsign;
|
|
|
|
std::string _submodel;
|
2011-10-17 17:41:59 +01:00
|
|
|
std::string _name;
|
2013-03-28 16:49:52 +00:00
|
|
|
std::string _parent;
|
|
|
|
|
2012-03-04 15:30:08 +01:00
|
|
|
/**
|
|
|
|
* Tied-properties helper, record nodes which are tied for easy un-tie-ing
|
|
|
|
*/
|
|
|
|
template <typename T>
|
|
|
|
void tie(const char* aRelPath, const SGRawValue<T>& aRawValue)
|
|
|
|
{
|
|
|
|
_tiedProperties.Tie(props->getNode(aRelPath, true), aRawValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
simgear::TiedPropertyList _tiedProperties;
|
2010-09-08 17:38:35 +01:00
|
|
|
SGPropertyNode_ptr _selected_ac;
|
2005-06-30 18:34:20 +00:00
|
|
|
SGPropertyNode_ptr props;
|
2007-06-07 16:30:26 +00:00
|
|
|
SGPropertyNode_ptr trigger_node;
|
2006-11-26 12:02:06 +00:00
|
|
|
SGPropertyNode_ptr model_removed; // where to report model removal
|
David Culp:
Here's a new batch of AI code which includes a working radar instrument.
I put the radar calculations into the existing AIAircraft class. It was
easier that way, and it can always be migrated out later if we have to.
Every tenth sim cycle the AIManager makes a copy of the current user state
information. When the AIAircraft updates it uses this information to
calculate the radar numbers. It calculates:
1) bearing from user to target
2) range to target in nautical miles
3) "horizontal offset" to target. This is the angle from the nose to the
target, in degrees, from -180 to 180. This will be useful later for a HUD.
4) elevation, in degrees (vertical angle from user's position to target
position)
5) vertical offset, in degrees (this is elevation corrected for user's pitch)
6) rdot (range rate in knots, note: not working yet, so I commented it out)
and three items used by the radar instrument to place the "blip"
7) y_shift, in nautical miles
8) x_shift, in nautical miles
9) rotation, in degrees
The radar instrument uses the above three items, and applies a scale factor to
the x-shift and y-shift in order to match the instrument's scale. Changing
the display scale can be done entirely in the XML code for the instrument.
Right now it's set up only to display a 40 mile scale.
The radar is an AWACS view, which is not very realistic, but it is useful and
demonstrates the technology. With just a little more work I can get a HUD
marker. All I need to do there is make a bank angle adjustment to the
current values.
2004-02-27 10:20:17 +00:00
|
|
|
FGAIManager* manager;
|
2003-12-21 20:12:55 +00:00
|
|
|
|
David Culp:
Here's a new batch of AI code which includes a working radar instrument.
I put the radar calculations into the existing AIAircraft class. It was
easier that way, and it can always be migrated out later if we have to.
Every tenth sim cycle the AIManager makes a copy of the current user state
information. When the AIAircraft updates it uses this information to
calculate the radar numbers. It calculates:
1) bearing from user to target
2) range to target in nautical miles
3) "horizontal offset" to target. This is the angle from the nose to the
target, in degrees, from -180 to 180. This will be useful later for a HUD.
4) elevation, in degrees (vertical angle from user's position to target
position)
5) vertical offset, in degrees (this is elevation corrected for user's pitch)
6) rdot (range rate in knots, note: not working yet, so I commented it out)
and three items used by the radar instrument to place the "blip"
7) y_shift, in nautical miles
8) x_shift, in nautical miles
9) rotation, in degrees
The radar instrument uses the above three items, and applies a scale factor to
the x-shift and y-shift in order to match the instrument's scale. Changing
the display scale can be done entirely in the XML code for the instrument.
Right now it's set up only to display a 40 mile scale.
The radar is an AWACS view, which is not very realistic, but it is useful and
demonstrates the technology. With just a little more work I can get a HUD
marker. All I need to do there is make a bank angle adjustment to the
current values.
2004-02-27 10:20:17 +00:00
|
|
|
// these describe the model's actual state
|
2012-03-04 15:30:08 +01:00
|
|
|
SGGeod pos; // WGS84 lat & lon in degrees, elev above sea-level in meters
|
|
|
|
double hdg; // True heading in degrees
|
|
|
|
double roll; // degrees, left is negative
|
|
|
|
double pitch; // degrees, nose-down is negative
|
2003-11-28 15:48:05 +00:00
|
|
|
double speed; // knots true airspeed
|
2006-06-24 00:00:27 +00:00
|
|
|
double altitude_ft; // feet above sea level
|
2006-06-09 18:48:57 +00:00
|
|
|
double vs; // vertical speed, feet per minute
|
2007-03-30 22:51:52 +00:00
|
|
|
double speed_north_deg_sec;
|
|
|
|
double speed_east_deg_sec;
|
2004-11-16 09:33:21 +00:00
|
|
|
double turn_radius_ft; // turn radius ft at 15 kts rudder angle 15 degrees
|
2010-09-10 23:51:25 +01:00
|
|
|
double altitude_agl_ft;
|
2003-11-28 15:48:05 +00:00
|
|
|
|
2004-06-11 13:49:07 +00:00
|
|
|
double ft_per_deg_lon;
|
|
|
|
double ft_per_deg_lat;
|
|
|
|
|
David Culp:
Here's a new batch of AI code which includes a working radar instrument.
I put the radar calculations into the existing AIAircraft class. It was
easier that way, and it can always be migrated out later if we have to.
Every tenth sim cycle the AIManager makes a copy of the current user state
information. When the AIAircraft updates it uses this information to
calculate the radar numbers. It calculates:
1) bearing from user to target
2) range to target in nautical miles
3) "horizontal offset" to target. This is the angle from the nose to the
target, in degrees, from -180 to 180. This will be useful later for a HUD.
4) elevation, in degrees (vertical angle from user's position to target
position)
5) vertical offset, in degrees (this is elevation corrected for user's pitch)
6) rdot (range rate in knots, note: not working yet, so I commented it out)
and three items used by the radar instrument to place the "blip"
7) y_shift, in nautical miles
8) x_shift, in nautical miles
9) rotation, in degrees
The radar instrument uses the above three items, and applies a scale factor to
the x-shift and y-shift in order to match the instrument's scale. Changing
the display scale can be done entirely in the XML code for the instrument.
Right now it's set up only to display a 40 mile scale.
The radar is an AWACS view, which is not very realistic, but it is useful and
demonstrates the technology. With just a little more work I can get a HUD
marker. All I need to do there is make a bank angle adjustment to the
current values.
2004-02-27 10:20:17 +00:00
|
|
|
// these describe the model's desired state
|
2006-06-24 00:00:27 +00:00
|
|
|
double tgt_heading; // target heading, degrees true
|
|
|
|
double tgt_altitude_ft; // target altitude, *feet* above sea level
|
|
|
|
double tgt_speed; // target speed, KTAS
|
2003-11-28 15:48:05 +00:00
|
|
|
double tgt_roll;
|
|
|
|
double tgt_pitch;
|
|
|
|
double tgt_yaw;
|
|
|
|
double tgt_vs;
|
|
|
|
|
David Culp:
Here's a new batch of AI code which includes a working radar instrument.
I put the radar calculations into the existing AIAircraft class. It was
easier that way, and it can always be migrated out later if we have to.
Every tenth sim cycle the AIManager makes a copy of the current user state
information. When the AIAircraft updates it uses this information to
calculate the radar numbers. It calculates:
1) bearing from user to target
2) range to target in nautical miles
3) "horizontal offset" to target. This is the angle from the nose to the
target, in degrees, from -180 to 180. This will be useful later for a HUD.
4) elevation, in degrees (vertical angle from user's position to target
position)
5) vertical offset, in degrees (this is elevation corrected for user's pitch)
6) rdot (range rate in knots, note: not working yet, so I commented it out)
and three items used by the radar instrument to place the "blip"
7) y_shift, in nautical miles
8) x_shift, in nautical miles
9) rotation, in degrees
The radar instrument uses the above three items, and applies a scale factor to
the x-shift and y-shift in order to match the instrument's scale. Changing
the display scale can be done entirely in the XML code for the instrument.
Right now it's set up only to display a 40 mile scale.
The radar is an AWACS view, which is not very realistic, but it is useful and
demonstrates the technology. With just a little more work I can get a HUD
marker. All I need to do there is make a bank angle adjustment to the
current values.
2004-02-27 10:20:17 +00:00
|
|
|
// these describe radar information for the user
|
2004-06-10 19:14:19 +00:00
|
|
|
bool in_range; // true if in range of the radar, otherwise false
|
David Culp:
Here's a new batch of AI code which includes a working radar instrument.
I put the radar calculations into the existing AIAircraft class. It was
easier that way, and it can always be migrated out later if we have to.
Every tenth sim cycle the AIManager makes a copy of the current user state
information. When the AIAircraft updates it uses this information to
calculate the radar numbers. It calculates:
1) bearing from user to target
2) range to target in nautical miles
3) "horizontal offset" to target. This is the angle from the nose to the
target, in degrees, from -180 to 180. This will be useful later for a HUD.
4) elevation, in degrees (vertical angle from user's position to target
position)
5) vertical offset, in degrees (this is elevation corrected for user's pitch)
6) rdot (range rate in knots, note: not working yet, so I commented it out)
and three items used by the radar instrument to place the "blip"
7) y_shift, in nautical miles
8) x_shift, in nautical miles
9) rotation, in degrees
The radar instrument uses the above three items, and applies a scale factor to
the x-shift and y-shift in order to match the instrument's scale. Changing
the display scale can be done entirely in the XML code for the instrument.
Right now it's set up only to display a 40 mile scale.
The radar is an AWACS view, which is not very realistic, but it is useful and
demonstrates the technology. With just a little more work I can get a HUD
marker. All I need to do there is make a bank angle adjustment to the
current values.
2004-02-27 10:20:17 +00:00
|
|
|
double bearing; // true bearing from user to this model
|
|
|
|
double elevation; // elevation in degrees from user to this model
|
|
|
|
double range; // range from user to this model, nm
|
|
|
|
double rdot; // range rate, in knots
|
|
|
|
double horiz_offset; // look left/right from user to me, deg
|
|
|
|
double vert_offset; // look up/down from user to me, deg
|
|
|
|
double x_shift; // value used by radar display instrument
|
|
|
|
double y_shift; // value used by radar display instrument
|
|
|
|
double rotation; // value used by radar display instrument
|
2012-03-04 15:30:08 +01:00
|
|
|
double ht_diff; // value used by radar display instrument
|
2003-11-28 15:48:05 +00:00
|
|
|
|
2013-03-28 16:49:52 +00:00
|
|
|
std::string model_path; //Path to the 3D model
|
2003-11-28 15:48:05 +00:00
|
|
|
SGModelPlacement aip;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2003-11-28 15:48:05 +00:00
|
|
|
bool delete_me;
|
2004-03-03 20:33:08 +00:00
|
|
|
bool invisible;
|
2004-05-21 16:50:19 +00:00
|
|
|
bool no_roll;
|
2007-03-30 22:51:52 +00:00
|
|
|
bool serviceable;
|
2010-11-13 16:29:34 +01:00
|
|
|
bool _installed;
|
2007-06-07 16:30:26 +00:00
|
|
|
int _subID;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2004-08-30 09:11:59 +00:00
|
|
|
double life;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2017-09-21 18:37:14 +01:00
|
|
|
std::unique_ptr<FGAIFlightPlan> fp;
|
2003-11-28 15:48:05 +00:00
|
|
|
|
2007-06-07 16:30:26 +00:00
|
|
|
bool _impact_reported;
|
|
|
|
bool _collision_reported;
|
2010-08-14 13:39:30 +01:00
|
|
|
bool _expiry_reported;
|
2007-06-07 16:30:26 +00:00
|
|
|
|
|
|
|
double _impact_lat;
|
|
|
|
double _impact_lon;
|
|
|
|
double _impact_elev;
|
|
|
|
double _impact_hdg;
|
|
|
|
double _impact_pitch;
|
|
|
|
double _impact_roll;
|
|
|
|
double _impact_speed;
|
|
|
|
|
2003-11-28 15:48:05 +00:00
|
|
|
void Transform();
|
2005-06-04 09:38:52 +00:00
|
|
|
void CalculateMach();
|
2004-06-11 13:49:07 +00:00
|
|
|
double UpdateRadar(FGAIManager* manager);
|
|
|
|
|
2011-10-11 21:43:24 +02:00
|
|
|
void removeModel();
|
2012-11-27 00:02:28 +01:00
|
|
|
void removeSoundFx();
|
2011-10-11 21:43:24 +02:00
|
|
|
|
2005-10-15 14:55:51 +00:00
|
|
|
static int _newAIModelID();
|
|
|
|
|
|
|
|
private:
|
2007-06-07 16:30:26 +00:00
|
|
|
int _refID;
|
2006-02-11 13:16:56 +00:00
|
|
|
object_type _otype;
|
2008-08-07 22:24:47 +00:00
|
|
|
bool _initialized;
|
2014-02-23 11:51:21 -08:00
|
|
|
osg::ref_ptr<osg::PagedLOD> _model;
|
2014-09-21 22:08:57 +02:00
|
|
|
osg::ref_ptr<osg::PagedLOD> _interior;
|
2011-11-25 13:39:10 +01:00
|
|
|
|
2012-01-08 13:28:49 +01:00
|
|
|
osg::ref_ptr<FGAIModelData> _modeldata;
|
2011-11-25 13:39:10 +01:00
|
|
|
|
2011-11-20 15:05:37 +01:00
|
|
|
SGSharedPtr<FGFX> _fx;
|
2005-10-15 14:55:51 +00:00
|
|
|
|
2004-01-22 21:13:47 +00:00
|
|
|
public:
|
2004-05-21 16:50:19 +00:00
|
|
|
object_type getType();
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2006-02-11 13:16:56 +00:00
|
|
|
virtual const char* getTypeString(void) const { return "null"; }
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2004-05-21 16:50:19 +00:00
|
|
|
bool isa( object_type otype );
|
|
|
|
|
2004-05-28 08:46:33 +00:00
|
|
|
void _setVS_fps( double _vs );
|
|
|
|
void _setAltitude( double _alt );
|
|
|
|
void _setLongitude( double longitude );
|
|
|
|
void _setLatitude ( double latitude );
|
2007-06-07 16:30:26 +00:00
|
|
|
void _setSubID( int s );
|
2004-01-22 21:13:47 +00:00
|
|
|
|
2010-09-10 23:51:25 +01:00
|
|
|
double _getAltitudeAGL(SGGeod inpos, double start);
|
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
double _getVS_fps() const;
|
|
|
|
double _getAltitude() const;
|
2004-05-28 08:46:33 +00:00
|
|
|
double _getLongitude() const;
|
2007-06-07 16:30:26 +00:00
|
|
|
double _getLatitude() const;
|
|
|
|
double _getElevationFt() const;
|
2004-05-28 08:46:33 +00:00
|
|
|
double _getRdot() const;
|
|
|
|
double _getH_offset() const;
|
|
|
|
double _getV_offset() const;
|
|
|
|
double _getX_shift() const;
|
|
|
|
double _getY_shift() const;
|
|
|
|
double _getRotation() const;
|
2007-03-30 22:51:52 +00:00
|
|
|
double _getSpeed() const;
|
|
|
|
double _getRoll() const;
|
|
|
|
double _getPitch() const;
|
|
|
|
double _getHeading() const;
|
|
|
|
double _get_speed_east_fps() const;
|
|
|
|
double _get_speed_north_fps() const;
|
2007-06-07 16:30:26 +00:00
|
|
|
double _get_SubPath() const;
|
|
|
|
double _getImpactLat() const;
|
|
|
|
double _getImpactLon() const;
|
|
|
|
double _getImpactElevFt() const;
|
|
|
|
double _getImpactHdg() const;
|
|
|
|
double _getImpactPitch() const;
|
|
|
|
double _getImpactRoll() const;
|
|
|
|
double _getImpactSpeed() const;
|
2008-02-15 11:06:27 +00:00
|
|
|
double _getXOffset() const;
|
|
|
|
double _getYOffset() const;
|
|
|
|
double _getZOffset() const;
|
2007-06-07 16:30:26 +00:00
|
|
|
//unsigned int _getCount() const;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
bool _getServiceable() const;
|
2007-06-07 16:30:26 +00:00
|
|
|
bool _getFirstTime() const;
|
|
|
|
bool _getImpact();
|
|
|
|
bool _getImpactData();
|
|
|
|
bool _getCollisionData();
|
2010-08-14 13:39:30 +01:00
|
|
|
bool _getExpiryData();
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2007-04-04 09:51:41 +00:00
|
|
|
SGPropertyNode* _getProps() const;
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2007-07-15 14:08:31 +00:00
|
|
|
const char* _getPath() const;
|
|
|
|
const char* _getSMPath() const;
|
|
|
|
const char* _getCallsign() const;
|
|
|
|
const char* _getTriggerNode() const;
|
|
|
|
const char* _getName() const;
|
|
|
|
const char* _getSubmodel() const;
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2007-03-30 22:51:52 +00:00
|
|
|
|
|
|
|
// These are used in the Mach number calculations
|
David Culp:
Here's a new batch of AI code which includes a working radar instrument.
I put the radar calculations into the existing AIAircraft class. It was
easier that way, and it can always be migrated out later if we have to.
Every tenth sim cycle the AIManager makes a copy of the current user state
information. When the AIAircraft updates it uses this information to
calculate the radar numbers. It calculates:
1) bearing from user to target
2) range to target in nautical miles
3) "horizontal offset" to target. This is the angle from the nose to the
target, in degrees, from -180 to 180. This will be useful later for a HUD.
4) elevation, in degrees (vertical angle from user's position to target
position)
5) vertical offset, in degrees (this is elevation corrected for user's pitch)
6) rdot (range rate in knots, note: not working yet, so I commented it out)
and three items used by the radar instrument to place the "blip"
7) y_shift, in nautical miles
8) x_shift, in nautical miles
9) rotation, in degrees
The radar instrument uses the above three items, and applies a scale factor to
the x-shift and y-shift in order to match the instrument's scale. Changing
the display scale can be done entirely in the XML code for the instrument.
Right now it's set up only to display a 40 mile scale.
The radar is an AWACS view, which is not very realistic, but it is useful and
demonstrates the technology. With just a little more work I can get a HUD
marker. All I need to do there is make a bank angle adjustment to the
current values.
2004-02-27 10:20:17 +00:00
|
|
|
|
2004-09-22 19:11:36 +00:00
|
|
|
double rho;
|
|
|
|
double T; // temperature, degs farenheit
|
|
|
|
double p; // pressure lbs/sq ft
|
2006-06-09 18:48:57 +00:00
|
|
|
double a; // speed of sound at altitude (ft/s)
|
|
|
|
double Mach; // Mach number
|
|
|
|
|
2004-09-22 19:11:36 +00:00
|
|
|
static const double e;
|
2004-09-22 08:47:05 +00:00
|
|
|
static const double lbs_to_slugs;
|
|
|
|
|
2004-05-28 08:46:33 +00:00
|
|
|
inline double _getRange() { return range; };
|
2007-06-24 07:57:45 +00:00
|
|
|
inline double _getBearing() { return bearing; };
|
|
|
|
|
2004-05-28 19:03:55 +00:00
|
|
|
static bool _isNight();
|
2011-04-11 22:23:53 +02:00
|
|
|
|
2013-03-28 16:49:52 +00:00
|
|
|
std::string & getCallSign();
|
2003-11-28 15:48:05 +00:00
|
|
|
};
|
|
|
|
|
2015-12-11 12:11:46 -06:00
|
|
|
typedef SGSharedPtr<FGAIBase> FGAIBasePtr;
|
|
|
|
|
2006-03-04 12:49:30 +00:00
|
|
|
inline void FGAIBase::setManager(FGAIManager* mgr, SGPropertyNode* p) {
|
2006-06-09 18:48:57 +00:00
|
|
|
manager = mgr;
|
|
|
|
props = p;
|
2006-02-11 13:16:56 +00:00
|
|
|
}
|
2003-12-21 20:12:55 +00:00
|
|
|
|
2006-02-11 13:16:56 +00:00
|
|
|
inline void FGAIBase::setPath(const char* model ) {
|
2006-06-09 18:48:57 +00:00
|
|
|
model_path.append(model);
|
2003-12-21 20:12:55 +00:00
|
|
|
}
|
|
|
|
|
2013-03-28 16:49:52 +00:00
|
|
|
inline void FGAIBase::setSMPath(const std::string& p) {
|
2007-03-30 22:51:52 +00:00
|
|
|
_path = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void FGAIBase::setServiceable(bool s) {
|
|
|
|
serviceable = s;
|
|
|
|
}
|
|
|
|
|
2003-12-21 20:12:55 +00:00
|
|
|
inline void FGAIBase::setSpeed( double speed_KTAS ) {
|
2006-06-09 18:48:57 +00:00
|
|
|
speed = tgt_speed = speed_KTAS;
|
2003-12-21 20:12:55 +00:00
|
|
|
}
|
|
|
|
|
2004-11-16 09:33:21 +00:00
|
|
|
inline void FGAIBase::setRadius( double radius ) {
|
2006-06-09 18:48:57 +00:00
|
|
|
turn_radius_ft = radius;
|
2004-11-16 09:33:21 +00:00
|
|
|
}
|
|
|
|
|
2003-12-21 22:16:57 +00:00
|
|
|
inline void FGAIBase::setHeading( double heading ) {
|
2006-06-09 18:48:57 +00:00
|
|
|
hdg = tgt_heading = heading;
|
2003-12-21 20:12:55 +00:00
|
|
|
}
|
|
|
|
|
2006-06-24 00:00:27 +00:00
|
|
|
inline void FGAIBase::setAltitude( double alt_ft ) {
|
|
|
|
altitude_ft = tgt_altitude_ft = alt_ft;
|
|
|
|
pos.setElevationFt(altitude_ft);
|
2004-01-22 21:13:47 +00:00
|
|
|
}
|
|
|
|
|
2010-09-10 23:51:25 +01:00
|
|
|
inline void FGAIBase::setAltitudeAGL( double alt_ft ) {
|
|
|
|
altitude_agl_ft = alt_ft;
|
|
|
|
}
|
|
|
|
|
2004-02-23 20:55:07 +00:00
|
|
|
inline void FGAIBase::setBank( double bank ) {
|
2006-06-09 18:48:57 +00:00
|
|
|
roll = tgt_roll = bank;
|
|
|
|
no_roll = false;
|
2004-02-23 20:55:07 +00:00
|
|
|
}
|
|
|
|
|
2006-02-09 12:29:05 +00:00
|
|
|
inline void FGAIBase::setPitch( double newpitch ) {
|
2006-06-09 18:48:57 +00:00
|
|
|
pitch = tgt_pitch = newpitch;
|
2006-02-09 12:29:05 +00:00
|
|
|
}
|
|
|
|
|
2003-12-21 22:16:57 +00:00
|
|
|
inline void FGAIBase::setLongitude( double longitude ) {
|
2006-06-15 08:29:43 +00:00
|
|
|
pos.setLongitudeDeg( longitude );
|
2003-12-21 20:12:55 +00:00
|
|
|
}
|
2007-06-07 16:30:26 +00:00
|
|
|
|
2003-12-21 22:16:57 +00:00
|
|
|
inline void FGAIBase::setLatitude ( double latitude ) {
|
2006-06-15 08:29:43 +00:00
|
|
|
pos.setLatitudeDeg( latitude );
|
2003-12-21 20:12:55 +00:00
|
|
|
}
|
|
|
|
|
2013-03-28 16:49:52 +00:00
|
|
|
inline void FGAIBase::setCallSign(const std::string& s) {
|
2007-07-15 14:08:31 +00:00
|
|
|
_callsign = s;
|
|
|
|
}
|
2013-03-28 16:49:52 +00:00
|
|
|
inline std::string& FGAIBase::getCallSign() {
|
2011-04-11 22:23:53 +02:00
|
|
|
return _callsign;
|
|
|
|
}
|
|
|
|
|
2008-02-15 11:06:27 +00:00
|
|
|
inline void FGAIBase::setXoffset(double x) {
|
|
|
|
_x_offset = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void FGAIBase::setYoffset(double y) {
|
|
|
|
_y_offset = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void FGAIBase::setZoffset(double z) {
|
|
|
|
_z_offset = z;
|
|
|
|
}
|
2007-07-15 14:08:31 +00:00
|
|
|
|
2008-02-15 11:06:27 +00:00
|
|
|
inline void FGAIBase::setPitchoffset(double p) {
|
|
|
|
_pitch_offset = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void FGAIBase::setRolloffset(double r) {
|
|
|
|
_roll_offset = r;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void FGAIBase::setYawoffset(double y) {
|
|
|
|
_yaw_offset = y;
|
|
|
|
}
|
2007-07-15 14:08:31 +00:00
|
|
|
|
2013-03-28 16:49:52 +00:00
|
|
|
inline void FGAIBase::setParentName(const std::string& p) {
|
2010-09-08 17:38:35 +01:00
|
|
|
_parent = p;
|
|
|
|
}
|
|
|
|
|
2013-03-28 16:49:52 +00:00
|
|
|
inline void FGAIBase::setName(const std::string& n) {
|
2010-09-10 23:51:25 +01:00
|
|
|
_name = n;
|
|
|
|
}
|
|
|
|
|
2003-12-21 20:12:55 +00:00
|
|
|
inline void FGAIBase::setDie( bool die ) { delete_me = die; }
|
2007-03-30 22:51:52 +00:00
|
|
|
|
2003-12-21 20:12:55 +00:00
|
|
|
inline bool FGAIBase::getDie() { return delete_me; }
|
|
|
|
|
2004-05-21 16:50:19 +00:00
|
|
|
inline FGAIBase::object_type FGAIBase::getType() { return _otype; }
|
|
|
|
|
2010-09-27 23:50:44 +01:00
|
|
|
inline void FGAIBase::calcRangeBearing(double lat, double lon, double lat2, double lon2,
|
|
|
|
double &range, double &bearing) const
|
|
|
|
{
|
|
|
|
// calculate the bearing and range of the second pos from the first
|
|
|
|
double az2, distance;
|
|
|
|
geo_inverse_wgs_84(lat, lon, lat2, lon2, &bearing, &az2, &distance);
|
|
|
|
range = distance * SG_METER_TO_NM;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline double FGAIBase::calcRelBearingDeg(double bearing, double heading){
|
|
|
|
double angle = bearing - heading;
|
|
|
|
SG_NORMALIZE_RANGE(angle, -180.0, 180.0);
|
|
|
|
return angle;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline double FGAIBase::calcTrueBearingDeg(double bearing, double heading){
|
|
|
|
double angle = bearing + heading;
|
|
|
|
SG_NORMALIZE_RANGE(angle, 0.0, 360.0);
|
|
|
|
return angle;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline double FGAIBase::calcRecipBearingDeg(double bearing){
|
|
|
|
double angle = bearing - 180;
|
|
|
|
SG_NORMALIZE_RANGE(angle, 0.0, 360.0);
|
|
|
|
return angle;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void FGAIBase::setMaxSpeed(double m) {
|
|
|
|
_max_speed = m;
|
|
|
|
}
|
|
|
|
|
2011-11-25 13:39:10 +01:00
|
|
|
|
2012-03-04 15:30:08 +01:00
|
|
|
#endif // _FG_AIBASE_HXX
|