Jump to content
The simFlight Network Forums

Recommended Posts

Posted

HI:

 

I´m programming my own tracker in CSharp, I managed to get few offsets working. The problem is that I want to track in real time, and that doesn´t happen. I heard that using a time you can, but I don´t have any idea on how to use it.

 

I left here my code:

using MetroFramework.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using FSUIPC;
 

namespace TAG_ACARS
{
    public partial class Form1 : MetroForm
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void metroLabel5_Click(object sender, EventArgs e)
        {

        }

        private void metroButton1_Click(object sender, EventArgs e)
        {
            try { // Attempt to open a connection to FSUIPC (running on any version of Flight Sim) 
                FSUIPCConnection.Open(); 
                // Opened OK 
            } 
            catch (Exception ex) 
            { 
                // Badness occurred - show the error message 
                MessageBox.Show(ex.Message, AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }
    
public  string AppTitle { get; set; }
        

private void metroButton2_Click(object sender, EventArgs e)
{
    FSUIPCConnection.Close();
}
        
private void textBox1_TextChanged(object sender, EventArgs e)
{
    Offset<int> airspeed = new Offset<int>(0x02BC);
       FSUIPCConnection.Process(); 
    double airpeedKnots = (double)airspeed.Value / 128d;
    this.textBox1.Text = airpeedKnots.ToString("f0");
    timer1.Enabled = true;
    
}

private void metroButton3_Click(object sender, EventArgs e)
{
    axWindowsMediaPlayer2.URL = "http://63.243.149.5/LOS40CMP3";
}

private void axWindowsMediaPlayer2_Enter(object sender, EventArgs e)
{

}

private void metroButton4_Click(object sender, EventArgs e)
{

}

private void metroButton6_Click(object sender, EventArgs e)
{
   
}

private void textBox5_TextChanged(object sender, EventArgs e)
{
    Offset<int> GroundSpeed = new Offset<int>(0x02B4);
    FSUIPCConnection.Process();
    double GroundSpeedKnots = (double)GroundSpeed.Value / 65536d;
    this.textBox5.Text = GroundSpeedKnots.ToString("f0");
}

private void textBox3_TextChanged(object sender, EventArgs e)
{
    Offset<double> agl = new Offset<double>(0x0020);
string altitude = agl.Value.ToString();
}

private void textBox11_TextChanged(object sender, EventArgs e)
{
    Offset<int> Flapscontrol = new Offset<int>(0x0BDC);
    

}

private void textBox7_TextChanged_1(object sender, EventArgs e)
{

}

private void textBox12_TextChanged(object sender, EventArgs e)
{
    Offset<int> ZeroFuelWeight = new Offset<int>(0x3BFC);
    FSUIPCConnection.Process();
    double ZeroFuelWeightlbs = (double)ZeroFuelWeight.Value / 256;
    this.textBox12.Text = ZeroFuelWeightlbs.ToString("f0");

}

private void textBox2_TextChanged(object sender, EventArgs e)
{
     Offset<int> verticalSpeed = new Offset<int>(0x02C8);
    double verticalSpeed_FeetPerMinute = (double)verticalSpeed.Value * 60d * 3.28084d / 256d;
    this.textBox2.Text = verticalSpeed_FeetPerMinute.ToString("");
}

private void textBox4_TextChanged(object sender, EventArgs e)
{
    Offset<int> gearPositionNose = new Offset<int>(0x0BEC);

    if (gearPositionNose.Value == 0)
    {
        this.textBox4.Text = "Gear Up";
    }
    else if (gearPositionNose.Value == 16383)
    {
        this.textBox4.Text = "Gear Down";
    }
    else
    {
        this.textBox4.Text = "Gear In Transit";
    }
}
}
} 
Posted

There is an example application in the main download package that has real-time updates.

 

If you haven't got this please download it from the following link. The zip also contains a user manual.

 

http://forum.simflight.com/topic/74848-fsuipc-client-dll-for-net-version-24/

 

 

About your code:

 

1. You must declare all the offsets at the class (form) level. Not in methods. Every time you declare an offset you are making a new copy of it. Eventually your program will run out of FSUIPC memory space.

 

2. To get realtime updates you need to do the following:

 

2.1 Drag a timer onto your form. (For the examples we assume it's called 'timer1'

 

2.2 Set the timer running after you open the connection to FSUIPC. Stop the timer before you close the connection.

 

2.3 In the form designer, go to the timer and create an event method for the 'Tick' event.

 

This 'tick' method will run at the specified Interval.

 

In this method you need to process() the offsets and then update your text boxes.

 

The whole thing should be something like this:

public partial class Form1 : MetroForm
        public string AppTitle { get; set; }

        private Offset<int> airspeed = new Offset<int>(0x02BC);
        private Offset<int> GroundSpeed = new Offset<int>(0x02B4);
        private Offset<int> ZeroFuelWeight = new Offset<int>(0x3BFC);
        private Offset<int> verticalSpeed = new Offset<int>(0x02C8);
        private Offset<int> gearPositionNose = new Offset<int>(0x0BEC);
        private Offset<int> Flapscontrol = new Offset<int>(0x0BDC);
        private Offset<double> agl = new Offset<double>(0x0020);

        public Form1()
        {
            InitializeComponent();
        }

        private void metroButton1_Click(object sender, EventArgs e)
        {
            try
            { // Attempt to open a connection to FSUIPC (running on any version of Flight Sim)
                FSUIPCConnection.Open();
                // start the timer
                timer1.Interval = 250; // in milliseconds (i.e. 4 times per second.) Adjust for your needs.
                timer1.Start();
                // Opened OK
            }
            catch (Exception ex)
            {
                // Badness occurred - show the error message
                MessageBox.Show(ex.Message, AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void metroButton2_Click(object sender, EventArgs e)
        {
            // stop the timer
            timer1.Stop();
            FSUIPCConnection.Close();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // get data from FSUIPC
            FSUIPCConnection.Process();
            // show data in the text boxes
            // Airspeed
            double airpeedKnots = (double)airspeed.Value / 128d;
            this.textBox1.Text = airpeedKnots.ToString("f0");
            // Ground speed
            double GroundSpeedKnots = (double)GroundSpeed.Value / 65536d;
            this.textBox5.Text = GroundSpeedKnots.ToString("f0");
            // altitude
            string altitude = agl.Value.ToString();
            // ZFW
            double ZeroFuelWeightlbs = (double)ZeroFuelWeight.Value / 256;
            this.textBox12.Text = ZeroFuelWeightlbs.ToString("f0");
            // VS
            double verticalSpeed_FeetPerMinute = (double)verticalSpeed.Value * 60d * 3.28084d / 256d;
            this.textBox2.Text = verticalSpeed_FeetPerMinute.ToString("");
            // Gear
            if (gearPositionNose.Value == 0)
            {
                this.textBox4.Text = "Gear Up";
            }
            else if (gearPositionNose.Value == 16383)
            {
                this.textBox4.Text = "Gear Down";
            }
            else
            {
                this.textBox4.Text = "Gear In Transit";
            }
        }
}

Paul

 

 

Posted

Thank you very much Paul!! You made my day. Tried it and worked!! Currently I´m adding some other offsets that I need and it´s working. When I´m done with that I will use a JSON to send data to my webpage. Thanks for all, now it´s all clear with the timer!!

Posted

I am having some problems now with making an events section, where flaps movement, pauses of the sim, slew mode, crashes, flaps, gear.... Remain logged to make sure the validator can sees it. And also a critical events section where things like overspeed, incorrect use of flaps remain logged too. But I can´t do that. I need some help...

 

 

Regards!

Posted

To log events when offsets change you need to keep a copy of the previous values. Then test against the current values. If they are different you can write the new value to the log. After every 'tick' you must update the last values with the current values.

 

Below is some code that shows logging 'pause/un-pause' and when the gear is put up and down.

 

1. Create variables to store the last values. These can be the same type as the raw 'value' of the offset (that's what I've used), or they could be the real-world values after conversion. These are at the form/class level, the same as the offsets.

        private Offset<ushort> pause = new Offset<ushort>(0x0264);
        private Offset<int> gearPositionNose = new Offset<int>(0x0BEC);

        private ushort lastPause;
        private int lastGearPositionNose;

2. Create a method to set these values from the current values of the offsets:

        private void setLastValues()
        {
            this.lastGearPositionNose = this.gearPositionNose.Value;
            this.lastPause = this.pause.Value;
        }

3. Call this method after open to set the initial values:

            try
            { // Attempt to open a connection to FSUIPC (running on any version of Flight Sim)
                FSUIPCConnection.Open();
                // Opened OK
                FSUIPCConnection.Process();
                setLastValues();
                // start the timer
                timer1.Interval = 250;
                timer1.Start();
            }
            catch (Exception ex)
            {
                // Badness occurred - show the error message
                MessageBox.Show(ex.Message, AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

4. In the TIck, test the current values of the relevant offsets and log if they are changed. Finally call the method to update the last values with the current ones (ready for the next tick).

        private void timer1_Tick(object sender, EventArgs e)
        {
            // Pause
            // If pause changed write it to the log
            FSUIPCConnection.Process();
            if (this.pause.Value != this.lastPause)
            {
                log("Sim was " + (pause.Value == 1 ? "PAUSED" : "UN-PAUSED"));
            }
            // Gear
            if (gearPositionNose.Value == 0)
            {
                this.textBox4.Text = "Gear Up";
                if (this.lastGearPositionNose != 0)
                {
                    log("Gear UP");
                }
            }
            else if (gearPositionNose.Value == 16383)
            {
                this.textBox4.Text = "Gear Down";
                if (this.lastGearPositionNose != 16383)
                {
                    log("Gear DOWN");
                }
            }
            else
            {
                this.textBox4.Text = "Gear In Transit";
            }
            setLastValues();
        }

5. For this demonstration, my 'log' method just adds an item to a ListBox on the form.

        private void log(string message)
        {
            string logLine = DateTime.Now.ToString() + ": " + message;
            this.listBox1.Items.Add(logLine);
        }

Paul

 

 

 

  • Upvote 1
Posted

Just one last time, guys, before you kill me ;) ;) ;)

 

How can I manage to make my tracker, give a value of your flight starting with 100% and with some penalties subtract from the inical 100%. I mean if you forgot to turn on landing lights on APP, subtract -10% from your initial score of 100%

 

Thx!! And I promised this will be my last question!!

Posted

How can I manage to make my tracker, give a value of your flight starting with 100% and with some penalties subtract from the inical 100%. I mean if you forgot to turn on landing lights on APP, subtract -10% from your initial score of 100%

 

 

 

Which part of this specifically are you having a problem with? Your description above seems to describe exactly how to do this.

 

Paul

Posted

Well, yes. Our president asked me to add that functionallity to the tracker. But tbh I've never programmed scores... so i would need help with that.

Posted

Here is how I would approach this:

 

1. Create a class to hold score items. These are going to be all the things you want to check for that calculate the overall score. I suggest you put this at the form/class level (at the same level as the offsets declarations). However, if you prefer you can put this in it's own class file and make it public.

        private class scoreItem
        {
            public string description;
            public int scoreValue;
            public bool failed = false;

            public scoreItem(string Description, int ScoreValue)
            {
                this.description = Description;
                this.scoreValue = ScoreValue;
            }
        }

2. Declare the offsets you need for the scoring. For this example you'll need these offsets: (To use the BitArray you may need to add 'using using System.Collections;' at the top of the form.

        private Offset<ushort> onGround = new Offset<ushort>(0x0366);
        private Offset<int> ias = new Offset<int>(0x02BC);
        private Offset<BitArray> lights = new Offset<BitArray>(0x0D0C, 2);
        private Offset<ushort> pause = new Offset<ushort>(0x0264);

3. Create a dictionary to hold all the scores. (Under the offsets).

        private Dictionary<string, scoreItem> scores;

4. Create a method to populate all the score items. For this example I only have two items: One is to lose points if you pause. The other is to lose points if you don't have the landing light on before take off. You can use the score value to 'weight' the items. So here pausing (10) is twice as bad as forgetting the landing lights (5).

        private void createScoreItems()
        {
            this.scores = new Dictionary<string, scoreItem>();
            // Added two possible penalties for demonstration
            // 1. Pausing the sim
            scoreItem pausing = new scoreItem("Fly the route without pausing the flight sim.", 10);
            this.scores.Add("pausing", pausing);
            // 2. Forgetting landing lights on takeoff
            scoreItem noLightsTakeOff = new scoreItem("Turn on the landing lights for take-off.", 5);
            this.scores.Add("noLightsTakeoff", noLightsTakeOff);
            // Add more here
        }

5. Create a method to work out the score: (I've done it here as a percentage)

        private double calculatePercentageScore()
        {
            int totalPossible = this.scores.Sum(s => s.Value.scoreValue);
            int notFailed = this.scores.Sum(s => s.Value.failed ? 0 : s.Value.scoreValue);
            return (double)notFailed / (double)totalPossible  * 100d;
        }

6. Create a method to show the score: Here I print the percentage score in a text box, and put all the score items in to two lists. One is items passed so far, the other is items failed so far:

        private void showScore()
        {
            // display the actual score
            this.txtScore.Text = calculatePercentageScore().ToString("F0") + "%";
            // show the passed and failed scores in the list
            this.lstFailed.Items.Clear();
            this.lstFailed.ForeColor = Color.Red;
            this.lstPassed.Items.Clear();
            foreach (scoreItem si in this.scores.Values)
            {
                if (si.failed)
                {
                    this.lstFailed.Items.Add(si.description);
                }
                else
                {
                    this.lstPassed.Items.Add(si.description);
                }
            }
        }

7. After you open the connection (or somewhere at the start of your application) call the methods to initialise the scores and show the starting scores:

            try
            { // Attempt to open a connection to FSUIPC (running on any version of Flight Sim)
                FSUIPCConnection.Open();
                // Opened OK
                FSUIPCConnection.Process();
                createScoreItems();
                showScore();
                // start the timer
                timer1.Interval = 250;
                timer1.Start();
            }
            catch (Exception ex)
            {
                // Badness occurred - show the error message
                MessageBox.Show(ex.Message, AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

8. In the timer tick, check the conditions for each score. If they have failed, mark the relevant score item as failed and show the new score.

            FSUIPCConnection.Process();
            // Check the pause score item
            if (pause.Value == 1)
            {
                // sim paused - fail the pause item
                this.scores["pausing"].failed = true;
                showScore();
            }
            // check the noLandingLightsTakeoff score item
            // If we're still on the ground and the IAS is over 60 and the lights are off then fail
            double iasKnots = (double)ias.Value / 128d;
            if (onGround.Value == 1 && iasKnots > 60 && !lights.Value[2])
            {
                this.scores["noLightsTakeoff"].failed = true;
                showScore();
            }

All of that will give you a working scoring system in real-time with the two example score items.

 

These conditions are fairly simple, you'll likely need more complicated checks involving keeping track of the flight phase (e.g. Before Taxi, Taxi, After take off, Top of climb, decent, approach etc).

 

Paul

Posted

Well, Paul... I finally managed to get my ACARS ready. Yesterday I released V1 without penalties and today I´m working on it, and it looks very cool... It´s been a bit hard for me, and also be sure that I couldn´t do the programm without your help, I´m stiill 14 years old and this is my first Windows app, I used to programm using Swift on iOS/OS X but I started to learn CSharp in early 2015... So I just wanna thank all of your help, Paul!!

 

I will leave here a link, if you wanna try the app and give me your opinion about it... I´ve made a test user in my website so you can login using:  Username: TAG100 Password: 123456

 

http://www.mediafire.com/download/qkwjm0q98d8f32d/TAG+ACARS+V1.0%282%29.rar

 

And once again Paul, thanks for all!! I will try to help as much as I can here.

 

Regards!!

Posted

The problem is that I use my own PHPvms so that's why PHPVMS is not included. I'm afraid I dont know VB.Net enough to help you. But why don't you try with C# is a very dynamic and easy language!!

Posted (edited)

Ok I will try to make an fresh acars system in C# for VAM (http://virtualairlinesmanager.net/).

I think your ACARS is for this system.

PM me

Thanks

Fred

 

Hi 

 

I am the creator of VAM Virtual Airlines Manager and also SIM ACARS. both are free and the SIM ACARS is totally compatible with VAM.

I am improving every day VAM and the ACARS but I would say both are very complete and will fit most of the VA needs. 

So far I have not posted here becasue I was waiting some new enhancement in my ACARS, but currently it is 100% working.

 

Here a few screenshots of the ACARS

 

2015-04-26-02_54_01-.png

 

2015-04-26-02_54_22-.png

 

 

and now a a screenshot of how the report looks in the VAM system

 

2015-04-26-03_54_24-Virtual-Airlines-Man

 

2015-03-15-18_47_19-Virtual-Airlines-Man

 

 

 

More info about VAM and SIM ACARS in the URL: http://virtualairlinesmanager.net/

 

I hope you like it.

Edited by VAM
Posted

Yes, but I suggest you Frederic to wait a bit with my code. Because it´s still not perfect and I have to talk with the creator of VAM because we still have some issues during the sending of the PIREP. So if one day Alejandro has time and he wants he will explain me few things about VAM and I will have the ACARS working 100%.

 

Regards!

  • 1 month later...
Posted

just my cent: check the offset size

        private Offset<int> Flapscontrol = new Offset<int>(0x0BDC);        private Offset<double> agl = new Offset<double>(0x0020);

as of the Fsuipc documentation both are 4 bytes long

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.