• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

smooth AI movement - the old favorite

B21

Messages
149
Country
unitedkingdom
Can anyone comment on the best way to move an AI object smoothly under the direct control of a simconnect client ? The issue has been around for a long time, fsrecorder seems to do pretty well so its possible, but I've seen lots of posts but no good answer. To some this post will seem a bit of a necro of the issue but I'm hoping experience has been gained since Russell's post.

I do not believe this is purely a function of update rates, and do not want to get into a debate about the latency of named pipes/udp/tcp etc. or why simconnect sucks.

Russell did a good job of posting this video in this other fsdeveloper post from last year, but I don't think he ever got a clear answer.

I do 100% understand the comments from folks that *if* you could update the AI position (lat/long/alt) 100 times a second *and* pass those updates to FSX with zero latency *and* ensure the updates are synchronised with the millisecond timestamp of the FSX frames *then* it would be smooth, but I don't think this is a viable technique, even though it seems the simplest.

My fundamental question is "is it possible to have the plane move smoothly between points relative to a shadowing user aircraft" even if the position updates are relatively infrequent from the simconnect client (e.g. even once every FOUR seconds). This would mean you would have be sending velocity or acceleration vectors to the AI object, not just simple lat/long/alt updates every visual frame. Like Russell, I'm *not* concerned at this stage with the jumps that may then occur every four seconds - it's the relative jitter during linear movement I want to address at this stage. I have no problem at all with the FREEZE and DISABLE SIM commands.

I think the basic answer needed is whether the AI aircraft can be given a position update including (e.g.) VELOCITY BODY Z and have that do what you'd expect until changed, or maybe the slew mode is helpful in a similar way.

Any help very much appreciated...

B21
 
Last edited:
Hi Folks

Ian -
Have you tried -
Rather than telling the aircraft where to be
tell the aircraft where to aim for next.

Thus letting the sim perform any interpolation,
(i.e. don't use slew mode).



If this is specifically for missions -
Jim's simvar.exe already implements this method.
AI plane control can be seen in Jim's Mercenary Rescue mission, (link in last post).



HTH
ATB
Paul
 
Last edited:
thanks for the quick response - I'm with you 100% - the question is how best to implement the technique. My program 'spec' is to read a number of 'IGC files' (industry-standard GPS tracklogs of aircraft (actually gliders usually) storing lat/long/alt at maybe 4-second intervals) and 'simply' replay those in FSX. The pitch/bank/heading have to be estimated from the tracklog and I can interpolate between the 4-second samples inside my simconnect app if I need to.

So my requirement would be satisfied if I just converted all the IGC files into a single fs-recorder 'frc' file and used fs-recorder, but there are a couple of subtleties that might make it worth writing my own code - mainly the correct handling of the timestamps in the IGC files.

So there are a few possible methods:

* just 'freeze lat/long/alt' and set the lat/lon/alt of the AI plane every visual sim frame - this gives apparent 'jitter' if you watch the AI aircraft from a user aircraft flying alongside. I have this working but with jitter, interpolating between the IGC trackpoints within simconnect and sending each update via SetDataOnSimObject.

* using 'freeze' events or 'sim disable', initially set the lat/long/alt of the AI aircraft in the sky but set 'heading' and 'velocity body z' in the hope the aircraft then actually moves - I've tried this but currently have the a/c stationary between SetDataOnSimObject calls even though I am setting velocity body z. Still looking at this though.

* set the heading of the AI aircraft using SetDataOnSimObject and put the AI aircraft into 'slew' mode and send the appropriate set-forward-slew-speed event - haven't tried this yet but at least will have to 'calibrate' the meaning of the slew events.

* use the simconnect AI waypoint function to dynamically set waypoints in front of the AI aircraft - my concern is I'd have maybe 3000 waypoints per AI aircraft (that's how many trackpoints per IGC file) plus I'd like to see if I could efficiently move 100 AI aircraft. Given the tracklog file contains the real path of an aircraft so the physics is pre-computed, I don't think I'd want FSX to try and re-compute the flying physics for each small step in the log unless there was no other way. I've used AI objects with waypoints in one of my missions, so I get the concept, although there are a few challenges using gliders...

