xpnteam/xpnet

Double Datarefs not having expected values

Closed this issue · 4 comments

HI, I just wrote a small test addin to log some positional stuff as follow:

    private Timer _timer = new Timer(1000);

    public Plugin(IXPlaneApi api)
    {
        _api = api ?? throw new ArgumentNullException(nameof(api));
        _timer.Elapsed += _timer_Elapsed;
        _timer.Start();
    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        _timer.Stop();
        try
        {
            IXPDataRef<string> tailNumber = _api.Data.GetString("sim/aircraft/view/acf_tailnum");
            IXPDataRef<double> elevationInMeters = _api.Data.GetDouble("sim/flightmodel/position/elevation");
            IXPDataRef<double> latitude = _api.Data.GetDouble("sim/flightmodel/position/latitude");
            IXPDataRef<double> longitude = _api.Data.GetDouble("sim/flightmodel/position/longitude");

            _api.Log.Log($"{tailNumber.Value} - {latitude.Value} - {longitude.Value} - {elevationInMeters.Value}");
        }
        catch (Exception ex)
        {
            _api.Log.Log(ex.Message);
        }

        _timer.Start();
    }

What I get is:

[08:34:01 ] N172SP - -0,105085954070091 - -1,32609446261682E-34 - -2,98653034477598E+28

What I Expected:

[08:34:01 ] N172SP - 13.xxx - 51.xxxx - 160.xxx

Do I have to convert the double values in some way to get the correct values?

Using X-Plane 11.31 and xpnet 0.1.5 (NUGet).

