TwinFan / LiveTraffic

LiveTraffic is an X-Plane multiplayer plugin, which fills your sky with live air traffic based on public flight tracking data.
https://twinfan.gitbook.io/livetraffic/
Other
101 stars 24 forks source link

Enhance DataRefs to work as featured read access to a/c info #86

Closed TwinFan closed 5 years ago

TwinFan commented 5 years ago

Current Situation / Problem LT already offers quite some DataRefs. So far they mainly served debugging purposes. But the idea has always been to enhance them in a way that other apps (LittleNavmap being the first candidate) could access all simulated aircrafts.

X-Plane has a set of DataRefs for info on the AI planes, but that only covers at max the number of configured AI planes. Still, what LT offers should be compatible down to the name and format to ease development and maintenance.

The current logic of LT‘s DataRefs is to write to the .../ac/key first then read from the .../ac... values. This is superior to the X-Plane standard array model and probably stays like that: If the a/c selected by writing the key vanishes then one would not without knowing subsequently read data of a random other plane but receives 0 values. Still need to see if this is usable in external apps. Also it is yet unclear if an external app has a chance of mapping an AI plane to any plane read via LT‘s DataRefs, cause LT has them all. Or if that is a necessary requirement at all.

The set of DataRefs offered by a/c might be incomplete and needs revisiting. It definitely has no text offerings yet, which could be implemented by array dataRefs.

Suggested Solution

Updated April 2019:

Benefits Other apps like LittleNavmap can do something with LT‘s data.

albar965 commented 5 years ago

XP multiplayer aircraft datarefs are already used by LNM but are limited. Xpconnect tries to find and read additional information from the .acf files. Not an option here as far as I understood.

I'd prefer an array or a list of datarefs before the write and read approach.
The latter one requires to write the index, leave the main plugin function and then read with the next iteration. Can be quite time consuming to read all AI aircraft, depending on number. What do you think? Alex

TwinFan commented 5 years ago

Read .acf is no option, correct.

The list of aircrafts in LT keeps changing. There is no guarantee that after you read the array of longitude values the next read of the array of latitude values has the same length, i.e. the same number of aircrafts. And you need to read quite many dataref arrays. Chances are high that every once in a while the data doesn't match up. That's what I want to avoid. There is no wait after writing to the 'key' dataref...just write '1' for the first a/c and read all info about the first aircraft. It is guaranteed to be consistent. Then write '2' and read the second...well...except if by that time '1' has vanished, '2' moved up to become one...and you are now reading the third...hell...it's no so easy.

OK, here's another approach, which would work with arrays, too, and chances for inconsistencies are present, but way less likely: I do provide arrays (note: with up to 50 aircrafts that can be lengthy arrays...but there's no technical reason it shouldn't work). I'll guarantee that aircrafts never change position within the array. If an aircraft vanishes the corresponding array values stay 0 (or any other reasonable N/A value...maybe max negative, i.e. 0xFF...FF), but the place stays occupied. It will be used again some time later when new aircrafts are created. Array length will increase over time, but I think we could even agree that the array size will never shrink. (Be aware...it will start over if user switched off aircraft display...) The only remaining issue with this approach is: You'll still need to read several dataRef arrays. And between any two reads an aircraft might vanish. You might have successfully read latitude...and when you get around to read longitude the aircraft is gone and its value comes back 0. That you would need to prepare for.

So...that's for numerical values, lat, lon, alt, head, speed and the like. If you are interested in text values, like registration, call sign and the like, how to deal with that? I don't think there area 2D-arrays, are they? Well...we could spell out an 2D array with fixed length second dimension. A call sign array would be 6x50=300 integers long. Or...actually...with 64bit integers I could just squeeze the entire call sign in just one integer...solved :)

albar965 commented 5 years ago

I see. Sorry, I did not dive into datarefs too deep yet. I need only the reading part so far.

So, the datarefs are updated by your callback immediately when I set the index (in my plugin context, so to speak). That makes your approach much easier to use and does not look like it adds a performance penalty. Lets stick with your current index method.

To mitigate the problems with "alive" or "moving" aircraft: It would help a lot if I could get an object id of any kind that would allow me to remove duplicates that appear while fetching the data. No idea how you can generate this internally. It could even be a hash on aircraft registration, flight number and type for example. You probably know better how to create one. I could remove duplicates and cache aircraft for a second or two to avoid flickering symbols when they disappear temporarily during fetching.

Alternatively: Implement some kind of simple transaction mechanism. The reader sets a dataref, indicating the begin of the reading process (or uses another method to do this). You put a whole list of aircraft aside for this reader to get a consistent result. After reading (indicated by dataref access again) you can release the list of aircraft. Not sure if this makes sense. Just thinking out loud.

The index access method will not work if multiple applications use it since daterefs are global as far as I understood.

It is not a terrible effort on my side to add this. I would only affect Little Xpconnect. The rest, Navmap and Navconnect can be used as is.

Alex

TwinFan commented 5 years ago

Relax...I‘d need to test my implementation anyway, so I‘ll provide an example...or actually even an API. How about you just call a function that returns a std::vector with all aircrafts?

Unique key is always provided: the ICAO Transponder code, that identifies an aircraft even in the real world.

You are right, however, regarding multi-plugin access...a write-first-read-many model wouldn’t work consistently then.

EDIT: As long as X-Plane is single threaded it actually would work...but let’s make future proof design. X-Plane might become multi-threaded with Vulcan, whatever that means for plugins...

Sent with GitHawk

albar965 commented 5 years ago

I'm totally relaxed. Just thinking out loud. (: I'd say that arrays are the best solution so far (https://developer.x-plane.com/code-sample/arraydataref/). Transponder code as unique key is perfect. Alex

TwinFan commented 5 years ago

Plugin ABC might be interested, too.