cheers.... B21
 
<snip> a fair bit of text omitted due to server crash...

in summary, the following approach is looking promising, having been tested to show 100% smooth movement of the ai object relative to the user aircraft:

(1) put the AI object into slew mode by sending in the "SLEW ON" event

(2) alter the forward speed of the object by sending it the "AXIS_SLEW_AHEAD_SET" event, or rotate it in pitch, bank or heading with the similar AXIS_SLEW_.. events. The DWORD value in the TransmitClientEvent controls the *speed* of the movement, not the absolute position of the object...
Here's something new, i.e. not a repeat of the posts we lost in the server crash: the formulae to give you the desired speeds are:
-x-x-x-x- AHEAD (DWORD) slew_rate = sqrt( "speed meters per second" * 45678 )
-x-x-x-x- ROTATE (DWORD) slew_rate = sqrt( "rotate radians/second" * 11240000)
Note that the speed of rotation for a given slew_rate DWORD value is the *same* whether you're setting pitch, bank or heading, assuming you're using the corresponding TransmitClientEvent. A POSITIVE value for the slew_rate DWORD value rotates the object HEADING to PORT, gives BANK PORT WING DOWN, or PITCH NOSE DOWN.

(3) because you are only *nudging* the ai object in the direction you want it to go (i.e. you are controlling velocities not the absolute position) you have to use RequestDataOnSimObject for the AI object say once-per-second and get the lat/long/alt/pitch/bank/heading of the ai object, so you can compare that with the position you actually want the aircraft, and decide which slew value to give it. If it's not clear, you are sending AXIS_SLEW_.._SET at most one-per-second, adjusting the *speed* with which the object moves forwards or rotates in pitch, bank or heading. If your object were an airliner, you could adjust the slew rates a lot less frequently.

This approach has the potential to be smoother than the simplest move-the-aircraft-through-explicit-lat/long/alt positions (requires updates on a per-frame basis) and far more efficient than the use of 'real' FSX AI flying through waypoints (requires air physics computed for every aircraft). But I haven't completed the programming of a multi-aircraft replay to see how effective the slew technique is in actual FSX...

B21
 
Last edited:
Hey B21,


AMAZING!, just tested the formulaes and works just nicely!, so far this method seems to solve this problem!. *ALL* looks and seems to work, however i noticed something:


It's "PITCH" and "ALTITUDE VELOCITY", when you send the KEY_AXIS_PITCH....it changes the PITCH rotation (as expected), however it wont change the aircrafts altitude, i think in this case you need also to use KEY_AXIS_ALT_SET, for set the ALTITUDE VELOCITY (in meters per second)...so i think that would require to make a different version of the "meters per second" formulae, because i tried converting from feet/min to meters/second (I used Google for this: "Convert 400 feet per minute to meters per second"..and it throws the results...), then apply the formulae for meters per second, but the SLEW value that it throws doesn't reflects the same feet/min speed (In my own aircraft's panel gauge for VERTICAL SPEED (VSI)...). This is how i tested it:


1) I select my aircraft (user aircraft) a cessna.
2) Loaded the sim into an airport
3) I had put my own aircraft (user aircraft *NOT* AI), in SLEW MODE
4) I placed my own aircraft (under SLEW MODE) into an altitude of 5000 feet above the ground level. You can also use the MAP option for place your aircraft into a higher altitude, for do this test.
5) Then i openned TrafficToolBox's Explorer
6) Select my own aircraft (user aircraft *NOT* AI)
7) Right-clicked then selected "Send Key Event"
8) Then i had used the: KEY_AXIS_SLEW_AHEAD_SET, and entered a value for "move" my own aircraft (user aircraft *NOT* AI), forward..it entered: 1282 (69 KIAS).
9) Then for "make" my own aircraft to "descend" to a lower altitude, i went back to the TrafficToolBox's Explorer..
10) Selected my own aircraft (user aircraft *NOT* AI), again....and..
11) Right-clicked it, then selected "Send Key Event"
12) Selected: KEY_AXIS_SLEW_PITCH_SET, and entered a high value for make my own aircraft (user aircraft *NOT* AI) to rotate the NOSE DOWN, so then it should "descend" in altitude....I entered a random value: 304.
13) As expected, the NOSE went DOWN,...
14) Now for STOP my own aircraft from rotating and keep the NOSE DOWN....i went back to the TrafficToolBox's Explorer..
15) Selected my own aircraft (user aircraft *NOT* AI)...
16) Right-clicked it, then selected "Send Key Event"
17) Selected: KEY_AXIS_SLEW_PITCH_SET, and entered a value of (ZERO): 0
18) As expected my own aircraft's nose is ALL THE WAY DOWN... and STOPPED rotating (pitch)
19) Then I had hit the SHIFT+Z keys (in my keyborad) for look at my own aircraft's altimeter to see if the altitude decreases..
20) I then noticed that my aircraft was at NOSE DOWN but the altitude didn't changed, it keep at same altitude, moving forward without change.
21) Also i looked at my own aircraft's panel, into the VSI (Vertical Speed Indicator) and it said like -6 feet/min.
22) According Google's calculator:


400 (feet per minute) = 2.03200 meters per second


Using the already existing formulae:


sqrt(2.03200 * 45678) = 304.6599 (SLEW value)


After i sent to my own aircraft: KEY_AXIS_SLEW_ALT_SET --> 304

My own aircraft panel's VSI (vertical Speed Indicator) says: -6 ft/min....YES! it descends (using KEY_AXIS_SLEW_ALT_SET)
however, doesn't reflects the 400 feet/min i tried to reproduce (using SLEW)...i guess the SLEW formulae just needs to be
updated a bit, and it will work without problems (i think)....cuz the already formulae for meters per second WORKS NICELY!
WITH: KEY_AXIS_SLEW_AHEAD_SET, and also same WORKS NICE with ROTATION!...very nice!


In other words, the KEY_AXIS_SLEW_ALT_SET works as similar as KEY_AXIS_SLEW_AHEAD_SET, the difference is:

KEY_AXIS_SLEW_ALT_SET: For move along the vertical axis (altitude...)
KEY_AXIS_SLEW_AHEAD_SET + KEY_AXIS_SLEW_HEADING_SET: For move along the lateral and longitudinal axises (forward and sideways...)


A part from that, this new method looks very very very nice, i must say!.....im very positive that this *should* work! (under multiplayer conditions)....


Best Regards,


Manuel Ambulo
 
Last edited:
yup Manuel I've repeated your testing using the traffic toolbox and confirmed your findings for vertical speed, and I've reverse-engineered the formula behind the KEY_AXIS_SLEW_ALT_SET DWORD value. So now we have:

* Forward movement (m/s) : AXIS_SLEW_AHEAD_SET, DWORD = sqrt( "speed meters per second" * 45678 )

* rotation speed pitch, bank, heading (rad/s): DWORD rate = sqrt( "rotate radians/second" * 11240000), using
** AXIS_SLEW_PITCH_SET (+ve = nose down) (NO CHANGE TO ALTITUDE)
** AXIS_SLEW_BANK_SET (+ve = port wing down)
** AXIS_SLEW_HEADING_SET (+ve = turn to port) (CHANGES DIRECTION OF MOVEMENT)

* vertical speed (m/s): AXIS_SLEW_ALT_SET, DWORD = sqrt("vertical speed m/s" * 3084000)
** +ve value moves aircraft DOWN.
** tested for vertical speeds -0..15m/s, rate 0..10,000. Have NOT tested negative values.

