Jump to content
The simFlight Network Forums

Paul Henty

Members
  • Posts

    1,652
  • Joined

  • Days Won

    74

Everything posted by Paul Henty

  1. Thanks, that's very kind of you. It's my pleasure to work with you guys. It's a good little group we have here and there are some great applications being built. Paul
  2. Your refresh rate really depends on what type of data you are getting and how you are using it. For example a black box flight recorder will require a high refresh rate (e.g. 30 times per second) whereas a moving map may only need to measure the aircraft position every few seconds. Also within the same application you might want to run different timers that work with different offset groups (see my UserGuide for more info on Offset groups) at different frequencies. Some data you might need to collect many times a second, some you only need maybe once per minute. Another way of doing that would be to use one fast timer and only process() the slower groups on every 10 ticks or whatever. Realistically you wouldn't need to update faster than the FS framerate because the data is only going to be different between frames. FSUIPC and my DLL can handle refresh rates of around 30 times per second (Timer Interval = 33ms) without a problem and this would be plenty fast enough even for a glass cockpit. You may even be able to go faster. The other thing you need to consider is the performance of your own program. If the contents of the timer tick() method takes say 60ms to run then this will be the fastest you can run the timer even if you give it a lower interval (e.g. 40ms). Basically, the rule of thumb is go as slow as you can get away with. If your application works fine with getting data every 60 seconds then there's not much point having a 100ms timer. Paul
  3. Pete Dowson, on 08 Jul 2013 - 11:42 PM, said: mgh said... There's nothing 'weird' about C#, although it might look that way if your only knowledge of it is what you see on this forum. People posting on this forum about C# (or VB.NET come to that) are usually beginners. People who have picked up what they can as a hobby by looking at 'example code' usually also written by beginners. They have no formal or deep understanding of the language they are using. They muddle through as best they can and post bizarre code and incorrect statements about C# because they don't really know what they are doing. What's posted on this forum is not a text book on C# or shining examples of what the language can do or how it works. The reasons to develop in C# (or VB.NET) rather than C/C++ would be very similar to why you would use C/C++ rather than assembler. It's a higher level language which is easier to learn and much faster to develop applications with, requiring fewer lines of code to be written. Also, you don't need to worry about technicalities like memory allocation/deallocation, pointers, message pumps etc. which makes it attractive to people who just want to get on and write their application rather than learn about the inner working of the PC and Windows first. Paul
  4. The string you are getting with failEngines.ToString() (FSUIPC.Offset`1[system.byte].) is the name of the class. That's what you have asked for by calling the ToString() method on the offset object. What you want is the string version of the Value of the offset which is: failEngines.Value.ToString(); Your conversion through an int is not required. You might also consider Graham's excellent suggestion of declaring the offset as a BitArray type. You might find it more convenient if you are working with more than one engine and are not familiar with bitwise operations. Paul
  5. Hi Francois, If you've not written too much code already you might want to take a look at my fsuipc interface dll for .NET. It's much easier to use and has many more features than the old C# SDK that you are currently using. Info and download here: http://forum.simflight.com/topic/40989-fsuipc-client-dll-for-net-version-20/ The package contains the DLL, a reference manual, a user guide and sample projects in C# and VB. Paul
  6. Hi Demian, PMDG aircraft use their own systems for things like autopilots. They do not use the normal Flight Sim systems. Since FSUIPC only gets the standard Flight Sim data, some data from PMDG aircraft is not normally available from FSUIPC. Other designers of very complex aircraft do the same thing and they and PMDG have their own SDKs for getting the data. However, FSUIPC had a 'bridge' added in 4.84 that lets you get data for the PMDG 737 NGX. This uses a different block of offsets from normal. See the document called "Offset Mapping for PMDG 737NGX" in your FSX "modules\fsuipc documents" folder. This doesn't seem to be available for any other PMDG plane or FSUIPC3 though. Paul
  7. No, you don't need to create any fuel or payload offsets in your code if you use PayloadServices. The DLL manages those for you behind the scenes. Paul
  8. ---------------------------------------------- Reading Payload and Fuel data ============================= The payload and fuel data is accessed from a new property on the FSUIPCConnection class called 'PayloadServices'. It's a good idea to assign this to a local variable to save typing FSUIPCConnection.PayloadServices all the time... // Get a reference to save so much typing... PayloadServices ps = FSUIPCConnection.PayloadServices; Whenever you want to get the latest payload and fuel data you just need to call RefreshData() on the PayloadServices object... // Get the latest data from FSUIPC ps.RefreshData(); Once you have done that there are lots of properties on the PayloadServices class that will give you weight and fuel data for the aircraft overall. For example: ps.PayloadWeightLbs ps.AircraftWeightLbs ps.FuelWeightLbs ps.FuelCapacityUSGallons Most are self-explanatory and there is Intellisense on everything. You also have access to the individual payload stations and fuel tanks. Here is an example of iterating through each payload station. // Go through each station and get the name and weight foreach (FsPayloadStation payloadStation in ps.PayloadStations) { string name = payloadStation.Name; double weight = payloadStation.WeightLbs; } You can do the same thing with the FuelTanks collection. This holds a FsFuelTank object for each possible tank. Some might not be in use for the current aircraft though. To access properties on a specific fuel tank you can use the following syntax: (This gets the current level of the Centre_Main tank in US Gallons. Other properties and tanks are available.) ps.GetFuelTank(FSFuelTanks.Centre_Main).LevelUSGallons Changing Payload and Fuel ========================= You can also write new values to individual payload stations or fuel tanks. To change the value of payload station, just change one of the weight properties for that station (Lbs, Kg etc). When you've made all the changes you want call WriteChanges() on your PayloadServices object. This will send all the changed values to FSUIPC. Fuel tanks are the same except, in addition to changing the weight, you can also change them by setting a new % full level or a volume in Gallons or Litres. Note that WriteChanges() send both Payload and Fuel changes in one go. Here's some code to set all the payload stations to 0 // Get the latest values ps.RefreshData(); // Go through each station and set weight to 0 foreach (FsPayloadStation payloadStation in ps.PayloadStations) { payloadStation.WeightLbs = 0; } // send the changes to FSUIPC ps.WriteChanges(); ------------------------------------------------------------- Thanks for the info about the XPUIPC offset. Paul
  9. 0x1400 is not a simple offset but the start address of a block of data that represents all the payload 'stations' on the aircraft. If you use the latest version of my DLL it gives you a much easier way to read and write the payload data (and fuel as well) than marshalling the data to and from this block yourself. The latest version 2.4 is attached to post 392 on this page. Instructions and code samples (in VB) for using the Payload Services can be found on page 19, post 371. In Flight Sim there is not one payload value, there are many payload stations for an aircraft and each plane has different stations added by the aircraft designer. If you want to set the total payload to 0 you need to set each individual station to 0. You can do this by iterating through them with a For Each loop as shown in the sample code. If you need any help using the payload features feel free to ask here. Paul
  10. I'm not really sure. I think the whole point of XPUIPC is to spoof the FSUIPC interface and report that FSX is running. If it didn't then some FSUIPC applications would not work with it as they check for a specific version of FS. Also there doesn't seem to be an ID number reserved for XPlane in the FSUIPC SDK documentation. I can only suggest contacting the makers of XPUIPC and see if they have a way you can detect it. They may have a way of reporting a different version number than FSX, or maybe they have some special offset you can check. Paul
  11. Below is code for a form that puts two menu items on the FS menu and responds to the user selecting these menu items. This shows you everything you need to do. If you want to put this behind a real form to see it working, you'll need two timers on the form called 'timerPollForInput' and 'timerKeepAlive'. You'll also have to change the namespace and class name to suit your project and wire up the _load event. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using FSUIPC; namespace TestApp { public partial class MenuDemo : Form { UserInputServices ui; public MenuDemo() { InitializeComponent(); } private void MenuDemo_Load(object sender, EventArgs e) { // Open FSUIPC FSUIPCConnection.Open(); // Get a reference to the UserInputServices ui = FSUIPCConnection.UserInputServices; // Add our Menu Items // The first parameter is the key and can be whatever you want. // We'll use this later to see which item was chosen. // The second patamter is the text to display on the menu item. // Putting an & before a letter makes it underlined and becomes the shortcut key. // Set the last paramter to true is you want to FS to pause when the user chooses this item. ui.AddMenuItem("MenuA", "Our Menu Item &A", false); ui.AddMenuItem("MenuB", "Our Menu Item &B", false); // Sink the MenuSelected event so we can respond ui.MenuSelected += new EventHandler<UserInputMenuEventArgs>(ui_MenuSelected); // Start our two timers. // This one keeps FSUIPC from deleting our menu items (every 4 seconds) this.timerKeepAlive.Interval = 4000; this.timerKeepAlive.Tick += new EventHandler(timerKeepAlive_Tick); this.timerKeepAlive.Start(); // This one checks to see if the user has selected a menu item (2 times a second). this.timerPollForInput.Interval = 500; this.timerPollForInput.Tick +=new EventHandler(timerPollForInput_Tick); this.timerPollForInput.Start(); } private void timerPollForInput_Tick(object sender, EventArgs e) { // Check if the user has selected our menu items ui.CheckForInput(); } private void timerKeepAlive_Tick(object sender, EventArgs e) { // Stop FSUIPC from deleting out menu items ui.KeepMenuItemsAlive(); } private void ui_MenuSelected(object sender, UserInputMenuEventArgs e) { // This method is called when the user selects one of our menu items. // Check which one and do stuff switch (e.ID) { case "MenuA": // Do menu A stuff here MessageBox.Show("Menu Item A selected!"); break; case "MenuB": // DO menu B stuf here MessageBox.Show("Menu Item B selected!"); break; } } private void Form2_FormClosing(object sender, FormClosingEventArgs e) { // Remove our menu items from FS ui.RemoveAll(); // Close FSUIPC FSUIPCConnection.Close(); } } } Paul
  12. Attached is version 2.4 of the DLL which will only be of interest to those addressing multiple instances of WideClient on the same machine. 1. Fixes a bug where you couldn't open a connection for any other class instance unless you had a class 0 wideclient/FS running. 2. Enables Payload, AITraffic and UserInput services for class instances > 0. To get a reference to the Payload/Traffic/UserInput object for a class instance use the new ...ForClass methods. E.g. to get the Payload services that's attached to class instance 2 use: PayloadServices ps2 = FSUIPCConnection.PayloadServicesForClass(2) Paul FSUIPCClient2.4_NET2.zip FSUIPCClient2.4_NET4.zip
  13. Hi Thomas, I can confirm this is a bug in my DLL. It seems that some of the higher level components like payload and AITraffic services are not aware of 'classes' and so always use the default class 0. Even if your code does not use them they do make a call to FSUIPC when the DLL initialises. So, if there is no class 0 connection then they throw an error. It'll take me a few days to sort this out properly. I'll post the fix here. Paul
  14. Hi Thomas, There is no overload that takes only the class number. The overload that takes only an integer is for requesting a specific version of flight sim without using the FlightSim enum. This is a bit confusing I admit, but not many people use multiple classes. To connect to a specific class, always use the overload that takes the class number and the flight sim version. You can pass 'any' if you want to work on all versions. e.g. to connect to class 1 for any version of FS use this: FSUIPCConnection.Open(1, FlightSim.Any); Paul
  15. Yes it should be fine. From what I've read 4.5 is just an enhanced version of 4.0 so any assembly compiled for 4.0 will also run under 4.5. Remember that the project still needs to target the x86 processor only. You can't compile your application to target x64 or 'any cpu'. Paul
  16. No it's the same, I just dropped the 'beta' tag because it's been well tested by now.
  17. Hi Thomas, It seems the DLL I uploaded was targeting the .NET 4 Framework so wouldn't have been usable in a .NET 2 project. I've edited that post with two versions, one for .NET 4 Client Profile and one for .NET 2. Paul
  18. Sorry, it seems I don't know how to use my own DLL! To get the fuel tank you must use the GetFuelTank() method. I've updated the code below and tested it on my system here on the default Cessna. Try FSUIPCConnection.Open(FlightSim.FSX) Dim ps As PayloadServices = FSUIPCConnection.PayloadServices ps.RefreshData() ps.GetFuelTank(FSFuelTanks.Left_Main).LevelUSGallons = 10 ps.WriteChanges() MsgBox("Done") Catch ex As Exception MessageBox.Show(ex.Message) End Try [/CODE] Paul
  19. Oh I think this could just be a problem with the code I gave you. I think you might need to call RefreshData() first to 'create' the fuel tanks so you can change them. Try this: Try FSUIPCConnection.Open(FlightSim.FSX) Dim ps As PayloadServices = FSUIPCConnection.PayloadServices ps.RefreshData() ps.FuelTanks(FSFuelTanks.Left_Main).LevelUSGallons = 50 ps.WriteChanges() MsgBox("Done") Catch ex As Exception MessageBox.Show(ex.Message) End Try [/CODE]
  20. Attached is version 2.3 of the DLL which includes some new features: 1. Read/write fuel and payload data 2. Allows you application to respond to keypresses, joystick buttons and menu items added to the FS menu by your application. There are two Zips. They contain the same DLL except for the version of the .NET framework they target. You can choose between the 2.0 Framework (NET2) or the 4.0 Framework Client Profile (NET4). If you don't know which one you need get the NET2 version. Reading Payload and Fuel data ============================= The payload and fuel data is accessed from a new property on the FSUIPCConnection class called 'PayloadServices'. It's a good idea to assign this to a local variable to save typing FSUIPCConnection.PayloadServices all the time... ' Get a reference to save so much typing... Dim ps As PayloadServices = FSUIPCConnection.PayloadServices Whenever you want to get the latest payload and fuel data you just need to call RefreshData() on the PayloadServices object... ' Get the latest data from FSUIPC ps.RefreshData() Once you have done that there are lots of properties on the PayloadServices class that will give you weight and fuel data for the aircraft overall. For example: ps.PayloadWeightLbs ps.AircraftWeightLbs ps.FuelWeightLbs ps.FuelCapacityUSGallons Most are self-explanatory and there is Intellisense on everything. You also have access to the individual payload stations and fuel tanks. Here is an example of iterating through each payload station. ' Go through each station and get the name and weight For Each (payloadStation As FsPayloadStation In ps.PayloadStations) Dim name As String = payloadStation.Name Dim weight As Double = payloadStation.WeightLbs Next payloadStation You can do the same thing with the FuelTanks collection. This holds a FsFuelTank object for each possible tank. Some might not be in use for the current aircraft though. To access properties on a specific fuel tank you can use the following syntax: (This gets the current level of the Centre_Main tank in US Gallons. Other properties and tanks are available.) ps.GetFuelTank(FSFuelTanks.Centre_Main).LevelUSGallons Changing Payload and Fuel ========================= You can also write new values to individual payload stations or fuel tanks. To change the value of payload station, just change one of the weight properties for that station (Lbs, Kg etc). When you've made all the changes you want call WriteChanges() on your PayloadServices object. This will send all the changed values to FSUIPC. Fuel tanks are the same except, in addition to changing the weight, you can also change them by setting a new % full level or a volume in Gallons or Litres. Note that WriteChanges() send both Payload and Fuel changes in one go. User Input - Menus =================== 1. First, declare a UserInputServices object using the WithEvents modifier ' Declare a UserInputServices object so we can use it in the code Private WithEvents userInput As UserInputServices 2. After opening the FSUIPC connection you need to set the variable above and add your menu items: ' Open the connection to FSUIPC FSUIPCConnection.Open() ' Set our userInput object to the UserInputServices userInput = FSUIPCConnection.UserInputServices ' Add our menu items (2 examples) ' First parameter is the ID we use to identify this menu item ' Second parameter is the Text for the menu item (Max 30 chars) ' use & before a letter to make it the shortcut key ' Third parameter specifies whether or not to pause FS when ' the menu item is selected. userInput.AddMenuItem("Menu1", "Menu Item &One", False) userInput.AddMenuItem("Menu2", "Menu Item &Two (Pauses FS)", True) Note that if you use a pausing menu item it will be your application's responsibility to unpause FS by writing to offset 0626 at the appropriate time. 3. You need add a new method to handle the MenuSelected event. This will be called when the user selects one of your menu items: Private Sub menuItemSelected(ByVal sender As Object, ByVal e As UserInputMenuEventArgs) Handles userInput.MenuSelected ' This sub gets called when a menu item is selected ' Use the e object to see which one (Check the ID) Select Case e.ID Case "Menu1" MessageBox.Show("Menu item 1 selected") Case "Menu2" MessageBox.Show("Menu item 2 selected") End Select End Sub 4. You need to call CheckForInput() regularly to check if the user has selected any menu items. If they have the above method above will automatically be called for you. Add this code in one of your timers. ' Check for input. Recommended every 200ms userInput.CheckForInput() 5. FSUIPC will delete your menu items after about 14 seconds. To prevent this you must tell FSUIPC that your application is still running and stills needs the menu items. You must call KeepMenuItemsAlive() regularly. Pete suggests every 8 seconds. So on an 8 second timer call: userInput.KeepMenuItemsAlive() 6. Before your application exits, call the RemoveAll() method to clean up your menu items. ' Remove our menu items userInput.RemoveAll() User Input - Buttons and Keys =============================== Similar to above except you use AddKeyPress() and AddJoystickButtonPress() to register the buttons/keys. You then sink the KeyPressed or ButtonPressed events to detect the user pressing the button/key. You still need to call the CheckForInput() regularly but KeepMenuItemsAlive() is obviously not required for buttons/keys. FSUIPCClient2.3_NET2.zip FSUIPCClient2.3_NET4.zip
  21. Hi ScKevin, First, if that is your real application code, then it's best not to keep opening and closing the connection. Just open once when your application starts and close before it unloads. Similarly only DIM the offsets once at the form (or class) level. Offsets are not garbage-collected when they go out of scope so your application will be requesting more and more data from FSUIPC with each press of the button. But maybe this is just test code to show the problem you are having... So turning to your fuel problem you have two conversions wrong as Pete has already explained above. Should be as follows: Dim LeftTankLevel As Double = LeftTankLevelGallons / FuelLeftCapacity.Value * 128D * 65536D FuelLeftTankLevel.Value = LeftTankLevel [/CODE] As an alternative to using the raw fuel offsets you could instead use the payload services in my DLL (Version 2.3) The code to set 50 Gallons in the left fuel tank would look like this: (Requires an already open connection) [CODE]Dim ps As PayloadServices = FSUIPCConnection.PayloadServices ps.RefreshData() ps.GetFuelTank(FSFuelTanks.Left_Main).LevelUSGallons = 50 ps.WriteChanges()[/CODE] The payload services allows you to read/write fuel tank and payload stations. There are also some properties that are derived and not available directly from FSUIPC. I'll put a post under this in a few minutes with version 2.3 of the DLL plus some sample code for the new features. I don't have the proper documentation done yet. Paul
  22. Hi Ruediger, It does work, but in my view the compiler is being far too generous! It's converting the hex string into an integer for you behind the scenes. This time, the compiler cannot to the conversion for you because there is more than one overload with two parameters. It doesn't know which one it should use. To get this to work you need to explicitly convert the string to an Integer using the Integer.Parse method. I recommend you always use this method, even if it does work the other way. I've separated the conversion here to make it easier to read, but you can of course put the conversion directly in the FSUIPC.Offset constructor parameters. Dim Newoffset = TextBox1.Text ' No &H is required. Dim IntNewoffset as Integer IntNewOffset = Integer.Parse(Newoffset, Globalization.NumberStyles.AllowHexSpecifier) Dim readoffset As Offset(Of UShort) = New FSUIPC.Offset(Of UShort)("Group1", IntNewoffset) Note that the Integer.Parse() conversion does not allow the string to include the "&H" prefix. Paul
  23. I would think that the path has to be from the perspective of the FX PC (server) not the client. From the path you are sending it looks like the flight plan is on the server PC. Try passing the local path, so something like C:\Users\..... If the flight plan was on the WideClient pc then you would need the UNC path to the client pc's shared folder. Paul
  24. Hi Ahmet, I'm also very confused because looking at my current source code, that error doesn't make much sense. Just to make sure you're running the same code as I have now, can you please update to the DLL I have attached and and rerun your application. Let me know if you still get the same error or a different one. Thanks, Paul FSUIPCClient.2.3.zip
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.