Train Plugin and Time Acceleration
3 posters
Page 1 of 1
Train Plugin and Time Acceleration
I have been playing around with the train plugin by modifying Odakyufan's. I was wondering if there is a way to prevent time acceleration from occurring from the plugin? The default keys are CTRL J.. maybe I can prevent those keys from doing anything in the simulator?
waterburn- Posts : 55
Join date : 2012-06-29
Re: Train Plugin and Time Acceleration
Sorry, but no.
OpenBVE reads the keyboard state once a frame via a low-level SDL call, which there isn't any way to block.
Nothing related to time acceleration is exposed via the plugin interface either.
Any chance of a clearer idea of what you're trying to achieve?
If you're running your own internal timers which are getting confused by the time acceleration, this isn't a particularly good idea- Try using the Data.ElapsedTime.Milliseconds value provided instead, as this possibly slightly confusingly represents in-game time.
This is primarily a FWIW, but you may be interested:
I have got a personal build of OpenBVE that I've been playing with the plugin interface to add some data.
To disable the time acceleration via the plugin, this is what you'd need to do:
Simple!
I haven't done anything more with this, or really publicly posted what I've been playing with, as I haven't done anything really significant compared to what is currently available. (Specifically, it passes the cant, curve radius & pitch values, plus added some additional plugin keys)
I might be prepared to build/ host something, but it needs a really good reason to choose to build a new fork.
Mildly related-
If you've got Odakyufan's original plugin template (odakyufanats.7z) in unmodified form, any chance of uploading it somewhere, please?
I'd like a look at some of the source comments, and I've mislaid the copy I did have.....
Edit:
Please let me know if you want a built version of OpenBVE containing the above to experiment with.
I'll need to do some cleaning up in the source code first (Have been playing with different methods of keyboard handling via OpenTK, and it's a little broken ATM), but you're more than welcome to it.
Cheers
Chris Lees
http://www.bvecornwall.co.uk
OpenBVE reads the keyboard state once a frame via a low-level SDL call, which there isn't any way to block.
Nothing related to time acceleration is exposed via the plugin interface either.
Any chance of a clearer idea of what you're trying to achieve?
If you're running your own internal timers which are getting confused by the time acceleration, this isn't a particularly good idea- Try using the Data.ElapsedTime.Milliseconds value provided instead, as this possibly slightly confusingly represents in-game time.
This is primarily a FWIW, but you may be interested:
I have got a personal build of OpenBVE that I've been playing with the plugin interface to add some data.
To disable the time acceleration via the plugin, this is what you'd need to do:
- Create a new bool value in the PluginManager.Plugin class. Call this DisableTimeAcceleration
- Add a corresponding bool value to the OpenBVEApi.ElapseData class.
- In the UpdatePlugin function in PluginManager.Plugin , read the value from ElapseData and set the local variable.
- In the MainLoop function, look for this under the control processing: Interface.Command.MiscTimeFactor. You then need to add a simple if condition referring to the bool you added above
Simple!
I haven't done anything more with this, or really publicly posted what I've been playing with, as I haven't done anything really significant compared to what is currently available. (Specifically, it passes the cant, curve radius & pitch values, plus added some additional plugin keys)
I might be prepared to build/ host something, but it needs a really good reason to choose to build a new fork.
Mildly related-
If you've got Odakyufan's original plugin template (odakyufanats.7z) in unmodified form, any chance of uploading it somewhere, please?
I'd like a look at some of the source comments, and I've mislaid the copy I did have.....
Edit:
Please let me know if you want a built version of OpenBVE containing the above to experiment with.
I'll need to do some cleaning up in the source code first (Have been playing with different methods of keyboard handling via OpenTK, and it's a little broken ATM), but you're more than welcome to it.
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Re: Train Plugin and Time Acceleration
Hey Chris,
Thanks for the help. I will be using Data.ElapsedTime.Milliseconds.. just needed to keep track of the amount of time for signal related timers. Also check your PM.
Thanks for the help. I will be using Data.ElapsedTime.Milliseconds.. just needed to keep track of the amount of time for signal related timers. Also check your PM.
waterburn- Posts : 55
Join date : 2012-06-29
Re: Train Plugin and Time Acceleration
In the Elapse function I see data.ElapsedTime.Seconds > 0.0 & data.ElapsedTime.Seconds < 1.0. I want updates to be made every 10 seconds so was looking at the game time and adding 10 to it. But the problem is when you time accelerate the 10 seconds becomes less.
waterburn- Posts : 55
Join date : 2012-06-29
Re: Train Plugin and Time Acceleration
I think you're getting a little muddled here
Let's look at it this way:
The data.ElapsedTime class provides two values- Seconds and milliseconds.
These represent in-game time. Take these examples:
Now, let's think about what would happen if you always used a 'real-world' time of 10 seconds between updates:
As you can see, there's a factor of 5 differential between the two figures, as we've speeded up time 5x. At 10km/h, this is relatively small. Now though, look at the difference at 100km/h:
A 100m difference is way, way out of tolerances.
Unless I'm completely missing what you're trying to do, select an appropriate update interval for the game running at a time factor of 1x, and use the data.ElapsedTime values.
Note: The total time taken in the 'real' world will be off by a few milliseconds either way. This phenomenon is called clock-drift, and unless you're trying to do high-precision nuclear calculations or something should be ignored.
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Let's look at it this way:
The data.ElapsedTime class provides two values- Seconds and milliseconds.
These represent in-game time. Take these examples:
- 60 seconds passes in the game's internal clock, at a time factor of 1x ==> Total time taken in the 'real' world is ~60 seconds
- 60 seconds passes in the game's internal clock, at a time factor of 5x ==> Total time taken in the 'real' world is ~12 seconds
Now, let's think about what would happen if you always used a 'real-world' time of 10 seconds between updates:
- Train travelling at 10km/h, for 10 'real world' seconds, at a time factor of 1x ==> 2.7m traveled.
- Train travelling at 10km/h for 10 'real world' seconds, at a time factor of 5x ==> 13.8m traveled. [50 in-game seconds]
As you can see, there's a factor of 5 differential between the two figures, as we've speeded up time 5x. At 10km/h, this is relatively small. Now though, look at the difference at 100km/h:
- Train travelling at 100km/h, for 10 'real world' seconds, at a time factor of 1x ==> 27m traveled.
- Train travelling at 100km/h for 10 'real world' seconds, at a time factor of 5x ==> 138m traveled. [50 in-game seconds]
A 100m difference is way, way out of tolerances.
Unless I'm completely missing what you're trying to do, select an appropriate update interval for the game running at a time factor of 1x, and use the data.ElapsedTime values.
Note: The total time taken in the 'real' world will be off by a few milliseconds either way. This phenomenon is called clock-drift, and unless you're trying to do high-precision nuclear calculations or something should be ignored.
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Re: Train Plugin and Time Acceleration
Wouldn't data.ElapsedTime only be the amount of time before function calls? What if less than 10 seconds elapse? Wouldn't it reset? I need the updates to be made every 10 seconds so was using the in game time as a reference.
waterburn- Posts : 55
Join date : 2012-06-29
Re: Train Plugin and Time Acceleration
You're still a little muddled
Does this make it any clearer:
You could choose not to reset it on re-initialisation (Jumping to stations), but it's highly advisable to do so.
data.ElapsedTime.Milliseconds is *not* a cumulative counter- It only tracks the in-game time between the previous call to PluginManager.Plugin.Elapse and the current one.
This function is called once a frame, so if you're getting 20fps, then you will have 20 updates per second & this value will be 50, and so-on.
If you want millisecond precision timing, then this example is changed slightly to subtract 10,000 milliseconds from your timer rather than simply reset it:
You could alternatively use data.TotalTime.Milliseconds / Seconds, which returns an absolute value for the current in-game time, but that's not something I'd really reccomend.
Post *exactly* what you're trying to do, and I can cook up a simple example.
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Does this make it any clearer:
- Code:
/*
* Timers Demo File
*/
using System;
using OpenBveApi.Runtime;
namespace Plugin
{
internal class TimerDemo : Device
{
//Stores the current timer value
internal double Timer;
internal int Counter;
internal TimerDemo(Train train) {
this.Train = train;
}
//Always reset the timer and counter to zero when we initialise
//The same is true for re-initialise
/// <summary>Is called when the system should initialize.</summary>
/// <param name="mode">The initialization mode.</param>
internal override void Initialize(InitializationModes mode) {
Timer = 0.0;
Counter = 0;
}
/// <summary>Is called when the system should re-initialize.</summary>
/// <param name="mode">The initialization mode.</param>
internal void Reinitialise(InitializationModes mode)
{
Timer = 0.0;
Counter = 0;
}
internal override void Elapse(ElapseData data, ref bool blocking) {
//Update the current timer value with the elapsed time
Timer += data.ElapsedTime.Milliseconds;
//If the timer has passed 10,000 milliseconds (10 seconds)
//Update the counter and reset the timer to zero
if(Timer >= 10000)
{
Counter++;
Timer = 0.0;
}
}
}
}
You could choose not to reset it on re-initialisation (Jumping to stations), but it's highly advisable to do so.
data.ElapsedTime.Milliseconds is *not* a cumulative counter- It only tracks the in-game time between the previous call to PluginManager.Plugin.Elapse and the current one.
This function is called once a frame, so if you're getting 20fps, then you will have 20 updates per second & this value will be 50, and so-on.
If you want millisecond precision timing, then this example is changed slightly to subtract 10,000 milliseconds from your timer rather than simply reset it:
- Code:
/*
* Timers Demo File
*/
using System;
using OpenBveApi.Runtime;
namespace Plugin
{
internal class TimerDemo : Device
{
//Stores the current timer value
internal double Timer;
internal int Counter;
internal TimerDemo(Train train) {
this.Train = train;
}
//Always reset the timer and counter to zero when we initialise
//The same is true for re-initialise
/// <summary>Is called when the system should initialize.</summary>
/// <param name="mode">The initialization mode.</param>
internal override void Initialize(InitializationModes mode) {
Timer = 0.0;
Counter = 0;
}
/// <summary>Is called when the system should re-initialize.</summary>
/// <param name="mode">The initialization mode.</param>
internal void Reinitialise(InitializationModes mode)
{
Timer = 0.0;
Counter = 0;
}
internal override void Elapse(ElapseData data, ref bool blocking) {
//Update the current timer value with the elapsed time
Timer += data.ElapsedTime.Milliseconds;
//If the timer has passed 10,000 milliseconds (10 seconds)
//Update the counter and reset the timer to zero
if(Timer >= 10000)
{
Counter++;
Timer -= 10000;
}
}
}
}
You could alternatively use data.TotalTime.Milliseconds / Seconds, which returns an absolute value for the current in-game time, but that's not something I'd really reccomend.
Post *exactly* what you're trying to do, and I can cook up a simple example.
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Re: Train Plugin and Time Acceleration
Thanks for the clarification Chris. Makes sense how I can use the elapsed time for a counter. If the simulator lags or the frames are lower that would have an effect on the elapsed time?
Is there a way I can use 10 seconds in real life instead of 10 seconds in game to prevent time acceleration from having an effect?
Is there a way I can use 10 seconds in real life instead of 10 seconds in game to prevent time acceleration from having an effect?
waterburn- Posts : 55
Join date : 2012-06-29
Re: Train Plugin and Time Acceleration
Short answer is no to both.
Longer answer:
OpenBVE is essentially a single-threaded, blocking application. This means that each function is called sequentially, and that each waits for the last to finish before moving on.
This is how it gets the in-game time, & derives the frame-rate from it:
At the start of each frame, a call is made to SDL.SDL_GetTicks (This is a high-precision timer)
This value is compared to the previous result, giving a total elapsed time vale.
The game then runs it's update functions, using this total elapsed time value.
Finally, the cycle repeats.
Essentially, the movement of our objects/ plugin data is technically one frame behind in terms of time. If there are multiple rapid changes in framerate, then the game's internal clock may get a little out of sync with 'real-life', but essentially not enough to worry about.
10 real-life seconds is a problem due to the single-threaded nature of OpenBVE- The ideal method of doing things would be to use a backgroundworker thread, but to do so would require hooking an event handler into the game's mainloop; Plugin code is *only* being executed whilst in the PluginManager.Plugin.Elapse function. (Whilst not quite strictly true, this is the easiest way to explain it)
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Longer answer:
OpenBVE is essentially a single-threaded, blocking application. This means that each function is called sequentially, and that each waits for the last to finish before moving on.
This is how it gets the in-game time, & derives the frame-rate from it:
At the start of each frame, a call is made to SDL.SDL_GetTicks (This is a high-precision timer)
This value is compared to the previous result, giving a total elapsed time vale.
The game then runs it's update functions, using this total elapsed time value.
Finally, the cycle repeats.
Essentially, the movement of our objects/ plugin data is technically one frame behind in terms of time. If there are multiple rapid changes in framerate, then the game's internal clock may get a little out of sync with 'real-life', but essentially not enough to worry about.
10 real-life seconds is a problem due to the single-threaded nature of OpenBVE- The ideal method of doing things would be to use a backgroundworker thread, but to do so would require hooking an event handler into the game's mainloop; Plugin code is *only* being executed whilst in the PluginManager.Plugin.Elapse function. (Whilst not quite strictly true, this is the easiest way to explain it)
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Re: Train Plugin and Time Acceleration
Chris I appreciate the explanation and will work with what we have. You mentioned the internal game time could be affected by lag / reduced frames.. would data.totaltime be more affected than data.elapsed time? I am using it for timed signals so even 1 second off could be a major concern.
waterburn- Posts : 55
Join date : 2012-06-29
Re: Train Plugin and Time Acceleration
No- They're differing ways of presenting the same data.
Any chance of a link to the prototype for your timed signals or an explanation of what you're trying to achieve?
I can't think of *any* signal in the real-world which requires a sub 1-second reaction time from the driver to a state-change, which is what you're implying you need.
Similarly, whilst you may get ~1s flashes on a flashing signal, I can't see why hitting exactly 10 seconds is so critical
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Any chance of a link to the prototype for your timed signals or an explanation of what you're trying to achieve?
I can't think of *any* signal in the real-world which requires a sub 1-second reaction time from the driver to a state-change, which is what you're implying you need.
Similarly, whilst you may get ~1s flashes on a flashing signal, I can't see why hitting exactly 10 seconds is so critical
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Re: Train Plugin and Time Acceleration
Timer signals that clear in 5 seconds instead of 4 seconds lets say within a 200 m block would be the difference between allowing 144 kph and 180 kph. It is not so much reaction time but the max allowed speed.
waterburn- Posts : 55
Join date : 2012-06-29
Re: Train Plugin and Time Acceleration
Are you thinking of something like the LU speed restrictive signals?
http://www.trainweb.org/tubeprune/signalling4.htm
If so, then you need to conceptualize them a little differently, as signalling in OpenBVE is a simple block affair.
First thing to do, is to write down a list of all possible signal states going up from the most restrictive, I.E.
Having done this, decide on the possible states your signal may display.
You then need to transmit this to your plugin. There are two basic methods of doing this:
Finally, use the SetSignal function in the plugin to inform your code of the current signal aspect, and hence the enforced speed restriction.
You can then check this speed restriction against the train's current speed, or alternatively use a beacon at the start and end of the block and measure the time taken between them.
Finally, keep the outer signal as a simple animated file, *not* a signal. Trigger this from a panel variable, which only toggles if you're under the appropriate speed.
This won't give you the 'passed a red signal' messsages, but it's the only way to get a signal to work in this manner
Cheers
Chris Lees
http://www.bvecornwall.co.uk
http://www.trainweb.org/tubeprune/signalling4.htm
If so, then you need to conceptualize them a little differently, as signalling in OpenBVE is a simple block affair.
First thing to do, is to write down a list of all possible signal states going up from the most restrictive, I.E.
- Stop
- Caution, prepare to stop
- Caution
- Restriction 80km/h
- Restriction 90km/h
- Restriction 100km/h
- Proceed at line speed
Having done this, decide on the possible states your signal may display.
You then need to transmit this to your plugin. There are two basic methods of doing this:
- Keep an internal list of all signal states.
- Format the data paramater of a beacon command to transmit the speed restrictions for each aspect.
Finally, use the SetSignal function in the plugin to inform your code of the current signal aspect, and hence the enforced speed restriction.
You can then check this speed restriction against the train's current speed, or alternatively use a beacon at the start and end of the block and measure the time taken between them.
Finally, keep the outer signal as a simple animated file, *not* a signal. Trigger this from a panel variable, which only toggles if you're under the appropriate speed.
This won't give you the 'passed a red signal' messsages, but it's the only way to get a signal to work in this manner
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Re: Train Plugin and Time Acceleration
To format the data parameter of the beacon command would I need to modify the openbve libraries?
waterburn- Posts : 55
Join date : 2012-06-29
Re: Train Plugin and Time Acceleration
Nothing at all about the source codes of the program, it just means that you have to insert a bunch of Track.Beacon with the data parameter as the index of the signal state, or something else you think that would be important.waterburn wrote:To format the data parameter of the beacon command would I need to modify the openbve libraries?
You may even choose to load data before start of scenario or just load-as-you-are-approraching, like
- Code:
0, .Beacon 8000; -1; 0; 1,
0, .Beacon 8010; -1; 0; 045000000,
0, .Beacon 8010; -1; 0; 045000050,
0, .Beacon 8010; -1; 0; 080000200,
0, .Beacon 8010; -1; 0; 065000650,
0, .Beacon 8010; -1; 0; 055000825,
0, .Beacon 8010; -1; 0; 045001100,
0, .Beacon 8010; -1; 0; 080001250,
0, .Beacon 8010; -1; 0; 000021250,
0, .Beacon 8020; -1; 0; 10000025,
0, .Beacon 8020; -1; 0; -10002100,
0, .Beacon 8021; -1; 0; -15000175,
0, .Beacon 8021; -1; 0; -30000200,
0, .Beacon 8021; -1; 0; -15000425,
0, .Beacon 8021; -1; 0; 0000450,
0, .Beacon 8021; -1; 0; 5001375,
0, .Beacon 8021; -1; 0; 10001400,
0, .Beacon 8021; -1; 0; 5001850,
0, .Beacon 8021; -1; 0; 0001875,
or
- Code:
37398
.Beacon 12; 0; 0; 05571198
.Beacon 13; 0; 0; 27
.Beacon 14; 0; 0; 14961592
37575
.Beacon 15; 0; 0; 70
.Beacon 17; 0; 0; 2
38200
.Beacon 17; 0; 0; 1
38225
.Beacon 15; 0; 0; 90
38725
.Beacon 17; 0; 0; 2
38775
.Beacon 16; 0; 0; 1045039150
38900
.Beacon 17; 0; 0; 1
39795
.Beacon 12; 0; 0; 04071405
.Beacon 13; 0; 0; 28
.Beacon 14; 0; 0; 15921609
2 different ways to input Track.Beacon data into the train plugin might finally work out the same, depends on how you code your mechanism.
You don't even need to modify the source of the program, even if you're solving using the first approrach. Just (maybe) the train plugin for some file reading, parsing (JSON, XML, CSV, blah blah blah), and storing into variable things. I don't see why you would ask this.
Re: Train Plugin and Time Acceleration
I was actually thinking of a specifically formatted integer from a single beacon, something like the UKTrainsys AI beacons:
http://railsimroutes.net/libraries/uktrainsys/release_notes.html#beacon-types-ai-guard
Parse this into an array and then play with the results as you desire.
Same end result, different ways of getting there
Cheers
Chris Lees
http://www.bvecornwall.co.uk
http://railsimroutes.net/libraries/uktrainsys/release_notes.html#beacon-types-ai-guard
Parse this into an array and then play with the results as you desire.
Same end result, different ways of getting there
Cheers
Chris Lees
http://www.bvecornwall.co.uk
Similar topics
» Strange acceleration data in train.dat file - what happens internally?
» The train plugin OS_SZ_Ats1.dll failed to load
» Class 35 Hymek acceleration values
» Even though the AI train hasn't stop completely, the AI train is open the doors.
» Localized train.txt (Different versions of train.txt depending on language)
» The train plugin OS_SZ_Ats1.dll failed to load
» Class 35 Hymek acceleration values
» Even though the AI train hasn't stop completely, the AI train is open the doors.
» Localized train.txt (Different versions of train.txt depending on language)
Page 1 of 1
Permissions in this forum:
You cannot reply to topics in this forum