Adjusting vertical speed ('ALT') does not seem to alter the forward speed ('AHEAD'). This is actually helpful if you are following timestamped waypoints as you can calculate the forward speed necessary to reach the next waypoint at the correct time without worrying about the extra length of a descending diagonal, and the required vertical speed can be computed independently. It just means the true airspeed is actually the hypotenuse of AHEAD and ALT m/s speeds (sqrt(AHEAD^2+ALT^2)). Also ALT being independent of pitch means you can adjust the pitch of the AI aircraft at low speeds without causing the aircraft to climb...

B21

* edit - I just had to update the ALT slew formula - I messed up converting from fpm to m/s...
 
Last edited:
So, we have the formulaes...now comes the *TRUE* testing: MULTIPLAYER!...that will definitivily decide if it's good or not...however, i'm very positive with this technique, is GREATLY EFFICIENT and EVEN BETTER than just update 24 or more times per second the lat-lon-alt.


So the KEY_AXIS_SLEW_AHEAD will be driven by the BODY VELOCITY .....Y or Z?....also i get sometimes confused...with XYZ or XZY


I assume that Y = Vertical Axis (Altitude), Z = Forward/Backwards Axis, X = Right/Left Axis (Sideways)....Im correct? (or wrong?)...

OR! is it?:


I assume that Z = Vertical Axis (Altitude), Y = Forward/Backwards Axis, X = Right/Left Axis (Sideways)....??????????


Another **COOL** thing with this is...that when you SLEW VERTICALLY (altitude) using KEY_AXIS_SLEW_ALT_SET, when the aircraft is descending, and it reaches the ground...IT STAYS! ON GROUND LEVEL!...i meant...that IT WILL LOOK MORE REAL!, because i already saw in multiplayer sessions, that sometimes others players aircrafts SEEMS TO *SINK* IN GROUND...and all we know it's the DIFFERENT SCENERY, that everyone has...however i think with this, the PLANES WIL TOUCH GROUND AND STAY THERE!.....so maybe NO MORE PLANES FLOATING OR SINKING IN GROUND...*MAYBE*


So in resume, so far...this technique LOOKS GREAT!


Best Regards,
 
Update - I now have an AI object following smoothly along the path created by a 'real' FSX aircraft sampled once-per-four-seconds (that I call the *lead* aircraft), by updating the slew rates of the AI aircraft once-per-second.

The basic idea is as described earlier in this thread, but that still left a lot of programming to simply control the AI object by adjusting the slew rates. The basic technique is a "following" AI algorithm as illustrated here. I *predict* where the lead aircraft is going to be FOUR SECONDS AHEAD (the predicted_point), and adjust the slew rates of the AI aircraft to turn towards that point.

All motion of the AI object is by sending the slew AHEAD/HEADING/BANK/PITCH/ALT commands which adjusts the corresponding linear or rotational speed, and in between my per-second updates the AI aircraft continues with the previously set velocities, i.e. if it's turning it will continue to turn. Testing shows the movement has none of the jitter present when doing absolute position updates via simconnect.

Manuel - to your specific question - for my purposes I am *not* reading the speed of the lead aircraft and sending that as a "slew ahead" event to the AI object - I am computing the speed required to reach the predicted_point of the lead aircraft from the AI object current position at the correct time, and sending the "slew ahead" rate appropriate for that speed - this will be very similar to the lead aircraft speed but has the effect that the AI object is always automatically correcting its position by turning *and* accelerating. The altitude control is the same - I compare the current AI altitude with the altitude of the lead aircraft 'predicted_point', and send the appropriate slew ALT command that would adjust the altitude over the next four seconds. A small subtlety is this computation is actually performed every *second* as that's the frequency I get the AI position updates via simconnect.

So the general principle remains to monitor the position of the AI object once-per-second, and send it slew commands to adjust its forward or vertical speed or adjust its rotational speed to continually correct its direction towards a forward predicted point of the lead aircraft.

