<?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>feedforward - BlownByTwins</title>
	<atom:link href="https://blownbytwins.co.uk/tag/feedforward/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>feedforward - 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>Boost Control on the Emtron KV12: Where the Target Really Comes From</title>
		<link>https://blownbytwins.co.uk/cars/mk4-supra/boost-control-emtron-kv12/</link>
		
		<dc:creator><![CDATA[john]]></dc:creator>
		<pubDate>Sat, 17 Oct 2026 07:00:00 +0000</pubDate>
				<category><![CDATA[Engine Management]]></category>
		<category><![CDATA[Mk4 Supra]]></category>
		<category><![CDATA[boost control]]></category>
		<category><![CDATA[emtron]]></category>
		<category><![CDATA[feedforward]]></category>
		<category><![CDATA[wastegate]]></category>
		<guid isPermaLink="false">https://blownbytwins.co.uk/?p=1208</guid>

					<description><![CDATA[<p>How boost is controlled on the Supra's Emtron KV12: a base table that never asks for boost, a user offset that does, a deliberate clamp, and a PID kept on a short lead so the feedforward does the work.</p>
<p>The post <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> 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/boost-control-emtron-kv12/">Boost Control on the Emtron KV12: Where the Target Really Comes From</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">There is nothing exotic about the boost control on this car. It is Emtron&#8217;s standard closed loop strategy. SRD Tuning built the base, and I have refined the duty cycles from logs since.</p>



<p class="wp-block-paragraph">What is worth showing is how the pieces fit together. Where the boost target actually comes from, which tables do the real work, and how the PID is kept out of the way.</p>



<p class="wp-block-paragraph">Each section is marked. <strong>Verified</strong> means it comes straight from the calibration. <strong>Theory</strong> means it is my reasoning, not something I have measured. <strong>Observed</strong> means it is how the car behaves on the road.</p>



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



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



<ul class="wp-block-list">
<li>2JZ-GTE VVTi, 3.4 litre, Pulsar G42-1200, pump fuel</li>



<li>Turbosmart 60 mm wastegate, 15 psi spring, which gives 18 psi as installed</li>



<li>Single Link boost control solenoid</li>



<li><a href="https://emtron.world/products/kv12" target="_blank" rel="noopener">Emtron KV12</a>, closed loop, absolute target, manifold pressure as the control input</li>
</ul>



<p class="wp-block-paragraph">Who did what matters here, so to be clear: the structure, the lockouts and the base duty cycles are SRD&#8217;s. My changes are to the initial position table, made from logged corrections, and none of them is more than 3 percent.</p>



<h2 class="wp-block-heading">Where the target comes from</h2>



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



<p class="wp-block-paragraph">Emtron builds the boost target from a base table, adds a stack of offsets, then clamps the result. Here is the base table:</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">Pedal demand</th><th style="padding:6px 8px">0 to 2,500 rpm</th><th style="padding:6px 8px">3,000 rpm and above</th></tr></thead><tbody>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">0%</td><td style="padding:6px 8px">40</td><td style="padding:6px 8px">40</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">10 to 30%</td><td style="padding:6px 8px">70</td><td style="padding:6px 8px">70</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">40 to 98%</td><td style="padding:6px 8px">80</td><td style="padding:6px 8px">100</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">Boost Target Table 1, kPa absolute, against throttle area demand from the pedal. Identical rows and columns are merged.</figcaption></figure>



<p class="wp-block-paragraph">Look at the biggest number in it. 100 kPa absolute is atmospheric. The base table on its own never asks for any boost at all.</p>



<p class="wp-block-paragraph">The boost comes from the first of the user offsets:</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">Manifold pressure</th><th style="padding:6px 8px">Offset, every rotary position</th></tr></thead><tbody>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">0 and 50 kPa</td><td style="padding:6px 8px">0</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">100, 125 and 150 kPa</td><td style="padding:6px 8px">+200</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">User 1 Target Offset Table, kPa, indexed on manifold pressure against the steering wheel rotary (CANRx Vehicle Mode 1). All eight rotary columns are identical.</figcaption></figure>



<p class="wp-block-paragraph">Once the manifold reaches atmospheric, 200 kPa is added to the target. So with the pedal past 40 percent:</p>



<ul class="wp-block-list">
<li>Below 3,000 rpm: 80 + 200 = <strong>280 kPa</strong> absolute</li>



<li>From 3,000 rpm: 100 + 200 = <strong>300 kPa</strong> absolute</li>
</ul>



<p class="wp-block-paragraph">And then the clamp. The Boost Target Clamp is <strong>300 kPa absolute</strong>, roughly 2.0 bar of boost at sea level. Whatever the offsets add up to, the target cannot go past it. That is deliberate. The car runs on pump fuel, and the clamp is the safety switch that stops anything else in the stack asking for more than the fuel will take.</p>



<p class="wp-block-paragraph">The rotary columns being identical is also deliberate. Every traction setting gets the same boost ceiling, and the torque model decides how much of it is actually used. Boost is not the throttle on this car. Torque is, and that is covered in <a href="https://blownbytwins.co.uk/cars/mk4-supra/traction-control-feedforward-pid/">Traction Control on 1,114 whp</a>.</p>



<h3 class="wp-block-heading">Why the offset can look on manifold pressure</h3>



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



<p class="wp-block-paragraph">An offset indexed on manifold pressure is a feedback loop: as pressure rises from 50 to 100 kPa, the target rises with it. That would be a problem if the solenoid were active through that range. It isn&#8217;t, which is the next table.</p>



<h2 class="wp-block-heading">When the solenoid is allowed to work</h2>



<p class="wp-block-paragraph"><strong>Status: Verified</strong></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">Lockout</th><th style="text-align:right;padding:6px 8px">Value</th></tr></thead><tbody>
<tr style="border-bottom:1px solid #ddd"><td style="padding:6px 8px">Throttle</td><td style="text-align:right;padding:6px 8px">10%</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="padding:6px 8px">Engine speed</td><td style="text-align:right;padding:6px 8px">1,800 rpm</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="padding:6px 8px">Manifold pressure</td><td style="text-align:right;padding:6px 8px">110 kPa</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="padding:6px 8px">Engine temperature</td><td style="text-align:right;padding:6px 8px">60 &deg;C</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">Boost OL/CL Lockouts, set by SRD. Below any of these the solenoid is switched off and the wastegate runs on its spring.</figcaption></figure>



<p class="wp-block-paragraph">The solenoid stays off until the manifold is already 10 kPa above atmospheric. By then the user offset has finished ramping in and the target is fixed. Off boost, cold, or at a whisker of throttle, the wastegate simply does what its spring tells it.</p>



<h2 class="wp-block-heading">What takes boost away</h2>



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



<p class="wp-block-paragraph">Three offsets pull the target down. Two are protection, and both are indexed against the target itself, so the higher the target, the more they take.</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 engine temp</th><th style="padding:6px 8px">up to 100 &deg;C</th><th style="padding:6px 8px">110 &deg;C</th><th style="padding:6px 8px">120 &deg;C and above</th></tr></thead><tbody>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">180 kPa</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">200 kPa</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">-10</td><td style="padding:6px 8px">-20</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">220 kPa</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">-40</td><td style="padding:6px 8px">-40</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">0</td><td style="padding:6px 8px">-50</td><td style="padding:6px 8px">-60</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">0</td><td style="padding:6px 8px">-50</td><td style="padding:6px 8px">-80</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">0</td><td style="padding:6px 8px">-50</td><td style="padding:6px 8px">-100</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">Engine Temperature Target Offset Table, kPa. Every column from -50 to 100 &deg;C is zero.</figcaption></figure>



<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 inlet air temp</th><th style="padding:6px 8px">up to 40 &deg;C</th><th style="padding:6px 8px">50</th><th style="padding:6px 8px">60</th><th style="padding:6px 8px">70</th><th style="padding:6px 8px">80</th><th style="padding:6px 8px">100</th><th style="padding:6px 8px">120</th></tr></thead><tbody>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">100 and 150 kPa</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">200 to 300 kPa</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">-3</td><td style="padding:6px 8px">-10</td><td style="padding:6px 8px">-20</td><td style="padding:6px 8px">-30</td><td style="padding:6px 8px">-40</td><td style="padding:6px 8px">-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">Air Temperature Target Offset Table, kPa. Identical rows are merged.</figcaption></figure>



<p class="wp-block-paragraph">The third is by gear, and it is there for the gearbox rather than the engine:</p>



<figure class="bbt-figure" style="margin:1.8rem 0"><table style="border-collapse:collapse;width:100%;font-size:0.85rem;text-align:center"><thead><tr style="border-bottom:2px solid #333"><th style="text-align:left;padding:6px">Gear</th><th style="padding:6px">R, N, 1 to 5</th><th style="padding:6px">6</th><th style="padding:6px">7</th><th style="padding:6px">8</th></tr></thead><tbody>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px">Offset, kPa</td><td>0</td><td>-10</td><td>-20</td><td>-30</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">Gear Target Offset Table.</figcaption></figure>



<p class="wp-block-paragraph">Sixth, seventh and eighth lose 10, 20 and 30 kPa to protect the ZF&#8217;s clutches from slip. Where that gearbox runs out of capacity is covered in <a href="https://blownbytwins.co.uk/?p=1093">Where the Stock ZF 8HP70 Gives Up</a>.</p>



<h2 class="wp-block-heading">The table that does the work</h2>



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



<p class="wp-block-paragraph">Everything above decides what boost to ask for. This decides how to get it. The initial position table is the feedforward: the solenoid duty the ECU applies before the PID has done anything at all.</p>



<figure class="bbt-figure" style="margin:1.8rem 0"><table style="border-collapse:collapse;width:100%;font-size:0.8rem;text-align:right"><thead><tr style="border-bottom:2px solid #333"><th style="text-align:left;padding:5px 6px">Target vs rpm</th><th style="padding:5px 6px">1,000 to 1,500</th><th style="padding:5px 6px">2,000 to 3,500</th><th style="padding:5px 6px">4,000</th><th style="padding:5px 6px">4,500</th><th style="padding:5px 6px">5,000</th><th style="padding:5px 6px">5,500</th><th style="padding:5px 6px">6,000</th><th style="padding:5px 6px">6,500</th><th style="padding:5px 6px">7,000</th><th style="padding:5px 6px">7,500</th><th style="padding:5px 6px">8,000</th></tr></thead><tbody>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:5px 6px">125 to 200 kPa</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:5px 6px">220 kPa</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">100</td><td style="padding:5px 6px">26.5</td><td style="padding:5px 6px">20.0</td><td style="padding:5px 6px">13.0</td><td style="padding:5px 6px">10.5</td><td style="padding:5px 6px">8.0</td><td style="padding:5px 6px">5.0</td><td style="padding:5px 6px">2.5</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">0</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:5px 6px">240 kPa</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">100</td><td style="padding:5px 6px">28.0</td><td style="padding:5px 6px">22.5</td><td style="padding:5px 6px">17.0</td><td style="padding:5px 6px">16.5</td><td style="padding:5px 6px">15.0</td><td style="padding:5px 6px">13.0</td><td style="padding:5px 6px">11.5</td><td style="padding:5px 6px">9.5</td><td style="padding:5px 6px">10.5</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:5px 6px">250 kPa</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">100</td><td style="padding:5px 6px">29.0</td><td style="padding:5px 6px">24.0</td><td style="padding:5px 6px">18.5</td><td style="padding:5px 6px">18.0</td><td style="padding:5px 6px">17.0</td><td style="padding:5px 6px">16.5</td><td style="padding:5px 6px">15.5</td><td style="padding:5px 6px">14.5</td><td style="padding:5px 6px">16.0</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:5px 6px">260 kPa</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">100</td><td style="padding:5px 6px">29.5</td><td style="padding:5px 6px">25.0</td><td style="padding:5px 6px">20.5</td><td style="padding:5px 6px">19.5</td><td style="padding:5px 6px">19.5</td><td style="padding:5px 6px">19.5</td><td style="padding:5px 6px">19.5</td><td style="padding:5px 6px">19.5</td><td style="padding:5px 6px">21.0</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:5px 6px">280 kPa</td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">100</td><td style="padding:5px 6px">31.0</td><td style="padding:5px 6px">28.0</td><td style="padding:5px 6px">24.5</td><td style="padding:5px 6px">23.0</td><td style="padding:5px 6px">24.5</td><td style="padding:5px 6px">26.0</td><td style="padding:5px 6px">27.5</td><td style="padding:5px 6px">29.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"><strong>300 kPa</strong></td><td style="padding:5px 6px">0</td><td style="padding:5px 6px">100</td><td style="padding:5px 6px"><strong>32.5</strong></td><td style="padding:5px 6px"><strong>30.5</strong></td><td style="padding:5px 6px"><strong>28.0</strong></td><td style="padding:5px 6px"><strong>26.0</strong></td><td style="padding:5px 6px"><strong>26.0</strong></td><td style="padding:5px 6px"><strong>30.0</strong></td><td style="padding:5px 6px"><strong>32.0</strong></td><td style="padding:5px 6px"><strong>36.5</strong></td><td style="padding:5px 6px"><strong>42.0</strong></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, boost target against engine speed. Bold is the row the car lives on at full demand. The table also has 320 and 340 kPa rows, which the 300 kPa clamp means are never used.</figcaption></figure>



<p class="wp-block-paragraph">Read the 300 kPa row from left to right and it tells the story of a pull.</p>



<p class="wp-block-paragraph"><strong>2,000 to 3,500 rpm: 100.</strong> Hold the wastegate shut and let the turbo spool. In practice this is 80, not 100, because the Max Duty table clamps the output at 80 percent everywhere. The 100 in the table is a way of saying &#8220;as much as you&#8217;re allowed&#8221;.</p>



<p class="wp-block-paragraph"><strong>4,000 rpm: 32.5.</strong> The turbo is lit. Drop straight to the duty that holds 300 kPa, so the gate opens instead of letting boost run past the target.</p>



<p class="wp-block-paragraph"><strong>5,500 to 6,000 rpm: 26.</strong> The lowest duty in the row.</p>



<p class="wp-block-paragraph"><strong>6,500 to 8,000 rpm: 30 rising to 42.</strong> More duty is needed to hold the same target as rpm rises.</p>



<p class="wp-block-paragraph">The lower rows show the spring at work. The spring holds 18 psi as installed, about 225 kPa absolute. So at a 220 kPa target the duty falls away as rpm rises, and by 7,500 rpm it is zero: the spring alone is enough. Every row above that is the solenoid adding pressure on top of the spring.</p>



<h3 class="wp-block-heading">Why the duty rises at the top</h3>



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



<p class="wp-block-paragraph">A wastegate valve is pushed open by exhaust pressure acting on its face, as well as by boost pressure acting on its diaphragm. As rpm rises, exhaust manifold pressure rises with it, and the valve gets more help opening. To hold the same boost, the solenoid has to fight harder, so the duty goes up. I don&#8217;t measure exhaust manifold pressure on this car, so that is the mechanism I&#8217;d expect rather than one I have logged.</p>



<h3 class="wp-block-heading">How I refined it</h3>



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



<p class="wp-block-paragraph">If the initial position were perfect, the PID would have nothing to correct. So the logs tell you where it is wrong. Wherever the closed loop consistently added or removed duty in the same cell, the feedforward was out by about that much.</p>



<p class="wp-block-paragraph">I moved those cells towards what the PID was asking for. None by more than 3 percent. It&#8217;s refinement, not a rebuild. The aim was to take work away from the closed loop wherever the data said it was doing work it shouldn&#8217;t have to.</p>



<h2 class="wp-block-heading">The PID: kept on a short lead</h2>



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



<p class="wp-block-paragraph">The loop runs at 35 Hz, against Emtron&#8217;s typical 25, with a deadband of ±0.1 kPa and no input or target filtering. Emtron&#8217;s own note on the control rate is worth repeating: change it and the gains need re-tuning, because every gain is effectively per calculation.</p>



<p class="wp-block-paragraph">All three gains are scheduled on boost target error. Negative error means boost is above target.</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">Error, kPa</th><th style="padding:6px 8px">-50</th><th style="padding:6px 8px">-25</th><th style="padding:6px 8px">-10</th><th style="padding:6px 8px">-5</th><th style="padding:6px 8px">-2</th><th style="padding:6px 8px">2</th><th style="padding:6px 8px">5</th><th style="padding:6px 8px">10</th><th style="padding:6px 8px">25</th><th style="padding:6px 8px">60</th></tr></thead><tbody>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">Proportional</td><td style="padding:6px 8px">0.50</td><td style="padding:6px 8px">0.50</td><td style="padding:6px 8px">0.20</td><td style="padding:6px 8px">0.20</td><td style="padding:6px 8px">0.10</td><td style="padding:6px 8px">0.10</td><td style="padding:6px 8px">0.50</td><td style="padding:6px 8px">0.50</td><td style="padding:6px 8px">0.50</td><td style="padding:6px 8px">0.50</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">Integral</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0.018</td><td style="padding:6px 8px">0.025</td><td style="padding:6px 8px">0.025</td><td style="padding:6px 8px">0.018</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td></tr>
<tr style="border-bottom:1px solid #ddd"><td style="text-align:left;padding:6px 8px">Derivative</td><td style="padding:6px 8px">3.00</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">0</td><td style="padding:6px 8px">3.00</td><td style="padding:6px 8px">3.00</td><td style="padding:6px 8px">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">Proportional, Integral and Derivative Gain Tables combined. The three tables use slightly different breakpoints; where a column is beyond a table&#8217;s axis, its end value is shown. Derivative is 0 from -40 to +5 kPa. Proportional also has a dMAP axis, flat apart from one cell, covered below.</figcaption></figure>



<p class="wp-block-paragraph">The integral is clamped as well: the Positive and Negative Integral Limit tables hold it to <strong>±5 percent duty</strong> at every rpm. Overall output is held between a 5 percent minimum and an 80 percent maximum.</p>



<p class="wp-block-paragraph">One cell in the proportional table stands out. At -25 kPa of error, with manifold pressure rising at 5 percent per second, the gain is <strong>10.00</strong> instead of 0.50. That is the overboost catch. Boost well over target and still climbing is the one situation where the controller is allowed to hit hard.</p>



<h3 class="wp-block-heading">Why it is shaped this way</h3>



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



<p class="wp-block-paragraph">Proportional gain is smallest near target. Once the boost is where it should be, small errors are corrected gently, so the solenoid isn&#8217;t hunting.</p>



<p class="wp-block-paragraph">Integral only works within 5 kPa of target and is zero beyond 10. During spool the error is enormous, and an integrator running through that would wind up and then overshoot when the turbo arrives. Here it simply doesn&#8217;t run until boost is close. Add the ±5 percent clamp and the integrator can trim the feedforward but never replace it.</p>



<p class="wp-block-paragraph">Derivative is active between 10 and 25 kPa below target. That is boost on its final approach, rising fast towards the target. Derivative reacts to rate of change, so it starts opening the gate before the boost gets there, taking the edge off the arrival rather than correcting an overshoot afterwards.</p>



<p class="wp-block-paragraph">It&#8217;s the same philosophy as the <a href="https://blownbytwins.co.uk/cars/mk4-supra/traction-control-feedforward-pid/">traction control</a>. Feedforward does the work. The closed loop is soft near target, gated where it could do harm, and clamped so it can never take over.</p>



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



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



<p class="wp-block-paragraph">Two things in the file worth knowing if you are reading your own:</p>



<ul class="wp-block-list">
<li>The Boost Solenoid Deadtime table is zero from 10 to 20 V, so solenoid duty isn&#8217;t corrected for supply voltage.</li>



<li>The Boost Overall Target Trim is zero. It&#8217;s a single number that shifts every target at once, which makes it a quick way to test a change without touching the tables.</li>
</ul>



<h2 class="wp-block-heading">Does it work?</h2>



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



<p class="wp-block-paragraph">Spooled by 3,400 rpm. On target by 4,200. And from there it pulls, hard, all the way to 8,400.</p>



<p class="wp-block-paragraph">That lines up with the table. The 100 percent hold ends at 3,500, the duty drops to 32.5 at 4,000, and the car is on target 200 rpm later.</p>



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



<p class="wp-block-paragraph">Get the feedforward right and the PID has almost nothing to do. Then let the logs tell you where it isn&#8217;t right: wherever the closed loop is consistently correcting, the initial position is wrong by that much.</p>



<p class="wp-block-paragraph">Every number here is specific to this turbo, this wastegate, this spring and this fuel. <strong>The data is not transferable, but the principle is.</strong></p>



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



<p class="wp-block-paragraph"><em>How the torque model decides how much of this boost is actually used is in <a href="https://blownbytwins.co.uk/cars/mk4-supra/traction-control-feedforward-pid/">Traction Control on 1,114 whp</a>. Why the top gears lose boost is in <a href="https://blownbytwins.co.uk/?p=1093">Where the Stock ZF 8HP70 Gives Up</a>. The fuel system feeding all of it is in <a href="https://blownbytwins.co.uk/?p=1194">Staged Injection on the Emtron KV12</a>. 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/boost-control-emtron-kv12/">Boost Control on the Emtron KV12: Where the Target Really Comes From</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/boost-control-emtron-kv12/">Boost Control on the Emtron KV12: Where the Target Really Comes From</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Erratic Shifts and Idle Overfuelling on the 2JZ: Finding a DBW Feed-Forward Fault</title>
		<link>https://blownbytwins.co.uk/cars/mk4-supra/dbw-feedforward-fault/</link>
		
		<dc:creator><![CDATA[john]]></dc:creator>
		<pubDate>Fri, 18 Sep 2026 16:07:52 +0000</pubDate>
				<category><![CDATA[Engine Management]]></category>
		<category><![CDATA[Mk4 Supra]]></category>
		<category><![CDATA[Tuning]]></category>
		<category><![CDATA[2jz]]></category>
		<category><![CDATA[air model]]></category>
		<category><![CDATA[emtron]]></category>
		<category><![CDATA[feedforward]]></category>
		<guid isPermaLink="false">https://blownbytwins.co.uk/?p=1156</guid>

					<description><![CDATA[<p>Inconsistent torque, delivery and shifts, with nothing obvious in the log. Working outwards from the symptom into the DBW loop, and the arithmetic that showed the integrator was spending its whole authority cancelling a feed-forward error.</p>
<p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/dbw-feedforward-fault/">Erratic Shifts and Idle Overfuelling on the 2JZ: Finding a DBW Feed-Forward Fault</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/dbw-feedforward-fault/">Erratic Shifts and Idle Overfuelling on the 2JZ: Finding a DBW Feed-Forward Fault</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 car was giving me inconsistent torque readings, inconsistent delivery, and downstream of both, inconsistent shifts. And on rarer occasions the car would overfuel like crazy when returning to idle. It&#8217;s done this maybe 6-8 times in 4000 miles of usage. Nothing in the log made the reason obvious.</p>



<p class="wp-block-paragraph">This is how I worked outwards from the symptom until the log told me where to look, and what the arithmetic said once I got there.</p>



<h2 class="wp-block-heading">Ruling things out</h2>



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



<p class="wp-block-paragraph">I expanded the log window out and walked the closed loop items one at a time. First question: was idle control intervening during the downshift? It was not. Verified and set aside.</p>



<p class="wp-block-paragraph">The next thing I noticed was that air mass was going erratic, and that is worth being precise about, because the air mass model on this car is a blend. Below 100 kPa it runs the throttle mass flow model exclusively and blends towards speed density above that. In the region where this fault appears the air mass estimate is therefore a function of throttle effective area and pressure ratio and nothing else. No speed density term diluting it, no trapped mass term in the estimate.</p>



<p class="wp-block-paragraph">So erratic air mass in that region means the blade, or the area characterisation, or both. It cannot mean much else.</p>



<p class="wp-block-paragraph">Pedal throttle demand translation was smooth through the whole event. The driver demand table was not doing this. That left the DBW loop, and the DBW PID was the gold seam.</p>


<p><!-- IMAGE SLOT A: emtron-dbw-pid-instability-log.png --></p>


<h2 class="wp-block-heading">What the loop was doing</h2>



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



<p class="wp-block-paragraph">Three things stand out.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="566" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/dbw_pid_errors-1024x566.png" alt="" class="wp-image-1160" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/dbw_pid_errors-1024x566.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/dbw_pid_errors-300x166.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/dbw_pid_errors-768x424.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/dbw_pid_errors-1536x848.png 1536w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/dbw_pid_errors.png 2046w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Proportional output is saturating at minus 100 percent repeatedly, and topping out near plus 63. That asymmetry is not the axis autoscaling being unhelpful. It is the loop reaching its closing clamp over and over while never reaching the opening one.</p>



<p class="wp-block-paragraph">Integral output is sitting around plus 24 percent and climbing slowly across the window. An integrator that keeps accumulating while the proportional term is pinned at its clamp is not doing the job an integrator is for.</p>



<p class="wp-block-paragraph">The motor command is swinging roughly minus 65 to plus 100 percent while the measured blade position only moves a few percent either side of 15. The blade is inertially filtered. It physically cannot follow a command oscillating at that rate, so the engine never sees the full excursion.</p>



<p class="wp-block-paragraph">That last point is the one that connects back to the shift. The engine does not see it, but the model does. Torque estimate comes from air mass, air mass in this region comes from the throttle mass flow model, and that model reads blade position directly. Every percent of blade wobble goes into the torque estimate whether or not the engine produced any of it.</p>



<p class="wp-block-paragraph">The gearbox was reacting to torque noise that did not exist at the crankshaft.</p>



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



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



<p class="wp-block-paragraph">This is where the log stops being suggestive and starts being conclusive. At the cursor, 38.138s in the screenshot above:</p>



<ul class="wp-block-list">
<li>Servo Position Main: 3.7 percent</li>



<li>Proportional output: 0.9 percent</li>



<li>Integral output: 24.3 percent</li>



<li>Derivative output: 0.0 percent</li>



<li>Motor command: 6.2 percent</li>
</ul>



<p class="wp-block-paragraph">My feed-forward table runs minus 30 at 0 percent and minus 15 at 5 percent. Interpolated linearly, feed-forward at 3.7 percent is minus 18.9.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="1080" height="678" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-motor-command-reconstruction.png" alt="Bar chart reconstructing the DBW motor command at 3.7 percent blade: feed-forward -18.9, proportional +0.9, integral +24.3 and derivative 0.0 percent motor duty, summing to +6.3 against a logged +6.2" class="wp-image-1172" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-motor-command-reconstruction.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-motor-command-reconstruction-300x188.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-motor-command-reconstruction-1024x643.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-motor-command-reconstruction-768x482.png 768w" sizes="(max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Reconstructing the motor command at 38.138 s. Shading is by absolute magnitude, so the two terms doing all the work are the ones that stand out.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Two things fall out of a match that close. Motor command is the summed controller output rather than a measured position, and feed-forward interpolates linearly between breakpoints.</p>



<p class="wp-block-paragraph">But the finding is the third thing. <strong>At a near steady 3.7 percent blade position, the integral had wound to plus 24.3 for no purpose other than to cancel a feed-forward of minus 18.9.</strong></p>



<p class="wp-block-paragraph">The feed-forward in the 0 to 5 percent band is asking for roughly 25 points of closing duty that the throttle body does not need. The integral is spending its entire authority undoing it. That is a large stored state sitting permanently in the loop, and every time the proportional term saturates and the target moves, that state has to unwind before anything else can settle.</p>



<p class="wp-block-paragraph">It is a far better explanation for a sustained oscillation than any single gain cell.</p>



<h2 class="wp-block-heading">The feed-forward step, and what it actually is</h2>



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


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="1080" height="364" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-feedforward-step-as-found-vs-revised.png" alt="Heatmap of DBW feed-forward, percent motor duty, against throttle target 0, 5, 6, 8 and 10 percent. As found: -30, -15, +10, +10, +10. Revised: -30, -15, -5, +5, +10" class="wp-image-1171" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-feedforward-step-as-found-vs-revised.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-feedforward-step-as-found-vs-revised-300x101.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-feedforward-step-as-found-vs-revised-1024x345.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-feedforward-step-as-found-vs-revised-768x259.png 768w" sizes="(max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Both rows are shaded against the same range, so the revision reads as a smoothing of the step rather than a change of shape.</figcaption></figure>
</div>


<p class="wp-block-paragraph">There is a 25 point change in motor duty for a 1 percent movement in target between 5 and 6 percent, and the log crosses that region immediately before one of the instabilities. My first instinct was that this was simply wrong. It is not, and this is the part most likely to be copied badly, so it is worth saying plainly.</p>



<p class="wp-block-paragraph">The return spring on a DBW body pulls the blade towards its limp home position from both directions. Below limp home you need negative duty to hold the blade down against the spring. Above it you need positive duty to hold it open. A feed-forward table that changes sign between two cells is not a tuning error. It is the table telling you where limp home sits.</p>



<p class="wp-block-paragraph">Delete the step and you have not removed the discontinuity. You have removed the compensation for it, and handed the spring preload to the integrator.</p>



<p class="wp-block-paragraph">The real problems are different. First, the magnitude of the low band values, which the arithmetic above says are too negative. Second, a 25 point change interpolated across 1 percent of travel behaves like a gain of 25 through a region the blade is oscillating in.</p>



<h2 class="wp-block-heading">The proportional gain table</h2>



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



<p class="wp-block-paragraph">The low position P gains are aggressive, and lopsided towards the negative error side.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="430" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-as-found.png" alt="Heatmap of DBW proportional gain as found, throttle target 5, 15 and 25 percent against target error -12 to +12 percent. Gains run from 12.00 at -12 percent error in the 5 and 15 percent rows down to 5.00 at +12 in every row" class="wp-image-1170" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-as-found.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-as-found-300x119.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-as-found-1024x408.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-as-found-768x306.png 768w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Proportional gain as found. Shaded against the same range as the revised table below, so the two are directly comparable.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Reading negative error as blade above target, the closing correction gets close to twice the gain available for an equivalent opening error, at every row.</p>



<p class="wp-block-paragraph">The spring makes this more interesting than a simple symmetry argument, because the asymmetry it creates flips across limp home. Above limp home the spring already assists closing, so the loop needs more authority to open and less to close. Below limp home it reverses.</p>



<p class="wp-block-paragraph">A table that favours the closing side at every row is therefore directionally right in the 5 percent row and wrong in the 15 and 25 percent rows. The blade sits at 15 to 17 percent through this event.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="430" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-revised.png" alt="Heatmap of DBW proportional gain as revised, throttle target 5, 15 and 25 percent against target error -12 to +12 percent, with every gain between 5.0 and 8.5 and 5.0 at +12 in every row" class="wp-image-1169" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-revised.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-revised-300x119.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-revised-1024x408.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-dbw-proportional-gain-revised-768x306.png 768w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Proportional gain, revised. Same shading range as above. The whole table reads cooler, and the 15 and 25 percent rows now favour the opening side.</figcaption></figure>
</div>


<p class="wp-block-paragraph">One caveat that anyone copying this needs to take seriously. The whole reading above depends on the error channel being target minus actual. If your ECU signs it the other way, the argument inverts and so does the revision. Confirm it on your own log before you touch a cell: find a step where the blade visibly lags a rising target, and read the sign.</p>



<h2 class="wp-block-heading">What I have not proved yet</h2>



<p class="wp-block-paragraph">I changed two tables at once. Until they are separated, no outcome can be attributed to either.</p>



<p class="wp-block-paragraph">I have not measured the true limp home position. The right way is to unpower the driver and read the TPS, then check whether the feed-forward breakpoints actually straddle it. If limp home sits at 6.5 percent rather than between 5 and 6, the compensation is being applied in the wrong place, and that alone would explain the instability without a single gain change.</p>



<p class="wp-block-paragraph">I have not confirmed the error sign convention from a step.</p>



<p class="wp-block-paragraph">And I left the 0 and 5 percent feed-forward cells alone, which are the two cells the arithmetic actually points at.</p>



<p class="wp-block-paragraph">I&#8217;m not declaring this as &#8220;fixed&#8221; yet. However, the gear change is smoother, particularly the upshift. The lower speed acceleration is cleaner and everything just feels much more refined. Always remember the first few percent of opening on a throttle blade are extremely non-linear, and even more so on a 82mm throttle body.</p>



<h2 class="wp-block-heading">The test that closes it</h2>



<p class="wp-block-paragraph">With the loop stable, park the blade at steady positions across 0 to 25 percent, in 2 percent steps through the 0 to 8 percent band, and log feed-forward and integral at each point.</p>



<p class="wp-block-paragraph">Wherever the integral is non-zero at steady state, the feed-forward is wrong by exactly that amount. That lets the whole low band feed-forward table be built by subtraction rather than by iteration. The position at which feed-forward crosses zero and the integral stays at zero is the true limp home. Any step within the sweep settles the sign convention.</p>



<p class="wp-block-paragraph">Run it on the same road and the same coast down and you also get a genuinely matched before and after, rather than two logs taken a week apart under different load.</p>



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



<p class="wp-block-paragraph"><strong>The data is not transferable, but the principle is.</strong></p>



<p class="wp-block-paragraph">A feed-forward table and an integrator are solving the same problem from opposite ends. If the integrator is carrying a large standing value at a steady operating point, the feed-forward is wrong by that amount, and you can read the correction straight off the log instead of iterating towards it.</p>



<p class="wp-block-paragraph">The throttle area table that the whole torque model sits on is covered in <a href="https://blownbytwins.co.uk/engine-management/throttle-body-effective-area/">Throttle Body Effective Flow Area</a>, and the same feed-forward versus PID argument applied to traction control is in <a href="https://blownbytwins.co.uk/engine-management/traction-control-feedforward-pid/">Traction Control on 1,114 whp</a>. Full specification is 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 a DBW loop and have taken a different view on any of this, particularly the limp home reasoning or the gain asymmetry, I would like to hear it.</p><p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/dbw-feedforward-fault/">Erratic Shifts and Idle Overfuelling on the 2JZ: Finding a DBW Feed-Forward Fault</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/dbw-feedforward-fault/">Erratic Shifts and Idle Overfuelling on the 2JZ: Finding a DBW Feed-Forward Fault</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Traction Control on 1,114 whp: Feedforward, PID, and Why It Never Cuts</title>
		<link>https://blownbytwins.co.uk/cars/mk4-supra/traction-control-feedforward-pid/</link>
		
		<dc:creator><![CDATA[john]]></dc:creator>
		<pubDate>Thu, 17 Sep 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[Engine Management]]></category>
		<category><![CDATA[Mk4 Supra]]></category>
		<category><![CDATA[Tuning]]></category>
		<category><![CDATA[emtron]]></category>
		<category><![CDATA[feedforward]]></category>
		<category><![CDATA[torque model]]></category>
		<category><![CDATA[traction control]]></category>
		<guid isPermaLink="false">https://blownbytwins.co.uk/?p=1118</guid>

					<description><![CDATA[<p>1,114 whp, 880 lb ft, and a 295 section road tyre on the back. Traction control on this car is not a driver aid. It is the thing that makes&#8230;</p>
<p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/traction-control-feedforward-pid/">Traction Control on 1,114 whp: Feedforward, PID, and Why It Never Cuts</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/traction-control-feedforward-pid/">Traction Control on 1,114 whp: Feedforward, PID, and Why It Never Cuts</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">1,114 whp, 880 lb ft, and a 295 section road tyre on the back. Traction control on this car is not a driver aid. It is the thing that makes the car usable at all.</p>



<p class="wp-block-paragraph">Most discussion of traction control stops at &#8220;it cuts power when the wheels spin&#8221;. That describes about a third of what is actually happening, and it is the least interesting third. The system on this car has a predictive half that tries to never need the reactive half, and the whole design is aimed at keeping the reactive half quiet.</p>



<p class="wp-block-paragraph">This is how it is set up, and why. Every table is reproduced in full.</p>



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



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



<ul class="wp-block-list">
<li><a href="https://emtron.world/products/kv12" target="_blank" rel="noopener">Emtron KV12</a>, torque based traction control</li>



<li>3.4 litre 2JZ-GTE VVTi, 1,114 whp on E85, torque limited to 880 lb ft</li>



<li>ZF 8HP70, 2.93 final drive, OS Giken LSD</li>



<li>Continental SportContact 7, 265/30/19 front and 295/30/19 rear</li>



<li>Four individual wheel speeds, three axis internal accelerometer</li>



<li>Eight position rotary on the steering wheel, over CAN</li>
</ul>



<p class="wp-block-paragraph">Everything below is my own work. The base calibration on this car came from SRD Tuning, but the traction control strategy is mine start to finish, which is the only reason I can show you the tables.</p>



<h2 class="wp-block-heading">The predictive half: torque feedforward</h2>



<p class="wp-block-paragraph">The core of the system is a table that answers one question: <strong>at what engine torque does this car lose traction?</strong></p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="1646" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-torque-feedforward-table.png" alt="Heatmap of the traction control torque feedforward table, slip target error -8 to +2 percent against engine torque 50 to 1,250 Nm. Every row is flat from 750 Nm upwards, with the zero slip error row clamped at 575 Nm" class="wp-image-1178" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-torque-feedforward-table.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-torque-feedforward-table-197x300.png 197w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-torque-feedforward-table-672x1024.png 672w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-torque-feedforward-table-768x1170.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-torque-feedforward-table-1008x1536.png 1008w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Torque Feed Forward Table, Nm. The torque at which traction is lost.</figcaption></figure>
</div>


<p class="wp-block-paragraph">It is indexed on engine torque with no reduction applied, against slip target error. The ECU looks up that number and feeds it forward as the torque target before any measurement of actual slip has influenced anything.</p>



<p class="wp-block-paragraph">That is the whole idea of feedforward. If the model is right, the engine never makes more torque than the tyres can take, the slip never happens, and the closed loop has nothing to correct.</p>



<p class="wp-block-paragraph">Look at the first two columns before anything else. At 50 Nm of engine torque the table returns 50, and at 150 it returns 150. Below about 150 Nm it is a pass through: the feedforward is not limiting anything, because at those loads there is nothing to limit.</p>



<h3 class="wp-block-heading">And this is where the normalisation matters</h3>



<p class="wp-block-paragraph">Read along the zero slip error row and the values climb: 245.3, 340.5, 430.9, 478.9, 527.0, 575.0. And then they stop. Flat at 575 Nm from 750 Nm of engine torque all the way to 1,250.</p>



<p class="wp-block-paragraph">That plateau is deliberate and it is the single most important thing in the setup.</p>



<p class="wp-block-paragraph">Extend the slope before the plateau and an unclamped table would be asking for roughly 815 Nm at the top of the range. The engine makes 1,193 Nm. So without the clamp, the feedforward would be handing the PID a target the tyres cannot deliver, and the PID would spend its entire life trying to close a gap that physics will not close.</p>



<p class="wp-block-paragraph">A saturated PID is not a controller. It is an actuator held wide open. You lose all the proportionality that makes traction control feel like assistance rather than interference.</p>



<p class="wp-block-paragraph">Clamping the feedforward at something the tyres can actually deliver means the PID always has authority in reserve. That is what &#8220;normalised&#8221; means here, and it is why the system feels like it is helping rather than fighting.</p>



<h3 class="wp-block-heading">Normalised against third</h3>



<p class="wp-block-paragraph">The feedforward table is written for third gear. Everything else is scaled off it by two correction tables.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="628" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-gear-drpm.png" alt="Heatmap of feedforward correction table 1, gears 1 to 8 against rate of change of engine speed 750 to 4,000 rpm per second, from 0 percent at low dRPM in the low gears to -32 percent in eighth at 4,000" class="wp-image-1177" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-gear-drpm.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-gear-drpm-300x174.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-gear-drpm-1024x595.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-gear-drpm-768x447.png 768w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Correction Table 1, percent applied to the feedforward torque.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Correction Table 1 is indexed on gear against rate of change of engine speed. In first at low dRPM the correction is zero. By eighth at 4,000 dRPM it is minus 32 percent.</p>



<p class="wp-block-paragraph">Which makes sense once you think about what dRPM means in each gear. Engine speed rising at 4,000 rpm per second in first is normal acceleration. The same rate in eighth means the driven wheels are going somewhere the car is not. The correction is reading the rate of change as evidence of impending slip, and pulling the target down before the slip calculation has caught up.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="812" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-slip-error.png" alt="Bar chart of feedforward correction table 2 against slip target error: -40 percent at -64, -20 at -32, -10 at -16, -4 at -8, -2 at -4, -1 at -2, 0 at -1 and +10 at 0 percent error" class="wp-image-1176" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-slip-error.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-slip-error-300x226.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-slip-error-1024x770.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-correction-slip-error-768x577.png 768w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Correction Table 2. Note the axis: it runs out to minus 64 percent slip error, far wider than the gain tables further down. These two tables are not directly comparable.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Correction Table 2 does the same job against slip target error directly, from minus 40 percent at large negative error up to plus 10 at zero. That positive 10 at zero error is worth noticing: when the car is exactly on target, the feedforward is allowed to ask for slightly more than the base table says.</p>



<h2 class="wp-block-heading">The slip target, and what the rotary actually does</h2>



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



<p class="wp-block-paragraph">Here is the part I had not seen anyone else do.</p>



<p class="wp-block-paragraph">The target slip table is indexed on <strong>lateral G</strong>, from minus 1.5 to plus 1.5, against the rotary position from the steering wheel.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="2004" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-lateral-g.png" alt="Heatmap of target slip table 1, rotary positions 0 to 12 against lateral G from -1.5 to +1.5. Most rows peak at zero lateral G, from 2 percent permitted slip at position 0 to 28 percent at position 12" class="wp-image-1179" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-lateral-g.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-lateral-g-162x300.png 162w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-lateral-g-552x1024.png 552w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-lateral-g-768x1425.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-lateral-g-828x1536.png 828w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Target Slip Table 1, permitted slip in percent. Row labels are the eight discrete CAN values the switch produces, so the ECU never interpolates between settings.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Almost every row is a dome. Maximum permitted slip in a straight line, tapering symmetrically as lateral load builds in either direction. At the loosest setting the car allows 28 percent slip straight ahead, falling to 25 at 1.5 G. At the tightest, 2 percent straight ahead and 1 percent once the car is properly loaded up.</p>



<p class="wp-block-paragraph">Setting 1 is the exception, and I would rather point at it than pretend it fits. It permits 2 percent straight ahead, rises to 3 percent at around 0.75 G in either direction, and comes back to 2.5 at full lateral load. It is the only row in the table that allows more slip while cornering than it does in a straight line.</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/emtron-traction-slip-target-vs-lateral-g.png" alt="Chart of permitted wheel slip against lateral G for three traction control settings, each forming a dome that peaks in a straight line and tapers as cornering load builds" class="wp-image-1120" /><figcaption class="wp-element-caption">The same data plotted. The dome is most pronounced in the middle settings and flattens at both extremes.</figcaption></figure>



<p class="wp-block-paragraph">So the rotary is not a gain switch and it is not an on/off. It selects <strong>how much slip you are allowed as a function of how hard you are cornering</strong>, and the system tightens automatically as lateral load increases without the driver doing anything.</p>



<h3 class="wp-block-heading">And then speed offsets all of it</h3>



<p class="wp-block-paragraph">Lateral G is not the only input to the slip target. A second table offsets it by road speed, and it does a lot of work at both ends.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="1382" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-offset-road-speed.png" alt="Heatmap of the target slip offset by front axle speed, 0 to 330 kph, for each rotary position: +9 points below 25 kph (up to +25 at position 12), zero from 45 to 160 kph, and negative from 180 kph, reaching between -2.0 and -9.4 at 330" class="wp-image-1175" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-offset-road-speed.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-offset-road-speed-234x300.png 234w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-offset-road-speed-800x1024.png 800w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-target-slip-offset-road-speed-768x983.png 768w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Target Slip Offset Table 1, percentage points added to or taken off the slip target by road speed.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Below 25 kph every setting adds nine percentage points of slip, and the loosest adds twenty five. That is the launch allowance. You cannot get a car like this moving from rest on a target of 2 percent, and without that offset the system would strangle it off the line.</p>



<p class="wp-block-paragraph">Between 45 and 160 kph the offset is zero and the lateral G table stands on its own. Above 180 it goes negative, and by 330 kph it is pulling back between 2 and 9.4 points depending on the setting.</p>



<p class="wp-block-paragraph">Which is the right way round. Wheel slip at 40 kph costs you a bit of time. Wheel slip at 300 kph costs you rather more than that.</p>



<h2 class="wp-block-heading">The reactive half: a deliberately soft PID</h2>



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



<p class="wp-block-paragraph">When the feedforward is not enough, the PID takes over. And the gains are the opposite shape to what most people would write. All three share exactly the same breakpoints, so they go in one table.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="430" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-gains.png" alt="Heatmap of the traction control PID gains against slip target error -25 to 0 percent: proportional 3.00 falling to 0.20, integral 0.000 rising to 0.020, derivative 3.00 falling to 0.10" class="wp-image-1174" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-gains.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-gains-300x119.png 300w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-gains-1024x408.png 1024w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-gains-768x306.png 768w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">Each row is shaded against its own range, because integral peaks at 0.020 and proportional at 3.00. The colour shows the shape, not the magnitude.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Proportional gain at zero slip error is 0.20. At minus 25 percent error it is 3.00. Derivative runs the same way, 0.10 at zero, and it saturates at 3.00 from minus 20 onwards.</p>



<p class="wp-block-paragraph">Both are smallest near target and largest far from it.</p>



<p class="wp-block-paragraph">That is a controller designed to be felt as little as possible. Around the target, where you spend almost all of your time, the loop barely reacts and the feedforward carries the car. Only when things run properly away does it bite hard.</p>



<p class="wp-block-paragraph">Tune it the conventional way round, with high gain near target for tight regulation, and you get a car that nibbles at the throttle constantly and feels like it is arguing with you.</p>



<h3 class="wp-block-heading">Integral is almost switched off, on purpose</h3>



<p class="wp-block-paragraph">Look at the integral row against the other two. Peak gain is 0.020, near target. At minus 25 it is <strong>zero</strong>.</p>



<p class="wp-block-paragraph">Zeroing the integral term exactly where the error is worst is anti windup by design. When the car is genuinely out of shape, the integrator stops accumulating instead of building up a correction you then have to unwind on the way out. An integrator that has wound up during a slide gives you a second event when it releases, and the second one is usually the one that catches people out.</p>



<p class="wp-block-paragraph">The rest of the PID setup backs that up:</p>



<ul class="wp-block-list">
<li>Integral control rate: 200 Hz</li>



<li>Integral positive clamp: 50.0 Nm</li>



<li>Integral negative clamp: -50.0 Nm</li>



<li>Minimum torque clamp: 50.0 Nm</li>



<li>Slip target filter: 4</li>
</ul>



<p class="wp-block-paragraph">Fifty Nm either side is a narrow band on an engine making 1,193. The integrator is there to trim, not to intervene.</p>



<h3 class="wp-block-heading">And the PID does not always run</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1080" height="1778" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-enable-table-1.png" alt="Heatmap of the PID enable table, driver demand torque 0 to 1,000 Nm against slip target error -6 to +5 percent. The loop is off below 300 Nm, then each extra 100 Nm enables one more column in a staircase" class="wp-image-1173" style="width:640px" srcset="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-enable-table-1.png 1080w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-enable-table-1-182x300.png 182w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-enable-table-1-622x1024.png 622w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-enable-table-1-768x1264.png 768w, https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-traction-pid-enable-table-1-933x1536.png 933w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /><figcaption class="wp-element-caption">PID Enable Table. 1 means the closed loop runs, 0 means it does not.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Below 300 Nm of driver demand it is zero across the whole row. The closed loop simply does not run.</p>



<p class="wp-block-paragraph">Above that it opens up as a staircase. At 300 Nm the loop only runs once slip error is worse than minus 3 percent. Every additional 100 Nm of driver demand brings one more column into play, until at 1,000 Nm it is active everywhere except the far positive corner.</p>



<p class="wp-block-paragraph">So the amount of authority the closed loop has is itself a function of how much the driver is asking for. At low demand, feedforward handles everything alone, which means the PID cannot introduce noise into normal driving, because at normal driving loads it is not switched on.</p>



<h2 class="wp-block-heading">What it is allowed to do about it</h2>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="540" height="195" src="https://blownbytwins.co.uk/wp-content/uploads/2026/09/emtron-torque-limit-actuator-priority.png" alt="Emtron torque limit strategy showing priority 1 throttle area, priority 2 ignition retard, and priority 3 set to OFF so cutting is disabled" class="wp-image-1125" /><figcaption class="wp-element-caption">Priority 1 throttle area, priority 2 ignition retard, priority 3 OFF.</figcaption></figure>



<p class="wp-block-paragraph">Emtron gives you three actuators for torque reduction, in a priority order. Mine reads throttle area, then ignition retard clamped at 11 degrees, then <strong>OFF</strong>.</p>



<p class="wp-block-paragraph">Cutting is disabled. On a car making 1,114 whp, the harshest tool in the box is not in the box.</p>



<p class="wp-block-paragraph">The throttle area minimum clamp bottoms out at 10 percent, so it never closes the throttle fully either. Torque reduction happens by moving the plate and pulling timing, and nothing else.</p>



<p class="wp-block-paragraph">That is a road car decision. Fuel or ignition cutting is fast and effective and it feels like being kicked. On a car that has to be pleasant on a motorway and predictable in the wet, an intervention that arrives as a smooth reduction rather than a hammer blow is worth more than the extra tenth of response.</p>



<h2 class="wp-block-heading">Does it work?</h2>



<p class="wp-block-paragraph">One number from a road log, second gear, full throttle:</p>



<p class="wp-block-paragraph"><strong>Torque reduction by retard: 8.1 percent.</strong></p>



<p class="wp-block-paragraph">Eight percent, in retard, on the second priority, with cutting unavailable and throttle intervention having already done its part. That is the system working gently in the conditions where a badly normalised setup would be reaching for everything it had.</p>



<p class="wp-block-paragraph">It is one data point from one log, so treat it as an illustration rather than proof. But it is the shape of result the whole design is aimed at.</p>



<h2 class="wp-block-heading">The principle, if you take nothing else</h2>



<p class="wp-block-paragraph">A PID is not there to make your feedforward work. It is there to handle what the feedforward could not have known about: a damp patch, a change in surface, a mid corner bump.</p>



<p class="wp-block-paragraph">If your feedforward target is unrealistic, the PID spends its authority correcting your model instead of correcting the road. It saturates, it escalates through the actuator list, and the car feels like it is fighting you.</p>



<p class="wp-block-paragraph">Normalise the target to something the tyres can actually deliver, gate the loop so it only runs when it is needed, keep the gains soft near target, and the reactive half stays quiet almost all the time.</p>



<p class="wp-block-paragraph">Which is the point. The best traction control is the one you do not notice.</p>



<h2 class="wp-block-heading">One thing to be clear about</h2>



<p class="wp-block-paragraph">Every number above is specific to this car: this power, these tyres, this gearbox, this weight distribution. <strong>The data is not transferable, but the principle is.</strong></p>



<p class="wp-block-paragraph">I have published the tables in full because seeing how something is structured teaches you far more than reading a description of it. Copy the structure. Do not copy the values.</p>



<p class="wp-block-paragraph">None of this works without trustworthy wheel speeds, which on a staggered setup is less automatic than it sounds. That is covered in <a href="https://blownbytwins.co.uk/?p=1111">Staggered Tyres and Traction Control</a>. The throttle area table that the whole torque model sits on is covered in <a href="https://blownbytwins.co.uk/engine-management/throttle-body-effective-area/">Throttle Body Effective Flow Area</a>. Full specification is 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 torque based traction control and have taken a different view on any of this, particularly the gain shape, the setting 1 anomaly or disabling cut, I would like to hear it. This is the part of the calibration I have changed my mind about most.</p><p>The post <a href="https://blownbytwins.co.uk/cars/mk4-supra/traction-control-feedforward-pid/">Traction Control on 1,114 whp: Feedforward, PID, and Why It Never Cuts</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/traction-control-feedforward-pid/">Traction Control on 1,114 whp: Feedforward, PID, and Why It Never Cuts</a> appeared first on <a rel="nofollow" href="https://blownbytwins.co.uk">BlownByTwins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
