Talk:Scripted AI Objects

From FlightGear wiki
Jump to navigation Jump to search

Target / Source handling

As Hooray said, this is the talk started here : We agree on the general way of doing it, and the goal we want.

For now, the script use 2 objects :

  1. the missile itself
  2. A "target" object which is an object with all variable available on the target aircraft/ship whatever...

The aircraft very specific variables are those used to setup the inital position of the missile : You give a pylon number and the script go look threw your aircraft to geo positionning the missile object and make it fire.( and the missile type...)

Instead of using this :

var DestinationOfFiring =;
var missile =, DestinationOfFiring );

a very, very simple way of doing it could be just feed the missile with 2 object and have someting like that:

 var SourceOfFiring =;
 var DestinationOfFiring =;
 var myMissile = new missile(origin:SourceOfFiring , target:DestinationOfFiring, type:missileType);

This is a quick way of doing the job. Perhaps the "Target" object needs to be completed, with "pylon number" or "pylon position" (and it also could be renamed). This will allow the script to be independant of any aircraft.

Using geo.Coord objects for dealing with source/targets

a target really is really just representing a position with lat/lon/alt - thus, it would make sense to simply use the existing geo.nas helpers here (geo.Coord) - if you need additional data, you can just sub-class geo.Coord to add your own fields - we are using this method in the MapStructre/TFC (traffic) layer. So I wouldn't make this more complicated than necessary. Obviously, targets/positions may be dynamic/changing, but that can also be realized using a geo.Coord sub-class, or a helper class with a geo.Coord member. Equally, missileType should probably just be another hash with a well-defined set of interfaces/methods. Overall, a simple MVC separation would definitely make sense here, which would allow you to have a custom 3D model, add animations to it, while having a plug&play FDM for different purposes. --Hooray (talk) 16:52, 28 October 2014 (UTC)

This is not only a quick way of doing it, this also something that can allow multiplayer firing : If (imagine a checkbox) the "MP firing property" is activated, it could reproduce a "AI model" on both side : On the SourceOfFiring's computer, but also a second "AI model" in the DestinationOfFiring's computer...(this a way of doing it...)


One thing we need to consider is how we coordinate code, i.e. use of version control etc.. Red Leader (Talk | contribs) 12:59, 28 October 2014 (UTC)

Coordination-wise, you should consider refactoring the existing code into separate modules/files and classes that can be independently maintained without requiring a ton of communication-obviously, being able to use git/gitorious would still help. --Hooray (talk) 16:00, 28 October 2014 (UTC)
We've had a number of users on the forum interested in these things, especially the FGUK guys would probably love to be involved in this. If you keep maintaining this article, I'll send heads-up to others who might be interested in this - even if just to provide feedback and advice. A few weeks ago, I talked with Algernon about these kinds of features so the FGUK guys should be all game - and a few others recently posted MapStructure/Canvas screen shots showing Combat-related developments[1].--Hooray (talk) 16:00, 28 October 2014 (UTC)
The more the better, Hooray. : Red Leader (Talk | contribs) 12:59, 28 October 2014 (UTC)

Missile FDM

And then once this is done, we could work later on a real FDM for the missile and what so ever. (Anyways, just my 2 cents opinion...) —5H1N0B1 (Talk | contribs) 14:08, 27 October 2014 (UTC)

Hi 5H1N0B1. Sorry I've not been able to get back to you sooner. Your suggestion seems quite good. Red Leader (Talk | contribs) 12:59, 28 October 2014 (UTC)

MP Support

Also, having MP firing would be a great feature. Red Leader (Talk | contribs) 12:59, 28 October 2014 (UTC)

For MP support, you'll want to use an intermediate class that uses the mp_broadcast.nas script to set up a comm channel for events (see bombable). --Hooray (talk) 16:00, 28 October 2014 (UTC)

Specs and Requirements

I think that we should also write down stuff that would be configurable on the missile (i.e. size and weight, but also seeker and guidance type). A while ago, I found a PDF that I think will be very useful

Red Leader (Talk | contribs) 12:59, 28 October 2014 (UTC)
I think what we should do first is to put down stuff that affects the missiles specs, such as guidance types, seeker type, etc., then split these into categories, such as FDM, Seeker, etc., and work from there.
Red Leader (Talk | contribs) 16:52, 28 October 2014 (UTC)
I've looked at the fox2.nas file and all those missile specs there are usually based on defaults provided by the aircraft-set.xml file - thus, I've extracted those portions to a separate XML file and using io.read_properties() to read in specs in an xml-configurable way. All those values will end up in a key/value map (hash), so can be easily accessed. For now, it's just a stub, but I'll probably generalize this a little more and move it to some sub-class, so that we can reuse the same mechanism for other missile. The commit can be seen at [2].--Hooray (talk) 13:05, 2 November 2014 (UTC)

