Some plots from my scripted steamer

Some plots from my scripted steamer

Postby TrabantDeLuxe » Wed Mar 29, 2017 9:37 am

Ello! Hope all of you are doing great.

So over the last few weeks, I have made great strides in scripting my engine. What started with "getting a bit of throttle lag", has become a bit more than that and I wanted to showcase it to some fresher - and perhaps more knowledgeable eyes. I'd like to stress that even though this is my own work, I have had valuable discussions that lead up to this, and couldn't have done this without some valuable discussions. Those in question know who they are. The title did warn you, so let's start with a bit of an introduction. The objective is to get a more prototypical, physics-based behaviour of the actual cylinder bit on a locomotive. Several sources do a really good job of indicating what goes on inside the cylinder as the wheels go round. Personally, I recommend Henderson (1904): Locomotive Operation; a technical and practical analysis. I have some text in italics, those are things I am not quite sure of.

Values are computed based on the current (virtual) control settings and the angular position of the wheels, as well as several other parameters. One thing you will quickly run in to, is the limitation that the framerate imposes on any serious work at higher speeds. To counteract this, in my script, some sensitive physics calculations are done in what I like to call the fast loop. It subdivides the frame into multiple subframes. Sub-iteration points of wheel-rotation are easily obtained by linearly spacing them out. I have noticed no ill effects of having a fast loop containing around 20 - 50 points. The plot below has a lot of data points, but I don't get nearly that FPS ;).

Image
Fig 1. Blue: Steam Chest Pressure, Pink: Cylinder Pressure (left, front end)

We start of by computing both the cylinder pressures and steam chest pressures. Cylinder pressures are based on an assumed indicator diagram, valve events, admission losses (based on RPM) and steam chest pressure. The steam chest pressure itself is the consequence of keeping track of the mass flow rate out of the steam chest (due to the cylinders filling up) and the regulator setting and pressure differential over the regulator. Notice there is no superheater* to complicate matters!

The steam chest behaves much as you would a reservoir of steam to expect. When standing still and opening the regulator, it quickly fills up. The rate at which it drains is very much dependent on RPM (i.e. speed) and cut-off. There's also a very nice bounce in the needle, but my engine technically has no steam chest gauge :lol: . Because the locomotive is not equipped with any drifting valves, the steam chest will drop below atmospheric when having the regulator shut and the motion in full gear.

Having all cylinder pressures, one may use the piston equations to find the torque on exerted on the cranks. In my case, I have also kept track of the accelerations of the pistons and connecting rods, using Newton's second law and substracting these from the piston force. The result is shown:

Image
Fig 2. Torque exerted on cranks. Blue: Left-hand, Pink: Right-hand.

Note that the torque does go negative, which I would attribute to the combined effect of mass inertia and pre-admission. When summated, the torque does stay positive for most cut-offs. At lower cut-offs, I have seen a tendency for the torque to have significant negative areas. Would this be the 'no-true-midgear' that you hear people speak of when discussing Stephensons' motion? Finally, from torque we can go to tractive effort, which is what we are interested in. This is also a good time to check for the adhesion limit. In my script, this is done in the fast loop, integrating rotational acceleration of the wheels.

Let's now exit the fast loop before we ask to much of lua. I've made a couple of observations about how tractive effort is handled in the game engine, depending on throttle setting. I believe it was Chris Barnes who came up with the formula:

TE = MaxForce * TE_vs_Speed.csv * TE_vs_Cutoff * (P_boiler/MaxP_Boiler) * Regulator