My interest is to replay 'IGC files', which are soaring GPS log files giving periodic samples of timestamped lat/long/alt. The technique could be used for multi-player if the lat/long/alt readings were piped over the network, but I'm not sure of a new requirement as that capability is already available in standard FSX. For what it's worth, I don't know what the non-Microsoft multi-player modules do - my guess is they try and control the exact position of the AI aircraft representing each user on a per-frame basis in the local client, but interpolate between infrequent updates across the network.

I've now flown with AI objects following a few different IGC tracklogs, but I haven't loaded up multiple tracklogs to see how the replay performance scales. I'm not far off from that though.

B21

p.s. as a minor anomaly, going into top-down view when in slew mode in the user aircraft causes the AI object to go beserk, even though you can watch the AI object perfectly fine in the other views... I haven't found out why this is.
 
Last edited:
Update - I now have an AI object following smoothly p.s. as a minor anomaly, going into top-down view when in slew mode in the user aircraft causes the AI object to go beserk, even though you can watch the AI object perfectly fine in the other views... I haven't found out why this is.

There's a speed scaling factor when switching to map view. It is applied also during normal slew mode.

Regarding using normal mode for animations and overwriting speed variables, this works for the body variables, but not for world variables.

The apparent reasons seems to be that body variables are the primary integrators in the flight model, while the world variables are just the transformed body variables. Since speeds are result of integration acceleration, body variables would not change too fast after being set by some user code.

Yet, body variables are subject to being updated by the flight model, even when aircraft position control is frozen, so it needs suffciently frequent updating to get the desired effect, which means one per second is not enough.

regards,
Peter
 
Last edited:
Thanks for the top-down view comment - I'll think about whether to trap for that situation. I wonder if the 'simulation speed' variable changes in that mode, so I should scale the slew params...

body variables are subject to being updated by the flight model... <snip> ...once
per second is not enough

I have the AI object in 'slew' mode, by sending it the 'slew on' event, and am controlling the body variables specifically in that mode e.g. by sending AXIS_SLEW_AHEAD_SET, DWORD=1000. This starts the object moving smoothly forwards and it will continue with a constant velocity until the next update from simconnect, regardless of how long I delay before doing that. I've found 1-second updates work quite well to guide an AI object along a chosen path. Was there something you've seen in slew mode that suggests some other issue? I'm well aware of the issues in regular flight mode, which is what caused me to investigate slew mode in the first place.

At the moment I have an aircraft flying smoothly around SeaTac airport, following a track recorded from another aircraft. I'm about to scale up the test with maybe 100 aircraft following that same path (with small offsets) to see what the performance looks like...

B21
 
worked like a charm...

I have a single test file with lat/long/alt/timestamp on a four-second interval, and as a test I created 100 AI objects all following the same path but offset by increments of 8m in altitude or 2 seconds in time. Slew method worked fine, with smooth movement of all the objects.

I used the stock FSX DG808S glider as the sample AI object, and framerates seemed *generally* unaffected by the number of AI objects I injected into the sim. There *was* a heavy graphics drawing workload when I had all 100 aircraft in view and I was up *close* - the DG808S clearly has a low-poly model which is used when you're maybe 200 meters away, but close up it becomes a high-poly model and 100 of these caused my framerate to drop to single digits. I believe the ai-object-controlled-by-slew-commands remains relatively efficient though...

A couple of pics:

100_ai_objects.jpg


100_ai_objects2.jpg


B21
 
Hi Folks

Ian -
re: Slew mode and accelerated time
The only oddity I've observed is that
at higher time-accelerated rates
there's an apparent discrepancy
between earth-rotation and the aircraft-position.

All ai gradually creep eastwards,
rather than maintaining their lat/lon posn.

HTH
ATB
Paul
 
All ai gradually creep eastwards,
rather than maintaining their lat/lon posn.

thanks Paul - it'll be interesting to see if this affects me, as each AI object in my technique is continually 'homing' in on a lat/long/alt target nominally four seconds ahead (with one-second course corrections). So it depends whether FSX standard AI is drifting off target or the actual lat/long coordinates in the FSX system are moving... I've no shortage of detail issues to address...

B21
 
Wow!, nice screenshots!.


