ctabuyo Posted June 26, 2015 Report Posted June 26, 2015 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"; } } } }
Paul Henty Posted June 26, 2015 Report Posted June 26, 2015 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
ctabuyo Posted June 26, 2015 Author Report Posted June 26, 2015 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!!
ctabuyo Posted June 29, 2015 Author Report Posted June 29, 2015 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!
Paul Henty Posted June 29, 2015 Report Posted June 29, 2015 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 1
ctabuyo Posted June 30, 2015 Author Report Posted June 30, 2015 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!!
Paul Henty Posted July 1, 2015 Report Posted July 1, 2015 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
ctabuyo Posted July 1, 2015 Author Report Posted July 1, 2015 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.
Paul Henty Posted July 2, 2015 Report Posted July 2, 2015 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
ctabuyo Posted July 3, 2015 Author Report Posted July 3, 2015 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!!
Frédéric-O DUCHEMIN Posted July 4, 2015 Report Posted July 4, 2015 Hi Paul & ctabuyoI will be interested by this topic and this app (I mean the spirit of this tracker seem good), Even if the part of phpvms not seem to be included. No chance to make that in vb ?Regards, Fred
ctabuyo Posted July 4, 2015 Author Report Posted July 4, 2015 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!!
Frédéric-O DUCHEMIN Posted July 6, 2015 Report Posted July 6, 2015 But why don't you try with C# is a very dynamic and easy language!! 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
VAM Posted July 6, 2015 Report Posted July 6, 2015 (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 and now a a screenshot of how the report looks in the VAM system More info about VAM and SIM ACARS in the URL: http://virtualairlinesmanager.net/ I hope you like it. Edited July 6, 2015 by VAM
ctabuyo Posted July 6, 2015 Author Report Posted July 6, 2015 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!
mroschk Posted August 20, 2015 Report Posted August 20, 2015 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now