odwdinc / Python-SimConnect

Python interface for MSFS2020 SimConnect.dll
GNU Affero General Public License v3.0
282 stars 106 forks source link

Python-SimConnect Help with P3D? #75

Closed vamshichittaluri closed 3 years ago

vamshichittaluri commented 3 years ago

Hello, First of all, I really want to thank you for providing such an amazing piece of software.

My name is Vamshi, a PhD student from Ryerson University, Toronto, we are working on a project in which we need to control a Prepar3D(P3D) simulation with external data sources (data coming in from a python program...we are using a gps data log file to send data into the simulation.)

I have landed on Python-SimConnect and have been thanking the gods for it serves the exact purpose. I am trying to run the setup and keep running into the following error:

"SIMCONNECT_EXCEPTION_VERSION_MISMATCH"

This is obviously because the SimConnect version being used and the s/w was designed for is FS2020. The P3D sim i am using is P3D V5 which has a simconnect version of 5.1.0. Thus, the server (P3D) does not match the Client SimConnect version. Since both FS2020 and P3D all develop with SimConnect to send/receive data, this should work.

I've also tried another thing, I've moved the simconnect.dll files from the P3D path into the python project file so that it can reference a dll generated with the libraries compiled on the P3D side. However, I get the following error:

" File "C:\Users\MIMS-PC\AppData\Local\Programs\Python\Python38\lib\ctypes__init.py", line 391, in getitem__ func = self._FuncPtr((name_or_ordinal, self)) AttributeError: function 'SimConnect_Open' not found"

It says simconnect_open not found, in the attributes.py file, we notice that the:

self.SimConnect = cdll.LoadLibrary(library_path)

SIMCONNECTAPI SimConnect_Open(

HANDLE * phSimConnect,

LPCSTR szName,

HWND hWnd,

DWORD UserEventWin32,

HANDLE hEventHandle,

DWORD ConfigIndex)

SIMCONNECTAPI SimConnect_Open is commented out.

These are two possible methods that I am trying right now. Looking forward to your reply and your guidance.

Can you please please please guide me through this? It will help me so much with my studies in creating an amazing data-driven simulation.

odwdinc commented 3 years ago

Hello Vamshi, Thanks for your interest! happy to help. few questions and hopefully some answers.

  1. Where is the P3D server running? As the system is expecting it to run on the system as Python-SimConnect. Note there are ways around this if need just not well documented. as you are receiving this message "SIMCONNECT_EXCEPTION_VERSION_MISMATCH" I am guessing this is not the case though.
  2. The attributes.py file has commented out autogen code form the SDK's SimConnect.h. This is code for the open function. https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/Attributes.py#L27-L29 https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/SimConnect.py#L137-L141
  3. looking at the code for P3D, This may be the root of the problem. https://www.prepar3d.com/SDKv5/sdk/simconnect_api/managed_simconnect_projects.html
    The native function calls SimConnect_Open and SimConnect_Close have been replaced by the SimConnect constructor, and Dispose method respectively.

my suggestions is to test with changing https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/Attributes.py#L27 to self.Open = self.SimConnect.SimConnect

and https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/Attributes.py#L34 to self.Close = self.SimConnect.Dispose

let me know if this helps. and good luck!

vamshichittaluri commented 3 years ago

Hey!

Thanks for the reply!

So, the server and client are both running on the same system. Thus, I did not make any change to the xmls/cfgs involved. However, when i make the changes you suggested, I get the following:

AttributeError: function 'SimConnect' not found

odwdinc commented 3 years ago

ok, is there another dll or are you using the LockheedMartin.Prepar3D.SimConnect.dll from SDK\lib\SimConnect\managed? it seem like P3D is moved to a managed dll and to use the full open/close might need the SimConnect.lib form SDK\lib\SimConnect if you can find an un-managed SimConnect.dll you should be good to go.

vamshichittaluri commented 3 years ago

Hey, Yeah. So I've been using LockheedMartin.Prepar3D.SimConnect.dll from SDK\lib\SimConnect\managed. I cannot find the un-managed SimConnect.dll anywhere on the SDK other than instances of:

C:\Program Files\Lockheed Martin\Prepar3D v5\redist\Interface, which i guess are legacy versions? they are named: Microsoft.FlightSimulator.SimConnect.dll. However, these are also nested inside their respective managed folders.

Should I try to find something on google? lol

odwdinc commented 3 years ago

you could try the Microsoft.FlightSimulator.SimConnect.dll if it works grate, if not then its probley managed as well.

I did find this gem, looks to be http://prepar3d.com/forum/viewtopic.php?f=6310&t=139299

you cannot run a newer SimConnect client with an older SimConnect Server

