Jump to content
The simFlight Network Forums

Paul Henty

Members
  • Posts

    1,652
  • Joined

  • Days Won

    74

Everything posted by Paul Henty

  1. Hi, So you'd like the DLL to maintain the connection in the background? Maybe it could fire an event when connected and when the connection is lost. I'll have a look at the implications - I agree it'll be a bit neater than the current way. I don't have FSX but I'm pretty sure there are some people using the DLL with FSX. The 1.1 release was pre-FSX. I'll see if Pete has a value for FSX and add it in. I have 1.2 being released soon with a a couple of minor bug fixes so I'll be able to incorporate it then. That's my fault - it's poorly written. For write-only offsets you still need to call Process(). What I meant in the doc was that the value is only written during process if the value of the local offset has been changed since the last process(). That is - it's not continuously wirting the same value. For read/write offsets - they a read on every process() except where the local offset value has been changed since the last process(). In this case the offset is written to FSUIPC and then goes back to read mode. Thanks! I hope it's useful. If you need any more info or help just ask... Paul
  2. Hi, Well the widths coming in in feet does add a bit of complication. The conversion from feet (or metres) to latitude is complicated by the fact that as you get closer the the poles, a degree of latitude represents fewer and fewer feet (or metres). There is a set formula for calculating this though. However, you then have to take into account how much of that you use and how much of the longitude you use. This of course depends on the heading. For example for a 36 runway the 'width' is all latitude. For a 27 runway it's all longitude. I think the best thing here would be to leave your program working off the four corner coordinates and have another program work these out from the runway data (I assume you're going to do some kind of import program anyway). Doing it this way would make the calculations at runtime faster as most of the complicated stuff would have been done during the import. I can probably get you a routine that works out the corners from the info you get from makerunways in a few days. I'll just need to find my maths hat. If this sounds like a plan I need to know exactly what data you have to work with from the makerunways program. I assume it's something like lon/lat of centre of the threshold, length, width, heading. What would also be helpful is if you could give me the four corners AND the make runways data for a few of your working airports. Then I have something to test against. Paul
  3. I don't know anything about BGL files sorry. MakeRunways seems to include runway widths. This is from the readme... Let me know if you need help modifying the routine I gave you to work with the new data (e.g. centreline + width, rather than four corners.) Paul
  4. Incase you don't already know, I have a .NET dll available for interfacing with FSUIPC. It has a number of advantages over the original SDK, for example it has support for doubles and it's object-oriented rather than procedural. Details and download in the sticky near the top of this forum. Paul
  5. Hi, I'm Paul, author of the .NET dll. I've never tested it against FSUIPC4/FSX because I don't own it but FSUIPC4 should be no different to 3 as far as the DLL is concerned. To check if there is a problem in the DLL or not, can you please try running one of my example apps provided (C# or VB.NET). They handle FS not being ready or being closed unexpectedly. See if they eventually connect if loaded before FSX, or if you shut down FSX and restart it while using the test app. If they work then the DLL is OK. Look at the source of the example apps and see if it different to what your code does. If the example apps show the same problems as your code or you need more help then let me know. Thanks, Paul
  6. Hi Graham, You need to be checking each boundry of the runway as opposed to just checking if it's in the four corners like you're doing at the moment. The main thing you need to find out is the latitudes of the edges of the runway at the plane's current longitude and vice verse. I've attached a graphic to show the maths for one boundry (NW/SW). (the lon/lat units have been simplified to make things clearer) We know the plane is at Lon 23.5E. But at what longitude is the edge of the runway at the current aircraft Latitude (24N)? To find out we use some basic trigonometry with right angled triangles... 1. We know the positions of the NW corner and SW corner. From this we can get the lengths of two sides of the triangle. (Blue numbers) 2. The ratio between these side is 10:5 = 2:1. 3. What we want to know is: How far across is the edge of the runway at 24N. ('X' on the diagram). 24N is only 6 south of from the NW latitude . This forms a smaller triangle inside the larger one. (In red) 4. The ratio of the sides of this smaller triangle will be the same at the larger one (2:1). 5. To if the long edge is 6 the short one will be 6/2 which is 3. 6. Add that distance to the NW longitude (20E) and you get the absolute longitude of where the runway starts. In this case 23E. 7. Since the aircraft is at 23.5E it's east of the west boundry and so we could be on the runway. You just do similar calculations for the other 4 boundries. If they all pass, you're on the runway. So here's a routine that will check if a point is within a quadrangle. This even works if the sides arn't parralel. It's important that you enter the corordinates of the four corners correctly or it won't work. They are labeled NW, NE, SW and SE. Just make sure your map is pointing north and it should be fairly easy to work out which is which. C# private bool AreaContainsPoint(double AreaNELat, double AreaNELon, double AreaSELat, double AreaSELon, double AreaSWLat, double AreaSWLon, double AreaNWLat, double AreaNWLon, double PointLat, double PointLon) { bool InArea = false; // Check if point is EAST of the NW/SW boundry if (PointLon > AreaNWLon + ((AreaSWLon - AreaNWLon) / (AreaNWLat - AreaSWLat) * (AreaNWLat - PointLat ))) { // Check if point is WEST of the NE/SE boundry if (PointLon < AreaNELon + ((AreaSELon - AreaNELon) / (AreaNELat - AreaSELat) * (AreaNELat- PointLat))) { // Check if point is NORTH of the SW/SE boundry if (PointLat > AreaSWLat + ((AreaSELat - AreaSWLat) / (AreaSELon - AreaSWLon) * (PointLon - AreaSWLon))) { // Check if point is South of the NW/NE boundry InArea = (PointLat < AreaNWLat + ((AreaNELat - AreaNWLat) / (AreaNELon - AreaNWLon) * (PointLon - AreaNWLon))); } } } return InArea; } VB.NET Private Function AreaContainsPoint(ByVal AreaNELat As Double, ByVal AreaNELon As Double, ByVal AreaSELat As Double, ByVal AreaSELon As Double, ByVal AreaSWLat As Double, ByVal AreaSWLon As Double, ByVal AreaNWLat As Double, ByVal AreaNWLon As Double, ByVal PointLat As Double, ByVal PointLon As Double) As Boolean Dim InArea As Boolean = False ' Check if point is EAST of the NW/SW boundry If (PointLon > AreaNWLon + ((AreaSWLon - AreaNWLon) / (AreaNWLat - AreaSWLat) * (AreaNWLat - PointLat))) Then ' Check if point is WEST of the NE/SE boundry If (PointLon < AreaNELon + ((AreaSELon - AreaNELon) / (AreaNELat - AreaSELat) * (AreaNELat - PointLat))) Then ' Check if point is NORTH of the SW/SE boundry If (PointLat > AreaSWLat + ((AreaSELat - AreaSWLat) / (AreaSELon - AreaSWLon) * (PointLon - AreaSWLon))) Then ' Check if point is South of the NW/NE boundry InArea = (PointLat < AreaNWLat + ((AreaNELat - AreaNWLat) / (AreaNELon - AreaNWLon) * (PointLon - AreaNWLon))) End If End If End If AreaContainsPoint = InArea End Function It's also worth noting that this assumes the earth is flat. That's probably not a problem with checking a small area like a runway. The larger the area you check, the more inaccurate it becomes because of the roundness of the earth. The maths to do it property taking into account the round earth is fairly complicated. Hope this works. I've started to put Lon/Lat support in the .NET client DLL. I'll put this in there as well. Can't say when I'll get time to finish it off though. Let me know how it goes... Paul
  7. Say you have: 40* 24' 36.1" 1. take the minutes and divide by 60 to convert to degrees: 24/60 = 0.4 2. take the seconds and divide by 3600 to convert to degrees: 36.1/3600 = 0.0100278 3. Add them both to the number of degrees: 40 + 0.4 + 0.0100278 = 40.4100278 so in short it's: Degrees + (Minutes / 60) + (Seconds / 3600) If the lon or lat degrees are -tve (e.g. -40* 24' 36.1") Then it's: Degrees - (Minutes / 60) - (Seconds / 3600) -40 - 0.4 - 0.0100278 = -40.4100278 I'm going to look at adding a Lon/Lat class or type into the DLL. It'll let you convert between the FS Integer format, the degrees decimal format, the degrees,minutes,seconds format and let you extract the degrees or minutes or seconds portion of the value. I'll try and get it done over Easter but I can't promise. Paul
  8. Hi Graham, 1. Take off the degrees part so you're left with only the value after the point 2. Multiply the result by 60 to convert to minutes. In .NET you can use the Math.Truncate method to get the integer portion and then subtract it leaving only the bit after the point. Here's how the whole thing looks: (This assumes a double called Lon has already been created and is holding the location in decimal degrees. What you end up with is another double which holds the number of Minutes represented by the deciimal portion of Lon). C# double lonMinutes = Math.Abs(lon - Math.Truncate(lon)) * 60d; VB.NET Dim lonMinutes As Double = Math.Abs(lon - Math.Truncate(lon)) * 60D BTW the 'Abs' method makes sure the answer is +tve. Otherwise for -tve degrees you'll end up with a -tve seconds value which probably isn't what you want. If you do, just delete "Math.Abs" - Leave the brackets in though! The same thing will work for Lat. LonMinutes now holds the number of minutes before the decimal point with the seconds represented as the part after the decimal point. That's as far as the FS display goes. You can however do the same operation on lonMinutes to get the number of seconds if you need to. I assume you need to do this for display purposes. If you are just trying to test the position of the aircraft in code I think it would be much easier just to use the raw decimal degrees that you get from FSUIPC. That way you only have to test one number and don't have to go through the conversion. If you need any more info let me know. Paul
  9. Hi Devon, I'm assuming that your app executes the Process() in a try, catch block. If FS is closed the Process() method should throw an FSUIPCException which you have to catch and then do whatever you need to. If you are doing this (as Luis above seems to be) but there's still an unhandled exception appearing from somewhere then there seems to be a problem. Can you let me know the exact exception wording (message) and its classtype. Can you also do me a quick favour? If you use C# or VB.NET can you load up one of my sample programs and see what happens when you unload FS while it's are running? It should handle it gracefully - ie, there should be a message box telling you the connection has been lost and the [connect] button should light. If you can give my any code snippits that would help too. My email address is in the documentation if you'd prefer email. Paul
  10. Hi Devon, Not a stupid question - it's simple when you know how, but if you don't know then it's not so easy! The offset for COM2 is specified as 2 bytes in the programmer’s documentation so we declare it as a 16 bit integer (ie, System.Int16, or Short in VB, or short in C#): VB: Dim com2bcd As Offset(Of Short) = New FSUIPC.Offset(Of Short)(&H3118) C#: Offset<short> com2bcd = new Offset<short>(0x3118); After processing, the value of this offset will be a number with the frequency encoded in BCD format. Each group of 4 bits out of the 16 specifies a digit in the frequency. To get this into a string representing the frequency we need to convert each group of 4 bits into a digit representing the value stored in those 4 bits. This is the same as converting a binary number into Hexadecimal format. Fortunately the .NET framework can do this for us. We use one of the overloads of the ToString method. We pass in "X" to request the number to be formatted in Hex: VB: Dim com2String As String = com2bcd.Value.ToString("X") C#: string com2String = com2bcd.Value.ToString("X"); What we now have is a four digit string where the first two are before the decimal point and the last two are after. For example if the frequency is 119.45 what we will have now is "1945". All we need to do now is put the missing 1 on the front and insert the decimal point thus: VB: com2String = "1" & com2String.Substring(0, 2) & "." & com2String.Substring(2, 2) c#: com2String = "1" + com2String.Substring(0, 2) + "." + com2String.Substring(2, 2); If you want to set a com frequency you'll need to reverse the process. The following shows using the static Parse method on the System.Int16 class to set the value of the com2bcd offset we declared. Note that you need to parse the 'interesting' four digits so you'll need to get the new frequency into that format first. VB: Dim newCom2Frequency As String = "1945" ' Set to 119.45 com2bcd.Value = Short.Parse(newCom2Frequency, Globalization.NumberStyles.AllowHexSpecifier) C#: string newCom2Frequency = "1945"; // Set to 119.45 com2bcd.Value = short.Parse(newCom2Frequency, System.Globalization.NumberStyles.AllowHexSpecifier); Hope this helps. If you need any more info just ask... Paul
  11. Hi Luis, The code you have posted looks OK to me. You've setup a Try/Catch block, so when the Process() executes and FS isn't arouond anymore the DLL should throw an error. You're catching this so there shouldn't be an unhandled exeption thrown to the debugger. You're right about the Close(), Open() at the start of your timer loop - you don't want to do that. It shouldn't be necassary. I can't really tell from your post what's going on - could you let me know: 1. Which line(s) the exception is being thrown on 2. The exact message and type of the exception(s) 3. Do you have any other methods in your application that also call Process()? Regards, Paul
  12. Hi Luis, The Lon and Lat offsets are 64 bit Integers which are called Long in C# and VB. (The underlying class is System.Int64 if you are using a different language). So the declaration of the offsets would be: C# private Offset<long> latFS = new Offset<long>(0x0560); private Offset<long> lonFS = new Offset<long>(0x0568); VB.NET Private latFS As Offset(Of Long) = New FSUIPC.Offset(Of Long)(&H560) Private lonFS As Offset(Of Long) = New FSUIPC.Offset(Of Long)(&H568) I've called them LonFS and LatFS because they return Lon and Lat in FS internal units. After calling Process() you can transform the FS Units into degrees with the following lines (as described in the FSUIPC Documentation) and you end up with a Double floating point type that holds the Lon/Lat as degress. C# // Convert Lat and Lon from FS Units into degrees (as a double), double lat = (double)latFS.Value * 90d / (10001750d * 65536d * 65536d); double lon = (double)lonFS.Value * 360d / (65536d * 65536d * 65536d * 65536d); . VB.NET ' Convert Lat and Lon from FS Units into degrees (as a double). Dim lat As Double = latFS.Value * 90D / (10001750D * 65536D * 65536D) Dim lon As Double = lonFS.Value * 360D / (65536D * 65536D * 65536D * 65536D) Paul
  13. VB2005 Express is Visual Basic.NET. It's a different language to VB6 but the syntax is similar. I recommend you have a look at my DLL that lets .NET languages talk to FSUIPC. It's in a sticky near the top of this forum. (Subject is: FSUIPC Client DLL for .NET - Release Version 1.1). You may find it easier to use than the current VB.NET SDK. It has an example application (and documentation) in VB.NET to show you how to use it. If you need any more help than the documentation provides feel free to email me. Paul
  14. Thanks Matt, Please make sure you've got the 1.1 version from the sticky at the top of the forum. The 1.0 version has a bug with the writes to FSUIPC. Paul
  15. The new dll (1.1) is now on the sticky post near the top of the forum. Paul
  16. There's two issues here - one is a bug in the DLL which I will fix tomorrow: When you do a write it continues to write on every process after that. I think this was intruduced in the last update. The other issue is that you're adding the two offsets into the default group by not specifying a group name. I'm guessing you have another loop somewhere that's also calling Process(). When you do that it'll write the message and delay offset again. You can fix your code (even with the broken DLL) by adding these offsets to a seperate group. Another thing you need to do is disconnet the group before these offsets go out of scope at the end of the function. As it stands at the moment you can only run this function once. The second time it will throw an error because you're trying to re-register the offsets Below is a new version which will fix it. The user guide describes the group and scope concepts in more detail. If you need any more explaination let me know. (BTW, I can't see any need for the WriteText bits. Just do FSWriteMessage.Value = Message) Public Function ShowFSMessage(ByVal Message As String, ByVal Delay As Integer) Dim FSWriteMessage As Offset(Of String) = New FSUIPC.Offset(Of String)("Message",&H3380, 127) Dim DelayMessage As Offset(Of Integer) = New FSUIPC.Offset(Of Integer)("Message",&H32FA) Dim WriteText As String WriteText = Message WriteText = WriteText FSWriteMessage.Value = WriteText DelayMessage.Value = Delay FSUIPC.FSUIPCConnection.Process("Message") FSUIPC.FSUIPCConnection.DisconnectGroup("Message") Return 0 End Function Hope this helps. Look out for the update tomorrow. Paul
  17. The release version can be found in the stickied post at the top of this forum: http://forums.simflight.com/viewtopic.php?t=53255 Paul
  18. VB has always supported 16-bit integers - they are called 'Integer'. 32-bit integers are called 'Long' in VB. 64-bit integers are not supported. VB6 does not support unsigned 16-bit or 32-bit integers. The 8-bit integer (Byte) is treated as unsigned. VB.NET 2003 added 64-Bit integers and changed the integer naming to the more usual: 16-Bit = Short 32-Bit = Integer 64-Bit = Long VB.NET 2005 finally added support for unsigned Integers: UShort, UInteger and ULong. Paul
  19. It's correct. It's about -20 degrees from north, which is another way of saying 340 which is what you were looking for. To translate your -20 into 340 just add 360. When you're working with headings this happen alot, sometimes you get negative headings, sometimes over they go over 360. As JD says, you just need to write a function to normalise them. He posted one eariler in this thread, about 12 messages up. It's called norm360. You need to call that everytime you do maths on a heading and you want it in conventional 0-360 notation. Paul
  20. Is the difference not due to magnetic variation? 0x0580 is a True heading, while the whisky compass, the gyro compass and the Autopilot heading at 0x07CC are all Magnetic headings. The current Magnetic Variation is at offset 0x02A0. If it's 20 degrees then your 0.312 is probably correct. Paul
  21. Version 2.0 is now out of date. Please get the latest version that is pinned at the top of this subforum. Thanks. Paul
  22. Hi Joao, Your code looks like it will work (except you need to change the res = r(i) to res = r(1) ) However, it's a bit more compilcated than it need be - you don't need to use an array of doubles: This should be all you need to do, but I don't have VB6 on my machine anymore so I can't test it: ------------------------------------------------------------------------ Private Function Read_Value(v As Long, n As Long) As Double Dim dwResult As Long Dim res As Double If FSUIPC_Read(v, n, VarPtr(res), dwResult) Then If FSUIPC_Process(dwResult) Then Read_Value = res Else ' Can't process End If Else ' Can't read End If End Function ------------------------------------------------------------------------ Give that a try. If it doesn't work I'm sure a proper VB6 programmer will stop by and help you out. :-) Paul
  23. You need to say what programmng languge you are using to get specific help for how to handle them in that specific language. However, in general you need to cast the 8-byte value directly to a 64 bit floating point type, (it's not an an 8byte Integer). The name of this type varies from language to language, as does the method of casting. In many languages the type you need is called a 'Double. Paul
  24. :-) I did volunteer back in February but I didn't do it because a guy called Pelle was already doing one. I'll have another look at it though. Paul
  25. Out of interest - Is this a wrapper around the VB.Net code that's in the SDK at the moment, or have you written the whole thing from scratch? Thanks, Paul
×
×
  • 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.