No conversion should be necessary. Do you have a way to verify that the datarefs have the value that you expect inside X-Plane? You can set X-Plane to show some DataRefs on-screen in the top-left corner of the screen for reference, or you can install something like this (https://developer.x-plane.com/tools/datarefeditor/) that will let you check that the DataRefs have the value you expect in X-Plane. If the values look right in the X-Plane UI and still don't look right inside your plugin, then we've probably got a bug to address here.

Ill check that as soon as I am getting home.
Reading my posted code again I had the idea that it may be a threading issue as _timer_elapsed is called from the timer thread. not from the x-plane thread.

Hi again, just made a test run without success.

The timer I used in the code above was from using System.Timers;. Not from the threading namespace.

The code I hacked together for todays test with some other "timer" implementation:

using System;
using System.Threading;
using System.Threading.Tasks;
using XPNet;

namespace PositionLogger
{
    [XPlanePlugin(
        name: "My Plugin",
        signature: "you.plugins.name",
        description: "Describe your plugin here."
    )]
    public class Plugin : IXPlanePlugin
    {
        private readonly IXPlaneApi _api;

        public Plugin(IXPlaneApi api)
        {
            _api = api ?? throw new ArgumentNullException(nameof(api));
        }

        public void Dispose()
        {
            // Clean up whatever we attached / registered for / etc.
        }

        public void Enable()
        {
            // Called when the plugin is enabled in X-Plane.

            // Replace this with your own initialization code.
            _api.Log.Log($"PositionLogger initializing on thread {Thread.CurrentThread.GetHashCode()}");
            DoLoop();
            _api.Messages.LiveryLoaded += Messages_LiveryLoaded;
        }

        private void Messages_LiveryLoaded(object sender, XPPlaneMessageEventArgs e)
        {
            _api.Log.Log($"PlaneNUmber: {e.PlaneNumber}");
        }

        private async Task DoLoop()
        {
            while (true)
            {
                try
                {
                    _api.Log.Log($"Query Dataref from thread {Thread.CurrentThread.GetHashCode()}");
                    IXPDataRef<string> tailNumber = _api.Data.GetString("sim/aircraft/view/acf_tailnum");
                    IXPDataRef<double> elevationInMeters = _api.Data.GetDouble("sim/flightmodel/position/elevation");
                    IXPDataRef<double> latitude = _api.Data.GetDouble("sim/flightmodel/position/latitude");
                    IXPDataRef<double> longitude = _api.Data.GetDouble("sim/flightmodel/position/longitude");

                    _api.Log.Log($"{tailNumber.Value} - {latitude.Value} - {longitude.Value} - {elevationInMeters.Value}");
                    await Task.Delay(10000);
                }
                catch (Exception ex)
                {
                    _api.Log.Log(ex.Message);
                }
            }
        }

        public void Disable()
        {
            // Called when the plugin is disabled in X-Plane.
        }        
    }
}

Wich gave me the following logfile:

**********
[14.02.2019 21:42:34] Logging Started
[09:42:34 ] XPNet CLR: Start
[09:42:34 ] XPNet CLR: Looking for plugin in (C:\XPlane\11\Resources\plugins\PotitionLogger).
[09:42:34 ] XPNet CLR: Inspecting plugin candidate: (Path = C:\XPlane\11\Resources\plugins\PotitionLogger\PositionLogger.dll).
[09:42:35 ] XPNet CLR: Enable
[09:42:35 ] PositionLogger initializing on thread 1
[09:42:35 ] Query Dataref from thread 1
[09:42:35 ]                                          - 0 - 0 - 0
[09:42:45 ] Query Dataref from thread 6
[09:42:45 ]                                          - 0 - 0 - 0
[09:42:55 ] Query Dataref from thread 7
[09:42:55 ]                                          - 0 - 0 - 0
[09:43:05 ] Query Dataref from thread 7
[09:43:05 ] N172SP                                   - 0 - 0 - 0
[09:43:06 ] PlaneNUmber: 0
[09:43:15 ] Query Dataref from thread 7
[09:43:15 ] N172SP                                   - -1,9006372148731E-25 - 0 - -3,18323145620525E-11
[09:43:25 ] Query Dataref from thread 7
[09:43:25 ] N172SP                                   - 0,221749976277351 - -9,86076131526265E-32 - -3,18323145620525E-11
[09:43:35 ] Query Dataref from thread 7
[09:43:35 ] N172SP                                   - 0,221749976277351 - -9,86076131526265E-32 - -3,18323145620525E-11
[09:43:45 ] Query Dataref from thread 7
[09:43:45 ] N172SP                                   - 0,221749976277351 - -9,86076131526265E-32 - -3,18323145620525E-11
[09:43:55 ] Query Dataref from thread 7
[09:43:55 ] N172SP                                   - 0,221749976277351 - -9,86076131526265E-32 - -3,18323145620525E-11
[09:44:05 ] Query Dataref from thread 7
[09:44:05 ] N172SP                                   - 0,221749976277351 - -9,86076131526265E-32 - -3,18323145620525E-11
[09:44:15 ] Query Dataref from thread 7
[09:44:15 ] N172SP                                   - 0,221749976277351 - -9,86076131526265E-32 - -3,18323145620525E-11
[09:44:25 ] Query Dataref from thread 7
[09:44:25 ] N172SP                                   - 5,33872868658094E-20 - 4,64823374235479E-10 - -6,8473414821928E+34
[09:44:35 ] Query Dataref from thread 7
[09:44:35 ] N172SP                                   - 5,36269010559856E-20 - 4,64823374235479E-10 - -5,16633537424215E+35
[09:44:45 ] Query Dataref from thread 7
[09:44:45 ] N172SP                                   - 6,00459777057619E-20 - 4,64823374235479E-10 - -4,17979897112054E+35
[09:44:55 ] Query Dataref from thread 7
[09:44:55 ] N172SP                                   - 6,00461586515209E-20 - 4,64823374235479E-10 - -4,02403006536449E+35
[09:45:05 ] Query Dataref from thread 7
[09:45:05 ] N172SP                                   - 6,00457450612147E-20 - 4,64823374235479E-10 - -3,73845373814508E+35
[09:45:15 ] Query Dataref from thread 7
[09:45:15 ] N172SP                                   - 6,00458872328824E-20 - 4,64823374235479E-10 - -3,76441522243775E+35
[09:45:25 ] Query Dataref from thread 7
[09:45:25 ] N172SP                                   - 6,00457838353059E-20 - 4,64823374235479E-10 - -3,97210709677914E+35
[09:45:35 ] Query Dataref from thread 7
[09:45:35 ] N172SP                                   - 6,00458549211398E-20 - 4,64823374235479E-10 - -3,86826115960845E+35
[09:45:45 ] Query Dataref from thread 7
[09:45:45 ] N172SP                                   - 6,0045893695231E-20 - 4,64823374235479E-10 - -3,66056928526705E+35
[09:45:55 ] Query Dataref from thread 7
[09:45:55 ] N172SP                                   - 6,00458226093971E-20 - 4,64823374235479E-10 - -3,7124922538524E+35
[09:46:05 ] Query Dataref from thread 7
[09:46:05 ] N172SP                                   - 6,00457579859117E-20 - 4,64823374235479E-10 - -3,8163381910231E+35
[09:46:15 ] Query Dataref from thread 7
[09:46:15 ] N172SP                                   - 6,00459970928075E-20 - 4,64823374235479E-10 - -3,68653076955973E+35
[09:46:25 ] Query Dataref from thread 6
[09:46:25 ] N172SP                                   - 6,00457838353059E-20 - 4,64823374235479E-10 - -3,73845373814508E+35
[09:46:35 ] Query Dataref from thread 7
[09:46:35 ] N172SP                                   - 6,00460423292473E-20 - 4,64823374235479E-10 - -3,86826115960845E+35
[09:46:45 ] Query Dataref from thread 7
[09:46:45 ] N172SP                                   - 6,00460164798532E-20 - 4,64823374235479E-10 - -3,84229967531577E+35
[09:46:55 ] Query Dataref from thread 7
[09:46:55 ]                                          - 6,00467273381921E-20 - 4,64823374235479E-10 - -3,63460780097438E+35
[09:46:56 ] XPNet CLR: Disable
[09:46:57 ] XPNet CLR: Stop

And a screen confirming the right data values:

cessna_172sp_2

So I am still thinking that it could be a threading issue. But as far as I read there is no Dispatcher or DispatchTimer in .net core to invoke stuff on the "main" thread.

How would you do a timer of any kind without threading? I hoped at least await Task.Delay() would send me back to the original thread after waiting. But does not seems so.

bergziege, your last question here last year slipped through the cracks. I'm going through closing old issues. Did you ever resolve this? Regarding the last thing you asked: you can't set your own thread-based timer in a plugin and make calls into X-Plane - X-Plane must only be called from the thread that it creates the Plugin on. Trying to read datarefs or make other calls back into X-Plane from other threads might crash the sim and might give you invalid data values, just as you're seeing. To do a timer, you have to let X-Plane do it for you. In XPNet you can do that with IXPlaneApi.Processing.RegisterFlightLoopHook().