https://www.prepar3d.com/forum/viewtopic.php?t=7502 Suggests the simconnect.dll form FSX/ESP should be good as long as it is an older or current gen.

http://prepar3d.net/forum/viewtopic.php?t=125348

it is possible for you to build your own simconnect.dll using the SDK files (simconnect.h and simconnect.lib).

So Try google, check out FSX/ESP might be helpful. if push comes to shove try compiling your own simconnect.dll ?? https://docs.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-160

good luck!

vamshichittaluri commented 3 years ago

Hey,

Thank you.

I tried the Microsoft.FlightSimulator.SimConnect.dll. and I get the following error when I run the python script.

OSError: [WinError 193] %1 is not a valid Win32 application, Do you know what this could mean?

https://stackoverflow.com/questions/25651990/oserror-winerror-193-1-is-not-a-valid-win32-application

according to this, it seems like I have to point to the python.exe file. I will check it out and update you.

I will explore this route as well as potentially compiling our own simconnect.dll.

odwdinc commented 3 years ago

OSError

miss matched python version 64bit vs 32bit.

Found this https://sites.google.com/site/fseoperationsguide/getting-started/using-the-fse-client/simconnect-client

Edit, The bit of python needs to match the bit of the DLL. aka a 64bit DLL needs 64bit python and 32bit DLL needs 32bit python. It looks like the older versions is 32bit so use 32bit python for testing. found DLL under C:\Windows\WinSxS\x86_microsoft.flightsimulator.simconnect_*******\

vamshichittaluri commented 3 years ago

Hey, So I installed Python 32 bit. And also pulled the DLL from the path you specified.

I get this: image Edit' I guess its saying the altitude = aq.get("PLANE_ALTITUDE") is returning a NoneType while it should be a float.

odwdinc commented 3 years ago

wow that's wonderful!! if you want to move you could try https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/local_example.py#L26-L36

Edit' I guess its saying the altitude = aq.get("PLANE_ALTITUDE") is returning a NoneType while it should be a float.

Just test altitude for None before adding back to altitude.

https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/RequestList.py#L18-L23

if the data is not found in the timeout then returns NoneType

maybe change _attemps is default to 10.

_time is for cashing results _time=0 disables cashing. aq = AircraftRequests(sm, _time=0, _attemps=20)

See for more samples. https://github.com/odwdinc/Python-SimConnect/blob/master/local_example.py

Also you are welcome to test the new Asyncio branch, no NoneType there :) https://github.com/odwdinc/Python-SimConnect/blob/asyncio-test/local_example.py

vamshichittaluri commented 3 years ago

Hey!

Thank you so much!!!!! IT works like a charm, I didn't check for the none type stuff yet. But I will do that later. I went ahead and played around by setting different altitude types... it works just correctly!

Thank you so much for your help! I will write up a report along with instructions that I realized to get this working with P3D. and contribute to this project :) This is such a great addition to what you have already committed to!

Once again! Thanks!!!!!

odwdinc commented 3 years ago

Glad to help, Happy Holladay's and all, and good luck with your PhD!

vamshichittaluri commented 3 years ago

Thank you! And good luck to you too on your endeavors! I have one question actually: The update rate of the sim, is it stuck to 2000ms? or can we make it any faster? I would like to update data in real time.

Kind Regards Vamshi

odwdinc commented 3 years ago

Thank you.

Where are you seeing 2000ms? There should be no delays in updating data, there might be some in receiving data.

Updates to SimConnect are called every 2ms via: https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/SimConnect.py#L171-L174

Data is pushed to SimConnect without delays via: https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/RequestList.py#L27-L31 Then: https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/SimConnect.py#L215-L240

vamshichittaluri commented 3 years ago

Oh! Nevermind, I thought it was 2secs sorry about that. Thanks!

vamshichittaluri commented 3 years ago

Hey Odwdinc,

Sorry to bug you again, The plane's altitude etc changes no problem. However, I keep getting this exception. Do yu have any idea on why is this is being thrown and how I can resolve it.

image

Thanks, Vamshi

odwdinc commented 3 years ago

Are you calling sm.quit() or sm.exit()? https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/SimConnect/SimConnect.py#L176-L179

looks like the error is started with call on sm.quit() line 35 on testing.py

Proper exit is: https://github.com/odwdinc/Python-SimConnect/blob/9d855a4492804005c7f50017102209a7675abd26/local_example.py#L23-L24

If you able to post some test code when you see the problem, I can take a look.

vamshichittaluri commented 3 years ago

Hey,

So I am using sm.exit() now. Howeer, I still recieve the following: image

Edit': Error Text:

Exception in thread Thread-1: Traceback (most recent call last): File "C:\Program Files (x86)\Python38-32\lib\threading.py", line 932, in _bootstrap_inner self.run() File "C:\Program Files (x86)\Python38-32\lib\threading.py", line 870, in run self._target(*self._args, **self._kwargs) File "C:\Program Files (x86)\Python38-32\lib\site-packages\SimConnect\SimConnect.py", line 173, in _run self.dll.CallDispatch(self.hSimConnect, self.my_dispatch_proc_rd, None) OSError: exception: access violation writing 0x037D0048

Edit2': Sorry I forgot to post the code I was running: very basic `from SimConnect import *

Create SimConnect link

sm = SimConnect() aq = AircraftRequests(sm, _time=0)

To find and set timeout of cached data to 200ms:

altitude = aq.find("PLANE_ALTITUDE")

Set the aircraft's current altitude

aq.set("PLANE_ALTITUDE", 10000)

sm.exit()

quit()`

odwdinc commented 3 years ago

Are you running form command line or form some IDE? I have had reports that some IDE's (Visual Studio) may cause errors. Can you test with this code on the command line?

from SimConnect import *
import logging
logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
LOGGER.info("START")
sm = SimConnect()
aq = AircraftRequests(sm, _time=0, _attemps=20)

pa = aq.find("PLANE_ALTITUDE")
print(pa.get())

sm.exit()
quit()
vamshichittaluri commented 3 years ago

I am running it on Idle. So it shouldnt be any issues as far as i know. But when i did run it on cmd, line by line and i get the following errors at this point: sm = SimConnect() image

odwdinc commented 3 years ago

So my best guess is that there is some python threading running in the background?? Maybe form the time you where calling sm.quit() vs sm.exit(). I know its silly but have you checked task manager? or a reboot? If nothing else can you test with https://docs.python.domainunion.de/3/library/faulthandler.html#module-faulthandler

also are you using python in a Virtual Environment?

vamshichittaluri commented 3 years ago

Hey,

Checked with a reboot as well as closing any instances of python on task manager... And no, not using it on a VE. Edit' came across the following: if you can make any sense out of it.

https://github.com/pywinauto/pywinauto/issues/451

odwdinc commented 3 years ago

Best guess is how windows handles 32bit apps in 64bit. As this is a windows only program I think we can get by with https://docs.python.org/3/library/ctypes.html#ctypes.WINFUNCTYPE

self.DispatchProc = WINFUNCTYPE(c_void_p, POINTER(SIMCONNECT_RECV), DWORD, c_void_p) 

vs https://github.com/odwdinc/Python-SimConnect/blob/139faea905e5938b9cd9022303e43d849dd4a8f1/SimConnect/Attributes.py#L75

I tested on the 64bit and see no errors replacing this line, hopefully this will help.

vamshichittaluri commented 3 years ago

Hey,

No, making the change still throws the same exceptions for some reason. Its so weird, cause, when i send a request for an altitude change, it does make the change and then throws this response :/

I am clearly lost at what the issue could be. However, it is throwing an OSError(OSError: exception: access violation writing 0x04220048), which in the link you posted and the following https://docs.python.org/3.4/library/ctypes.html

shows the potential issue:

ctypes exports the cdll, and on Windows windll and oledll objects, for loading dynamic link libraries.You load libraries by accessing them as attributes of these objects. cdll loads libraries which export functions using the standard cdecl calling convention, while windll libraries call functions using the stdcall calling convention. oledll also uses the stdcall calling convention, and assumes the functions return a Windows HRESULT error code. The error code is used to automatically raise an OSError exception when the function call fails.

Thank you for all your kind help.

vamshichittaluri commented 3 years ago

Hey!! I managed to get it fixed!!!! I had to change the following:

https://github.com/odwdinc/Python-SimConnect/blob/139faea905e5938b9cd9022303e43d849dd4a8f1/SimConnect/Attributes.py#L18 --> self.SimConnect = windll.LoadLibrary(library_path)

and then

self.DispatchProc = CFUNCTYPE(c_void_p, POINTER(SIMCONNECT_RECV), DWORD, c_void_p)

to

self.DispatchProc = WINFUNCTYPE(c_void_p, POINTER(SIMCONNECT_RECV), DWORD, c_void_p)

in the attributes file.

Thank you so much for all the help!!

Kind Regards Vamshi

odwdinc commented 3 years ago

wonderful! All push the changes to the repo, as the have no effect on the 64bit version. Thank you for working this out!

vamshichittaluri commented 3 years ago

Thank you so much!! I will write the "guide" to get it up on P3D as well. Happy Holidays! Kind Regards Vamshi

timlzh commented 2 years ago

Thank you so much!! I will write the "guide" to get it up on P3D as well. Happy Holidays! Kind Regards Vamshi

Sorry to bother you but I wonder could you please upload the copy you have changed to match P3D? Thank you!