Generalizing the existing code

You'll find that most of these requirements will basically evolve automatically once you start refactoring the existing code into separate classes and files, while still supporting additional aircraft/use-cases. That is basically what we did with Gijs' NavDisplay code - and it can now be used on arbitrary aircraft, while also supporting an arbitrary number of instances per aircraft. We are even supporting an "AI aircraft" mode-which means that you can get a ND view for an arbitrary AI aircraft (including even AI nodes like a Bombable bot or AI missile). To make things sufficiently flexible and configurable we're using "behavior hashes" that can override default behavior (fields/methods). With efforts like these, over-engineering is a very real danger - it will probably get you farther to just refactor the existing code and incrementally make it support additional use-cases/aircraft, and extend the code over time. Currently, the main issue still is that the module is aircraft specific-once this restriction is removed, you'll see other aircraft developers join the effort over time, especially those without any stakes in the m2000-5, but still interested in combat feature.--Hooray (talk) 17:04, 28 October 2014 (UTC)

I think that we should instead call this the "AI guided weapons system" or "AI guided munitions." After all, we aren't just talking about missile, we're also talking about guided bombs. The same system can and should be used for both. That's what I think anyway. Red Leader (Talk | contribs) 19:56, 28 October 2014 (UTC)

Functional separation into guidance, autopilot and FDM

From a functional standpoint, I would suggest to look at the way FlightGear's subsystems are divided into distinct components and then simply model this code accordingly by introducing helper classes for components like 1) the FDM, 2) the autopilot, 3) the "route managerh". That way, a guidance system would simply implement the route manager system's interface. As I stated elsewhere, it would make a lot of sense to maintain parity with the property tree-level FDM/AP and RM systems. Primarily, this will ensure consistency - secondly, it will ensure that future updates would provide a sane migration path, i.e. for using C++ level hooks that are currently not exposed to scripting space - we do have a number of contributors who tinkered with supporting multiple instances of the FDM/AP and RM subsystems - in fact, the AP system already supports multiple instances (see the property-rules system). And multiple FDM instances can also be supported for JSBSim FDMs - the route manager (RM) seems to be not sufficiently generic, but Durk and Zakalawe have repeatedly stated being interested in generalizing this part, too[3]. Which basically means that there will be less repetitive/integration work necessary if/once those changes should materialize at some point. Thus, it would be a good idea not to re-invent the wheel entirely in scripting space - there's useful existing C++ code for these things (FDM, AP, RM), and exposing things to scripting space using Nasal/CppBind also has never been so easy. The other benefit is obviously that people will intuitively know how to deal with scripted AI objects because the property tree interfaces would be closely modeled after existing conventions.--Hooray (talk) 13:36, 29 October 2014 (UTC)
Hi Hooray. Thanks for the suggestions. I think that, for now, we'll concentrate on keeping it in Nasal. At a later stage, we could look at implementing parts of the system in other parts of FG.
Red Leader (Talk | contribs) 16:34, 29 October 2014 (UTC)

right, but you misunderstood - I wasn't suggesting to move this out of Nasal anytime soon, but to just keep the design sufficiently generic so that components can be replaced at a later time, no matter if that involves other Nasal modules or really existing C++ code. The main problems that flug, xiii and others had when implementing these features was working around hard-coded design restrictions-those can be entirely prevented once a modular design is used like the one discussed above - without making things any more difficult. In fact, separation of concerns will be greatly simplified-and it does make sense to treat any entity like an airborne vehicle with a fdm, autopilot and route manager/guidance system. All this can be done entirely in scripting space using Nasal. The key is just the layered design using the property tree for I/O between systems--Hooray (talk) 16:42, 29 October 2014 (UTC)

OK, so the way I understand it is that the code should generic enough so that, for example, in the future YASim supports multiple instances, we could take out the Nasal FDM and instead translate the missile through the sky according to properties generated by a YASim instance.
Red Leader (Talk | contribs) 17:01, 29 October 2014 (UTC)
correct, but this is not specific to FDMs - all the autopilot/routing logic that people tend to reinvent in Nasal is significantly overlapping with existing, generic, C++ subsystems that are currently not yet exposed to Nasal. Thus, the main thing is using properties analogous to the actual C++ subsystems for interacting with the FDM/AP and RM components, which will ensure that a reusable and generic design is established, while preparing it for future updates. Otherwise, there will be more and more Nasal code doing what the C++ code is known to be very good at already.--Hooray (talk) 18:00, 29 October 2014 (UTC)
I've taken your code and refactored it to add stubs for separating things like FDM, guidance and autopilot - I've also added a self-test routine that I am hoping to extend over time - it should be self-contained, i.e. not rely on any aircraft/scenery. But it would seem to make sense to also move away from the static model_path and instead introduce a ModelMgr class so that multiple models per stage can be easily supported according to the missile.nas discussion above. This class could then also manage effects/animations and so on. You will find my changes in the "scripted-ai-submodels' branch. HTH--Hooray (talk) 00:02, 31 October 2014 (UTC)