My notes:
  • Both the TractiveEffortvsSpeed and TractiveEffortvsCutoff are straightforward multipliers. Speed is in MPH; Cutoff seems to be normalised (i.e. don't use a fractional number as the max cut-off!).
  • The MaxForce parameter is in kilopounds-force.
  • The regulator is a straightforward multiplier.
  • There is something with the boiler pressure, but I do not know exactly what. TS's steam chest pressure makes zero sense to me.

For now assume that we've got the boiler pressure at an optimum at all times, until we figure out how that is handled in game. We can set both the CSV's to be a flat 1 for all speed and cutoff, and can then modulate the regulator to set the tractive effort. To account for a negative torque, use a parameter that sets the reverser in the opposite direction.

Image
Fig 3. Tractive effort. Blue: Value reported by using Call("GetTractiveEffort"). Green: As calculated in the fast loop.

The result looks something like the above. There are some differences, but let's agree that the results are correct "within an order of magnitude". A very fun aspect of this script is that, when starting, there exist arrangements of the valve gear for which the locomotive will barely start when not in full gear. Some parameters need sorting out, but I feel that the performance of the locomotive is convincingly prototypical.

Now for a couple of downsides or points I'll need to think about.
  • The tractive effort is in principle completely unrelated to the in-game cut-off. The reverser control however is still related to the exhaust effect, and thus to steam production rates. If there is a way to break or minimise this coupling, the reverser could freely be used to modulate steam consumption, adjusting steam production via the blower only.
  • The biggest breakdown is in water consumption. I have done preliminary investigations, that show that under the above scripting, water consumption is severely underestimated. Furthermore, the percentage of underestimation varies depending on speed, cut-off, and the like. The order of magnitude is in 25-50%. However, given that water consumption is basically equal to the steam mass through the cylinders - plus a bit for the air pump and the like, once again we could use the reverser to account for this.

So. That's it for now, Maybe I'll think of something to add or append to this post, but for now maybe it would be nice to have some input from others. If there's need for plots, I can do a couple of test runs and log some data!

Thanks,

Björn
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Re: Some plots from my scripted steamer

Postby TrabantDeLuxe » Fri May 05, 2017 3:38 pm

The biggest breakdown is in water consumption. I have done preliminary investigations, that show that under the above scripting, water consumption is severely underestimated. Furthermore, the percentage of underestimation varies depending on speed, cut-off, and the like. The order of magnitude is in 25-50%. However, given that water consumption is basically equal to the steam mass through the cylinders - plus a bit for the air pump and the like, once again we could use the reverser to account for this.


And after a bit of fiddling, I've managed to get this working. There is no clear relationship between in-game reverser setting and steam rates, but we can still use the reverser to influence how much steam is being taken from the boiler. The objective is to match the amount of water that has (according to the fast loop) gone through the cylinders, and the decrease in boiler water level, corrected for steam usage by other causes (safeties, injectors, etc.).

To start, let me reiterate that the fast loop amongst other things comes up with the mass of steam that flows from the steam chest into the cylinders. Integrating this over time gives us CylSteamConsumption in kilograms. This is our target, so to speak. Now let's figure out how much water has actually disappeared from the boiler, which can be found via the control value of the water gauge, times the MaxWaterMass, plus any feed water through the injectors:

Code: Select all
-- This bit does the steam consumption via the reverser
   if gFirst then
      -- Initialise, gFirst becomes false after first iteration.
      TotalSteamConsumption_sim = 0
      SafetySteamConsumption_sim = 0
      InjLSteamConsumption_sim  = 0
      InjectedWater = 0

      ReverserMagnitude = 0.01
   end

   -- Get simulation steam consumption:
   MaxWaterMass = 869.63   -- [kg], in the blueprint this is MaxWaterMass [lbs]

   -- Total injected water
        -- InjLWaterYield is a function that spits out the total amount of water an injector yields.
   InjectedWater = InjectedWater + dTime*InjLWaterYield(LiveInjectorSteamOnOff, LiveInjectorWater)      -- [kg]

   -- This bit calculates how much water has disappeared from the boiler:
        -- boilerwaterlevel is the gauge glass level.
   TotalSteamConsumption_sim = ((1 - boilerwaterlevel) * MaxWaterMass) + InjectedWater      -- [kg]


Now not all of this water that has gone has gone through the cylinders. There are some other appliances that leech water, such as in this example case the safeties and the injector. For the safeties values can be obtained through the blueprints, the injectors I've just had to run a million experiments and come up with a linear fitted estimate.

Code: Select all
-- Steam out through the safeties.
   SafetySteamConsumption_sim = SafetySteamConsumption_sim + (SafetyValve1*((8000*0.4537)/3600) + SafetyValve2*((500*0.4537)/3600))*dTime   -- [kg]

   -- Steam out through Left-hand Injector
   InjLSteamConsumption_sim = InjLSteamConsumption_sim + InjLSteamUsage(LiveInjectorSteamOnOff, LiveInjectorWater)         -- [kg]


Nearly there. Let's deduct the above two from TotalSteamConsumption_sim, to get the value of what TS thinks goes through the cylinders:

Code: Select all
-- Then, the cylinder consumption is total consumption minus all bits and bobs that leech steam.
   CylSteamConsumption_sim = TotalSteamConsumption_sim - SafetySteamConsumption_sim - InjLSteamConsumption_sim            -- [kg]


So. We have what should have gone through the cylinders CylSteamConsumption according to the fancy fast loop, and whatever TS thinks CylSteamConsumption_sim is. Those two should be matched by modulating the reverser. "deLuxe, my good man, is this the time for a PID controller?" I hear you say.

It is indeed. But I've left the integral term out as it's horribly difficult to tune.

Code: Select all
-- Modulate Reverser:
   do
      --  Sweet lawd a PD controller.
      if gFirst then
         prevWaterRateError = 0
      end

      local WaterRateError = CylSteamConsumption - CylSteamConsumption_sim
      local dWaterRateError = (WaterRateError - prevWaterRateError)/dTime

      local kP_WaterRate = 0.120
      local kD_WaterRate = 0.160

      ReverserMagnitude = bound(1e-12, ReverserMagnitude + dTime*(kP_WaterRate*WaterRateError + kD_WaterRate*dWaterRateError), 1.0)
                -- bound(min, variable, max) is a convenience funtion that bounds a variable between min and max.

      prevWaterRateError = WaterRateError
      PIDERROR = WaterRateError    -- For debugging.
   end


I won't explain all the bits and bobs about PD controllers here, but suffice to say, it tries to minimize the difference between TS and actual water consumption. Note that ReverserMagnitude is that absolute value of the reverser setting, a direction parameter is given based on computed tractive effort (i.e. negative for TE < 0). Exact zero values are not permitted, as that would kill of any tractive effort. Finally, somewhere down the script we set the reverser, and presto. Realistic water consumption for all nerdy enough to care.
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Re: Some plots from my scripted steamer

Postby VictoryWorks » Mon May 08, 2017 11:25 am

Very nice indeed. I'm probably missing something somewhere but doesn't this have a knock on effect to the game tractive effort/acceleration if the reverser is being set to control water consumption rather than cut off?
User avatar
VictoryWorks
Driver
 
Posts: 333
Joined: Mon Apr 07, 2014 1:22 pm
Has thanked: 41 times
Been thanked: 224 times

Re: Some plots from my scripted steamer

Postby TrabantDeLuxe » Mon May 08, 2017 1:24 pm

Hi,

It's more likely that I've forgot to explain things well enough.

If you would use this in conjunction with 'normal' cutoff-TE .csv's it would. However, the way I've set it up, the tractive effort is made independent of the in-game reverser by having a .csv that looks like this:

Code: Select all
0.0,1.0
0.5,1.0
1.0,1.0


The speed-TE relationship follows a similar 'flat' pattern.

It doesn't matter where the cutoff is in-game, tractive effort is modulated purely through the in-game regulator. The virtual reverser and virtual regulator serve as input for the 'fast loop', which basically simulates a steam engine going round and round, and spits out amongst others the actual tractive effort.
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Re: Some plots from my scripted steamer

Postby VictoryWorks » Mon May 08, 2017 1:57 pm

Yup, that makes sense. A very clever guy did the same thing for us with the GT3's gas turbine - a flat TE "curve" and then power is controlled through the regulator which has a simulation of the twin stage turbine and gears.
User avatar
VictoryWorks
Driver
 
Posts: 333
Joined: Mon Apr 07, 2014 1:22 pm
Has thanked: 41 times
Been thanked: 224 times

Re: Some plots from my scripted steamer

Postby TrabantDeLuxe » Mon May 08, 2017 2:19 pm

It's a very nice and flexible technique indeed. The fun thing is that it opens the way to more complex systems, but you do feel like coaxing TS into doing things you want it to do. But still, the 'fun' we could have with scripting.

Didn't the GWR have a de Glehn at one point? :lol:
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Re: Some plots from my scripted steamer

Postby VictoryWorks » Tue May 09, 2017 8:53 am

It does. You should have tried it before we had the virtual controls - the first complex steam loco, my GWR 56xx, had the brake with a notch at 0.49 so I could change the value whilst the mechanical lubricator wasn't working to create a leak but you wouldn't see it shown on the UI as "Applied" as it treated 0.49 as 0 for display purposes :lol:
It's amazing how much more we can do now via scripting, mostly thanks to Matt P's influence which is why I'm rather glad that he's in charge of TSW.

I think the GWR had 3 De Glehn compounds that Churchward bought for testing purposes and used in service until the late 1920's.
User avatar
VictoryWorks
Driver
 
Posts: 333
Joined: Mon Apr 07, 2014 1:22 pm
Has thanked: 41 times
Been thanked: 224 times

Re: Some plots from my scripted steamer

Postby TrabantDeLuxe » Mon May 22, 2017 10:30 pm

Absolutely no virtual controls? Oh dear...

Meanwhile, I did a couple of runs logging indicator-horsepower and water consumption. The conclusion was that the locomotive was not thirsty enough, when comparing to real-world data. Why is that? Because in my perfect universe saturated steam never, ever, ever condenses. Up to now. I have adopted a model that is a simplified model based on the model described in this paper by W.B. Hall. In short, a few key points:

  • The cylinder casting serves as a heat-sink, adopting a temperature somewhere between the steam temperature at admission (roughly 190°C) and the steam temperature when exhausting (roughly 100°C). Higher cut-offs tend to increase the temperature, lower cutoffs will tend to lower the temperature. There's also a small temperature gradient in the cylinder walls, but I confess to not fully understanding this - esp. when considering the transient problem!.
  • As heat leaves the steam mass, a proportion of it will convert to liquid. This liquid forms a 'film' on the cylinder walls, which effectively insulates the cylinders, thereby reducing condensation rate.
  • Hall does not go into the effects after the admission phase, but I've adopted a model where re-evaporation of the liquid film, and partial exhaustion into the blastpipe are possible. This exhaustion is highly subject to parametrisation (i.e. just try a number).
  • The volume of steam lost into condensation causes a drop in pressure, and subsequently during the admission phase, more steam may rush in again.

I figure that some of the liquid must come out through the blastpipe, as otherwise the cylinders fill up with condensation in no time. After some trial and error, I've gotten a setting that generates somewhat believable numbers. A figure often used in the judgement of locomotive efficiency is the 'Steam per IHP per hour'; as shown in the plot below:

Image
Steam usage [lbs per IHP-hour] versus speed, for different cut-offs. Full steam chest pressure (160 PSI/11 atmospheres). 100 kmh converts to 245 rpm.

Compare this to tests performed on a slightly smaller locomotive by W.F.M. Goss more than a century ago:

Image
Steam usage [lbs per IHP-hour] versus speed, for different cut-offs. Taken from the Purdue Locomotive Tests - a pretty comprehensive resource.

Goss notes that the engine he had available wasn't the best to go around at the time of testing. Full details are given in his work, but it's basically a super-jupiter.

So, interesting? I think so. It's at least good to see some resemblance to prototypical data. The major point to be taken from the plots is that condensation renders low (<25%) cutoffs unusable. I would attribute this to a combination of lead and low cylinder temperature, caused by the high degree of expansion. The minimum cut-off for this particular locomotive is 15%, so keep in mind that 25% is having the reach rod nearly all the way in.

Also note the relatively high consumption at lower speed, when the steam has ample time to condense in the cylinder. Most effecient working is possible at around 70 km/h.

Incidentally, this problem is exactly what de Glehn et al tried to counteract when compounding locomotives - by having steam expand less in the same cylinder, the cylinder walls remained nearer the steam temperature, thus reducing condensation. In order to still work expansively, you just use a system of H.P. and L.P. cylinders.

Or just superheat, that's another possibility. Not as cool as having a double reverser and regulator though. :lol:
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Re: Some plots from my scripted steamer

Postby DominusEdwardius » Tue Jun 06, 2017 12:25 am

Just a point of note, I remember reading a while back that on saturated engines you rarely if ever drop below 30-40% cutoff as they are just basically worthless under that cutoff. Most drivers once linked down to 40% cutoff would then henceforth drive by the regulator instead. Also the lack of virtual controls was an utter nightmare in the past, combined by the physical limitations of the original blueprint editor which meant the engine had an actual physical limit to the amount of controls, emitters, animations etc. If you had more emitters you had to have less controllers and so on, now that was an utter nightmare to work around. The Jinty was designed right up to the limit, literally one more emitter or control and the original BPE couldn't use the xml properly.
Edward
Regards Edward

Meshtools - Scripter and Sound Artist
http://www.meshtools.co.uk
https://www.facebook.com/Meshtools
User avatar
DominusEdwardius
Passed Fireman
 
Posts: 114
Joined: Mon Mar 31, 2014 11:25 am
Location: Loughborough, UK
Has thanked: 10 times
Been thanked: 40 times

Re: Some plots from my scripted steamer

Postby TrabantDeLuxe » Wed Jun 07, 2017 1:18 pm

I recall reading that "locomotives have been carefully designed to provided most efficient working at 25% cut-off", and that if that cutoff provides too much oompf for the train and speed you like, use the regulator to control speed. Going near mid-gear is indeed about the worst thing to do on these engines.

Was the limit 255 controls/animations/childs by any chance? Recall reading about that on UKTS and being slightly worried.
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Next

Return to Rolling Stock General

Who is online

Users browsing this forum: No registered users and 2 guests