I didn't realized that you were able to create so much numbers of AIs at same time. Im working in a "dogfight" proyect.....and i was asking myself if it could be possible to "re-use" SIMCONNECT REQUEST's IDs, for example:

If i create a simulated object then delete it (after a period of time), and create new ones using the request IDs of those deleted objects

Best Regards,


Manuel Ambulo
 
Last edited:
you don't need (or want) to re-use request id's. The essential method is described by Beatle here.

You're just trying to ensure request id's are unique, with the confusing bit being they're defined in an 'enum' which seems to suggest each one has to be explicitly defined, but in fact you can use thousands (tweaked from Beatle):
Code:
enum Requests
{
    REQUEST1,
    REQUEST2,
    REQUEST_AI_POS =   0x00100000, // here's the example we're interested in
    REQUEST3 = 0x00200000, // this entry ensures a large range is free
}

UINT ai_index = 0;

// and then wherever you want a request id for a new aircraft, use
//  (UINT)REQUEST_AI_POS + ai_index

// and where you generally have a 'case' statement in your message
 processing procedure, *precede* that with

    if (dwRequestID >= (UINT)REQUEST_AI_POS && 
        dwRequestID < (UINT)REQUEST_AI_POS + 10000) 
          // choose some max number of objects you will create at one time
    {
       UINT ai_index = (UINT)dwRequestID - (UINT)REQUEST_AI_POS;
        // do something relevant here
    }

B21

p.s. my test of multiple aircraft worked first time (woohoo) and the sight of 100 aircraft flying smoothly around SeaTac airfield in formation was cooler than the screenshot.
 
Last edited:
Thanks B21,

Actually i use a counter

Code:
unsigned long Total_SC_Requests;


And i just simply do this for every new request


Code:
Total_SC_Requests  = Total_SC_Requests + 1;
New_ReqId = Total_SC_Requests;


And i associate that "New_ReqId" with a structure of an AI object then, when i handle the msgs coming from FlightSim, i can distinguish which AI made that specified Request ID


My question above, was because, I'm not sure if the 1000 objects or request limit (imposed by the FSX SDK) is applied to:


1) When you generate equal or more than 1000 request IDs or objects...at same time (say, in less than 1 second or maybe 2 seconds)


OR!!!


2) When you generate equal or more than 1000 request IDs or objects...during the entire session that your SimConnect client is connected to the Flight Sim.


Im asking this, because in my program i'll need to create an X number of Simulated Objects per second (Example: 14 objects per second), everytime the user presses a key in his/her keyboard. Each of those Simulated Objects will be "deleted" by my program, after each of them spend more than 2 seconds in the simulation. Giving the chance to generate more Simulated Objects. When the user releases that key in his/he keyboard, then my program will stop creating those Simulated Objects.


NOTE: Each of those Simulated Objects doesnt have complex geometry. They are more "simpler" than that "flour bomb" that the FSX has. So i think wont impact FSX performace.


Best Regards,


Manuel Ambulo
 
Last edited:
The 1000 limit is on simultaneously active recurring periodic requests (PERIOD_SIMFRAME, PERIOD_VISUALFRAME, PERIOD_SECOND, etc).
 
FYI the slew-mode AI movement has proved solid in all my testing and the freeware product I'm working on is pretty much finished and will be released when the beta-testing is completed:

sim_logger homepage

To finish the story with regard to *smooth* AI movement, I've been able to follow planes like in the screenshot below with absolutely ZERO jitter, even though I am only updating the AI objects forward, vertical and 3-axis rotational speeds once-per-second.

B21

pilot_view.jpg
 
Hey B21,


Excelent images. Definitivily, the slew-mode is generates really nice smooth movements.

Im working in my multiplayer project, but didn't finished it. But from what i can see, it can be possibly that i could get that kind of smooth movements. However, my technique is different of reallocating the AI, i stil need to test that, but so far from what i saw...the slew-mode itself looks pretty cool. :)


Best Regards,


Manuel
 
Back
Top