Extending geo.Coord using sub-classing

A suggestion that I have is to expand geo.Coord to hold orientation values. That would mean we could handle target and have their lat/lon/alt/pitch/roll/heading at our fingertips. Red Leader (Talk | contribs) 17:03, 29 October 2014 (UTC)

like I said, this is trivial to do using sub-classing, so need to touch geo.nas at all - just create your own geo.Coord sub-class and add helpers for getting the corresponding properties via props.nas --Hooray (talk) 17:55, 29 October 2014 (UTC)

PS Hooary, how do you sub-class an existing Nasal class? Red Leader (Talk | contribs) 20:15, 29 October 2014 (UTC)

No special syntax/techniques involved - it just involves adding fields/methods to the new object, either directly - or via inheritance (the parents vector). I've added stubs to Philosopher's OO article at: --Hooray (talk) 21:00, 29 October 2014 (UTC)

Hi guys, you just go really too fast for me but I really like the way it goes. Seems to be clear code and could be really generic. I'll try to contribute a little but time, sadly is missing here ! —5H1N0B1 (Talk | contribs) 22:02, 29 October 2014 (UTC)

Things to keep in mind

Few things, just to be sure, and to remember :

  • a) The missiles object have to be loaded/created only once the fire order have been triggered.
  • b) The missile have 3 or 4 states : 1) Ignition (very high acceleration + special 3D light), 2) "Cruise"/fuse mode, with propulsion, 3) last part of the flight, no more fuel, using kinetic energy nad 4) explosion part. The flight behavior is different for each of the state, we must not forget that in the future ai fdm. (The biggest change is for thurst vectoring missiles)

The 4 state have been scripted both in fox2 & missile. They also use 3 differents 3D object each time. (Ignition don't have special model) The explosion part could be separeted from the missile object itself and be generic, as the smoke part.

  • c) We will have trajectory calculation. We must understand that time is a frame time. At high speed, and low fps, large distance could be traveled, and this must not affect missile/object behavior.
  • d) Just a request for the future : I saw lot of calculation in flightgear, and we will have a lot here. Could we, please for once, directly code/calculate in SI units...
  • e) What do you think about unguided/unpropelled munition. Actually this use the submodels system. Couldn't we add them here ? This would greatly simplify weapon system.
  • f) In the fdm part we have to not forget : "Parachute" bomb, but also missiles that launch itself "sub bomb" like fragmentation or Apache anty runway missile. I'm not syaing we have to code that, but perhaps code in a way we could include that after.
  • g) Anyways the code you wrotten here is very clear, and my remarks earlier concerns futur developppement.

5H1N0B1 (Talk | contribs) 16:26, 30 October 2014 (UTC) Every day, from everything and everybody, there is a truth to learn (talk) 15:29, 30 October 2014 (UTC)

To me, this sounds all very do-able - but obviously, it is a matter of priorities in terms of manpower and time that can be dedicated to this - most of us have many other areas/projects that we're juggling already. Thus, to state my own priorities, and to clarify where I'd be interested in helping:
  • I'd like to help extend the posted code such that tanker.nas and existing missile systems can be implemented using this code
  • Specifically, I would like to support a handful of different aircraft/use-cases, including other missiles, and at some point hopefully also other types of "payloads"
  • Primarily, I am interested in refactoring existing code to generalize the underlying concepts and to come up with an OO framework, where all the generic code lives in shared directory, instead of being copied&pasted into various places under $FG_AIRCRAFT
  • I might also be able to hook this up to galvedro's failure management code, so that missiles or aircraft systems may suffer failures and respond properly
  • in the really long-term, I'd also like to see flug's code reviewed and generalized accordingly, so that we can come up with a library/module for controlling AI objects in scripted fashion - without being specific to combat/missile use.
  • I am personally not opposed to any combat functionality in FG, but I do understand that this is a controversial topic-thus, I'd prefer to come up with generic building blocks that are not specific to combat use only - e.g. by having a "uav" framework instead of a drone/missile framework.
  • Structurally, I would suggest to come up with a new Nasal submodule under $FG_ROOT/Nasal/ai and add our ai.nas and missile.nas files there so that they can be independently developed, while being strictly optional
  • specific instances I would like to instantiate explicitly by using io.include(), analogous to the failure management framework or MapStructure
  • I do believe that it is very important to separate all components properly and to establish the property tree as the sole interfacing mechanism between guidance/autopilot and FDM-I am thinking in terms of having *.guidance, *.autopilot and *.fdm files that contain Nasal sub-classes implementing the corresponding lower-level interfaces (base classes)
  • that way, aircraft developers may not necessarily have to touch any *.nas files but just work with a certain subset of Nasal, analogous to MapStructure implementation files
  • I think there's really just 8-12 main base classes missing that can probably be prototyped by looking at existing use-cases (tanker.nas, fox2.nas. missile.nas) - once the code is sufficiently generic, I would hope to port those files to make them use the new framework, and then get aircraft developers involved to update their work accordingly.
