CentraleSupélecDépartement informatique
Plateau de Moulon
3 rue Joliot-Curie
F-91192 Gif-sur-Yvette cedex
Using tag relations for modeling engine ignition

This small TESL specification models the ignition in a four-stroke petrol engine. It uses 3 time scales:

  • the crankshaft time scale, measuring the rotation of the engine in degrees
  • the camshaft time scale, measuring the rotation of the camshafts in degrees
  • the real time scale, measuring physical time in seconds

camshaft camshaft α crankshaft ms

The relation between the crankshaft and camshaft time scales is fixed. In a four stroke engine, the camshaft turns twice as fast as the crankshaft because each cylinder produces thrust every other revolution.

The relation between the crankshaft time scale and real time depends on the rotation speed of the engine.

In order for the mix of air and gas to explode just after the piston reaches the top dead center, the ignition spark must be produced in advance. This advance is defined on the real time scale because it corresponds to the physical time it takes for the mix to ignite. However, the information which is available for triggering the ignition is the angular position of the camshaft.

Each piston reaches its top dead center position every turn of the crankshaft. Compression top dead centers, when the mix is compressed and must be ignited, alternate with exhaust top dead centers, when the fumes of the combustion are pushed out to the exhaust pipes. In this example, we create a spark only before compression top dead centers. We assume a symmetric ignition scheme on the other camshaft, which drives the spark plugs of the other cylinders.

Using different time scales and tag relations makes modeling this system quite easy with TESL.

Q-clock realtime    // in seconds
Q-clock crankshaft  // in degrees
Q-clock camshaft    // in degrees
tag relation crankshaft = 2 * camshaft + 0 // crankshaft turns twice as fast as camshaft

let int rpm = 2000  // engine rotation speed in degrees/minute
let int one_turn = 360  // one turn is 360 degrees
let int one_minute = 60 // one minute is 60 seconds
let rational degrees_per_sec = [rational $rpm] * $one_turn / $one_minute  // 12000 deg/s
tag relation crankshaft = $degrees_per_sec * realtime + 0

// Make the engine run by generating periodic TDC events
Q-clock top_dead_center periodic 1 offset 0
// camshaft angle advances by 360 degrees each top dead center
tag relation crankshaft = $one_turn * top_dead_center + 0

// Clocks of exhaust and compression top dead centers
U-clock exhaust_tdc
top_dead_center every 2 implies exhaust_tdc
U-clock compress_tdc
top_dead_center every 2 starting at 1 implies compress_tdc

U-clock ignition
let decimal ignition_advance = 8E-3 // spark triggered 8ms before TDC
// Get ignition delay after TDC from ignition advance and RPMs
let rational period = [rational $one_minute] / $rpm
let rational ignition_delay = $period - $ignition_advance
// Ignition 8ms before compression TDC = 30ms - 8ms = 22ms after exhaust TDC at 2000rpm

// Trigger ignition
exhaust_tdc time delayed by $ignition_delay on realtime implies ignition

@tagref camshaft
@maxstep 8
@output svg  select realtime, crankshaft, top_dead_center, camshaft, exhaust_tdc, compress_tdc, ignition
             from 0 to 550
             xscale 0.5    // for camshaft time scale
             border="-10 0 0 5" standalone

This specification gives the following result, with the camshaft angle as global timeline:

we can see that an ignition advance of 8ms corresponds to an advance of 48° measured on the camshaft when the engine runs at 2000rpm.