Jump to content
The simFlight Network Forums

getting FLOAT64 from C sharp


Recommended Posts

It depends how you are talking to FSUIPC. I suspect you are using the C# SDK from the official FSUIPC SDK download. That doesn't support Float64s which is one of the reasons I wrote my FSUIPC Client DLL for .NET programmers.

You can read about it and download it in the sticky posting above:

http://forums.simflight.com/viewtopic.php?f=54&t=53255

If you're too far down the road of development to switch all your code then let me know and I'll see if I can provide you with a workaround for the original SDK or add float64 support to it.

I'll need to spend a bit of time on though so I'd prefer it if you use my DLL if at all possible.

Paul

Link to comment
Share on other sites

  • 2 years later...

Wooooooow!!!!

Man I am disapointed!!! :(

I have been working on a piece of software for some time. A lot has been developed and let to the end the reading of float64 values. Now that I am working on solving this last milestone, I find this topic, I find that I can't handle these values. Man, you can't imagine the words that came out of my mouth. Pfffffff...

What can I do now? Start all over again and use phenty's DLL. That's an idea but I am really not into that, unless as a last resource.

Phenty, can you help me? Privode some code or pseudo-code so I can resume my work? Thank you anyway.

Best regards to all,

LOMBA, Emmanuel.

Link to comment
Share on other sites

Phenty, can you help me? Privode some code or pseudo-code so I can resume my work? Thank you anyway.

Sure, just add these 4 methods to the Fsuipc class in the fsuipc.cs file. They will add read and write support for FLOAT64 ('double' in C#) and FLOAT32 ('float' in C#). You can use these just as you do for int, long, short etc.

_get method for double (FLOAT64):

        ///<summary>Retrieve data read from FSUIPC using token passed during read request</summary>
        ///<param name="token">The unique identifier token returned from the Read call</param>
        ///<param name="result">Contains the "error-code" if method's boolean comes back false</param>
        ///<return>true if successful, false otherwise.  If false, dwResult contains the "error-code"</return>
        public bool FSUIPC_Get(ref int Token, ref double Result)
        {
            int dwSize = 8;
            byte[] getBuffer = new byte[dwSize];
            if ((Token < 0) || (Token > IPC_BUFFER_SIZE - (4 + dwSize)))
            { //Token out of range
                return false;
            }
            IntPtr heapbuf = Marshal.AllocHGlobal(4);
            Marshal.Copy(IPC, Token, heapbuf, 4);
            int Size = Marshal.ReadInt32(heapbuf);
            Marshal.FreeHGlobal(heapbuf);
            if (dwSize > Size)
            {
                dwSize = Size;    //Max size of return block is size of block written
            }
            int idx = Token + 4;    //go past size block
            while (idx < Token + 4 + dwSize)
            {
                getBuffer[idx - Token - 4] = IPC[idx];
                idx = idx + 1;
            }
            if (IPCdr[Token])
            {
                Result = BitConverter.ToDouble(getBuffer, 0);
                IPCdr[Token] = false;
                return true;
            }
            else
            {    // if (data ready flag not set, function returns false and value found
                return false;
            }
        }

_get method for float (FLOAT32):

        ///<summary>Retrieve data read from FSUIPC using token passed during read request</summary>
        ///<param name="token">The unique identifier token returned from the Read call</param>
        ///<param name="result">Contains the "error-code" if method's boolean comes back false</param>
        ///<return>true if successful, false otherwise.  If false, dwResult contains the "error-code"</return>
        public bool FSUIPC_Get(ref int Token, ref float Result)
        {
            int dwSize = 4;
            byte[] getBuffer = new byte[dwSize];
            if ((Token < 0) || (Token > IPC_BUFFER_SIZE - (4 + dwSize)))
            { //Token out of range
                return false;
            }
            IntPtr heapbuf = Marshal.AllocHGlobal(4);
            Marshal.Copy(IPC, Token, heapbuf, 4);
            int Size = Marshal.ReadInt32(heapbuf);
            Marshal.FreeHGlobal(heapbuf);
            if (dwSize > Size)
            {
                dwSize = Size;    //Max size of return block is size of block written
            }
            int idx = Token + 4;    //go past size block
            while (idx < Token + 4 + dwSize)
            {
                getBuffer[idx - Token - 4] = IPC[idx];
                idx = idx + 1;
            }
            if (IPCdr[Token])
            {
                Result = BitConverter.ToSingle(getBuffer, 0);
                IPCdr[Token] = false;
                return true;
            }
            else
            {    // if (data ready flag not set, function returns false and value found
                return false;
            }
        }

_write method for double (FLOAT64)

        ///<summary>Submits a write request</summary>
        ///<param name="dwOffset">The memory offset where the referenced value is located</param>
        ///<param name="param">The value to be written</param>
        ///<param name="token">Contains the unique identifier token used to Get the value</param>
        ///<param name="dwResult">Contains the "error-code" if method's boolean comes back false</param>
        ///<return>true if successful, false otherwise.  If false, dwResult contains the "error-code"</return>
        public bool FSUIPC_Write(int dwOffset, double param, ref int Token, ref int dwResult)
        {
            int dwSize = 8;
            byte[] writeBuffer = new byte[dwSize];
            writeBuffer = BitConverter.GetBytes(param);
            if ((IPCAlloc + dwSize + 4) >= (IPC_BUFFER_SIZE - 1))
            {  //Reset ptr to startbuf
                IPCAlloc = 0;
            }
            // Assign Token as index into IPC Buffer FifO, and clear data ready flags
            Token = IPCAlloc;
            int i;
            for (i = IPCAlloc; i < (IPCAlloc + 4 + dwSize - 1); i++)
            { // 4=size of int datablock size hdr
                IPC[i] = 0;
                IPCdr[i] = false;
            }
            IPCAlloc = IPCAlloc + 4 + dwSize;    //first four bytes data block size (Int) plus data
            IntPtr heapbuf = Marshal.AllocHGlobal(4);
            Marshal.WriteInt32(heapbuf, dwSize);      // Translate size Int32 to unmanaged byte stream
            Marshal.Copy(heapbuf, IPC, Token, 4);     // Write size header to IPC array
            Marshal.FreeHGlobal(heapbuf);
            for (i = 0; i < dwSize; i++)
            {
                IPC[Token + 4 + i] = writeBuffer[i];       //xfer byte array to IPC managed FifO buffer
            }
            return FSUIPC_Write_Req(dwOffset, dwSize, Token, ref dwResult);
        }

_write method for float (FLOAT32)

        ///<summary>Submits a write request</summary>
        ///<param name="dwOffset">The memory offset where the referenced value is located</param>
        ///<param name="param">The value to be written</param>
        ///<param name="token">Contains the unique identifier token used to Get the value</param>
        ///<param name="dwResult">Contains the "error-code" if method's boolean comes back false</param>
        ///<return>true if successful, false otherwise.  If false, dwResult contains the "error-code"</return>
        public bool FSUIPC_Write(int dwOffset, float param, ref int Token, ref int dwResult)
        {
            int dwSize = 4;
            byte[] writeBuffer = new byte[dwSize];
            writeBuffer = BitConverter.GetBytes(param);
            if ((IPCAlloc + dwSize + 4) >= (IPC_BUFFER_SIZE - 1))
            {  //Reset ptr to startbuf
                IPCAlloc = 0;
            }
            // Assign Token as index into IPC Buffer FifO, and clear data ready flags
            Token = IPCAlloc;
            int i;
            for (i = IPCAlloc; i < (IPCAlloc + 4 + dwSize - 1); i++)
            { // 4=size of int datablock size hdr
                IPC[i] = 0;
                IPCdr[i] = false;
            }
            IPCAlloc = IPCAlloc + 4 + dwSize;    //first four bytes data block size (Int) plus data
            IntPtr heapbuf = Marshal.AllocHGlobal(4);
            Marshal.WriteInt32(heapbuf, dwSize);      // Translate size Int32 to unmanaged byte stream
            Marshal.Copy(heapbuf, IPC, Token, 4);     // Write size header to IPC array
            Marshal.FreeHGlobal(heapbuf);
            for (i = 0; i < dwSize; i++)
            {
                IPC[Token + 4 + i] = writeBuffer[i];       //xfer byte array to IPC managed FifO buffer
            }
            return FSUIPC_Write_Req(dwOffset, dwSize, Token, ref dwResult);
        }

Let me know if you need any help using them or they don't work as expected.

Paul

Link to comment
Share on other sites

Hello Paul,

many many thanks for your help.

I copied the four methods you provided in your last post, recompiled the code, but unfortunately nothing changed.

So far, for testing purposes, I am trying to read the cowl flaps lever position value as follows (please take a look):

//Global variables
double cowl_flaps = 0.0;

(...)

//cowl flaps
result = fsuipc.FSUIPC_Read(0x37F0, 8, ref token, ref dwResult);
result = fsuipc.FSUIPC_Process(ref dwResult);
result = fsuipc.FSUIPC_Get(ref token, ref dwResult);
cowl_flaps = dwResult;
textBox4.Text = cowl_flaps.ToString();

This value should be between 0.0 and 1.0 (fully open and fully closed, respectively). However I always get a signed integer.

For example, when in FSInterrogate I get 0,78, in my textbox I get -1889785610.

What am I missing or doing wrong? Thank you very much for your help!!!

Best regards,

LOMBA, Emmanuel.

Link to comment
Share on other sites

What am I missing or doing wrong? Thank you very much for your help!!!

When you use the fsuipc_get() method, the 'result' parameter must be the same type as the data stored in the FSUIPC offset. In this case the data is stored as a FLOAT64, so you need to pass a double variable (cowl_flaps) as the 'result' (not dwResult which I suspect is an int or long).

So your code should be this:

//Global variables
double cowl_flaps = 0.0;

(...)

//cowl flaps
result = fsuipc.FSUIPC_Read(0x37F0, 8, ref token, ref dwResult);
result = fsuipc.FSUIPC_Process(ref dwResult);
result = fsuipc.FSUIPC_Get(ref token, ref cowl_flaps);
textBox4.Text = cowl_flaps.ToString();

Paul

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • 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.