--Hooray (talk) 17:02, 30 October 2014 (UTC)
@5H1N0B1: About point d): I think the reason for not using the SI-system is that most formulas are laid out in the gravitational Foot–pound–second system This is a link to a Wikipedia article in US aeronautical engineering textbooks (which are often used internationally in higher education and sometimes also are freely available).
Johan G (Talk | contribs) 19:44, 30 October 2014 (UTC)

Actually fox2.nas and missile.nas convert Imperial unit in SI unit, do the calculation in SI, and reconvert it in Imperial unit. (seriously gravity in foot-pound-second...o_O' ?) Another thing : About bombable. I tried to install it once on missile.nas : I discoverd that the bombable variable is already implemented since fox2.nas, and after testing I rememeber shooting bombable C172 invation with missiles... So if bombable still use the same system it could be easy to keep the fox2 orignal implementation. I never tested it with bombable and multiplayer... —5H1N0B1 (Talk | contribs) 14:46, 31 October 2014 (UTC)

Modified tanker.nas version using ai.nas

Like I said, before you told me you were interested in exploring this, I already started some work related to this - I'd suggest you wait until I have committed those changes so that you can take a look - it's mainly structural stuff ensuring that the existing GUI dialog can be used to instantiate a new tanker using ai.nas - everything else is "as is" and still needs to be adapted, but I thought this could help lower the barrier to entry. It's up to you obviously to decide if you want to use or discard those changes. --Hooray (talk) 17:19, 2 November 2014 (UTC)

Ok, I've committed those additions[4] - it isn't yet using ai.nas though, it's just a slightly modified version of tanker.nas that is loaded into a different namespace, and integrated via the tanker.xml GUI dialog, so that the actual file doesn't need to be modified. We can now easily replace existing functionality without there being any chance to break anything. Even though reset/re-init handling may still need some work/tweaking, because I haven't reviewed tanker.nas for any hard-coded namespace references yet.--Hooray (talk) 18:14, 2 November 2014 (even though it might make sense to UTC)

I've looked at the Tanker class in tanker.nas and it would seem pretty straightforward to use your ai.Obj class there, so depending on you getting git/gitorious access shortly, I can also prototype the whole thing in the meantime. It would definitely be a good thing to grow a library of tests, including not just scripts for testing the missile functionality, but also ai.Obj itself - and under the hood, aircraft functionality is going to be crucial either way. Once tanker.nas is ported, we could also adapt the code to add an f14 aircraft that can actually fire the new missiles to exercise the code without relying on a particular aircraft/location setup. Thus, I'd suggest the following priorities:

  • review tanker.nas and port the Tanker class
  • review bombable.nas and other use-cases to help generalize the new ai/missile.nas modules
  • look at the guidance/autopilot logic and come up with corresponding base classes

--Hooray (talk) 19:36, 2 November 2014 (UTC)

missile.nas feedback

I've started refactoring some of its code to implement the FDM base class - so here's some initial feedback. The main things preventing us from using the file/class "as is" are:

  • there's the hard-coded assumptions that missiles are started by the main aircraft, i.e. no support for AI aircraft firing missiles
  • mainly, this requires any uses of hard-coded properties referring to /orientation /position and /velocities - especially the release() and update() methods to be generalized
  • missile specs management is unnecessarily verbose, and not yet entirely generic - simply because of the way specs are loaded - it would be much easier to simply use a hash for configuring each missile, instead of having the hack in Loading_Missiles.nas[5]
  • 3-4 methods are much too big - i.e. need to be decoupled and refactored, especially to separate the FDM vs. guidance logic and the proximity detection stuff
  • making the code use ai.nas in its original form would be straightforward, but establishing the component separation is more work, and is currently preventing the code from being easily reused elsewhere
  • also, as is usually the case whenever complex Nasal code is involved, state management is not encapsulated at all, and done in a pretty roundabout fashion using lots of nested conditionals, i.e. no generic mechanism (state machine) in place
  • overall, missile.nas remains the best option for coming up with a generic framework, but there's quite some refactoring work to do still
  • how to proceed from here depends on who's willing to collaborate - otherwise, I may simply rewrite large portions of it, which would obviously take longer than providing feedback on what to change...

--Hooray (talk) 23:20, 4 November 2014 (UTC)

I'll have a look this week end and will try to work of some points of the roadmap. I think the whole things goes in the right direction.The point here from what I can see is to follow the roadmap. Perhaps (as we all have complex schedule) we could splitt more the work in tiny little task that we can do in 1 hour... If following the roadmap we could come up with : 1)Creating the ai object (done)

2)display it (done)

