<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>calibration - BlownByTwins</title>
	<atom:link href="https://blownbytwins.co.uk/tag/calibration/feed/" rel="self" type="application/rss+xml" />
	<link>https://blownbytwins.co.uk</link>
	<description>Just a tale of one man and his cars...</description>
	<lastBuildDate>Sat, 24 Oct 2026 15:03:59 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://blownbytwins.co.uk/wp-content/uploads/2023/05/cropped-wp20128381-1-32x32.jpg</url>
	<title>calibration - BlownByTwins</title>
	<link>https://blownbytwins.co.uk</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Tuning the Supra’s Boost Control: PID Gains Were Only Part of the Problem</title>
		<link>https://blownbytwins.co.uk/cars/mk4-supra/supra-boost-control-pid-initial-position/</link>
		
		<dc:creator><![CDATA[john]]></dc:creator>
		<pubDate>Sat, 24 Oct 2026 15:03:56 +0000</pubDate>
				<category><![CDATA[Mk4 Supra]]></category>
		<category><![CDATA[Tuning]]></category>
		<category><![CDATA[2jz]]></category>
		<category><![CDATA[boost control]]></category>
		<category><![CDATA[calibration]]></category>
		<category><![CDATA[emtron]]></category>
		<category><![CDATA[feedforward]]></category>
		<category><![CDATA[pid]]></category>
		<category><![CDATA[supra]]></category>
		<category><![CDATA[tuning]]></category>
		<category><![CDATA[turbo]]></category>
		<category><![CDATA[wastegate]]></category>
		<guid isPermaLink="false">https://blownbytwins.co.uk/?p=1239</guid>

					<description><![CDATA[<p>The latest boost-control work on my Supra started with the PID tables. It ended up exposing a problem in the initial wastegate-duty table that PID alone wasn’t dealing with effectively.&#8230;</p>
<p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/supra-boost-control-pid-initial-position/">Tuning the Supra’s Boost Control: PID Gains Were Only Part of the Problem</a> first appeared on <a href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
<p>The post <a rel="nofollow" href="https://blownbytwins.co.uk/cars/mk4-supra/supra-boost-control-pid-initial-position/">Tuning the Supra’s Boost Control: PID Gains Were Only Part of the Problem</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">The latest boost-control work on my Supra started with the PID tables. It ended up exposing a problem in the initial wastegate-duty table that PID alone wasn’t dealing with effectively.</p>



<p class="wp-block-paragraph">Boost demand is influenced by the torque model, so the target moves with operating conditions. That makes Boost Target Error the useful measure: how closely actual pressure follows what the ECU is requesting.</p>



<p class="wp-block-paragraph">A steady target makes diagnosis easier, but the car needs to track changing demand properly too.</p>



<p class="wp-block-paragraph">How the target is built, and the PID tables as they stood before this work, are in <a href="https://blownbytwins.co.uk/cars/mk4-supra/boost-control-emtron-kv12/">Boost Control on the Emtron KV12: Where the Target Really Comes From</a>. That post describes refining the initial position table by no more than 3 percent at a time. The changes here are much larger, and they are provisional.</p>



<h2 class="wp-block-heading">What the original logs showed</h2>



<p class="wp-block-paragraph">The earlier logs contained periods where boost remained around 10–25 kPa below target, alongside substantial changes in wastegate duty.</p>



<p class="wp-block-paragraph">Three features of the original calibration stood out:</p>



<ul class="wp-block-list">
<li>An isolated 10.00 proportional-gain cell, at −25 kPa error with manifold pressure rising at 5 %/second, compared with 0.50 in every other cell at that error.</li>



<li>Integral gain dropping to zero at ±10 kPa error, limiting its ability to correct a sustained deficit outside the narrow near-target region.</li>



<li>Derivative output making sizeable contributions to duty during some transients.</li>
</ul>



<p class="wp-block-paragraph">Those observations justified investigating the tables, but they didn’t establish a complete replacement calibration. Some logs also had gaps exceeding a second and channels updating at different rates. That limits how confidently individual output changes can be tied to events happening a few hundredths of a second apart.</p>



<h2 class="wp-block-heading">The first PID revision</h2>



<p class="wp-block-paragraph">The first revision removed the isolated proportional-gain spike, extended modest integral action further from target and reduced the positive-error derivative gains.</p>



<p class="wp-block-paragraph">These were trial values, not a finished calibration.</p>



<h3 class="wp-block-heading">Proportional gain</h3>



<figure class='bbt-figure' style='margin:1.8rem 0'><table style='border-collapse:collapse;width:100%;max-width:340px;font-size:0.85rem'><thead><tr style='border-bottom:2px solid #333'><th style='text-align:left;padding:6px 8px'>Error, kPa</th><th style='text-align:right;padding:6px 8px'>P gain</th></tr></thead><tbody>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−25</td><td style='text-align:right;padding:6px 8px'>0.50</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−10</td><td style='text-align:right;padding:6px 8px'>0.20</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−5</td><td style='text-align:right;padding:6px 8px'>0.20</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−2</td><td style='text-align:right;padding:6px 8px'>0.10</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+2</td><td style='text-align:right;padding:6px 8px'>0.10</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+5</td><td style='text-align:right;padding:6px 8px'>0.50</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+10</td><td style='text-align:right;padding:6px 8px'>0.50</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+25</td><td style='text-align:right;padding:6px 8px'>0.50</td></tr>
</tbody></table><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Proportional Gain Table after the first revision. All six dMAP rows (−5, −2, −1, +1, +2 and +5 %/second) are identical. The original differed in one cell only: 10.00 at −25 kPa and +5 %/second.</figcaption></figure>



<p class="wp-block-paragraph">The only change from the original was the 10.00 cell. With it gone, proportional gain no longer depends on how fast pressure is rising.</p>



<p class="wp-block-paragraph">That made the gain surface consistent. It did not establish that overshoot would improve. That cell was the overboost catch: boost well above target and still climbing was the one situation where the controller was allowed to hit hard. Removing it removes that correction too.</p>



<p class="wp-block-paragraph">The table is also asymmetric, which was inherited rather than introduced. Gain is 0.20 at −5 and −10 kPa, against 0.50 at +5 and +10 kPa. Proportional correction is weaker when boost is above target than when it is below.</p>



<h3 class="wp-block-heading">Integral gain</h3>



<figure class='bbt-figure' style='margin:1.8rem 0'><table style='border-collapse:collapse;width:100%;max-width:340px;font-size:0.85rem'><thead><tr style='border-bottom:2px solid #333'><th style='text-align:left;padding:6px 8px'>Error, kPa</th><th style='text-align:right;padding:6px 8px'>I gain</th></tr></thead><tbody>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−50</td><td style='text-align:right;padding:6px 8px'>0.000</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−10</td><td style='text-align:right;padding:6px 8px'>0.010</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−5</td><td style='text-align:right;padding:6px 8px'>0.018</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−2</td><td style='text-align:right;padding:6px 8px'>0.025</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+2</td><td style='text-align:right;padding:6px 8px'>0.025</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+5</td><td style='text-align:right;padding:6px 8px'>0.018</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+10</td><td style='text-align:right;padding:6px 8px'>0.010</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+50</td><td style='text-align:right;padding:6px 8px'>0.000</td></tr>
</tbody></table><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Integral Gain Table after the first revision. In the original, gain was zero at ±10 kPa and beyond.</figcaption></figure>



<p class="wp-block-paragraph">The near-target values stayed unchanged. Adding 0.010 at ±10 kPa allowed integral action to extend beyond the original narrow region, tapering towards zero at ±50 kPa.</p>



<p class="wp-block-paragraph">The integral limits remained ±5 duty percentage points.</p>



<h3 class="wp-block-heading">Derivative gain</h3>



<figure class='bbt-figure' style='margin:1.8rem 0'><table style='border-collapse:collapse;width:100%;max-width:340px;font-size:0.85rem'><thead><tr style='border-bottom:2px solid #333'><th style='text-align:left;padding:6px 8px'>Error, kPa</th><th style='text-align:right;padding:6px 8px'>D gain</th></tr></thead><tbody>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−50</td><td style='text-align:right;padding:6px 8px'>3.00</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>−40</td><td style='text-align:right;padding:6px 8px'>0.00</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>0</td><td style='text-align:right;padding:6px 8px'>0.00</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+5</td><td style='text-align:right;padding:6px 8px'>0.00</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+10</td><td style='text-align:right;padding:6px 8px'>1.50</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+20</td><td style='text-align:right;padding:6px 8px'>1.50</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+25</td><td style='text-align:right;padding:6px 8px'>1.50</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>+60</td><td style='text-align:right;padding:6px 8px'>0.00</td></tr>
</tbody></table><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Derivative Gain Table after the first revision. The +10 to +25 kPa cells were 3.00 in the original.</figcaption></figure>



<p class="wp-block-paragraph">The gains at +10, +20 and +25 kPa were halved from 3.00 to 1.50. The negative-error end was retained.</p>



<p class="wp-block-paragraph">The output limits remained 5–80% duty, and the initial-position table was initially left unchanged.</p>



<p class="wp-block-paragraph">That last decision became important.</p>



<h2 class="wp-block-heading">Why boost status mattered</h2>



<p class="wp-block-paragraph">Some of the earlier duty changes coincided with changes between Emtron boost status 15: ON–Mass Flow Limit and 1: ON.</p>



<p class="wp-block-paragraph">Those transitions could change both the final boost target and the initial duty selected from the table. A sharp duty change therefore wasn’t automatically evidence of a PID problem.</p>



<p class="wp-block-paragraph">The distinction matters on this car because the final boost request is influenced by the torque model. Looking only at the base target, or only at the PID outputs, misses part of the control sequence.</p>



<p class="wp-block-paragraph">Boost system status and boost PID status are also separate channels. Their numbers cannot be interpreted interchangeably.</p>



<p class="wp-block-paragraph">Status names are from Emtron’s <a href="https://docs.emtronaustralia.com.au/engine-management/reference/enums/boost-status/index.html" target="_blank" rel="noopener">Boost Status reference</a>.</p>



<p class="wp-block-paragraph">The sixth-gear log below shows how large those transitions are. Between about 3,000 and 3,100 rpm, the status flipped between 1: ON and 15: ON–Mass Flow Limit four times. Each flip moved the target between 290 kPa and roughly 190–200 kPa, and moved commanded duty between 80% and about 31%. None of that was the PID.</p>



<p class="wp-block-paragraph">At a target near 190 kPa the initial position also read zero, because the table holds zero at 200 kPa and below. From about 3,100 rpm the status stayed at 15 for the rest of the pull, so the whole overshoot happened with the mass flow limit setting the target.</p>



<h2 class="wp-block-heading">The run that exposed the overshoot</h2>



<p class="wp-block-paragraph">The next useful log contained a sixth-gear pull from approximately 3,000 to 4,300 rpm, with no shift recorded during the pull.</p>



<p class="wp-block-paragraph">It showed a clear overshoot:</p>



<figure class='bbt-figure' style='margin:1.8rem 0'><table style='border-collapse:collapse;width:100%;font-size:0.85rem'><thead><tr style='border-bottom:2px solid #333'><th style='text-align:left;padding:6px 8px'>Measurement</th><th style='text-align:right;padding:6px 8px'>Recorded result</th></tr></thead><tbody>
<tr style='border-bottom:1px solid #ddd'><td style='padding:6px 8px'>Worst logged Boost Target Error</td><td style='text-align:right;padding:6px 8px'>−57.6 kPa / −8.4 psi</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='padding:6px 8px'>Peak manifold pressure</td><td style='text-align:right;padding:6px 8px'>326.9 kPa absolute</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='padding:6px 8px'>Peak gauge boost</td><td style='text-align:right;padding:6px 8px'>223.7 kPa / 32.4 psi</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='padding:6px 8px'>Approximate time more than 10 kPa above target</td><td style='text-align:right;padding:6px 8px'>0.9 seconds</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='padding:6px 8px'>Median error in the short final tracking section</td><td style='text-align:right;padding:6px 8px'>+4.9 kPa / +0.7 psi</td></tr>
</tbody></table><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Sixth-gear pull, approximately 3,000 to 4,300 rpm, on the first PID revision with the original initial position table.</figcaption></figure>



<p class="wp-block-paragraph">Positive error means actual pressure is below target. Negative error means it is above target.</p>



<p class="wp-block-paragraph">This wasn’t simply an apparent overshoot caused by the target suddenly falling. During the initial pressure rise above target, the target itself increased from approximately 261 to 271 kPa absolute.</p>



<p class="wp-block-paragraph">Actual pressure climbed much faster.</p>



<p class="wp-block-paragraph">The maximum logged error and maximum manifold pressure occurred at slightly different timestamps. With independently updating channels, those figures should not be forced into an exact same-row calculation.</p>



<figure class='bbt-figure' style='margin:1.8rem 0'><svg viewBox='0 0 380 466' role='img' aria-labelledby='bbtc1t bbtc1d' xmlns='http://www.w3.org/2000/svg' style='width:100%;max-width:480px;height:auto;display:block;background:#ffffff;font-family:inherit;font-size:13px'><title id='bbtc1t'>Boost target, manifold pressure and Boost Target Error during the sixth-gear pull</title><desc id='bbtc1d'>Manifold pressure crosses the boost target at about 3,680 rpm and peaks at 326.9 kPa absolute while the target is about 271 kPa. Boost Target Error reaches minus 57.6 kPa and stays more than 10 kPa above target for about 0.9 seconds.</desc><rect x='138.0' y='84' width='94.8' height='170' fill='#f3f2ef'/><rect x='138.0' y='294' width='94.8' height='120' fill='#f3f2ef'/><line x1='40' x2='370' y1='254.0' y2='254.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='258.0' text-anchor='end' fill='#52514e'>150</text><line x1='40' x2='370' y1='211.5' y2='211.5' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='215.5' text-anchor='end' fill='#52514e'>200</text><line x1='40' x2='370' y1='169.0' y2='169.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='173.0' text-anchor='end' fill='#52514e'>250</text><line x1='40' x2='370' y1='126.5' y2='126.5' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='130.5' text-anchor='end' fill='#52514e'>300</text><line x1='40' x2='370' y1='84.0' y2='84.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='88.0' text-anchor='end' fill='#52514e'>350</text><text x='40.0' y='16.0' text-anchor='start' fill='#0b0b0b' font-weight='600'>Pressure, kPa absolute</text><line x1='40' x2='370' y1='414.0' y2='414.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='418.0' text-anchor='end' fill='#52514e'>−60</text><line x1='40' x2='370' y1='390.0' y2='390.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='394.0' text-anchor='end' fill='#52514e'>−40</text><line x1='40' x2='370' y1='366.0' y2='366.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='370.0' text-anchor='end' fill='#52514e'>−20</text><line x1='40' x2='370' y1='342.0' y2='342.0' stroke='#b9b8b2' stroke-width='1'/><text x='34' y='346.0' text-anchor='end' fill='#52514e'>0</text><line x1='40' x2='370' y1='318.0' y2='318.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='322.0' text-anchor='end' fill='#52514e'>20</text><line x1='40' x2='370' y1='294.0' y2='294.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='298.0' text-anchor='end' fill='#52514e'>40</text><line x1='58.6' x2='58.6' y1='66' y2='71' stroke='#b9b8b2'/><text x='58.6' y='62' text-anchor='middle' fill='#52514e'>3,500 rpm</text><line x1='135.6' x2='135.6' y1='66' y2='71' stroke='#b9b8b2'/><text x='135.6' y='62' text-anchor='middle' fill='#52514e'>3,700</text><line x1='199.4' x2='199.4' y1='66' y2='71' stroke='#b9b8b2'/><text x='199.4' y='62' text-anchor='middle' fill='#52514e'>3,900</text><line x1='291.1' x2='291.1' y1='66' y2='71' stroke='#b9b8b2'/><text x='291.1' y='62' text-anchor='middle' fill='#52514e'>4,100</text><line x1='40' x2='56' y1='36' y2='36' stroke='#2a78d6' stroke-width='2' stroke-linecap='round'/><text x='62' y='40' fill='#0b0b0b'>Manifold pressure</text><line x1='196.4' x2='212.4' y1='36' y2='36' stroke='#eb6834' stroke-width='2' stroke-linecap='round'/><text x='218.4' y='40' fill='#0b0b0b'>Boost target</text><path d='M42.3,183.1 L45.6,181.9 L52.2,181.4 L58.6,180.6 L62.0,179.7 L66.8,177.7 L73.4,176.7 L78.3,175.5 L83.3,173.9 L88.2,173.2 L94.7,170.9 L99.6,169.1 L104.5,167.5 L111.0,166.2 L116.0,164.2 L119.2,160.5 L125.8,160.4 L132.3,159.4 L135.6,158.5 L140.6,157.6 L145.4,157.0 L148.7,156.8 L153.7,155.5 L160.2,154.5 L165.1,152.9 L168.3,152.0 L171.6,151.2 L178.2,150.7 L183.1,150.9 L188.0,151.2 L193.0,151.7 L199.4,153.5 L204.4,155.4 L209.3,155.5 L214.2,155.5 L219.1,155.7 L224.0,156.8 L227.3,156.2 L233.8,156.4 L237.1,156.9 L243.7,157.0 L248.6,157.6 L253.5,158.0 L258.4,159.0 L264.9,158.1 L269.8,159.3 L274.8,159.1 L279.7,159.8 L284.6,163.9 L291.1,160.8 L297.7,160.0 L305.9,159.7 L309.1,159.7 L314.1,158.8 L319.0,159.0 L320.6,159.2 L323.9,159.2 L328.7,158.8 L335.3,158.6 L340.2,158.6 L345.2,158.9 L348.4,159.7 L353.3,159.5 L358.3,160.0 L363.2,159.6 L369.7,159.4' fill='none' stroke='#eb6834' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'/><path d='M42.3,214.2 L45.6,212.7 L52.2,210.5 L58.6,208.2 L62.0,205.6 L66.8,203.8 L73.4,200.1 L78.3,196.8 L83.3,194.2 L88.2,190.5 L94.7,188.5 L99.6,185.8 L104.5,181.0 L111.0,176.1 L116.0,173.3 L119.2,169.1 L125.8,163.7 L132.3,157.6 L135.6,152.9 L140.6,146.3 L145.4,141.4 L148.7,135.9 L153.7,128.9 L160.2,121.6 L165.1,116.2 L168.3,111.3 L171.6,107.9 L178.2,105.1 L183.1,103.6 L188.0,106.3 L193.0,115.2 L199.4,122.7 L204.4,129.2 L209.3,131.5 L214.2,134.6 L219.1,134.3 L224.0,140.6 L227.3,144.0 L233.8,149.9 L237.1,153.4 L243.7,156.0 L248.6,157.5 L253.5,159.1 L258.4,160.2 L264.9,162.0 L269.8,163.6 L274.8,166.4 L279.7,165.9 L284.6,168.1 L291.1,168.1 L297.7,166.5 L305.9,167.0 L309.1,163.3 L314.1,162.6 L319.0,162.4 L320.6,162.3 L323.9,163.4 L328.7,160.6 L335.3,163.0 L340.2,163.8 L345.2,162.5 L348.4,162.3 L353.3,163.4 L358.3,164.9 L363.2,166.4 L369.7,167.1' fill='none' stroke='#2a78d6' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'/><circle cx='183.1' cy='103.6' r='4.5' fill='#2a78d6' stroke='#ffffff' stroke-width='2'/><text x='191.1' y='107.6' text-anchor='start' fill='#0b0b0b' font-weight='normal'>326.9 kPa</text><text x='40.0' y='284.0' text-anchor='start' fill='#0b0b0b' font-weight='600'>Boost Target Error, kPa (+ = below target)</text><path d='M42.3,296.4 L45.6,299.6 L52.2,300.1 L58.6,304.0 L62.0,304.9 L66.8,306.0 L73.4,308.9 L78.3,310.3 L83.3,313.7 L88.2,316.6 L94.7,316.0 L99.6,318.8 L104.5,322.4 L111.0,328.3 L116.0,328.2 L119.2,331.3 L125.8,338.0 L132.3,344.6 L135.6,350.5 L140.6,358.0 L145.4,363.7 L148.7,369.2 L153.7,375.4 L160.2,390.1 L165.1,393.5 L168.3,400.9 L171.6,403.4 L178.2,411.1 L183.1,406.8 L188.0,405.4 L193.0,396.7 L199.4,385.6 L204.4,377.8 L209.3,377.9 L214.2,373.2 L219.1,371.2 L224.0,364.4 L227.3,357.1 L233.8,353.4 L237.1,350.3 L243.7,341.9 L248.6,341.8 L253.5,340.1 L258.4,340.6 L264.9,336.1 L269.8,335.9 L274.8,331.7 L279.7,332.6 L284.6,336.1 L291.1,331.1 L297.7,329.4 L305.9,331.7 L309.1,338.0 L314.1,333.1 L319.0,338.2 L320.6,338.5 L323.9,338.0 L328.7,339.2 L335.3,335.9 L340.2,337.6 L345.2,337.2 L348.4,339.2 L353.3,332.3 L358.3,337.0 L363.2,334.3 L369.7,332.6' fill='none' stroke='#2a78d6' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'/><circle cx='178.2' cy='411.1' r='4.5' fill='#2a78d6' stroke='#ffffff' stroke-width='2'/><text x='186.2' y='415.1' text-anchor='start' fill='#0b0b0b' font-weight='normal'>−57.6 kPa</text><text x='263.7' y='385.2' text-anchor='start' fill='#52514e' font-weight='normal'>10+ kPa over</text><text x='263.7' y='400.2' text-anchor='start' fill='#52514e' font-weight='normal'>target, ~0.9 s</text><line x1='40' x2='370' y1='424' y2='424' stroke='#b9b8b2' stroke-width='1'/><line x1='48.9' x2='48.9' y1='424' y2='428' stroke='#b9b8b2'/><text x='48.9' y='441' text-anchor='middle' fill='#52514e'>3.5</text><line x1='101.3' x2='101.3' y1='424' y2='428' stroke='#b9b8b2'/><text x='101.3' y='441' text-anchor='middle' fill='#52514e'>4.0</text><line x1='153.7' x2='153.7' y1='424' y2='428' stroke='#b9b8b2'/><text x='153.7' y='441' text-anchor='middle' fill='#52514e'>4.5</text><line x1='206.0' x2='206.0' y1='424' y2='428' stroke='#b9b8b2'/><text x='206.0' y='441' text-anchor='middle' fill='#52514e'>5.0</text><line x1='258.4' x2='258.4' y1='424' y2='428' stroke='#b9b8b2'/><text x='258.4' y='441' text-anchor='middle' fill='#52514e'>5.5</text><line x1='310.8' x2='310.8' y1='424' y2='428' stroke='#b9b8b2'/><text x='310.8' y='441' text-anchor='middle' fill='#52514e'>6.0</text><line x1='363.2' x2='363.2' y1='424' y2='428' stroke='#b9b8b2'/><text x='363.2' y='441' text-anchor='middle' fill='#52514e'>6.5</text><text x='205.0' y='458' text-anchor='middle' fill='#52514e'>Seconds from full pedal</text></svg><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Logged 17 October 2026 on the first PID revision with the original initial position table. Shaded: more than 10 kPa above target.</figcaption></figure>



<h2 class="wp-block-heading">The initial-duty table explained much of it</h2>



<p class="wp-block-paragraph">At approximately 3,680 rpm, boost was almost on target:</p>



<ul class="wp-block-list">
<li>Boost Target Error: +3.3 kPa</li>



<li>Initial duty: 75.5%</li>



<li>Final commanded duty: 74.6%</li>
</ul>



<p class="wp-block-paragraph">The engine was already reaching the requested pressure while the controller was still commanding substantial spool duty.</p>



<p class="wp-block-paragraph">The original initial-position table held 100% duty through 3,500 rpm for target rows from 220 to 340 kPa. It then dropped sharply towards the values at 4,000 rpm.</p>



<figure class='bbt-figure' style='margin:1.8rem 0'><table style='border-collapse:collapse;width:100%;font-size:0.85rem;text-align:right'><thead><tr style='border-bottom:2px solid #333'><th style='text-align:left;padding:6px 8px'>Target vs rpm</th><th style='padding:6px 8px'>2,000 to 3,500</th><th style='padding:6px 8px'>4,000</th><th style='padding:6px 8px'>4,500</th></tr></thead><tbody>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>220 kPa</td><td style='padding:6px 8px'>100</td><td style='padding:6px 8px'>26.5</td><td style='padding:6px 8px'>20.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>240 kPa</td><td style='padding:6px 8px'>100</td><td style='padding:6px 8px'>28.0</td><td style='padding:6px 8px'>22.5</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>250 kPa</td><td style='padding:6px 8px'>100</td><td style='padding:6px 8px'>29.0</td><td style='padding:6px 8px'>24.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>260 kPa</td><td style='padding:6px 8px'>100</td><td style='padding:6px 8px'>29.5</td><td style='padding:6px 8px'>25.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>280 kPa</td><td style='padding:6px 8px'>100</td><td style='padding:6px 8px'>31.0</td><td style='padding:6px 8px'>28.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>300 kPa</td><td style='padding:6px 8px'>100</td><td style='padding:6px 8px'>32.5</td><td style='padding:6px 8px'>30.5</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>320 kPa</td><td style='padding:6px 8px'>100</td><td style='padding:6px 8px'>35.5</td><td style='padding:6px 8px'>33.5</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>340 kPa</td><td style='padding:6px 8px'>100</td><td style='padding:6px 8px'>40.0</td><td style='padding:6px 8px'>36.5</td></tr>
</tbody></table><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Initial Position Table, % duty, before this revision. This is the table the first PID revision ran with. Rows below 220 kPa are zero throughout, as are the 1,000 and 1,500 rpm columns.</figcaption></figure>



<p class="wp-block-paragraph">For the 260 kPa target row, interpolation produced this curve:</p>



<figure class='bbt-figure' style='margin:1.8rem 0'><table style='border-collapse:collapse;width:100%;max-width:340px;font-size:0.85rem'><thead><tr style='border-bottom:2px solid #333'><th style='text-align:left;padding:6px 8px'>Engine speed, rpm</th><th style='text-align:right;padding:6px 8px'>Initial duty, %</th></tr></thead><tbody>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>3,500</td><td style='text-align:right;padding:6px 8px'>100.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>3,600</td><td style='text-align:right;padding:6px 8px'>85.9</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>3,700</td><td style='text-align:right;padding:6px 8px'>71.8</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>3,800</td><td style='text-align:right;padding:6px 8px'>57.7</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>3,900</td><td style='text-align:right;padding:6px 8px'>43.6</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>4,000</td><td style='text-align:right;padding:6px 8px'>29.5</td></tr>
</tbody></table><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Original initial position at a 260 kPa target, interpolated between the 3,500 and 4,000 rpm breakpoints. Anything above 80% is commanded as 80% by the output limit.</figcaption></figure>



<p class="wp-block-paragraph">The table tapered spool assistance according to engine speed, without directly accounting for how close actual boost had come to target.</p>



<p class="wp-block-paragraph">In this sixth-gear pull, boost reached target before RPM had advanced far enough through that taper. Feedback then had to remove a large amount of duty while pressure was already rising rapidly.</p>



<p class="wp-block-paragraph">Between target crossing and the pressure peak, about half a second, the taper itself took initial duty from 75.5% to about 51%, and P removed roughly another 26 points. Pressure kept rising anyway.</p>



<p class="wp-block-paragraph">That strongly implicated the feedforward transition. It did not prove that every aspect of the overshoot came from that table.</p>



<h2 class="wp-block-heading">What P, I and D were doing</h2>



<p class="wp-block-paragraph">The individual outputs helped separate the causes.</p>



<p class="wp-block-paragraph"><strong>P was correcting the overshoot.</strong> It eventually removed approximately 27 duty percentage points. That correction arrived as negative error developed, but it did not prevent the pressure peak.</p>



<p class="wp-block-paragraph">It was also starting from its weakest settings. Between −2 and −10 kPa the gain was 0.10 to 0.20, reaching 0.50 only at −25 kPa. This overshoot passed −25 kPa with pressure still rising, which is the region the removed 10.00 cell used to cover. The log can’t show what that cell would have done, but this run went through the conditions it was there for.</p>



<p class="wp-block-paragraph"><strong>I was not winding up and driving the event.</strong> Integral output was approximately zero at target crossing and slightly negative at the peak. Increasing integral correction would not address the main cause shown here.</p>



<p class="wp-block-paragraph"><strong>D had a gap around target crossing.</strong> The revised table had zero derivative gain from +5 to −40 kPa error, as the original did.</p>



<p class="wp-block-paragraph">As error approached zero from the positive side, derivative gain tapered away. It then remained zero through the first 40 kPa of overboost, approximately 5.8 psi. Gain only returns beyond −40 kPa, reaching 3.00 at −50. With a worst logged error of −57.6 kPa, derivative gain was available only over the last 18 kPa or so of the overshoot.</p>



<p class="wp-block-paragraph">The log shows what that did. Above target, derivative output was zero from about −13 kPa to beyond −50 kPa. Its only negative contribution there was −2.1 points, at the peak. As pressure began to fall it switched to +6 and then +12 points, with boost still 30 to 50 kPa over target.</p>



<p class="wp-block-paragraph">That is derivative doing its job, resisting the rate of change. Here, though, it was adding duty to an engine that was still overboosting, and final commanded duty briefly climbed from 17% back to 46% in that window. On this run, the −50 kPa end of the D table added more duty during recovery than it removed at the peak.</p>



<p class="wp-block-paragraph">The combination was the problem: high initial duty approaching target, with weak proportional and no derivative correction through target crossing.</p>



<p class="wp-block-paragraph">The first D revision had retained that gap. The later log showed why it could not be treated as a validated overshoot-control calibration.</p>



<figure class='bbt-figure' style='margin:1.8rem 0'><svg viewBox='0 0 380 490' role='img' aria-labelledby='bbtc2t bbtc2d' xmlns='http://www.w3.org/2000/svg' style='width:100%;max-width:480px;height:auto;display:block;background:#ffffff;font-family:inherit;font-size:13px'><title id='bbtc2t'>Initial position, final commanded duty and P, I and D outputs during the sixth-gear pull</title><desc id='bbtc2d'>Initial position holds 100% (commanded as 80%) until about 3,530 rpm, then tapers. At 3,682 rpm and +3.3 kPa error the final duty is 74.6%. Proportional output falls to minus 26.7% near the peak; integral stays between zero and minus 1.8%; derivative is zero above target until the peak, then adds up to 12% during recovery.</desc><rect x='138.0' y='84' width='94.8' height='160' fill='#f3f2ef'/><rect x='138.0' y='288' width='94.8' height='130' fill='#f3f2ef'/><line x1='40' x2='370' y1='244.0' y2='244.0' stroke='#b9b8b2' stroke-width='1'/><text x='34' y='248.0' text-anchor='end' fill='#52514e'>0</text><line x1='40' x2='370' y1='212.0' y2='212.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='216.0' text-anchor='end' fill='#52514e'>20</text><line x1='40' x2='370' y1='180.0' y2='180.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='184.0' text-anchor='end' fill='#52514e'>40</text><line x1='40' x2='370' y1='148.0' y2='148.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='152.0' text-anchor='end' fill='#52514e'>60</text><line x1='40' x2='370' y1='116.0' y2='116.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='120.0' text-anchor='end' fill='#52514e'>80</text><line x1='40' x2='370' y1='84.0' y2='84.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='88.0' text-anchor='end' fill='#52514e'>100</text><text x='40.0' y='16.0' text-anchor='start' fill='#0b0b0b' font-weight='600'>Wastegate duty, %</text><line x1='40' x2='370' y1='418.0' y2='418.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='422.0' text-anchor='end' fill='#52514e'>−30</text><line x1='40' x2='370' y1='392.0' y2='392.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='396.0' text-anchor='end' fill='#52514e'>−20</text><line x1='40' x2='370' y1='366.0' y2='366.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='370.0' text-anchor='end' fill='#52514e'>−10</text><line x1='40' x2='370' y1='340.0' y2='340.0' stroke='#b9b8b2' stroke-width='1'/><text x='34' y='344.0' text-anchor='end' fill='#52514e'>0</text><line x1='40' x2='370' y1='314.0' y2='314.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='318.0' text-anchor='end' fill='#52514e'>10</text><line x1='40' x2='370' y1='288.0' y2='288.0' stroke='#e6e5e1' stroke-width='1'/><text x='34' y='292.0' text-anchor='end' fill='#52514e'>20</text><line x1='58.6' x2='58.6' y1='66' y2='71' stroke='#b9b8b2'/><text x='58.6' y='62' text-anchor='middle' fill='#52514e'>3,500 rpm</text><line x1='135.6' x2='135.6' y1='66' y2='71' stroke='#b9b8b2'/><text x='135.6' y='62' text-anchor='middle' fill='#52514e'>3,700</text><line x1='199.4' x2='199.4' y1='66' y2='71' stroke='#b9b8b2'/><text x='199.4' y='62' text-anchor='middle' fill='#52514e'>3,900</text><line x1='291.1' x2='291.1' y1='66' y2='71' stroke='#b9b8b2'/><text x='291.1' y='62' text-anchor='middle' fill='#52514e'>4,100</text><line x1='40' x2='56' y1='36' y2='36' stroke='#2a78d6' stroke-width='2' stroke-linecap='round'/><text x='62' y='40' fill='#0b0b0b'>Initial position</text><line x1='189.2' x2='205.2' y1='36' y2='36' stroke='#eb6834' stroke-width='2' stroke-linecap='round'/><text x='211.2' y='40' fill='#0b0b0b'>Final commanded duty</text><line x1='40' x2='370' y1='116.0' y2='116.0' stroke='#8a8984' stroke-width='1'/><text x='366.0' y='111.0' text-anchor='end' fill='#52514e' font-weight='normal'>80% output limit</text><path d='M42.3,84.0 L45.6,84.0 L52.2,84.0 L58.6,85.6 L62.0,86.4 L66.8,90.4 L73.4,92.0 L78.3,92.8 L83.3,99.2 L88.2,99.2 L94.7,103.2 L99.6,107.2 L104.5,104.0 L111.0,106.4 L116.0,114.4 L119.2,116.0 L125.8,123.2 L132.3,127.2 L135.6,130.4 L140.6,131.2 L145.4,130.4 L148.7,136.0 L153.7,138.4 L160.2,146.4 L165.1,144.0 L168.3,149.6 L171.6,157.6 L178.2,150.4 L183.1,162.4 L188.0,160.0 L193.0,157.6 L199.4,166.4 L204.4,165.6 L209.3,182.4 L214.2,184.8 L219.1,181.6 L224.0,188.8 L227.3,188.8 L233.8,195.2 L237.1,180.8 L243.7,188.8 L248.6,196.8 L253.5,196.8 L258.4,196.8 L264.9,196.8 L269.8,197.6 L274.8,197.6 L279.7,197.6 L284.6,198.4 L291.1,199.2 L297.7,198.4 L305.9,199.2 L309.1,199.2 L314.1,199.2 L319.0,199.2 L320.6,199.2 L323.9,199.2 L328.7,198.4 L335.3,200.0 L340.2,200.0 L345.2,200.0 L348.4,200.0 L353.3,200.0 L358.3,200.8 L363.2,200.8 L369.7,200.8' fill='none' stroke='#2a78d6' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'/><path d='M42.3,116.0 L45.6,116.0 L52.2,116.0 L58.6,116.0 L62.0,116.0 L66.8,116.0 L73.4,116.0 L78.3,116.0 L83.3,116.0 L88.2,116.0 L94.7,116.0 L99.6,116.0 L104.5,116.0 L111.0,116.0 L116.0,116.0 L119.2,116.0 L125.8,124.6 L132.3,127.5 L135.6,129.1 L140.6,136.6 L145.4,140.0 L148.7,153.4 L153.7,161.6 L160.2,167.8 L165.1,184.5 L168.3,188.0 L171.6,198.1 L178.2,198.7 L183.1,217.0 L188.0,200.3 L193.0,170.1 L199.4,194.1 L204.4,190.2 L209.3,208.3 L214.2,207.5 L219.1,199.2 L224.0,197.8 L227.3,201.3 L233.8,201.3 L237.1,185.1 L243.7,192.2 L248.6,200.2 L253.5,199.7 L258.4,199.4 L264.9,198.1 L269.8,196.6 L274.8,194.6 L279.7,193.4 L284.6,188.8 L291.1,196.6 L297.7,196.5 L305.9,193.1 L309.1,199.7 L314.1,197.9 L319.0,196.3 L320.6,198.4 L323.9,198.6 L328.7,198.6 L335.3,198.2 L340.2,197.1 L345.2,199.0 L348.4,198.9 L353.3,195.2 L358.3,198.2 L363.2,194.1 L369.7,194.1' fill='none' stroke='#eb6834' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'/><circle cx='125.8' cy='124.6' r='4.5' fill='#eb6834' stroke='#ffffff' stroke-width='2'/><line x1='88.0' y1='172.4' x2='125.8' y2='130.6' stroke='#52514e' stroke-width='1'/><text x='48.0' y='186.4' text-anchor='start' fill='#0b0b0b' font-weight='normal'>74.6% at +3.3 kPa</text><text x='40.0' y='278.0' text-anchor='start' fill='#0b0b0b' font-weight='600'>PID contributions, % duty</text><path d='M42.3,340.0 L45.6,340.0 L45.6,340.0 L52.2,340.0 L52.2,340.0 L58.6,340.0 L58.6,339.7 L62.0,339.7 L62.0,339.7 L66.8,339.7 L66.8,339.7 L73.4,339.7 L73.4,339.7 L78.3,339.7 L78.3,339.7 L83.3,339.7 L83.3,340.0 L88.2,340.0 L88.2,340.0 L94.7,340.0 L94.7,339.7 L99.6,339.7 L99.6,339.7 L104.5,339.7 L104.5,339.7 L111.0,339.7 L111.0,339.7 L116.0,339.7 L116.0,340.0 L119.2,340.0 L119.2,340.0 L125.8,340.0 L125.8,340.0 L132.3,340.0 L132.3,340.0 L135.6,340.0 L135.6,340.0 L140.6,340.0 L140.6,340.3 L145.4,340.3 L145.4,340.3 L148.7,340.3 L148.7,340.3 L153.7,340.3 L153.7,341.3 L160.2,341.3 L160.2,341.3 L165.1,341.3 L165.1,342.3 L168.3,342.3 L168.3,342.3 L171.6,342.3 L171.6,342.3 L178.2,342.3 L178.2,342.3 L183.1,342.3 L183.1,342.3 L188.0,342.3 L188.0,342.3 L193.0,342.3 L193.0,342.3 L199.4,342.3 L199.4,342.3 L204.4,342.3 L204.4,342.3 L209.3,342.3 L209.3,343.1 L214.2,343.1 L214.2,343.1 L219.1,343.1 L219.1,343.1 L224.0,343.1 L224.0,343.9 L227.3,343.9 L227.3,343.9 L233.8,343.9 L233.8,344.4 L237.1,344.4 L237.1,344.4 L243.7,344.4 L243.7,344.4 L248.6,344.4 L248.6,344.7 L253.5,344.7 L253.5,344.7 L258.4,344.7 L258.4,344.4 L264.9,344.4 L264.9,344.4 L269.8,344.4 L269.8,343.9 L274.8,343.9 L274.8,343.9 L279.7,343.9 L279.7,343.9 L284.6,343.9 L284.6,342.6 L291.1,342.6 L291.1,342.6 L297.7,342.6 L297.7,342.1 L305.9,342.1 L305.9,342.1 L309.1,342.1 L309.1,341.6 L314.1,341.6 L314.1,341.6 L319.0,341.6 L319.0,340.8 L320.6,340.8 L320.6,340.8 L323.9,340.8 L323.9,340.8 L328.7,340.8 L328.7,340.5 L335.3,340.5 L335.3,340.5 L340.2,340.5 L340.2,340.5 L345.2,340.5 L345.2,340.0 L348.4,340.0 L348.4,340.0 L353.3,340.0 L353.3,340.0 L358.3,340.0 L358.3,339.2 L363.2,339.2 L363.2,339.2 L369.7,339.2 L369.7,338.2' fill='none' stroke='#eb6834' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'/><path d='M42.3,342.6 L45.6,342.6 L45.6,343.6 L52.2,343.6 L52.2,343.6 L58.6,343.6 L58.6,339.0 L62.0,339.0 L62.0,339.0 L66.8,339.0 L66.8,340.3 L73.4,340.3 L73.4,340.3 L78.3,340.3 L78.3,340.3 L83.3,340.3 L83.3,345.7 L88.2,345.7 L88.2,345.7 L94.7,345.7 L94.7,345.5 L99.6,345.5 L99.6,345.5 L104.5,345.5 L104.5,347.0 L111.0,347.0 L111.0,347.0 L116.0,347.0 L116.0,342.3 L119.2,342.3 L119.2,342.3 L125.8,342.3 L125.8,349.6 L132.3,349.6 L132.3,349.6 L135.6,349.6 L135.6,349.6 L140.6,349.6 L140.6,340.0 L145.4,340.0 L145.4,340.0 L148.7,340.0 L148.7,340.0 L153.7,340.0 L153.7,340.0 L160.2,340.0 L160.2,340.0 L165.1,340.0 L165.1,340.0 L168.3,340.0 L168.3,340.0 L171.6,340.0 L171.6,340.0 L178.2,340.0 L178.2,345.5 L183.1,345.5 L183.1,345.5 L188.0,345.5 L188.0,324.4 L193.0,324.4 L193.0,324.4 L199.4,324.4 L199.4,308.8 L204.4,308.8 L204.4,308.8 L209.3,308.8 L209.3,340.0 L214.2,340.0 L214.2,340.0 L219.1,340.0 L219.1,340.0 L224.0,340.0 L224.0,340.0 L227.3,340.0 L227.3,340.0 L233.8,340.0 L233.8,340.0 L237.1,340.0 L237.1,340.0 L243.7,340.0 L243.7,340.0 L248.6,340.0 L248.6,340.0 L253.5,340.0 L253.5,340.0 L258.4,340.0 L258.4,340.0 L264.9,340.0 L264.9,340.0 L269.8,340.0 L269.8,340.0 L274.8,340.0 L274.8,340.0 L279.7,340.0 L279.7,340.0 L284.6,340.0 L284.6,337.4 L291.1,337.4 L291.1,337.4 L297.7,337.4 L297.7,320.5 L305.9,320.5 L305.9,320.5 L309.1,320.5 L309.1,338.4 L314.1,338.4 L314.1,338.4 L319.0,338.4 L319.0,340.0 L320.6,340.0 L320.6,340.0 L323.9,340.0 L323.9,340.0 L328.7,340.0 L328.7,340.0 L335.3,340.0 L335.3,340.0 L340.2,340.0 L340.2,340.0 L345.2,340.0 L345.2,340.0 L348.4,340.0 L348.4,340.0 L353.3,340.0 L353.3,340.0 L358.3,340.0 L358.3,340.0 L363.2,340.0 L363.2,340.0 L369.7,340.0 L369.7,341.3' fill='none' stroke='#1baf7a' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'/><path d='M42.3,287.2 L45.6,287.2 L45.6,292.7 L52.2,292.7 L52.2,292.7 L58.6,292.7 L58.6,295.8 L62.0,295.8 L62.0,295.8 L66.8,295.8 L66.8,301.3 L73.4,301.3 L73.4,301.3 L78.3,301.3 L78.3,301.3 L83.3,301.3 L83.3,307.5 L88.2,307.5 L88.2,307.5 L94.7,307.5 L94.7,312.2 L99.6,312.2 L99.6,312.2 L104.5,312.2 L104.5,318.7 L111.0,318.7 L111.0,318.7 L116.0,318.7 L116.0,325.7 L119.2,325.7 L119.2,325.7 L125.8,325.7 L125.8,332.7 L132.3,332.7 L132.3,332.7 L135.6,332.7 L135.6,332.7 L140.6,332.7 L140.6,344.7 L145.4,344.7 L145.4,344.7 L148.7,344.7 L148.7,344.7 L153.7,344.7 L153.7,366.8 L160.2,366.8 L160.2,366.8 L165.1,366.8 L165.1,391.7 L168.3,391.7 L168.3,391.7 L171.6,391.7 L171.6,391.7 L178.2,391.7 L178.2,408.6 L183.1,408.6 L183.1,408.6 L188.0,408.6 L188.0,409.4 L193.0,409.4 L193.0,409.4 L199.4,409.4 L199.4,391.2 L204.4,391.2 L204.4,391.2 L209.3,391.2 L209.3,378.7 L214.2,378.7 L214.2,378.7 L219.1,378.7 L219.1,378.7 L224.0,378.7 L224.0,370.9 L227.3,370.9 L227.3,370.9 L233.8,370.9 L233.8,347.5 L237.1,347.5 L237.1,347.5 L243.7,347.5 L243.7,347.5 L248.6,347.5 L248.6,340.3 L253.5,340.3 L253.5,340.3 L258.4,340.3 L258.4,339.5 L264.9,339.5 L264.9,339.5 L269.8,339.5 L269.8,334.3 L274.8,334.3 L274.8,334.3 L279.7,334.3 L279.7,334.3 L284.6,334.3 L284.6,328.6 L291.1,328.6 L291.1,328.6 L297.7,328.6 L297.7,328.0 L305.9,328.0 L305.9,328.0 L309.1,328.0 L309.1,329.9 L314.1,329.9 L314.1,329.9 L319.0,329.9 L319.0,334.0 L320.6,334.0 L320.6,334.0 L323.9,334.0 L323.9,334.0 L328.7,334.0 L328.7,339.7 L335.3,339.7 L335.3,339.7 L340.2,339.7 L340.2,339.7 L345.2,339.7 L345.2,335.1 L348.4,335.1 L348.4,335.1 L353.3,335.1 L353.3,335.1 L358.3,335.1 L358.3,333.2 L363.2,333.2 L363.2,333.2 L369.7,333.2 L369.7,329.6' fill='none' stroke='#2a78d6' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'/><circle cx='188.0' cy='409.4' r='4.5' fill='#2a78d6' stroke='#ffffff' stroke-width='2'/><text x='178.0' y='424.4' text-anchor='end' fill='#0b0b0b' font-weight='normal'>P −26.7</text><circle cx='199.4' cy='308.8' r='4.5' fill='#1baf7a' stroke='#ffffff' stroke-width='2'/><text x='207.4' y='312.8' text-anchor='start' fill='#0b0b0b' font-weight='normal'>D +12.0</text><text x='254.6' y='359.7' text-anchor='start' fill='#0b0b0b' font-weight='normal'>I −1.8</text><line x1='40' x2='56' y1='476' y2='476' stroke='#2a78d6' stroke-width='2' stroke-linecap='round'/><text x='62' y='480' fill='#0b0b0b'>Proportional</text><line x1='160.4' x2='176.4' y1='476' y2='476' stroke='#eb6834' stroke-width='2' stroke-linecap='round'/><text x='182.4' y='480' fill='#0b0b0b'>Integral</text><line x1='252.0' x2='268.0' y1='476' y2='476' stroke='#1baf7a' stroke-width='2' stroke-linecap='round'/><text x='274.0' y='480' fill='#0b0b0b'>Derivative</text><line x1='40' x2='370' y1='428' y2='428' stroke='#b9b8b2' stroke-width='1'/><line x1='48.9' x2='48.9' y1='428' y2='432' stroke='#b9b8b2'/><text x='48.9' y='445' text-anchor='middle' fill='#52514e'>3.5</text><line x1='101.3' x2='101.3' y1='428' y2='432' stroke='#b9b8b2'/><text x='101.3' y='445' text-anchor='middle' fill='#52514e'>4.0</text><line x1='153.7' x2='153.7' y1='428' y2='432' stroke='#b9b8b2'/><text x='153.7' y='445' text-anchor='middle' fill='#52514e'>4.5</text><line x1='206.0' x2='206.0' y1='428' y2='432' stroke='#b9b8b2'/><text x='206.0' y='445' text-anchor='middle' fill='#52514e'>5.0</text><line x1='258.4' x2='258.4' y1='428' y2='432' stroke='#b9b8b2'/><text x='258.4' y='445' text-anchor='middle' fill='#52514e'>5.5</text><line x1='310.8' x2='310.8' y1='428' y2='432' stroke='#b9b8b2'/><text x='310.8' y='445' text-anchor='middle' fill='#52514e'>6.0</text><line x1='363.2' x2='363.2' y1='428' y2='432' stroke='#b9b8b2'/><text x='363.2' y='445' text-anchor='middle' fill='#52514e'>6.5</text><text x='205.0' y='462' text-anchor='middle' fill='#52514e'>Seconds from full pedal</text></svg><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Same pull. P, I and D update less often than the other channels in this log, so they are drawn as steps. Final commanded duty is clamped at 80%.</figcaption></figure>



<h2 class="wp-block-heading">Adding resolution where the problem occurred</h2>



<p class="wp-block-paragraph">Seven engine-speed breakpoints were added to the initial-position table: 3,250, 3,600, 3,700, 3,800, 3,900, 4,100 and 4,250 rpm.</p>



<p class="wp-block-paragraph">The existing 3,500 and 4,000 rpm breakpoints were kept. The 4,000 rpm values stayed as they were. The 3,500 rpm values did not: for the 220–280 kPa rows they came down from 100% to between 50 and 57%.</p>



<p class="wp-block-paragraph">Adding columns alone changes nothing if the new values simply reproduce the old interpolation. The purpose was to create enough resolution to reshape the transition deliberately.</p>



<p class="wp-block-paragraph">The revision reduced duty earlier and brought it closer to the existing 4,000 rpm values before the previous target-crossing point. It covers the 220–280 kPa rows from 3,250 to 3,900 rpm.</p>



<figure class='bbt-figure' style='margin:1.8rem 0'><div style='overflow-x:auto;-webkit-overflow-scrolling:touch'><table style='border-collapse:collapse;width:100%;min-width:520px;font-size:0.8rem;text-align:right;white-space:nowrap'><thead><tr style='border-bottom:2px solid #333'><th style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>Target</th><th style='padding:5px 6px'>3,250</th><th style='padding:5px 6px'>3,500</th><th style='padding:5px 6px'>3,600</th><th style='padding:5px 6px'>3,700</th><th style='padding:5px 6px'>3,800</th><th style='padding:5px 6px'>3,900</th><th style='padding:5px 6px'>4,000</th><th style='padding:5px 6px'>4,100</th><th style='padding:5px 6px'>4,250</th></tr></thead><tbody>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>220 kPa</td><td style='padding:5px 6px'><strong>80.0</strong></td><td style='padding:5px 6px'><strong>50.0</strong></td><td style='padding:5px 6px'><strong>42.0</strong></td><td style='padding:5px 6px'><strong>35.0</strong></td><td style='padding:5px 6px'><strong>30.0</strong></td><td style='padding:5px 6px'><strong>28.0</strong></td><td style='padding:5px 6px'>26.5</td><td style='padding:5px 6px'>25.0</td><td style='padding:5px 6px'>23.5</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>240 kPa</td><td style='padding:5px 6px'><strong>80.0</strong></td><td style='padding:5px 6px'><strong>52.0</strong></td><td style='padding:5px 6px'><strong>43.0</strong></td><td style='padding:5px 6px'><strong>36.0</strong></td><td style='padding:5px 6px'><strong>32.0</strong></td><td style='padding:5px 6px'><strong>30.0</strong></td><td style='padding:5px 6px'>28.0</td><td style='padding:5px 6px'>27.0</td><td style='padding:5px 6px'>25.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>250 kPa</td><td style='padding:5px 6px'><strong>80.0</strong></td><td style='padding:5px 6px'><strong>54.0</strong></td><td style='padding:5px 6px'><strong>44.0</strong></td><td style='padding:5px 6px'><strong>37.0</strong></td><td style='padding:5px 6px'><strong>33.0</strong></td><td style='padding:5px 6px'><strong>31.0</strong></td><td style='padding:5px 6px'>29.0</td><td style='padding:5px 6px'>28.0</td><td style='padding:5px 6px'>26.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>260 kPa</td><td style='padding:5px 6px'><strong>80.0</strong></td><td style='padding:5px 6px'><strong>55.0</strong></td><td style='padding:5px 6px'><strong>45.0</strong></td><td style='padding:5px 6px'><strong>38.0</strong></td><td style='padding:5px 6px'><strong>34.0</strong></td><td style='padding:5px 6px'><strong>31.5</strong></td><td style='padding:5px 6px'>29.5</td><td style='padding:5px 6px'>28.5</td><td style='padding:5px 6px'>27.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>280 kPa</td><td style='padding:5px 6px'><strong>80.0</strong></td><td style='padding:5px 6px'><strong>57.0</strong></td><td style='padding:5px 6px'><strong>47.0</strong></td><td style='padding:5px 6px'><strong>40.0</strong></td><td style='padding:5px 6px'><strong>36.0</strong></td><td style='padding:5px 6px'><strong>33.0</strong></td><td style='padding:5px 6px'>31.0</td><td style='padding:5px 6px'>30.5</td><td style='padding:5px 6px'>29.5</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>300 kPa</td><td style='padding:5px 6px'>100.0</td><td style='padding:5px 6px'>100.0</td><td style='padding:5px 6px'>86.5</td><td style='padding:5px 6px'>73.0</td><td style='padding:5px 6px'>59.5</td><td style='padding:5px 6px'>46.0</td><td style='padding:5px 6px'>32.5</td><td style='padding:5px 6px'>32.0</td><td style='padding:5px 6px'>31.5</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>320 kPa</td><td style='padding:5px 6px'>100.0</td><td style='padding:5px 6px'>100.0</td><td style='padding:5px 6px'>87.0</td><td style='padding:5px 6px'>74.0</td><td style='padding:5px 6px'>61.5</td><td style='padding:5px 6px'>48.5</td><td style='padding:5px 6px'>35.5</td><td style='padding:5px 6px'>35.0</td><td style='padding:5px 6px'>34.5</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:5px 6px;position:sticky;left:0;background:#fff;box-shadow:inset -1px 0 0 #ddd'>340 kPa</td><td style='padding:5px 6px'>100.0</td><td style='padding:5px 6px'>100.0</td><td style='padding:5px 6px'>88.0</td><td style='padding:5px 6px'>76.0</td><td style='padding:5px 6px'>64.0</td><td style='padding:5px 6px'>52.0</td><td style='padding:5px 6px'>40.0</td><td style='padding:5px 6px'>39.5</td><td style='padding:5px 6px'>38.5</td></tr>
</tbody></table></div><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Initial Position Table, % duty, after the revision, with engine speed in rpm across the top. Bold cells were changed. Everything else is either an original value or what EMtune interpolated, rounded to the nearest 0.5, when the new breakpoints were inserted.</figcaption></figure>



<p class="wp-block-paragraph">These are provisional trial values, chosen to reduce the excessive duty carried into target crossing. They were not calculated from measured equilibrium wastegate requirements.</p>



<p class="wp-block-paragraph">At 3,700 rpm and a 260 kPa target, initial duty falls from approximately 72% to 38%. That is a substantial change, with a possible cost in spool response.</p>



<p class="wp-block-paragraph">The 80% at 3,250 rpm changes less than it looks. It matches the 80% output limit, so while boost is still below target the commanded duty there is the same as before. The real reduction starts at 3,500 rpm.</p>



<p class="wp-block-paragraph">The 4,100 and 4,250 rpm columns are there for later shaping. For now they hold interpolated values only.</p>



<h2 class="wp-block-heading">Checking the entries mattered</h2>



<p class="wp-block-paragraph">The first screenshot of the edited table showed that the 280 kPa row had been missed.</p>



<p class="wp-block-paragraph">That would have affected operation below 280 kPa too, because the ECU interpolates between target rows. EMtune had filled the new 3,700 rpm cell in that row with 72.5%, the original interpolation rounded to the nearest 0.5. At 270 kPa and 3,700 rpm, that would have produced approximately 55.25% initial duty, rather than the intended 39%.</p>



<p class="wp-block-paragraph">The row was corrected before considering the revision complete.</p>



<p class="wp-block-paragraph">A separate limitation remains above it. The 300–340 kPa rows retain the original aggressive spool profile, and the step into them is steepest at 3,500 rpm:</p>



<figure class='bbt-figure' style='margin:1.8rem 0'><table style='border-collapse:collapse;width:100%;font-size:0.85rem;text-align:right'><thead><tr style='border-bottom:2px solid #333'><th style='text-align:left;padding:6px 8px'>Target</th><th style='padding:6px 8px'>3,500 rpm</th><th style='padding:6px 8px'>3,700 rpm</th></tr></thead><tbody>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>280 kPa</td><td style='padding:6px 8px'>57.0</td><td style='padding:6px 8px'>40.0</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>290 kPa</td><td style='padding:6px 8px'>78.5</td><td style='padding:6px 8px'>56.5</td></tr>
<tr style='border-bottom:1px solid #ddd'><td style='text-align:left;padding:6px 8px'>300 kPa</td><td style='padding:6px 8px'>100.0</td><td style='padding:6px 8px'>73.0</td></tr>
</tbody></table><figcaption class='bbt-table-note' style='font-size:0.8rem;color:#5f5f5f;line-height:1.5;margin:0.6rem 0 0'>Initial duty, %, in the current table. 290 kPa is interpolated between the 280 and 300 kPa rows.</figcaption></figure>



<p class="wp-block-paragraph">That matters in sixth gear. With the 10 kPa sixth-gear target offset, 290 kPa is the full-demand target in that gear, and this log requested exactly that whenever the status returned to 1: ON. The revised 220–280 kPa region does not establish that the rest of the table is suitable.</p>



<h2 class="wp-block-heading">Where the calibration stands</h2>



<p class="wp-block-paragraph">The revised initial-position values have been checked in the calibration screenshots. There is not yet a subsequent log demonstrating their effect.</p>



<p class="wp-block-paragraph">P, I and D are being held unchanged for the first comparison so the effect of the feedforward change can be assessed separately. Three closed-loop issues remain open: the derivative gap from +5 to −40 kPa, the weaker proportional gain above target now that the 10.00 cell has gone, and a −50 kPa derivative gain that adds duty during recovery from overboost.</p>



<p class="wp-block-paragraph">The next assessment centres on Boost Target Error:</p>



<ul class="wp-block-list">
<li>Peak negative error during boost arrival.</li>



<li>Time spent above target.</li>



<li>Recovery after the peak.</li>



<li>Any additional positive error or slower spool introduced by the reduced duty.</li>



<li>Behaviour when the torque model changes the target or boost-control state.</li>
</ul>



<p class="wp-block-paragraph">The useful result will be a smaller, shorter overshoot without creating an excessive boost deficit elsewhere. Until that is demonstrated, this remains a calibration under development.</p>



<p class="wp-block-paragraph">The lesson from this stage is specific: before asking PID to correct a boost error, examine the initial duty it is correcting around. In this run, boost was arriving on target with roughly three-quarters duty still commanded. That was the first problem to address.</p>



<p class="wp-block-paragraph">More to come.</p>



<p class="wp-block-paragraph"></p><p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/supra-boost-control-pid-initial-position/">Tuning the Supra’s Boost Control: PID Gains Were Only Part of the Problem</a> first appeared on <a href="https://blownbytwins.co.uk">BlownByTwins</a>.</p><p>The post <a rel="nofollow" href="https://blownbytwins.co.uk/cars/mk4-supra/supra-boost-control-pid-initial-position/">Tuning the Supra’s Boost Control: PID Gains Were Only Part of the Problem</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tuning Cruise Control on a 1,000+ bhp Toyota Supra</title>
		<link>https://blownbytwins.co.uk/cars/mk4-supra/supra-cruise-control-emtron-pid-tuning/</link>
		
		<dc:creator><![CDATA[john]]></dc:creator>
		<pubDate>Wed, 07 Oct 2026 14:13:36 +0000</pubDate>
				<category><![CDATA[Engine Management]]></category>
		<category><![CDATA[Mk4 Supra]]></category>
		<category><![CDATA[Tuning]]></category>
		<category><![CDATA[calibration]]></category>
		<category><![CDATA[cruise control]]></category>
		<category><![CDATA[dbw]]></category>
		<category><![CDATA[emtron]]></category>
		<guid isPermaLink="false">https://blownbytwins.co.uk/?p=1210</guid>

					<description><![CDATA[<p>How to read a cruise control log on a torque-based Emtron KV12: one sample log from a 2JZ Supra, six checks that derive what P, I, D and base torque are really doing, and the formulas to redo them for your own gearing.</p>
<p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/supra-cruise-control-emtron-pid-tuning/">Tuning Cruise Control on a 1,000+ bhp Toyota Supra</a> first appeared on <a href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
<p>The post <a rel="nofollow" href="https://blownbytwins.co.uk/cars/mk4-supra/supra-cruise-control-emtron-pid-tuning/">Tuning Cruise Control on a 1,000+ bhp Toyota Supra</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Cruise control is not the first system anyone thinks about on a heavily modified Supra. On a torque-based standalone, though, it is one of the most revealing. Cruise never touches the throttle directly. It asks the engine for torque and trusts every layer underneath to deliver it, so if the torque model, the throttle-area table or the drive-by-wire loop is wrong, cruise is where it shows.</p>



<p class="wp-block-paragraph">This is not a list of gains to copy. Gearing, tyre size and mass change every number below. What carries over is the method: take one sample log, and derive from it what each part of the controller is actually doing. Each check comes with the formula to redo it on your own car.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">The control path</h2>



<p class="wp-block-paragraph">Emtron is not commanding throttle position from speed error. The chain is:</p>



<pre class="wp-block-code"><code>Speed error → Cruise PID → torque correction
Torque Target Base + correction → Torque Target Final
Torque Target Final → TMF → throttle-area demand → DBW → engine torque</code></pre>



<figure class="wp-block-image size-large"><img decoding="async" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-control-path-v2.png" alt="Block diagram of the Emtron cruise control path: speed error into the cruise PID, the correction added to a base torque latched when SET is pressed, final torque through TMF to throttle area demand, DBW, engine, ZF 8HP70 and vehicle, with front axle average speed fed back as the cruise speed input"/><figcaption class="wp-element-caption">Cruise sits on top of the torque model. Everything inside the dashed box was tuned before any cruise gain was touched.</figcaption></figure>



<p class="wp-block-paragraph">That ordering matters. Cruise PID behaviour is only meaningful once the layers below it are stable, because any error in the throttle-area model or the DBW loop arrives at the cruise controller looking like road load. On this car the <a href="https://blownbytwins.co.uk/cars/mk4-supra/throttle-body-effective-area/">throttle-area table</a> and DBW PID were both reworked first.</p>



<h2 class="wp-block-heading">How Emtron scales the gains</h2>



<p class="wp-block-paragraph">Emtron&#8217;s cruise gains map directly to torque:</p>



<ul class="wp-block-list">
<li><strong>P = 1.00</strong> gives ±10 Nm for every 1 km/h of speed error.</li>



<li><strong>I = 0.010</strong> gives ±10 Nm/s for every 1 km/h of sustained speed error.</li>
</ul>



<p class="wp-block-paragraph">So P = 1.20 should give 12 Nm per km/h immediately, and I = 0.003 should add 3 Nm every second per km/h for as long as the error lasts. Those two numbers are what the log gets checked against.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1950" height="1050" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-p-versus-i-torque.png" alt="Chart of torque contribution against time for a constant 1 km/h speed error: P of 1.20 gives a flat 12 Nm, while I of 0.003, 0.005 and 0.007 ramp at 3, 5 and 7 Nm per second" class="wp-image-1213" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-p-versus-i-torque.png 1950w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-p-versus-i-torque-300x162.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-p-versus-i-torque-1024x551.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-p-versus-i-torque-768x414.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-p-versus-i-torque-1536x827.png 1536w" sizes="(max-width: 1950px) 100vw, 1950px" /><figcaption class="wp-element-caption">P is a step, I is a ramp.</figcaption></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">The sample log</h2>



<figure class="wp-block-image size-large"><img decoding="async" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/emtron-cruise-closed-loop-setup.png" alt="EMtune Cruise Closed Loop Setup screen: speed channel Front Axle Speed (Avg), proportional gain 1.20, integral gain 0.007, derivative gain 0.10, deadband 0.2 kph, maximum torque clamp 350 Nm, minimum torque clamp minus 50 Nm"/><figcaption class="wp-element-caption">The current calibration. The sample log below was recorded with Integral Gain at 0.003 and everything else as shown.</figcaption></figure>



<p class="wp-block-paragraph">The sample is one drive with cruise set three times, all in eighth gear at around 120 km/h, about four minutes of cruise in total. The longest engagement ran for just over three minutes on an ordinary undulating road.</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-log-run-trace.png" alt="Logged cruise run at 120.8 km/h: road speed wanders between about 118 and 126 km/h over three minutes while Torque Target Base stays flat at 189 Nm and Torque Target Final moves between about 125 and 215 Nm"/><figcaption class="wp-element-caption">The longest run. Speed wanders slowly either side of target; base torque never moves.</figcaption></figure>



<p class="wp-block-paragraph">Summary of the three engagements, ignoring the first five seconds after each set:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Run</th><th>Target</th><th>Base torque</th><th>Max deviation</th><th>Mean absolute error</th><th>Time within ±1 km/h</th><th>Mean error</th></tr></thead><tbody><tr><td>1 (194 s)</td><td>120.8 km/h</td><td>189 Nm</td><td>5.6 km/h</td><td>1.9 km/h</td><td>32%</td><td>1.0 km/h over</td></tr><tr><td>2 (31 s)</td><td>120.2 km/h</td><td>190 Nm</td><td>4.2 km/h</td><td>1.2 km/h</td><td>49%</td><td>1.0 km/h over</td></tr><tr><td>3 (34 s)</td><td>119.3 km/h</td><td>215 Nm</td><td>6.4 km/h</td><td>2.9 km/h</td><td>42%</td><td>2.1 km/h over</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Deviations of up to about ±3 mph, slow rather than fast. The checks below work out why.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">What to look for</h2>



<h3 class="wp-block-heading">1. Is cruise using the speed you think it is?</h3>



<p class="wp-block-paragraph">Log <code>Cruise - Speed Input</code> alongside whichever channel you selected as the source. Here the source is <code>Front Axle Speed (Avg)</code>, and the two match sample for sample. On a rear-wheel-drive car that is the right source: the front wheels are undriven, so their speed is road speed, not road speed plus whatever slip the rear tyres are carrying.</p>



<p class="wp-block-paragraph">If the two channels disagree on your car, stop there. Nothing else in the analysis means anything until the controller and the log are looking at the same speed.</p>



<h3 class="wp-block-heading">2. What is base torque actually doing?</h3>



<p class="wp-block-paragraph">It is tempting to read <code>Cruise - Torque Target Base</code> as a live road-load estimate. In this log it isn&#8217;t. It is captured when SET is pressed (189, 190 and 215 Nm on the three runs) and then stays flat for the whole engagement. Every newton-metre of movement in Final is closed-loop correction.</p>



<p class="wp-block-paragraph">That makes the moment you press SET part of the calibration. Run 3 was set at 215 Nm, more than the car needed to hold 119 km/h, and it spent the whole run about 2 km/h over target with the controller holding a negative correction the entire time. The base is a starting point. Whatever it gets wrong, the closed loop has to carry.</p>



<h3 class="wp-block-heading">3. Does P match the setting?</h3>



<p class="wp-block-paragraph">Make a derived channel for the correction and plot it against speed error:</p>



<pre class="wp-block-code"><code>Speed Error = Cruise - Speed Target − Cruise - Speed Input
Correction  = Cruise - Torque Target Final − Cruise - Torque Target Base</code></pre>



<figure class="wp-block-image size-large"><img decoding="async" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-log-p-response-scatter.png" alt="Scatter of torque correction against speed error for 5,436 logged samples, lying on a straight line with a fitted slope of 11.1 Nm per km/h against an expected 12 Nm per km/h"/><figcaption class="wp-element-caption">Every sample with cruise engaged. A straight line through the origin, with a flat step either side of zero.</figcaption></figure>



<p class="wp-block-paragraph">A straight-line fit gives 11.1 Nm per km/h, which looks slightly low against the 12 expected from P = 1.20. Look closely at the middle of the plot, though: the samples step flat across zero. That is the ±0.2 km/h deadband, and Emtron does not just zero the error inside it. It subtracts the deadband from the error everywhere:</p>



<pre class="wp-block-code"><code>P term = 10 × P × (|Speed Error| − deadband) × sign(Speed Error)</code></pre>



<p class="wp-block-paragraph">Fit against that instead and the slope comes out at 12.0 Nm per km/h, with every sample within 1 Nm of the line, which is the resolution of the logged torque channels. P is doing exactly what its setting says.</p>



<h3 class="wp-block-heading">4. Is the integral doing anything?</h3>



<p class="wp-block-paragraph">This is the check that matters most, and it falls straight out of check 3. Subtract the P term from the correction. Whatever is left is the integral and derivative:</p>



<pre class="wp-block-code"><code>Residual = Correction − P term</code></pre>



<p class="wp-block-paragraph">Then work out what the integral should have contributed. Accumulate the deadbanded speed error over the run and multiply by 1000 × I. For the long run in the sample, the error integrates to about −200 km/h·s. At I = 0.003 that is roughly −600 Nm of integral action, enough to pin the correction against the −50 Nm clamp for the second half of the run.</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-log-integral-check.png" alt="Logged torque correction overlaid with a proportional-only reconstruction, which matches it almost exactly, and with the expected proportional plus integral correction at I 0.003, which diverges widely and sits on the minus 50 Nm clamp"/><figcaption class="wp-element-caption">The logged correction (black) and the P-only reconstruction (green dashed) are indistinguishable. The red line is what I = 0.003 should have added.</figcaption></figure>



<p class="wp-block-paragraph">In the sample log the residual is zero to within the 1 Nm logging resolution. The correction is proportional only. You can see the consequence on the road too: between about 85 and 110 seconds into the long run, the car sat 3 to 5 km/h over target while the correction barely moved. A working integrator would have kept pulling torque off for the whole of that period.</p>



<p class="wp-block-paragraph">When this check comes back empty, adjusting the integral gain is the wrong next move. Find out why the integrator is not contributing first: whether it is gated by a condition, scaled differently from what you expect, or whether the calibration in the car is not the one you think you loaded. If your firmware can log the individual cruise P, I and D outputs, log them.</p>



<h3 class="wp-block-heading">5. Translate the error into your own car</h3>



<p class="wp-block-paragraph">A proportional-only cruise controller always leaves a steady error when the load changes, because it needs an error to make torque. The size of that error is set by P and by your gearing, which is why nobody else&#8217;s numbers transfer.</p>



<p class="wp-block-paragraph">The extra engine torque a gradient demands:</p>



<pre class="wp-block-code"><code>ΔT_engine = (m × g × sin θ × r_tyre) / (gear ratio × final drive)</code></pre>



<p class="wp-block-paragraph">And the speed error a P-only controller settles at to deliver it:</p>



<pre class="wp-block-code"><code>Δv ≈ ΔT_engine / (10 × P) + deadband</code></pre>



<p class="wp-block-paragraph">For the Supra in eighth (about 0.67) with the 2.93 final drive, a 0.33 m tyre and roughly 1650 kg, a 2% gradient needs about 55 Nm more at the engine. At 12 Nm per km/h that is about 4.8 km/h of steady error, almost exactly the ±3 mph drift in the sample log.</p>



<p class="wp-block-paragraph">Put your own mass, tyre and gearing in and you will get a different number. A car cruising in a lower gear, or on a shorter final drive, sees less engine torque per percent of gradient and a smaller error for the same P.</p>



<h3 class="wp-block-heading">6. Is D visible?</h3>



<p class="wp-block-paragraph">Not at D = 0.10 in this sample. Once the P term is removed there is nothing left above the logging resolution, so nothing can be attributed to D either. At cruise the rate of change of speed error is small, and so is anything a derivative term makes from it.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Changes since the sample</h2>



<p class="wp-block-paragraph">Integral Gain has since gone from 0.003 to 0.005 and then to 0.007, one step at a time, with P held at 1.20, D at 0.10 and the deadband and clamps unchanged.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1950" height="1050" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-integral-gain-progression.png" alt="Bar chart of integral torque build-up rate at 1, 2 and 3 km/h of sustained error for I of 0.003, 0.005 and 0.007: 3, 6, 9; 5, 10, 15; and 7, 14, 21 Nm per second" class="wp-image-1211" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-integral-gain-progression.png 1950w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-integral-gain-progression-300x162.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-integral-gain-progression-1024x551.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-integral-gain-progression-768x414.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-integral-gain-progression-1536x827.png 1536w" sizes="(max-width: 1950px) 100vw, 1950px" /><figcaption class="wp-element-caption">What each setting should add per second of sustained error, if the integrator is running.</figcaption></figure>



<p class="wp-block-paragraph">Each step gets judged by check 4 before anything else. A road test on its own cannot separate a better controller from a flatter road. If the residual is still flat at 0.007, the gain was never the problem.</p>



<h2 class="wp-block-heading">When the integral is working: what to expect</h2>



<p class="wp-block-paragraph">From torque to road speed, a car is close to a pure integrator: net torque sets acceleration, and speed is acceleration accumulated. Wrap a PI controller around that and you get a second-order loop whose damping depends on the ratio of the two gains:</p>



<pre class="wp-block-code"><code>k  = (gear ratio × final drive) / (r_tyre × m) × 3.6     km/h per second, per engine Nm
ζ ≈ (k × 10 × P) / (2 × √(k × 1000 × I))</code></pre>



<p class="wp-block-paragraph">Raise I with P fixed and the loop recovers faster but with less damping. For the Supra&#8217;s numbers, damping falls from about 0.39 at I = 0.003 to 0.26 at I = 0.007, and P would need to be around 1.8 to 1.9 to hold the original damping. Your k is different, so your numbers will be too.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="2100" height="1110" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-gain-progression-model-prediction.png" alt="Simulated speed traces for P 1.20 with I 0.003, 0.005 and 0.007, plus P 1.86 with I 0.007, through the same climb. Higher integral recovers faster but crosses target more; raising P alongside it settles fastest" class="wp-image-1216" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-gain-progression-model-prediction.png 2100w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-gain-progression-model-prediction-300x159.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-gain-progression-model-prediction-1024x541.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-gain-progression-model-prediction-768x406.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-gain-progression-model-prediction-1536x812.png 1536w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-gain-progression-model-prediction-2048x1083.png 2048w" sizes="(max-width: 2100px) 100vw, 2100px" /><figcaption class="wp-element-caption">Model, not a log. The trend is the point: more I alone means more crossing of target, and P is what buys the damping back.</figcaption></figure>



<p class="wp-block-paragraph">Each tuning error then has its own signature in the speed trace:</p>



<ul class="wp-block-list">
<li><strong>Too little P:</strong> weak immediate correction. The car sags at the start of every disturbance.</li>



<li><strong>Too much P:</strong> fast oscillation around target, set by the delay in the torque path.</li>



<li><strong>Too little or no I:</strong> a steady offset that follows the gradient, which is what the sample log shows.</li>



<li><strong>Too much I:</strong> slow overshoot and repeated crossing of target.</li>



<li><strong>D:</strong> works on acceleration, which is small and noisy at cruise. If overshoot appears, P is usually the stronger lever.</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="2100" height="1260" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-tuning-failure-modes.png" alt="Four simulated speed traces for the same two-percent climb: too little integral drifts slowly, too much integral overshoots repeatedly, too much proportional oscillates quickly around target, and matched gains recover and settle" class="wp-image-1212" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-tuning-failure-modes.png 2100w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-tuning-failure-modes-300x180.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-tuning-failure-modes-1024x614.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-tuning-failure-modes-768x461.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-tuning-failure-modes-1536x922.png 1536w, https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-pid-tuning-failure-modes-2048x1229.png 2048w" sizes="auto, (max-width: 2100px) 100vw, 2100px" /><figcaption class="wp-element-caption">Illustrative simulation, not logged data. Fast wobble points at P, slow wobble at I.</figcaption></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Log layout</h2>



<p class="wp-block-paragraph">Everything above comes from four panels and three derived channels.</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://blownbytwins.co.uk/wp-content/uploads/2026/10/cruise-log-layout-v2.png" alt="Suggested four-panel log layout: speed panel with speed target, speed input and derived speed error; torque panel with base and final torque targets and derived correction and residual; throttle panel with DBW target, DBW actual and throttle area demand; context panel with MAP, gear and shift state"/><figcaption class="wp-element-caption">If the residual is anything other than flat, that is your integral and derivative at work.</figcaption></figure>



<p class="wp-block-paragraph">Gear and shift state are there to exclude kickdowns and upshifts. They change the torque-to-speed relationship mid-run and will look like controller misbehaviour if left in.</p>



<h2 class="wp-block-heading">Current configuration</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Parameter</th><th>Value</th></tr></thead><tbody><tr><td>Speed source</td><td>Front Axle Speed (Avg)</td></tr><tr><td>Proportional Gain</td><td>1.20</td></tr><tr><td>Integral Gain</td><td>0.007 (sample log at 0.003)</td></tr><tr><td>Derivative Gain</td><td>0.10</td></tr><tr><td>Deadband</td><td>±0.2 km/h</td></tr><tr><td>Maximum Torque Clamp</td><td>+350 Nm</td></tr><tr><td>Minimum Torque Clamp</td><td>−50 Nm</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">The broader point</h2>



<p class="wp-block-paragraph">On a torque-managed standalone, cruise depends on the ECU understanding throttle area, airflow, engine torque, DBW response, road speed and transmission state. Get any of those wrong and cruise will find it.</p>



<p class="wp-block-paragraph">The sample log is a good example of why gains should be derived from the log rather than from how the car feels. The drift looked like a weak integral. The log showed P working exactly as set, a base torque frozen at the moment SET was pressed, and an integral contributing nothing at all. Three different facts, and only one of them is about the integral gain.</p>



<p class="wp-block-paragraph">Run the same six checks on your own log before you change a number.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><em>Part of the Emtron KV12 series on a 3.4 litre 2JZ. Cruise leans on the same torque model as the <a href="https://blownbytwins.co.uk/?p=1118">traction control strategy</a> and the <a href="https://blownbytwins.co.uk/cars/mk4-supra/throttle-body-effective-area/">throttle-area table</a> underneath both. Full specification is on the <a href="https://blownbytwins.co.uk/toyota-supra-mk4-delta/">Supra project page</a>.</em></p><p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/supra-cruise-control-emtron-pid-tuning/">Tuning Cruise Control on a 1,000+ bhp Toyota Supra</a> first appeared on <a href="https://blownbytwins.co.uk">BlownByTwins</a>.</p><p>The post <a rel="nofollow" href="https://blownbytwins.co.uk/cars/mk4-supra/supra-cruise-control-emtron-pid-tuning/">Tuning Cruise Control on a 1,000+ bhp Toyota Supra</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Staggered Tyres and Traction Control: What the ECU Corrects, and What It Can&#8217;t</title>
		<link>https://blownbytwins.co.uk/cars/mk4-supra/staggered-tyres-traction-control/</link>
		
		<dc:creator><![CDATA[john]]></dc:creator>
		<pubDate>Thu, 10 Sep 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[Engine Management]]></category>
		<category><![CDATA[Mk4 Supra]]></category>
		<category><![CDATA[Tuning]]></category>
		<category><![CDATA[calibration]]></category>
		<category><![CDATA[emtron]]></category>
		<category><![CDATA[traction control]]></category>
		<category><![CDATA[wheel speed]]></category>
		<guid isPermaLink="false">https://blownbytwins.co.uk/?p=1111</guid>

					<description><![CDATA[<p>If you run staggered tyres and a standalone ECU with traction control, there is a field in your configuration that almost certainly matters more than you think it does. It&#8230;</p>
<p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/staggered-tyres-traction-control/">Staggered Tyres and Traction Control: What the ECU Corrects, and What It Can’t</a> first appeared on <a href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
<p>The post <a rel="nofollow" href="https://blownbytwins.co.uk/cars/mk4-supra/staggered-tyres-traction-control/">Staggered Tyres and Traction Control: What the ECU Corrects, and What It Can&#8217;t</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">If you run staggered tyres and a standalone ECU with traction control, there is a field in your configuration that almost certainly matters more than you think it does. It is the tyre size.</p>



<p class="wp-block-paragraph">Not for speedometer calibration. For whether your traction control knows the difference between wheelspin and a rear tyre that is simply a different size to the front one.</p>



<h2 class="wp-block-heading">The problem, in one number</h2>



<p class="wp-block-paragraph">My car runs 265/30/19 at the front and 295/30/19 at the rear. Work the rolling diameters out:</p>



<ul class="wp-block-list">
<li>Front: 482.6 mm rim + (2 &times; 79.5 mm sidewall) = <strong>641.6 mm</strong></li>



<li>Rear: 482.6 mm rim + (2 &times; 88.5 mm sidewall) = <strong>659.6 mm</strong></li>
</ul>



<p class="wp-block-paragraph">The rear is 2.8 percent larger, so for any given road speed it turns about 2.7 percent slower than the front. Put the other way round, the front turns 2.8 percent faster than the rear, which is the figure you will see between the raw channels.</p>



<p class="wp-block-paragraph">A traction control strategy that compares driven wheel speed against undriven wheel speed and calls the difference slip would therefore see a permanent 2.8 percent slip. At a steady 50 mph on a flat road, doing nothing. Every slip target you set would be sitting on top of an offset that has nothing to do with grip.</p>



<h2 class="wp-block-heading">What the ECU does about it</h2>



<p class="wp-block-paragraph"><strong>Status: Verified</strong></p>



<p class="wp-block-paragraph">On the <a href="https://emtron.world/products/kv12" target="_blank" rel="noopener">Emtron</a> you give it two things per axle: the number of teeth on the ABS reluctor, and the tyre size.</p>



<p class="wp-block-paragraph">In my case that is 48 teeth on the Toyota hubs at both ends, and the two tyre sizes above. The ECU converts each tyre size string into a rolling diameter, combines it with the tooth count, and derives a scalar that normalises one axle against the other.</p>



<p class="wp-block-paragraph">The tooth count cancels here because both ends are 48. On a car with different reluctors front and rear it would not, which is exactly why the ECU asks for both rather than just the tyre size.</p>



<p class="wp-block-paragraph">You can watch it work. At a steady cruise on a flat road, in the same log, at the same moment:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1200" height="631" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/wheel-speed-raw-vs-corrected-slip.png" alt="Bar chart comparing raw wheel speed channels reading 2.8 percent apart against a corrected Drive Slip channel reading zero at steady cruise" class="wp-image-1128" /><figcaption class="wp-element-caption">Same car, same log, same moment. The raw channels show the geometry. The corrected channel shows the truth.</figcaption></figure>



<ul class="wp-block-list">
<li><strong>Raw wheel speed channels: 2.8 percent apart.</strong> Exactly the geometry, uncorrected.</li>



<li><strong>Drive Slip: 0 percent.</strong> Corrected, and reading the truth.</li>
</ul>



<p class="wp-block-paragraph">That pair is worth knowing about, because if you go looking at raw wheel speed channels and find them 2.8 percent apart, nothing is wrong. Those are sensor channels. The correction is applied downstream, inside the slip calculation, and the corrected channel is the one that tells you whether it is working.</p>



<h2 class="wp-block-heading">The failure mode nobody warns you about</h2>



<p class="wp-block-paragraph">The correction is derived from a tyre size you typed in. It has no way of knowing what is actually bolted to the car.</p>



<p class="wp-block-paragraph">This car has been through 18 inch wheels on Yokohama A052, and is now on 19 inch Rays G025 with a staggered Continental SportContact 7 setup. If the configuration still held the old sizes, every wheel speed on the car would be wrong, road speed would be wrong, and the slip calculation would be wrong.</p>



<p class="wp-block-paragraph">And none of it would look broken. The ECU would be doing correct arithmetic on stale inputs, confidently, forever.</p>



<p class="wp-block-paragraph">So: change your wheels or tyres, change the configuration. It belongs on the same checklist as the alignment.</p>



<h2 class="wp-block-heading">What geometry cannot reach</h2>



<p class="wp-block-paragraph"><strong>Status: Working conclusion</strong></p>



<p class="wp-block-paragraph">The scalar is calculated from the free rolling diameter, meaning the tyre&#8217;s size when nothing is pushing on it. What the wheel actually rolls on is the loaded radius, which is smaller, because the sidewall deflects under the weight of the car.</p>



<p class="wp-block-paragraph">That deflection is not the same front to rear. My rear sidewall is 88.5 mm against 79.5 mm at the front, and it carries more load. So the real ratio between the two axles is not quite the ratio the ECU calculated.</p>



<p class="wp-block-paragraph">Worse, it moves. Under hard acceleration weight transfers rearward, the rear sidewall squashes further, the rear rolling radius shrinks, and the rear wheels read faster for the same road speed. The system sees slip that is partly just the tyre changing shape.</p>



<p class="wp-block-paragraph">Which means the residual error is largest exactly when traction control is working hardest, and it errs in the direction of over-reading slip.</p>



<p class="wp-block-paragraph">Add the slower drifts on top: cold pressure against hot, a fresh tyre against a half worn one, a summer session against a winter one. All of them change rolling radius. None of them change the number in the configuration.</p>



<p class="wp-block-paragraph">I have not quantified any of that on this car. It is reasoning from geometry rather than measurement, and it stays a working conclusion until there is a number behind it.</p>



<h2 class="wp-block-heading">The check that takes two minutes</h2>



<p class="wp-block-paragraph">Flat road, steady 50, constant throttle, no load transfer. Log all four wheel speeds and your corrected slip channel.</p>



<p class="wp-block-paragraph">If corrected slip reads zero, your static correction is right. If it reads a consistent offset, either your configured tyre sizes do not match the car, or your tyres have worn far enough to matter.</p>



<p class="wp-block-paragraph">Do it after every tyre change, and once mid-season. It costs nothing and it is the only way to know whether the number your traction control is acting on means anything.</p>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<p class="wp-block-paragraph"><strong>Why this matters more than it sounds.</strong> Everything the traction control does downstream, the slip target, the feedforward torque model, the PID that corrects what the model missed, is built on the assumption that slip is being measured correctly. Get this wrong and every one of those tables is being tuned against a number that has an offset baked into it. The strategy that sits on top of these wheel speeds is covered in <a href="https://blownbytwins.co.uk/?p=1118">Traction Control on 1,114 whp</a>.</p>



<p class="wp-block-paragraph">Full specification and the wheel and tyre setup are on the <a href="https://blownbytwins.co.uk/toyota-supra-mk4-delta/">Supra project page</a>.</p>



<p class="wp-block-paragraph">If you run staggered tyres and have measured your loaded radius rather than assuming the free one, I would like to know how far apart they were. That is the number this article is missing.</p><p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/staggered-tyres-traction-control/">Staggered Tyres and Traction Control: What the ECU Corrects, and What It Can’t</a> first appeared on <a href="https://blownbytwins.co.uk">BlownByTwins</a>.</p><p>The post <a rel="nofollow" href="https://blownbytwins.co.uk/cars/mk4-supra/staggered-tyres-traction-control/">Staggered Tyres and Traction Control: What the ECU Corrects, and What It Can&#8217;t</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Throttle Body Effective Flow Area: Building a Correct Area vs Position Table</title>
		<link>https://blownbytwins.co.uk/cars/mk4-supra/throttle-body-effective-area/</link>
		
		<dc:creator><![CDATA[john]]></dc:creator>
		<pubDate>Thu, 27 Aug 2026 09:33:33 +0000</pubDate>
				<category><![CDATA[Engine Management]]></category>
		<category><![CDATA[Mk4 Supra]]></category>
		<category><![CDATA[Tuning]]></category>
		<category><![CDATA[air model]]></category>
		<category><![CDATA[calibration]]></category>
		<category><![CDATA[dbw]]></category>
		<category><![CDATA[emtron]]></category>
		<category><![CDATA[throttle body]]></category>
		<guid isPermaLink="false">https://blownbytwins.co.uk/?p=1074</guid>

					<description><![CDATA[<p>Open any modern standalone ECU that runs a throttle-based air model and you&#8217;ll find a table mapping throttle position to flow area. Open a dozen real calibrations and a good&#8230;</p>
<p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/throttle-body-effective-area/">Throttle Body Effective Flow Area: Building a Correct Area vs Position Table</a> first appeared on <a href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
<p>The post <a rel="nofollow" href="https://blownbytwins.co.uk/cars/mk4-supra/throttle-body-effective-area/">Throttle Body Effective Flow Area: Building a Correct Area vs Position Table</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Open any modern standalone ECU that runs a throttle-based air model and you&#8217;ll find a table mapping throttle position to flow area. Open a dozen real calibrations and a good number of those tables will be a straight line from zero to full scale.</p>



<p class="wp-block-paragraph">A straight line is the one shape the table physically cannot be.</p>



<p class="wp-block-paragraph">This isn&#8217;t a precision quibble. In the operating band where the engine spends most of its life, meaning idle, overrun, light cruise and the first few percent of tip-in, a linear table over-states flow area by a factor of two to four. Every downstream calculation inherits that error: fuel mass, torque estimation, pedal mapping, and on a drive-by-wire car, the inverse map the controller uses to decide where to put the plate.</p>



<p class="wp-block-paragraph">This article covers the geometry of why, the compressible flow equations that turn area into mass, what a throttle mass flow (TMF) model does with the result, and a repeatable method for building a table that&#8217;s correct rather than convenient.</p>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<h2 class="wp-block-heading">Part 1: The geometry</h2>



<h3 class="wp-block-heading">The projection</h3>



<p class="wp-block-paragraph">A butterfly valve is a disc on a shaft in a cylindrical bore. Air gets past it through whatever cross-section the disc doesn&#8217;t block, viewed along the bore axis.</p>



<p class="wp-block-paragraph">Set up coordinates: the bore axis is <strong>z</strong>, the shaft runs along <strong>x</strong>, and the plate rotates about the shaft. Call the plate&#8217;s angle from the bore-normal plane <strong>α</strong>, and the angle it sits at when hard against the closed stop <strong>α₀</strong>.</p>



<p class="wp-block-paragraph">For the plate to seal in a cylindrical bore at angle α₀, it can&#8217;t be a circle. The intersection of a cylinder of radius <em>R</em> with a plane tilted at α₀ is an ellipse with semi-axes <em>R</em> and <em>R/cos α₀</em>. So the plate is elliptical, with the long axis running across the shaft.</p>



<p class="wp-block-paragraph">Project that plate onto the plane normal to the flow at an arbitrary angle α, and you get an ellipse with semi-axes:</p>



<ul class="wp-block-list">
<li><strong>R</strong> along the shaft</li>



<li><strong>R · cos α / cos α₀</strong> across it</li>
</ul>



<p class="wp-block-paragraph">Which gives the blocked area directly:</p>



<pre class="wp-block-code"><code>A_blocked = πR² · (cos α / cos α₀)</code></pre>



<p class="wp-block-paragraph">And therefore:</p>



<pre class="wp-block-code"><code>A_open = πR² · (1 − cos α / cos α₀)</code></pre>



<p class="wp-block-paragraph">Two sanity checks. At α = α₀ the cosine ratio is 1 and open area is zero, because the plate fills the bore. At α = 90° the ratio is zero, open area equals bore area, and the plate is edge-on. Both correct.</p>



<h3 class="wp-block-heading">Why it can&#8217;t be linear</h3>



<p class="wp-block-paragraph">Differentiate the open area with respect to α:</p>



<pre class="wp-block-code"><code>dA/dα = πR² · sin α / cos α₀</code></pre>



<p class="wp-block-paragraph">Near the closed position, sin α is small. The area barely moves. Expand the cosine for small openings and you get area growing with <strong>the square</strong> of the angle, not the first power:</p>



<pre class="wp-block-code"><code>1 − cos α ≈ α² / 2</code></pre>



<p class="wp-block-paragraph">A quadratic. That&#8217;s the whole argument. The throttle plate has to swing through a meaningful angle before it uncovers meaningful area, because at small angles you&#8217;re only exposing the thin crescent at the edge of a tilted ellipse.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="2560" height="1355" src="https://blownbytwins.co.uk/wp-content/uploads/2026/08/throttle_body_effective_area_vs_linear_assumption-scaled.png" alt="Chart comparing the true geometric open area of an 82 mm butterfly throttle against a linear table, showing the real curve sitting far below the straight line across the lower range" class="wp-image-1097" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/08/throttle_body_effective_area_vs_linear_assumption-scaled.png 2560w, https://blownbytwins.co.uk/wp-content/uploads/2026/08/throttle_body_effective_area_vs_linear_assumption-300x159.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/08/throttle_body_effective_area_vs_linear_assumption-1024x542.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/08/throttle_body_effective_area_vs_linear_assumption-768x407.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/08/throttle_body_effective_area_vs_linear_assumption-1536x813.png 1536w, https://blownbytwins.co.uk/wp-content/uploads/2026/08/throttle_body_effective_area_vs_linear_assumption-2048x1084.png 2048w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /><figcaption class="wp-element-caption">Geometric open area against throttle position for an 82 mm bore, 9° closed angle, 83° open stop. The dashed line is what a linear table assumes.</figcaption></figure>



<p class="wp-block-paragraph">Put numbers on it. Take an 82 mm bore, a closed angle of 9°, an open stop at 83°, and a throttle position axis that runs 0 to 100% of mechanical travel:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>TPS %</th><th>Plate angle</th><th>Open area (mm²)</th><th>% of bore</th><th>Linear table says</th><th>Error</th></tr></thead><tbody><tr><td>2</td><td>10.5°</td><td>20</td><td>0.4%</td><td>106</td><td>5.3×</td></tr><tr><td>6</td><td>13.4°</td><td>81</td><td>1.5%</td><td>317</td><td>3.9×</td></tr><tr><td>10</td><td>16.4°</td><td>151</td><td>2.9%</td><td>528</td><td>3.5×</td></tr><tr><td>20</td><td>23.8°</td><td>389</td><td>7.4%</td><td>1056</td><td>2.7×</td></tr><tr><td>40</td><td>38.6°</td><td>1102</td><td>20.9%</td><td>2112</td><td>1.9×</td></tr><tr><td>60</td><td>53.4°</td><td>2124</td><td>40.2%</td><td>3169</td><td>1.5×</td></tr><tr><td>80</td><td>68.2°</td><td>3320</td><td>62.9%</td><td>4225</td><td>1.3×</td></tr><tr><td>100</td><td>83.0°</td><td>4677</td><td>88.6%</td><td>5281</td><td>1.1×</td></tr></tbody></table></figure>



<p class="wp-block-paragraph"><em>(Bore area 5281 mm². Shaft blockage included, see below. Linear column assumes full scale = bore area.)</em></p>



<p class="wp-block-paragraph">The error is worst exactly where it hurts most. A big throttle on a big engine cruises at single-digit TPS. That&#8217;s the region where a linear table is out by a factor of four.</p>



<h3 class="wp-block-heading">The shaft</h3>



<p class="wp-block-paragraph">The shaft blocks area too, but not in the way most people assume. Its projected area is roughly <em>shaft diameter × bore diameter</em>, so call it 8 mm × 82 mm ≈ 656 mm², over 12% of the bore.</p>



<p class="wp-block-paragraph">But at small openings the shaft is hidden behind the plate&#8217;s projection. The plate&#8217;s projected ellipse is nearly as wide as the bore, and the shaft sits along its centreline. Shaft blockage only becomes real once the plate has swung far enough that its projection narrows past the shaft width, which on typical geometry is somewhere past 60 to 70°.</p>



<p class="wp-block-paragraph">So the shaft is irrelevant at idle and dominant at wide-open throttle. If you&#8217;ve ever wondered why a throttle body flows meaningfully less than its nominal bore area suggests at WOT, that&#8217;s most of the answer.</p>



<h3 class="wp-block-heading">What the closed-form misses</h3>



<p class="wp-block-paragraph">The clean equation above is a thin-plate, sharp-edged idealisation. Real hardware has:</p>



<ul class="wp-block-list">
<li><strong>Plate thickness.</strong> A 2 mm plate at 15° presents a real edge to the flow, not a mathematical line.</li>



<li><strong>A seal taper or step in the bore</strong> at the closed position, common on OEM bodies to control leakage and stop the plate binding.</li>



<li><strong>A relieved or chamfered plate edge</strong>, which changes the effective flow path at small angles specifically.</li>



<li><strong>Screw heads</strong> on the plate face where it&#8217;s fastened to the shaft.</li>



<li><strong>Non-concentricity</strong> between the plate&#8217;s rotation axis and the bore centreline on some designs.</li>
</ul>



<p class="wp-block-paragraph">None of these are worth modelling analytically. Integrate the geometry numerically and stop pretending you have a closed form. The code is fifteen lines and it handles the shaft correctly for free.</p>



<pre class="wp-block-code"><code>import numpy as np

def open_area(alpha_deg, alpha0_deg, bore_d, shaft_d, n=2000):
    """
    Geometric open area of a butterfly valve, by numerical integration.

    alpha_deg  : plate angle from the bore-normal plane (deg); ~90 = fully open
    alpha0_deg : plate angle at the closed stop (deg)
    bore_d     : bore diameter (mm)
    shaft_d    : shaft diameter (mm)

    Returns (area_mm2, fraction_of_bore_area)
    """
    R  = bore_d / 2.0
    a  = np.deg2rad(alpha_deg)
    a0 = np.deg2rad(alpha0_deg)

    # projected plate ellipse: semi-axis R along shaft, R*cos(a)/cos(a0) across
    sx = R
    sy = max(R * np.cos(a) / np.cos(a0), 1e-12)

    g = np.linspace(-R, R, n)
    X, Y = np.meshgrid(g, g)

    in_bore  = (X**2 + Y**2) &lt;= R**2
    in_plate = ((X / sx)**2 + (Y / sy)**2) &lt;= 1.0
    in_shaft = np.abs(Y) &lt;= shaft_d / 2.0

    cell = (2 * R / (n - 1))**2
    area = np.count_nonzero(in_bore &amp; ~in_plate &amp; ~in_shaft) * cell
    return area, area / (np.pi * R**2)


def servo_to_angle(tps_pct, alpha0_deg, alpha_max_deg):
    """Linear travel-to-angle map. Verify this on your own hardware."""
    return alpha0_deg + (tps_pct / 100.0) * (alpha_max_deg - alpha0_deg)


for tps in &#091;0, 1, 2, 3, 5, 8, 12, 20, 30, 45, 60, 80, 100]:
    ang = servo_to_angle(tps, 9.0, 83.0)
    a, f = open_area(ang, 9.0, 82.0, 8.0)
    print(f"{tps:5.1f}%  {ang:5.1f}°  {a:8.1f} mm²  {f*100:5.2f}%")</code></pre>



<h3 class="wp-block-heading">Servo position is not plate angle</h3>



<p class="wp-block-paragraph">The table&#8217;s axis is usually servo or throttle position in percent. That is a percentage of <em>mechanical travel</em>, mapped through the sensor calibration. It is not plate angle, and it is not flow area.</p>



<p class="wp-block-paragraph">Two things break here routinely:</p>



<p class="wp-block-paragraph"><strong>The zero point.</strong> TPS 0% is wherever the sensor was zeroed, which is typically the closed stop. But the closed stop is often set slightly <em>below</em> the sealing angle so the plate loads against it, or slightly above so it doesn&#8217;t jam. If your assumed α₀ is a degree out, your area predictions at low TPS are out by a large multiple, because you&#8217;re on the steepest part of a quadratic.</p>



<p class="wp-block-paragraph"><strong>The full-scale point.</strong> Plates rarely reach 90°. Mechanical stops usually land somewhere between 80° and 86°, and the linkage may not be perfectly linear across the range. On a DBW body with a direct gear train it&#8217;s close enough to linear to be usable. Verify rather than assume.</p>



<p class="wp-block-paragraph"><strong>Measure both.</strong> Command the throttle to a known position, remove the intake pipe, and measure the plate angle directly. A digital angle gauge against the plate face is good to a few tenths of a degree, which is plenty. Do it at 0%, 100%, and three or four points in between to confirm linearity. This is twenty minutes of work that determines whether everything downstream is right or wrong.</p>



<h3 class="wp-block-heading">The scaling trap</h3>



<p class="wp-block-paragraph">If a table has been carried over from a different throttle body, check what it was scaled by.</p>



<p class="wp-block-paragraph">Area scales with the <strong>square</strong> of diameter. Going from 68 mm to 82 mm:</p>



<ul class="wp-block-list">
<li>Diameter ratio: 82 / 68 = <strong>1.206</strong></li>



<li>Area ratio: 82² / 68² = <strong>1.454</strong></li>
</ul>



<p class="wp-block-paragraph">Scale by diameter instead of area and every entry is 17% low. That&#8217;s the obvious error.</p>



<p class="wp-block-paragraph">The subtler one: even a correctly area-scaled table has the wrong <em>shape</em>. Closed angle, open stop angle, and shaft-to-bore ratio all differ between bodies, and none of them scale with diameter. The same shaft in a smaller bore blocks a larger fraction of it. A table lifted from another throttle body and multiplied by a constant is wrong in a way no single multiplier can fix.</p>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<h2 class="wp-block-heading">Part 2: From area to mass flow</h2>



<p class="wp-block-paragraph">Geometric area isn&#8217;t flow area. Two corrections stand between them.</p>



<h3 class="wp-block-heading">Discharge coefficient</h3>



<p class="wp-block-paragraph">Real flow through an orifice separates at the edge and forms a vena contracta narrower than the geometric opening. The ratio of actual to ideal flow is the discharge coefficient, <strong>Cd</strong>.</p>



<p class="wp-block-paragraph">For a butterfly valve, Cd is a function of plate angle, and to a lesser extent of Reynolds number and pressure ratio. Typical values sit somewhere in the 0.6 to 0.8 range across most of the travel, though published data varies considerably with plate profile and bore geometry. The behaviour at very small openings, where the flow is a thin slot jet past a tilted edge, is the least consistent across sources.</p>



<p class="wp-block-paragraph">If your ECU exposes a separate Cd or flow-correction table against angle, keep the geometric table geometric and put the empirical correction in the Cd table. Two tables, two jobs, and you can reason about each independently. If it only exposes one &#8220;effective area&#8221; table, you&#8217;re folding Cd into it, which works, but means the table is no longer verifiable against geometry, and you lose the ability to sanity-check it with a ruler and a protractor.</p>



<h3 class="wp-block-heading">The compressible flow equation</h3>



<p class="wp-block-paragraph">Air through a restriction is compressible. The standard isentropic nozzle relation:</p>



<pre class="wp-block-code"><code>ṁ = Cd · A · (P_up / √(R_s · T_up)) · Ψ(PR)</code></pre>



<p class="wp-block-paragraph">where <code>PR = P_down / P_up</code>, <code>R_s = 287 J/kg·K</code>, and Ψ depends on whether the flow is choked.</p>



<p class="wp-block-paragraph"><strong>Critical pressure ratio</strong> for air (γ = 1.4):</p>



<pre class="wp-block-code"><code>PR_crit = (2 / (γ+1))^(γ/(γ-1)) = 0.528</code></pre>



<p class="wp-block-paragraph"><strong>Subsonic (PR &gt; 0.528):</strong></p>



<pre class="wp-block-code"><code>Ψ = √( (2γ/(γ-1)) · ( PR^(2/γ) − PR^((γ+1)/γ) ) )</code></pre>



<p class="wp-block-paragraph"><strong>Choked (PR ≤ 0.528):</strong></p>



<pre class="wp-block-code"><code>Ψ = √γ · (2/(γ+1))^((γ+1)/(2(γ-1))) = 0.6847</code></pre>



<p class="wp-block-paragraph">Both expressions agree at PR = 0.528, as they must.</p>



<h3 class="wp-block-heading">The consequence nobody expects: your throttle is choked at idle</h3>



<p class="wp-block-paragraph">Idle manifold pressure on a healthy engine might be 35 kPa absolute, against roughly 101 kPa ambient upstream. That&#8217;s a pressure ratio of 0.35, well below critical.</p>



<p class="wp-block-paragraph"><strong>The throttle is sonic.</strong> Flow is at the speed of sound in the gap between plate and bore.</p>



<p class="wp-block-paragraph">That has a specific and useful consequence: when choked, mass flow depends only on Cd, area, upstream pressure and upstream temperature. <strong>Manifold pressure has no influence whatsoever.</strong> Ψ is pinned at 0.6847 and stays there.</p>



<p class="wp-block-paragraph">Which means at idle, the model reduces to:</p>



<pre class="wp-block-code"><code>ṁ = Cd · A · P_ambient / √(R_s · T_up) · 0.6847</code></pre>



<p class="wp-block-paragraph">Every percent of error in your area table becomes a percent of error in calculated air mass, with nothing to absorb it. There is no MAP feedback, no VE term, no second path. Area <em>is</em> the model.</p>



<p class="wp-block-paragraph">Work out where choking ends: PR = 0.528 against 101 kPa ambient means MAP = 53 kPa. Anything below that is choked, which covers idle, overrun, and most light-load cruise on a large-displacement engine. A big proportion of normal driving sits in the region where the area table is the sole determinant of calculated airflow.</p>



<p class="wp-block-paragraph">This is the single strongest reason to get the table right, and the reason area errors show up as idle and cruise fuelling problems specifically.</p>



<h3 class="wp-block-heading">The boosted case, and why pre-throttle pressure matters</h3>



<p class="wp-block-paragraph">Now put the throttle under boost. Upstream is charge pipe pressure, say 200 kPa absolute; downstream is plenum, say 190 kPa. PR = 0.95. Deeply subsonic, and this is where Ψ gets vicious.</p>



<p class="wp-block-paragraph">Run the numbers:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>PR</th><th>Ψ</th></tr></thead><tbody><tr><td>0.96</td><td>0.276</td></tr><tr><td>0.95</td><td>0.306</td></tr><tr><td>0.94</td><td>0.335</td></tr><tr><td>0.93</td><td>0.361</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">A <strong>1% change in pressure ratio produces roughly a 9% change in mass flow.</strong> The function is nearly vertical up here.</p>



<p class="wp-block-paragraph">Which brings us to the thing that decides whether a throttle model can work in boost at all: <strong>you must know the pressure upstream of the throttle plate.</strong></p>



<p class="wp-block-paragraph">Without a pre-throttle sensor, the ECU has to infer it, usually from a modelled pressure drop across the intercooler and pipework, or from a boost target, or by assuming it equals MAP plus some offset. All of those are estimates, and the sensitivity above means a 2 kPa estimation error at part throttle in boost produces a double-digit percentage error in calculated air mass.</p>



<p class="wp-block-paragraph"><strong>Fit the sensor.</strong> On a naturally aspirated engine you can argue that ambient is close enough. On a boosted engine running a throttle-based air model, a pre-throttle pressure sensor is not an optional refinement. It&#8217;s the difference between a model and a guess.</p>



<p class="wp-block-paragraph"><em>My own car runs both sides: pre-throttle and post-throttle pressure are each measured, not inferred. On a throttle mass flow model those two sensors are not instrumentation, they are part of the model, and the pressure ratio between them is the term the whole calculation hinges on. Full sensing list is on the <a href="https://blownbytwins.co.uk/toyota-supra-mk4-delta/">specification page</a>.</em></p>



<p class="wp-block-paragraph">Note also that the <em>sign</em> of the problem inverts across the throttle range. At small openings the pressure ratio is low, the flow is choked or near-choked, and the model is insensitive to downstream pressure but exquisitely sensitive to area. At large openings in boost the pressure ratio approaches unity, area error matters less, and pressure error dominates. Different regions of the same table fail for different reasons.</p>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<h2 class="wp-block-heading">Part 3: What the ECU does with it</h2>



<h3 class="wp-block-heading">The throttle mass flow model</h3>



<p class="wp-block-paragraph">A throttle mass flow model, TMF in Emtron&#8217;s vocabulary, with equivalents under different names across most modern standalone platforms, computes cylinder air mass from the throttle rather than from the manifold.</p>



<p class="wp-block-paragraph">Broadly:</p>



<ol class="wp-block-list">
<li>Throttle position → plate angle (via the servo map)</li>



<li>Plate angle → geometric area (via the area table)</li>



<li>Area × Cd → effective area</li>



<li>Effective area + upstream pressure + upstream temperature + pressure ratio → mass flow through the throttle</li>



<li>Mass flow → cylinder filling → fuel</li>
</ol>



<p class="wp-block-paragraph">Contrast that with speed density, which computes cylinder air mass from manifold pressure, air temperature, engine speed and a volumetric efficiency table. <a href="https://blownbytwins.co.uk/previous-cars/r34gtr/new-ecu-time/">I first wrote about why that distinction mattered in 2023</a>, when choosing an ECU for the R34, long before I understood how much sat underneath it.</p>



<p class="wp-block-paragraph">The two models fail in opposite ways, which is precisely why good ECUs run both:</p>



<p class="wp-block-paragraph"><strong>Speed density</strong> is accurate in steady state because MAP is a direct measurement of what&#8217;s actually in the manifold. It&#8217;s <em>late</em> in transients, because the manifold takes time to fill and the sensor reports the result rather than the intent. Stab the throttle and the MAP sensor tells you what happened a few tens of milliseconds ago.</p>



<p class="wp-block-paragraph"><strong>Throttle mass flow</strong> is immediate, because the plate moves before the manifold responds, so the model sees the demand as it happens. But it&#8217;s an inference stacked on a chain of assumptions: area table, Cd, servo map, upstream pressure. Every one of those is a place to be wrong.</p>



<p class="wp-block-paragraph">So the ECU blends them: TMF-weighted during transients where response matters, SD-weighted in steady state where accuracy matters, with a handover region between.</p>



<h3 class="wp-block-heading">Diagnosing the handover</h3>



<p class="wp-block-paragraph">The handover is where calibration errors become visible, and it&#8217;s diagnostically valuable for exactly that reason. If your two models disagree, the blend region will show a fuelling discontinuity that tracks the blend weighting rather than any physical parameter.</p>



<p class="wp-block-paragraph">Log fuel trim, or measured lambda error, against whatever variable drives the blend. Three patterns:</p>



<p class="wp-block-paragraph"><strong>A step at the handover.</strong> The two models disagree at that operating point. One is wrong; the trim jumps as authority transfers.</p>



<p class="wp-block-paragraph"><strong>A ramp through the handover.</strong> The models disagree by a growing margin across the region. Usually indicates a slope error in one of them, either a VE table with the wrong shape, or an area table with the wrong curvature.</p>



<p class="wp-block-paragraph"><strong>Clean through the handover, but offset either side.</strong> Both models share a common error downstream of the blend, such as injector characterisation, a global trim, or fuel pressure.</p>



<p class="wp-block-paragraph">That third case is where things get interesting, because a common error can <em>hide</em> the first two. Which leads to the diagnostic fork.</p>



<h3 class="wp-block-heading">The fork: when the symptom contradicts the geometry</h3>



<p class="wp-block-paragraph">Here&#8217;s a scenario worth walking through, because it&#8217;s a trap.</p>



<p class="wp-block-paragraph">Suppose you determine your area table over-states area by roughly 3× in the idle band, established from geometry, exactly as above. The model is being told there&#8217;s three times as much air going past the plate as there really is.</p>



<p class="wp-block-paragraph">You&#8217;d expect the engine to run <strong>rich</strong> at idle, and the fuel model to read <strong>high</strong>.</p>



<p class="wp-block-paragraph">Now suppose your logs show the opposite: TMF reading around 9% <em>low</em> at idle, with a positive fuel correction propping it up.</p>



<p class="wp-block-paragraph">Both observations can&#8217;t be direct consequences of the same cause. Something else is in the chain. Three branches, all testable:</p>



<p class="wp-block-paragraph"><strong>Branch 1: a global trim is masking the shape error.</strong> Somewhere there&#8217;s a multiplier, a fuel scaling constant, or a Cd table that was adjusted until mid-range worked. That adjustment is fighting the area error, and the residual at idle is what&#8217;s left after the fight. Test: remove or neutralise the compensating term and see whether idle error grows in the direction the geometry predicts. If it does, the geometry diagnosis stands and the trim was a bandage.</p>



<p class="wp-block-paragraph"><strong>Branch 2: the Cd table is pulling the other way.</strong> If Cd is populated with values that fall sharply at small openings, it may be cancelling much of the geometric over-statement. Test: multiply the area and Cd tables together and plot the product against angle. That product is what the model actually uses. If the product is close to geometrically correct, the individual tables are wrong but the model isn&#8217;t, which means fixing the area table alone will break it.</p>



<p class="wp-block-paragraph"><strong>Branch 3: the axis doesn&#8217;t mean what you think.</strong> The table may be indexed on plate angle rather than percentage travel; or on a normalised area rather than absolute; or the &#8220;servo position&#8221; channel may be the commanded target rather than the measured position, which differ during any transient and can differ statically if there&#8217;s a calibration offset. Test: command a known position, measure the actual plate angle, and confirm which number the table is being indexed on.</p>



<p class="wp-block-paragraph"><strong>Resolve the fork before changing anything.</strong> The failure mode here is correcting the area table on sound geometric grounds, discovering the engine now runs badly, and concluding the geometry was wrong. The geometry isn&#8217;t wrong. Something else in the chain was compensating for it, and you&#8217;ve now removed one half of a matched pair.</p>



<p class="wp-block-paragraph">Which is the general rule: <strong>compensating errors must be corrected together or not at all.</strong> If a wrong area table and a wrong global trim have been co-calibrated to produce acceptable fuelling, fixing either one alone makes the car worse. Identify both, correct both, revalidate.</p>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<h2 class="wp-block-heading">Part 4: The dual-use trap</h2>



<p class="wp-block-paragraph">On a drive-by-wire car, the throttle area table is usually consumed in two directions.</p>



<p class="wp-block-paragraph"><strong>Forward</strong>, for the air model: position → area → mass flow → fuel.</p>



<p class="wp-block-paragraph"><strong>Inverse</strong>, for torque-based control: torque demand → required mass flow → required area → <strong>target throttle position</strong>.</p>



<p class="wp-block-paragraph">The same table. Read backwards.</p>



<p class="wp-block-paragraph">That inverse map is not an edge case. It is what every torque-based system on the car leans on. When <a href="https://blownbytwins.co.uk/?p=1118">traction control</a> decides to pull torque and reaches for throttle area as its first actuator, this table is what turns a torque request into a plate position. An area table that is wrong at small openings makes every one of those interventions wrong too.</p>



<p class="wp-block-paragraph">Three consequences.</p>



<h3 class="wp-block-heading">Fixing the fuel model changes the pedal</h3>



<p class="wp-block-paragraph">If the table over-states area at small openings, the inverse map under-commands position for a given torque request, because the controller thinks a tiny opening delivers a lot of air, so it asks for a tiny opening. Correct the table and the same pedal input now produces a larger commanded opening.</p>



<p class="wp-block-paragraph">Which is <em>correct</em>, but it isn&#8217;t <em>the same</em>. Tip-in response, idle control authority, cruise position and any part-throttle torque limiter behaviour all shift. Expect to revalidate driveability alongside fuelling, and don&#8217;t do it on a road.</p>



<h3 class="wp-block-heading">Non-monotonicity breaks the inverse map</h3>



<p class="wp-block-paragraph">A table with hand-entered noise, where area at 5% exceeds area at 6%, is merely inaccurate in the forward direction. It&#8217;s <em>ill-posed</em> in the inverse direction.</p>



<p class="wp-block-paragraph">Inverting a non-monotonic function means that for some torque demands, more than one throttle position satisfies the request. Depending on how the solver is implemented, you get target jumps, hunting, or an oscillation whose frequency is set by the controller rather than by anything physical.</p>



<p class="wp-block-paragraph">Where does hand-entry noise usually live? In the low-percentage cells, because that&#8217;s where people have been poking at values trying to fix an idle problem. Which is exactly where idle control and tip-in operate.</p>



<p class="wp-block-paragraph"><strong>Check monotonicity explicitly.</strong> It takes one line:</p>



<pre class="wp-block-code"><code>assert np.all(np.diff(area_table) &gt; 0), "Area table is non-monotonic"</code></pre>



<p class="wp-block-paragraph">If that fails, no amount of downstream tuning will produce stable control.</p>



<h3 class="wp-block-heading">The table is not a tuning parameter</h3>



<p class="wp-block-paragraph">The strongest reason to build the area table from geometry rather than from fitting: it&#8217;s the only table in the chain that has a <strong>verifiable, physical, single correct answer</strong>.</p>



<p class="wp-block-paragraph">VE is empirical. Cd is empirical. Injector characterisation is empirical. Geometric flow area is a solid modelling problem with one right answer, computable from four measurements, and it does not change as the engine ages.</p>



<p class="wp-block-paragraph">Once it&#8217;s correct, it&#8217;s correct permanently, and every empirical table downstream is being fitted against a fixed truth rather than against another set of assumptions. That&#8217;s what makes the rest of the calibration converge instead of chasing itself.</p>



<p class="wp-block-paragraph">Treating the area table as somewhere to dial in a fuelling problem throws away the one fixed reference point in the entire model.</p>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<h2 class="wp-block-heading">Part 5: Method</h2>



<ol class="wp-block-list">
<li><strong>Measure the hardware.</strong> Bore diameter, shaft diameter, plate thickness. Callipers.</li>



<li><strong>Measure the closed angle.</strong> Digital angle gauge against the plate face at the closed stop. This number matters more than any other single measurement, because it sets where you sit on the quadratic.</li>



<li><strong>Measure the open stop.</strong> Same method, throttle commanded to 100%.</li>



<li><strong>Verify the servo map.</strong> Command 20%, 40%, 60%, 80%; measure the angle at each. Confirm the travel-to-angle relationship is linear before assuming it.</li>



<li><strong>Compute the geometric table numerically.</strong> Use the code above, at the resolution your ECU&#8217;s table supports. Populate the low-percentage region densely, because that&#8217;s where the curvature is, and where linear interpolation between widely-spaced breakpoints does the most damage.</li>



<li><strong>Check monotonicity.</strong> Every cell strictly greater than the one before.</li>



<li><strong>Handle Cd deliberately.</strong> Separate table if the ECU allows it. If not, decide consciously what Cd assumption you&#8217;re folding in and write it down.</li>



<li><strong>Identify existing compensating terms before you change anything.</strong> Global fuel multipliers, mass fuel corrections, Cd tables, anything that&#8217;s been trimmed to make the current calibration work. These come out or get re-derived in the same change.</li>



<li><strong>Validate against logs.</strong> With the corrected table, TMF and SD should converge in steady state without a compensating pad. That convergence is your proof, not the smoothness of the fuel trim, which can be smooth for the wrong reasons.</li>



<li><strong>Revalidate driveability</strong>, because you have just changed the inverse map that determines where the plate goes.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<h2 class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">A butterfly valve&#8217;s open area grows with the square of plate angle near closed, not linearly. In the idle-to-light-cruise band, a linear table over-states area by two to four times.</p>



<p class="wp-block-paragraph">Below roughly 53 kPa manifold pressure, the throttle is choked and manifold pressure has no effect on flow at all. Area and upstream pressure are the entire model. Above that, in boost, the flow function is so steep that a 1% pressure ratio error produces a 9% mass flow error, which is why pressure sensors either side of the plate are mandatory rather than optional on a boosted throttle-model car.</p>



<p class="wp-block-paragraph">The area table is the only table in the air model with a single verifiable correct answer. Build it from geometry, keep the empirical corrections in the tables designed for them, and check it&#8217;s monotonic before wondering why the drive-by-wire target is hunting.</p>



<p class="wp-block-paragraph">And if fixing it makes the engine worse, you&#8217;ve found a compensating error, not a mistake in the maths.</p>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<p class="wp-block-paragraph"><em>This is the first of a series on the Emtron KV12 running a 3.4 litre 2JZ. The torque model that sits on top of this table drives the <a href="https://blownbytwins.co.uk/?p=1118">traction control strategy</a>, and it is also what caps engine torque at the <a href="https://blownbytwins.co.uk/?p=1093">measured limit of the gearbox</a>. Full specification and measurement conditions are on the <a href="https://blownbytwins.co.uk/toyota-supra-mk4-delta/">Supra project page</a>.</em></p>



<p class="wp-block-paragraph">If you have built one of these tables from geometry and found the Cd behaviour at very small openings differs from the published ranges, I would like to hear about it. That is the part of this I trust least.</p><p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/throttle-body-effective-area/">Throttle Body Effective Flow Area: Building a Correct Area vs Position Table</a> first appeared on <a href="https://blownbytwins.co.uk">BlownByTwins</a>.</p><p>The post <a rel="nofollow" href="https://blownbytwins.co.uk/cars/mk4-supra/throttle-body-effective-area/">Throttle Body Effective Flow Area: Building a Correct Area vs Position Table</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
