Elvas Tower: Expand potential of TCS scripting - Elvas Tower

Jump to content

Posting Rules

All new threads will be started by members of the Open Rails team, Staff, and/or Admins. Existing threads started in other forums may get moved here when it makes sense to do so.

Once a thread is started any member may post replies to it.
  • 13 Pages +
  • « First
  • 8
  • 9
  • 10
  • 11
  • 12
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

Expand potential of TCS scripting Rate Topic: -----

#91 User is offline   Serana 

  • Conductor
  • Group: Status: Contributing Member
  • Posts: 489
  • Joined: 21-February 13
  • Gender:Male
  • Location:St Cyr l'Ecole (France)
  • Simulator:Open Rails
  • Country:

Posted 30 August 2020 - 08:49 AM

On the MSFS (and FSX and Prepar3D) side, they are using a library called SimConnect as an interface between the flight simulator and the "scripts".
Well, they are not really scripts since they must be compiled.
If the code is executed out of the flight sim process, the developers can use C, C++; C# and VB.Net.
If the code is executed inside of the flight sim process, the developers can only use C++ and compile into WebAssembly format.

SimConnect C++ library is basically composed of functions without classes (procedural programming).
For example, in order to get access to a variable of the aircraft, you have to write this for example:


static enum DATA_DEFINE_ID {
  DEFINITION_1,
  DEFINITION_2
};

static enum DATA_REQUEST_ID {
    REQUEST_1,
    REQUEST_2,
};

struct Struct1
{
    double  kohlsmann;
    double  altitude;
    double  latitude;
    double  longitude;
};
// Match string definitions from the Simulation Variables document with the client defined ID

hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Kohlsman setting hg", "inHg");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Indicated Altitude", "feet");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Latitude", "degrees");
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Longitude", "degrees");

// Sections of code in DispatchProc

....
SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_2, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);
....
// When the data is received -- cast it to the correct structure type

case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
{
  SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA*) pData;

  switch(pObjData->dwRequestID)
  {
    case REQUEST_2:

      Struct1 *pS = (Struct1*)&pObjData->dwData;
   
      // Add code to process the structure appropriately

      break;
  }
break;
}
....



It's a mess...

For gauges, things are a bit easier since it does not use SimConnect.
For example, to get a variable:
struct sCompassVars
{
	NVGcontext* m_nvgctx = nullptr;
	ENUM m_eDegrees;
	ENUM m_ePlaneHeadingDegreesTrue;
	int m_iFont;
};

sCompassVars g_CompassVars;

...
g_CompassVars.m_eDegrees = get_units_enum("DEGREES");
g_CompassVars.m_ePlaneHeadingDegreesTrue = get_aircraft_var_enum("PLANE HEADING DEGREES TRUE");
FLOAT64 fHeading = aircraft_varget(g_CompassVars.m_ePlaneHeadingDegreesTrue, g_CompassVars.m_eDegrees, 0);
...


Much better. But not every gauges are written in C++.
A new way of creating gauges has been introduced in MSFS: the gauges are written in HTML, CSS and JS.
I'll try to find a way to use this approach for Open Rails.

#92 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 30 August 2020 - 09:52 AM

Oh, no, it isn't necessary. :) I'm not convinced yet, that it is any better than what we are using now. :) But thank you for the examples, it is a good insight! Definitely we need to continue the C# way, and I am not convinced that involving html/css/js would bring us any good either. :)

#93 User is offline   Serana 

  • Conductor
  • Group: Status: Contributing Member
  • Posts: 489
  • Joined: 21-February 13
  • Gender:Male
  • Location:St Cyr l'Ecole (France)
  • Simulator:Open Rails
  • Country:

Posted 30 August 2020 - 10:14 AM

For HTML/CSS/JS, that's only for things that will be rendered on the cabview (like the gauges in MSFS).
It's is easier to create GUI with web technologies than with XNA/MonoGame/DirectX rendering.




#94 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 30 August 2020 - 10:14 AM

If I interpret it well, the first one is a kind of a "subscribe-on-data-stream" with a predefined update interval, where the update() function must be started with processing the data "pushed", right?

#95 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 30 August 2020 - 11:27 AM

 Serana, on 30 August 2020 - 10:14 AM, said:

For HTML/CSS/JS, that's only for things that will be rendered on the cabview

Ah, sorry, I thought you are mentioning the scripting part.

#96 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 30 August 2020 - 11:37 AM

 cesarbl, on 30 August 2020 - 01:03 AM, said:

However, the addition of this signals isn't enough when simulating continuous systems like LZB or ETCS L2, where ideally there should be a script running at trackside, communicating with the on-board script. For these systems, deeper signalling and track information is needed.

This is what Rob was talking about on the 1st page. We must hope, that if he develops the described new track circuit logic and signals with abilities to interact with the trains in his own version of OpenRails, he is willing to share that with us.

#97 User is offline   mrmosky 

  • Engineer
  • Group: Status: Contributing Member
  • Posts: 648
  • Joined: 02-October 16
  • Gender:Male
  • Location:Chasetown
  • Simulator:Openrails
  • Country:

Posted 30 August 2020 - 01:22 PM

I don't understand most of the above, but when you are talking about cabviews, are you also including 3d cabs?

I am asking this as I have a particular interest in this and feel that 3d cabs are the way forward.

Geoff

#98 User is offline   Serana 

  • Conductor
  • Group: Status: Contributing Member
  • Posts: 489
  • Joined: 21-February 13
  • Gender:Male
  • Location:St Cyr l'Ecole (France)
  • Simulator:Open Rails
  • Country:

Posted 30 August 2020 - 03:08 PM

Yes, of course. For me, cabviews include 2D and 3D.

#99 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 05 September 2020 - 02:28 AM

This weekend I have a chance to take a look on the code by a real computer (till now I was just browsing it via a mobile phone :) ). I haven't decided yet if I want to come back coding, but I feel more that I have to make some adjustments to this part. The current code in some aspects seems unfinished (beyond the big unfinishment of at some point just dropping Locomotive() in, instead of designing proper interface functions). For example the following code works only in lucky cases:
        T NextDivergingSwitchItem<T>(float maxDistanceM, ref T retval, Train.TrainObjectItem.TRAINOBJECTTYPE type)
        {
            var LocalTrainInfo = Locomotive.Train.GetTrainInfo();
            SignalDistance = float.MaxValue;
            foreach (var foundItem in Locomotive.Train.MUDirection == Direction.Reverse ? TrainInfo.ObjectInfoBackward : TrainInfo.ObjectInfoForward)
            {

There's an unused LocalTrainInfo object created at every function call, even if the function is called multiple times in a script (spinning the garbage collector). Instead correctly, the once-per-frame created TrainInfo object is used, but currently this is only created in the NextSignalItem() function, so if the NextDivergingSwitchItem() above is called fist in a script, it would not yet have a working TrainInfo object to search in.

I also don't understand, why a distinct Train.NextTrailingDivergingSwitchDistanceM() function was created, instead of extending the TrainInfo class to contain these objects too. Facing switches are contained, but trailing switches aren't. Is there a particular reason it was done this dirty way? If there is no particular reason for that, then my intention is to fix this. (Actually the same question applies for the generic signals too, I need more investigation. If I finally get enough time for OpenRails.) I would also like to add the missing interfaces, so that the improper Locomotive() could be removed once and forever.

I think the code review process did not work particularly well for the PR-s of this feature, but knowing that there are so few active developers around, I guess we all must be happy, that some developers are doing something at all. (I feel also myself guilty a bit in this regard.)

#100 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 7,006
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 05 September 2020 - 12:58 PM

In the code chunk there is in effect an error: in the foreach line the references shouldn't be to TrainInfo, but to LocalTrainInfo.
I also accept your note that this should be computed only once for every loop, and I may try to modify it.
Thanks for the kind "dirty way" expression. As TrainInfo has its main use outside of the TCS management, and as TCS management is often not used, I didn't want to add further computations to get additional data within TrainInfo that aren't used outside of the TCS management.

As you are reviewing the TCS-related code, could you pls comment on this pre-existing line?
                       return list[forsight < list.Count ? forsight : list.Count - 1];

In case forsight is >= list.Count, the last element of the list is returned, instead of signalling that what was asked for isn't available. I don't think this is correct, if I have correctly interpreted the code.

  • 13 Pages +
  • « First
  • 8
  • 9
  • 10
  • 11
  • 12
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users