xpnteam / xpnet

Develop X-Plane plugins in .NET.
MIT License
50 stars 15 forks source link

Double Datarefs not having expected values #23

Closed bergziege closed 4 years ago

bergziege commented 5 years ago

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).

jaurenq commented 5 years ago

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.

bergziege commented 5 years ago

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.

bergziege commented 5 years ago

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.

jaurenq commented 4 years ago

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().