3)Creating the initial position of this objec, depending of the "source"/launcher paramters (this involve trigonometric calculation if I remember right...

4) Also we have for the "missile/bomb/lanched drone case" think how manage the pylon positioning issue. (Do we put it in the source object ?)

5)Detection:this is a big part : the ideal would be to have the "radar" object that we discussed once Hooray. This object could do Infrared detection, radar detection, could make the target disapeared if there "terrain" etc... and then if there is detection, it should provide command to the FDM (wanted pitch, wanted Roll, wanted heading). But Perhaps just a radar object could not be enough for al ai object (like tanker, drones, terrain following missiles etc).I don't really know how to do this but the idea would be to have both a kind of autopilot & a radar ... (Anyways the autopilot should also include the tanker behaviour : with base returning, virage ?, dialogs ?) And also we have to make a prevision script : just following a target isn't enough for the detection part. Some of missile should predict the next position(s) of the target and anicipate, in order to be more precise. This is important when a aircraft come from the front. a "simple following detection" will make the missile avoid the target. We also let the code open enough to include tomorrow a "flares sensibility" (MP player would love that)

6)Then comes the fdm. This should be the tough part. I don't see how make this generic. Cause we have : terrain following (simplified), sea level following, aim54 High altitude cruise missile, other cruise missile/ai (drone and tankers), vectoring thurst missile (wich become less agile with no fuel), breaked bomb (with parachute), and simple missile

7) the proximity detection & detonate the "missile"

If we subdivise it perhpas we could go forward. Anyways...perhaps I can not have a suffisant big mind or stand back to make something generic enough...So do not hesitate to show me the way :D As I said earlier, I will look this this week end.

5H1N0B1 (Talk | contribs) 10:40, 05 November 2014 (UTC)

That sounds good to me - for the sake of simplicity, I would merely add a new method, e.g. "setReferenceFrameCallback()" which takes a callback for getting the origin as a geo.Coord - i.e. usually geo.aircraft_position.latlon() - but could also be an arbitrary AI node instead. To simplify mission specs handling, I'd suggest to use a generic hash for all specs and use the missile name as the identifier, analogous to the ND styles hash, e.g.:
var MissileSpecs = {
## specs for the Aim7
 'Aim-7': {
  models: {default:'AIM-7.xml', with_smoke:'AIM-7_smoke.xml' },
 'max-detection-range-nm': 9,
 'fov-deg': 25

## specs for the Aim9
 'Aim9': {
  models: {default:'aim-9.xml', with_smoke:'aim-9_smoke.xml' },
 # ...
## you can add other missiles here


As you can see, you would have one outer hash named "MissileSpecs", which would contain embedded hashes with specs for missile - all using identical keys, so that you can look up arbitrary specs by doing this: var fov_deg = MissileSpecs['Aim-7']['fov-deg']; All the if/getprop logic in missile.nas and Load_Missiles.nas can then be removed, and you can add arbitrary other state there, too. --Hooray (talk) 23:35, 5 November 2014 (UTC)

Generalization of different fuses

It struck me the other day (no pun intended) that detection for guidance and for fusing maybe should be separated or that the fusing should be a child to the guidance. There are many types of fuses and ways to trigger them see this edit.

Johan G (Talk | contribs) 12:04, 8 November 2014 (UTC)

Vehicle Categories

  • Terrain
  • Water
  • Airborne
  • Hybrid (any combination of the above)

Updated code

My suggestion would be to remove the old stuff/examples, and just add all existing code to the article using the collapsible template for now, so that we can continue developing this without any git-related overhead.--Hooray (talk) 11:06, 6 February 2016 (EST)