Improved J661 support: Difference between revisions

Jump to navigation Jump to search
m
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Background =
= Background =
Establish the interface requirements for better [[J661]] support, so that J661 and FlightGear can collaborate in a more efficient, and overall better, fashion. So that J661 may connect to a running FlightGear instance in order to use simulated flight data to drive avionics simulated by j661.
Establish the interface requirements for better [[J661]] support, so that J661 and FlightGear can collaborate in a more efficient, and overall better, fashion. So that J661 may connect to a running FlightGear instance in order to use simulated flight data to drive avionics simulated by j661.
Referring to the code in http://gitorious.org/fg/flightgear/blobs/next/src/Network/props.cxx My suggestion would be to extend the telnet ("props") module in FlightGear, so that we add a new helper class named "PropertySubscription" and then extend the class "PropsChannel" to get a new member std::vector<PropertySubscription*> Then, we'd add two new commands "subscribe" and "unsubscribe" to the telnet command handler, where "subscribe" would simply take the property tree string, create a new instance of PropertySubscription( property ) and then append it to the std::vector "subscriptions" which would be an instance specific member field. The command "unsubscribe" would then merely lookup the listener and delete it from the vector.
The telnet-based approach is the cleanest and most portable solution without breaking backward compatibility, simply because it'd just be new commands that clients could make use of or not. However, it would probably make sense to really require each session to configure its own subscriptions (listeners actually), right? I mean, we don't want to register listeners that fire for any other sessions - only the once that actually registered the listener. Obviously, you need to respond not just with the value of the property, but also a property identifier - so that the connected client knows what property the value belongs to. And then we could either have the telnet server respond with a full "property=value" reply like:
/foo/bar/altitude-ft=1500
(Which'd still be fairly verbose, but certainly better than right now) Obviously, that'd be the simplest method - fairly easy to implement without too much thinking... However, I think it would make sense to use a compressed form, e.g. one where a hash of the property is internally used - and also in responses, such as a 3-4 byte hash of the full property tree string, stored in hexadecimal- so that the response is more compressed and more efficient than using the full property string every time, i.e. consider: 7FEA=100


= Requirements =
= Requirements =
Line 11: Line 19:


= Ideas =
= Ideas =
** Handling multiple properties **
== Handling multiple properties ==
* One thing that would be great would maybe to be able to have more than one parameter to the output for the client in one telnet output (for example all the properties that have been requested), but even without that, performance should be far better than with polling I think.
* One thing that would be great would maybe to be able to have more than one parameter to the output for the client in one telnet output (for example all the properties that have been requested), but even without that, performance should be far better than with polling I think.
* For your information, in the ARINC 661 protocol, the User Application concatenates several "commands" in the same buffer, denoting each specific command by its ID (and in the case of ARINC, also it's widget ID, but it's not relevant to our problem). In our User Application implementation (which happens to be coded in C++), a lot of parameters which are considered as cyclic are send regardless of their value change, because they change often. However the Server checks for their change, and in this case, it does not go further than their decoding. It turned out that the time the Server takes to decode a huge buffer and make its checks is negligible (of the order of 1 ms for example).
* For your information, in the ARINC 661 protocol, the User Application concatenates several "commands" in the same buffer, denoting each specific command by its ID (and in the case of ARINC, also it's widget ID, but it's not relevant to our problem). In our User Application implementation (which happens to be coded in C++), a lot of parameters which are considered as cyclic are send regardless of their value change, because they change often. However the Server checks for their change, and in this case, it does not go further than their decoding. It turned out that the time the Server takes to decode a huge buffer and make its checks is negligible (of the order of 1 ms for example).
Line 22: Line 30:
== Hashing ==
== Hashing ==
* hashing is already supported by the property tree itself (see SimGear library), it is in fact used internally for storing properties, so one of the easiest ways to hashing support would be directly exposing and using the hashes computed by the property tree: http://simgear.sourceforge.net/doxygen/classSGPropertyNode.html It seems, the hash code is stored as an unsigned int (private storage), see line #01758 in http://simgear.sourceforge.net/doxygen/props_8hxx_source.html So it would just be a matter of adding the following to the public interface of the "bucket" class: inline unsigned int getHashcode() const {return hashcode;} And then add a corresponding wrapper to the top level SGPropertyNode class for accessing a node's hash. Either as a static method or as a member function using the "this" pointer. Something along these lines would then allow using hashes of properties internally, which would also reduce bandwidth requirements.
* hashing is already supported by the property tree itself (see SimGear library), it is in fact used internally for storing properties, so one of the easiest ways to hashing support would be directly exposing and using the hashes computed by the property tree: http://simgear.sourceforge.net/doxygen/classSGPropertyNode.html It seems, the hash code is stored as an unsigned int (private storage), see line #01758 in http://simgear.sourceforge.net/doxygen/props_8hxx_source.html So it would just be a matter of adding the following to the public interface of the "bucket" class: inline unsigned int getHashcode() const {return hashcode;} And then add a corresponding wrapper to the top level SGPropertyNode class for accessing a node's hash. Either as a static method or as a member function using the "this" pointer. Something along these lines would then allow using hashes of properties internally, which would also reduce bandwidth requirements.
* I realize that this whole idea of hashing properties makes things more obfuscated, but I guess it'd still be beneficial. Also, it would be possible to implement the "subscribe" command in a fashion so that it implicitly accepts a valid property argument and automatically responds with the computed hash value for the corresponding properties. That way, client's would not need to know about (or replicate) the hashing mechanism being used in FG, rather they would just parse the server-side response after issuing a "subscribe" command and then store hash value in a client-side map, invalid/erroneous subscriptions could be handled by a hard-coded "INVALID" response instead, which'd also be easy to parse and process in the client.
* The server would sort of confirm a valid subscription by echoing back the computed hash value for the registered property listener. From an API point of view that would also be fairly clean and actually well-encapsulated, because the hashing algorithm is contained inside FG and could even change arbitrarily with any upcoming releases, without introducing breakage.


= Patch prototype =
= Patch prototype =

Navigation menu