1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Monitor AI Objects

Discussion in 'SimConnect' started by Christoph, 15 Feb 2017.

  1. Christoph

    Christoph

    Joined:
    15 Feb 2017
    Messages:
    3
    Country:
    newzealand
    Hi All,

    I've come across this MSDN article about monitoring AI objects (in particular AI aircraft) however as has been mentioned elsewhere on this forum, the sample code is no longer accessible. If anyone does have a copy and would be willing to share it would be VERY much appreciated!

    Since I don't have it, I've had to hack my own code (i'm a very new developer so please excuse any mistakes).

    I've made a call to the SimConnect_RequestDataOnSimObjectType to get a list of AI aircraft:
    Code:
    // Get a list of AI objects to monitor
    simconnect.RequestDataOnSimObjectType(DATA_REQUESTS.REQUEST_AI_OBJECT_ID_BYTYPE, DEFINITIONS.AI_AIRCRAFT_DATA, MAXIMUM_RADIUS, SIMCONNECT_SIMOBJECT_TYPE.AIRCRAFT);
    I'm subscribed to receive the reply:
    Code:
    simconnect.OnRecvSimobjectDataBytype += new SimConnect.RecvSimobjectDataBytypeEventHandler(simconnect_OnRecvSimobjectData);
    And I do receive the reply as I see the Aircraft ID written to the console, but I have no idea what kind of data structure to receive this list of aircraft in
    Code:
    void simconnect_OnRecvSimobjectData(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA data)
    {
        switch ((DATA_REQUESTS)data.dwRequestID)
        {
            case DATA_REQUESTS.REQUEST_AI_OBJECT_ID_BYTYPE:
    
                Write.Console("Aircraft ID: " + data.dwObjectID)
                DO SOMETHING HERE!!!
           
                break;
    
            default:
                displayText("Unknown request ID: " + data.dwRequestID);
                break;
        }
    }
    All I know is once I have the list of AI aircraft I need to call something like this to start receiving the data...
    Code:
    simconnect.RequestDataOnSimObject(DATA_REQUESTS.REQUEST_AI_AIRCRAFT_DATA, DEFINITIONS.AI_AIRCRAFT_DATA, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD.SECOND, SIMCONNECT_DATA_REQUEST_FLAG.DEFAULT, 0, 0, 0);
     
  2. Christoph

    Christoph

    Joined:
    15 Feb 2017
    Messages:
    3
    Country:
    newzealand
    I think my problem is related to the RequestID which must be of type ENUM but also unique for each AI aircraft...
     
  3. Zpelican

    Zpelican

    Joined:
    19 Apr 2016
    Messages:
    7
    Country:
    unitedstates
    Hi Christoph,
    Unfortunately I was never able to locate the Monitor AI Objects code so I had to do it on my own. The good news is I have made lots of progress since, so I might be able to help you. The only downside is that all my coding has been done in VB.net but it was all derived from the C samples so it should be ok. So in looking at your code, it seems like you're on the right track. But I just want to clarify.. when you do a
    OnRecvSimobjectDataBytype you will not receive a "list" - you will received an individual data set for each AI aircraft which will be stored in the structure you defined. The "data packages" will come in one after another, overwriting the structure each time (you will see this if you step thru the code). Each time you receive the data, you need to store it somewhere. I store mine in a datatable, adding a new row for each incoming AI aircraft data "package". Once you have those stored, then you can do a RequestDataOnSimObject with the specific ObjectID. I'm not sure what you're trying to do, but you may not need to do a specific ObjectID request since you are already getting the data in your table. So essentially you can repeat your data request in a timed loop and then update your table (creating new records for new objectIds and updating records with existing ObjectIDs) In this instance you do not need a new specific request ID (I ran into that too, but I never found an instance where I needed a unique one).
    In my code I pull in all the AI aircraft data, put it in a table and keep updating it every 500ms. Then if I need specifics, I run a separate request, by ObjectID, and store it in another structure and do stuff related only to that ai aircraft.

    What are you trying to accomplish? Maybe I can help further.

    Cheers,
    Marc
     
  4. Zpelican

    Zpelican

    Joined:
    19 Apr 2016
    Messages:
    7
    Country:
    unitedstates
    I wanted to add - for my monitoring of an individual AI aircraft, I create a whole new Simconnect Class (passing the ObjectID when creating it), new connection etc. That way I can manipulate individual AI aircraft and all their data and events are compartmentalized in the class, so I don't need unique request IDs etc.. seems to run cleaner and safer, not to mention easier to maintain.
    M
     
  5. Zpelican

    Zpelican

    Joined:
    19 Apr 2016
    Messages:
    7
    Country:
    unitedstates
    void simconnect_OnRecvSimobjectData(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA data)
    {
    switch ((DATA_REQUESTS)data.dwRequestID)
    {
    case DATA_REQUESTS.REQUEST_AI_OBJECT_ID_BYTYPE:

    Write.Console("Aircraft ID: " + data.dwObjectID)
    >> Here is where you would add the record to your table, or array, or a structure. Your preference. But you have to "move" (copy) the data
    out of the simconnect data structure because it will be overwritten on the next iteration.

    break;

    default:
    displayText("Unknown request ID: " + data.dwRequestID);
    break;
    }
    }
     
  6. ddawson

    ddawson Resource contributor

    Joined:
    27 Sep 2006
    Messages:
    601
    Country:
    canada
    The structure you need is driven by the DATA_DEFINITION. You won't get the whole list of aircraft at once. Your callback function is invoked once for each aircraft that meets the search criteria.
    https://msdn.microsoft.com/en-us/library/cc526983.aspx#SimConnect_RequestDataOnSimObjectType
     
  7. Christoph

    Christoph

    Joined:
    15 Feb 2017
    Messages:
    3
    Country:
    newzealand
    Thanks so much guys, that was very useful and I got it working! Here were my issues:
    1. I needed a unique RequestID for each call to RequestDataOnSimObject so that I could switch subscriptions to each AI aircraft on and off. This was solved by setting my REQUEST.AIRCRAFT_DATA enum to a high number (i.e. 10000). My RequestID then becomes 10000 + data.dwRequestID (the unique ID of the AI aircraft)
    2. I was only subscribed to RecvSimobjectDataEventHandler, I needed to subscribe to RecvSimobjectDataBytypeEventHandler as well
    3. To differentiate the replies for each aircraft and handle them with a single switch/case, we first check if data.dwRequestID is greater than 10000 (i.e. it must be a reply to an aircraft data request), if it is we set it back to 10000
    I'm sure there are better or more optimal ways of doing this, but for now it works and I will continue to improve where I can but if anyone has any suggestions I'd be MORE than happy to hear them!
    Code:
    // Set my request ENUM to a high value
    enum REQUEST
        {
            AIRCRAFT_LIST,
            AIRCRAFT_DATA = 10000
        };
    
    // Subscribe to callbacks from simconnect.RequestDataOnSimObjectType and invoke simconnect_OnRecvSimobjectData
    simconnect.OnRecvSimobjectData += new SimConnect.RecvSimobjectDataEventHandler(simconnect_OnRecvSimobjectData);
    simconnect.OnRecvSimobjectDataBytype += new SimConnect.RecvSimobjectDataBytypeEventHandler(simconnect_OnRecvSimobjectData);
    
    // Ask SimConnect for AI Aircraft objects
    simconnect.RequestDataOnSimObjectType(REQUEST.AIRCRAFT_LIST, DEFINE.AIRCRAFT_DATA, MAXIMUM_RADIUS, SIMCONNECT_SIMOBJECT_TYPE.AIRCRAFT);
    
    // Receive replies
    void simconnect_OnRecvSimobjectData(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA data)
    {
        // If dwRequestID is larger than 10000, set dwRequestID to 10000 to be actioned by switch case
        if (data.dwRequestID > (int)REQUEST.AIRCRAFT_DATA)
        {
            data.dwRequestID = (int)REQUEST.AIRCRAFT_DATA;
        }
    
        switch ((REQUEST)data.dwRequestID)
        {
            // Callback with list of all aircraft
            case REQUEST.AIRCRAFT_LIST:
                displayText("Received " + data.dwentrynumber + " of " + data.dwoutof);
    
                // Subscribe to each aircraft for data
                simconnect.RequestDataOnSimObject(REQUEST.AIRCRAFT_DATA + (int)data.dwObjectID, DEFINE.AIRCRAFT_DATA, data.dwObjectID, SIMCONNECT_PERIOD.SECOND, SIMCONNECT_DATA_REQUEST_FLAG.DEFAULT, 0, 0, 0);
               
                break;
    
            // Callback from each aircraft
            case REQUEST.AIRCRAFT_DATA:
                if (data.dwObjectID != SimConnect.SIMCONNECT_OBJECT_ID_USER)
                {
                    // DO SOMETHING WITH THE DATA
                }
    
                break;
        }
    }
     

Share This Page