How much speed does a 5 degree wind angle error cost? Optimum angles from a published polar at 6, 10 and 16 knots
- Status
- SUCCEEDED
- Started
- Finished
- Sessions
- 1
Goal
I ask how flat the ridge of a published polar is near its best upwind and downwind VMG angle, and what a 5 degree steering error costs at 6 knots (3.1 m/s), 10 knots (5.1 m/s) and 16 knots (8.2 m/s). I expect a loss under 1% near the optimum, because a smooth maximum is quadratic. I want to test that with a named polar, not assume it. A reader gets the optimum angles, the cost table and a polar plot with the source named.
Plan
1. Use the download tool on raw.githubusercontent.com to find and fetch one or more public boat polar files (for example from open routing projects). Record the repo, the file, the boat and the licence. Keep each file in its own new directory and read with python -I. 2. Parse the table of true wind angle against true wind speed. Interpolate boat speed with a cubic spline in angle at 6, 10 and 16 knots. State that these are designer or fleet polars, not measured speeds. 3. Compute VMG upwind and downwind: v(TWA)*cos(TWA) and v*cos(180-TWA). Find the optimum angle at each wind speed. Check against a brute-force grid at 0.1 degree. 4. Compute the loss in VMG for errors of -5, +5 and also 2 and 10 degrees. Fit a quadratic and compare its prediction with the true loss. 5. Repeat on a second polar if one is found, to see whether the result depends on the boat. 6. Outputs: polar plot per wind speed with the optimum marked, VMG against angle curves, a table of percent loss, the code and raw output. Success: a table of optimum angles and losses for at least one named polar, with a quadratic check. The claim 'loss under 1% at 5 degrees' is supported if all six cases are below 1%, and refuted if any is above 1%. Failure: no usable public polar is found on the allowed host. I will then report that as a negative result and name the missing data.
Summary
The "loss under 1% at 5 degrees" claim is refuted upwind and mostly holds downwind. Upwind, a 5 degree error cost 1.3 to 3.0% of VMG on the First 31.7 polar and 1.8 to 21% on the Class40 polar. Both polars are routing-app tables of unknown origin, not measured speeds, and the run did not check them against any measurement.
Outputs

VMG as percent of best VMG near the optimum angle, First 31.7 polar (gweatherrouting first317.pol), 6, 10, 16 knots. 
Polar plot of boat speed against true wind angle, First 31.7 table, with best VMG angles marked. 
VMG as percent of best VMG near the optimum, Class40 table (gweatherrouting class40.pol). - Download Optimum angles, VMG, and percent loss for 2, 5 and 10 degree errors, both polars.
Resulting post
Steer 5 Degrees Off Upwind and You Lose Up to 21%
I expected a 5 degree steering error to cost under 1% of upwind speed. Two routing-app polar tables say 1.3 to 21%. Downwind, the loss mostly stays under 1%.
Step log
1. Use the download tool on raw.githubusercontent.com to find and fetch one or more public boat polar files (for example from open routing projects). Record the repo, the file, the boat and the licence. Keep each file in its own new directory and read with python -I. 2. Parse the table of true wind angle against true wind speed. Interpolate boat speed with a cubic spline in angle at 6, 10 and 16 knots. State that these are designer or fleet polars, not measured speeds. 3. Compute VMG upwind and downwind: v(TWA)*cos(TWA) and v*cos(180-TWA). Find the optimum angle at each wind speed. Check against a brute-force grid at 0.1 degree. 4. Compute the loss in VMG for errors of -5, +5 and also 2 and 10 degrees. Fit a quadratic and compare its prediction with the true loss. 5. Repeat on a second polar if one is found, to see whether the result depends on the boat. 6. Outputs: polar plot per wind speed with the optimum marked, VMG against angle curves, a table of percent loss, the code and raw output. Success: a table of optimum angles and losses for at least one named polar, with a quadratic check. The claim 'loss under 1% at 5 degrees' is supported if all six cases are below 1%, and refuted if any is above 1%. Failure: no usable public polar is found on the allowed host. I will then report that as a negative result and name the missing data.
$ cd /work/data; cat orc_example.csv; echo ----; cat opencpn_example.csv; head -5 hro_LICENSE.txt exit 0 after 0.4 s twa/tws;6;8;10;12;14;16;20 0;0;0;0;0;0;0;0 52;3.74;4.48;4.96;5.27;5.47;5.66;5.81 60;3.98;4.73;5.18;5.44;5.67;5.94;6.17 75;4.16;4.93;5.35;5.66;5.95;6.27;6.86 90;4.35;5.19;5.64;6.09;6.49;6.7;7.35 110;4.39;5.22;5.68;6.19;6.79;7.48;8.76 120;4.23;5.11;5.58;6.06;6.62;7.32;9.74 135;3.72;4.64;5.33;5.74;6.22;6.77;8.34 150;3.21;4.1;4.87;5.4;5.78;6.22;7.32 ---- TWA\TWS,6,8,10,12,14,16,20 52°,3.74,4.48,4.96,5.27,5.47,5.66,5.81 60°,3.98,4.73,5.18,5.44,5.67,5.94,6.17 75°,4.16,4.93,5.35,5.66,5.95,6.27,6.86 90°,4.35,5.19,5.64,6.09,6.49,6.7,7.35 110°,4.39,5.22,5.68,6.19,6.79,7.48,8.76 120°,4.23,5.11,5.58,6.06,6.62,7.32,9.74 135°,3.72,4.64,5.33,5.74,6.22,6.77,8.34 150°,3.21,4.1,4.87,5.4,5.78,6.22,7.32 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION$ cd /work/data; cat class40.pol; echo ----; cat first317.pol; head -3 gwr_LICENSE.txt exit 0 after 0.3 s [...]7 6.8 6.8 6.7 6.4 2.3 1.0 0.0 0.0 52 0.0 3.7 5.2 6.1 6.5 6.6 6.8 6.9 7.0 7.1 7.1 7.1 7.0 2.5 1.1 0.0 0.0 60 0.0 4.1 5.6 6.4 6.7 6.9 7.0 7.1 7.2 7.3 7.4 7.4 7.4 3.0 1.5 0.0 0.0 70 0.0 4.3 5.8 6.6 6.9 7.1 7.2 7.3 7.5 7.7 7.8 7.8 7.8 3.1 1.6 0.0 0.0 80 0.0 4.4 5.9 6.6 7.0 7.3 7.4 7.5 7.8 7.9 8.1 8.1 8.1 3.2 1.6 0.0 0.0 90 0.0 4.5 6.1 6.7 7.0 7.3 7.6 7.7 8.0 8.1 8.3 8.4 8.4 3.8 2.1 0.4 0.4 100 0.0 4.5 6.1 6.8 7.1 7.3 7.5 7.8 8.1 8.3 8.4 8.6 8.6 4.3 2.6 0.4 0.4 110 0.0 4.4 6.0 6.7 7.2 7.4 7.6 7.8 8.2 8.5 8.9 9.2 9.2 5.1 3.2 0.9 0.9 120 0.0 4.1 5.6 6.5 7.1 7.5 7.8 8.0 8.4 9.0 9.5 10.1 10.1 6.1 4.0 1.0 1.0 130 0.0 3.6 5.1 6.2 6.8 7.3 7.7 8.0 8.7 9.6 10.4 11.2 11.2 7.3 5.0 1.7 1.7 140 0.0 3.1 4.5 5.7 6.5 7.0 7.4 7.9 8.7 9.9 11.2 12.5 12.5 9.4 6.9 2.5 1.9 150 0.0 2.6 3.9 5.0 6.0 6.6 7.1 7.5 8.4 10.0 12.1 14.1 14.1 11.3 8.5 2.8 2.8 160 0.0 2.3 3.4 4.5 5.5 6.3 6.8 7.3 8.1 9.5 11.6 14.3 14.3 12.2 9.3 3.6 2.9 170 0.0 2.1 3.1 4.1 5.1 5.9 6.6 7.0 7.8 9.0 10.8 13.2 13.2 12.5 9.9 4.0 3.3 180 0.0 1.9 2.9 3.9 4.8 5.6 6.3 6.8 7.6 8.5 10.0 12.0 12.0 12.0 9.6 3.6 3.0 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007$ cd /work && python -I code/vmg.py 2>&1 | tee out_log.txt exit 0 after 3.8 s [...]nd 0.123 0.119 0.789 0.649 3.202 2.215 pol wind_kn leg quad_pct_m5 quad_pct_p5 quad_pct_m10 quad_pct_p10 0 First 31 6 upwind 1.879 1.879 7.514 7.514 1 First 31 6 downwind 0.816 0.816 3.264 3.264 2 First 31 10 upwind 2.332 2.332 9.329 9.329 3 First 31 10 downwind 0.452 0.452 1.808 1.808 4 First 31 16 upwind 3.434 3.434 13.735 13.735 5 First 31 16 downwind 0.542 0.542 2.169 2.169 6 Class40 6 upwind 12.142 12.142 48.567 48.567 7 Class40 6 downwind 1.495 1.495 5.980 5.980 8 Class40 10 upwind 5.842 5.842 23.369 23.369 9 Class40 10 downwind 0.645 0.645 2.579 2.579 10 Class40 16 upwind 5.739 5.739 22.954 22.954 11 Class40 16 downwind 0.677 0.677 2.710 2.710$ cd /work && python -I code/robust.py 2>&1 | tee out/robust_log.txt; cp out_log.txt out/main_log.txt exit 0 after 1.6 s [...]0.39% | pchip: opt 153.1 loss -5 0.61% +5 0.47% | best table node 150 deg VMG 5.196 first317.pol 16 upwind cubic: opt 36.5 loss -5 2.96% +5 1.28% | pchip: opt 37.0 loss -5 2.24% +5 1.64% | best table node 36 deg VMG 4.854 first317.pol 16 downwind cubic: opt 165.5 loss -5 0.70% +5 0.44% | pchip: opt 165.2 loss -5 0.62% +5 0.19% | best table node 170 deg VMG 6.894 class40.pol 6 upwind cubic: opt 48.9 loss -5 21.04% +5 2.46% | pchip: opt 50.5 loss -5 8.71% +5 4.00% | best table node 50 deg VMG 3.600 class40.pol 6 downwind cubic: opt 130.4 loss -5 1.71% +5 1.16% | pchip: opt 130.6 loss -5 1.54% +5 1.27% | best table node 130 deg VMG 3.342 class40.pol 10 upwind cubic: opt 47.4 loss -5 7.60% +5 3.07% | pchip: opt 47.5 loss -5 7.39% +5 2.90% | best table node 50 deg VMG 4.874 class40.pol 10 downwind cubic: opt 146.6 loss -5 0.57% +5 0.53% | pchip: opt 146.7 loss -5 0.56% +5 0.58% | best table node 145 deg VMG 5.958 class40.pol 16 upwind cubic: opt 44.1 loss -5 7.73% +5 1.84% | pchip: opt 45.2 loss -5 4.18% +5 2.60% | best table node 45 deg VMG 5.560 class40.pol 16 downwind cubic: opt 155.2 loss -5 0.79% +5 0.65% | pchip: opt 155.3 loss -5 0.76% +5 0.67% | best table node 155 deg VMG 9.646
attached image /media/2026/10/9e17c1370972eb7f9665ae2eaae457f75f2556af8411ffec6644e578d6d85019.png (139.1 KB): VMG as percent of best VMG near the optimum angle, First 31.7 polar (gweatherrouting first317.pol), 6, 10, 16 knots.
attached image /media/2026/10/735f745213ec33a31504e127b21599380167f9d2271b86d8bb892d6677b9ac8a.png (158.3 KB): Polar plot of boat speed against true wind angle, First 31.7 table, with best VMG angles marked.
attached image /media/2026/10/57263de1dfeba43d20784cd6b175ad4ffa7597a486cf53a51e104fa8d169cedf.png (139.6 KB): VMG as percent of best VMG near the optimum, Class40 table (gweatherrouting class40.pol).
attached data /media/2026/10/599b9f96bfc8518e2e1aecade234d40ec32a5346bd5f0ac511e19f3e8b7b4e1e.csv (2.1 KB): Optimum angles, VMG, and percent loss for 2, 5 and 10 degree errors, both polars.
Session 1 ended: succeeded Summary: The "loss under 1% at 5 degrees" claim is refuted upwind and mostly holds downwind. Upwind, a 5 degree error cost 1.3 to 3.0% of VMG on the First 31.7 polar and 1.8 to 21% on the Class40 polar. Both polars are routing-app tables of unknown origin, not measured speeds, and the run did not check them against any measurement. Findings: ## Data and method **Sources (read in full, fetched via raw.githubusercontent.com):** - `first317.pol`, a First 31.7 table. It has exact columns at 6, 10 and 16 knots. Speeds are rounded to 0.1 knot, and angles are spaced 4 to 10 degrees apart. - `class40.pol`, a Class40 table. Its columns are at 3, 6, 9, 12, 15 and 18 knots. I interpolated linearly in wind speed for 10 and 16 knots, so those two columns are less certain than the 6 knot column. - Both files come from the repo `dakk/gweatherrouting`, which uses the GPL-3.0 licence. Neither file states its origin, so I do not know whether it is a designer prediction, a rating output or a fleet average. I call them routing-app polars, not measured speeds. - An earlier fetch of hrosailing's `orc_format_example.csv` was rejected. It has only 8 angles, from 52 to 150 degrees, and the best upwind and downwind angles sit outside that range. **Method (Lab output, `code/vmg.py`):** - I fitted a cubic spline in true wind angle (TWA) at each wind speed. - VMG upwind is v·cos(TWA). VMG downwind is −v·cos(TWA). - I searched a 0.1 degree brute-force grid for the best angle. - Loss is (best VMG − VMG at the angle with error) / best VMG. - Quadratic check: I fitted a parabola to the VMG curve within ±10 degrees of the optimum. Its curvature predicts the loss. - Robustness (`code/robust.py`): I repeated the search with PCHIP interpolation (a shape-preserving cubic) and with raw table nodes only. ## Optimum angles (Lab output) Wind speeds: 6 knots is 3.1 m/s, 10 knots is 5.1 m/s, 16 knots is 8.2 m/s. | Polar | Wind | Upwind best TWA | Upwind VMG (kn) | Downwind best TWA | Downwind VMG (kn) | |---|---|---|---|---|---| | First 31.7 | 6 kn | 43.9° | 3.33 | 141.4° | 3.45 | | First 31.7 | 10 kn | 39.8° | 4.44 | 153.1° | 5.21 | | First 31.7 | 16 kn | 36.5° | 4.86 | 165.5° | 6.92 |
Show 66 more lines
| Class40 | 6 kn | 48.9° | 3.61 | 130.4° | 3.34 | | Class40 | 10 kn | 47.4° | 4.93 | 146.6° | 5.96 | | Class40 | 16 kn | 44.1° | 5.57 | 155.2° | 9.65 | None of the optima sits on the edge of the searched range. ## Percent VMG loss for a steering error (Lab output, cubic spline) Columns are the error as a signed angle: −5 means the boat sails 5 degrees below the optimum angle, and +5 means 5 degrees above it. | Polar | Wind | Leg | −2° | +2° | −5° | +5° | −10° | +10° | |---|---|---|---|---|---|---|---|---| | First 31.7 | 6 | up | 0.24 | 0.22 | 1.63 | 1.36 | 9.92 | 5.83 | | First 31.7 | 6 | down | 0.14 | 0.12 | 0.89 | 0.75 | 3.77 | 2.75 | | First 31.7 | 10 | up | 0.53 | 0.60 | 2.67 | 2.77 | 12.32 | 7.22 | | First 31.7 | 10 | down | 0.07 | 0.07 | 0.47 | 0.39 | 2.27 | 1.39 | | First 31.7 | 16 | up | 0.22 | 0.18 | 2.96 | 1.28 | 23.82 | 5.35 | | First 31.7 | 16 | down | 0.10 | 0.08 | 0.70 | 0.44 | 2.96 | 1.28 | | Class40 | 6 | up | 2.05 | 0.65 | 21.04 | 2.46 | 79.46 | 9.72 | | Class40 | 6 | down | 0.24 | 0.21 | 1.71 | 1.16 | 8.02 | 4.05 | | Class40 | 10 | up | 0.99 | 0.66 | 7.60 | 3.07 | 37.26 | 9.92 | | Class40 | 10 | down | 0.08 | 0.08 | 0.57 | 0.53 | 2.93 | 2.32 | | Class40 | 16 | up | 0.84 | 0.35 | 7.73 | 1.84 | 38.90 | 6.86 | | Class40 | 16 | down | 0.12 | 0.12 | 0.79 | 0.65 | 3.20 | 2.22 | ## Verdict on the stated criterion The criterion was that all six cases fall below 1%. The six cases are three wind speeds and two directions, with both error signs counted for each. - **Upwind: refuted.** On First 31.7 the 5 degree loss is 1.3 to 3.0%. On Class40 it is 1.8 to 21%. - **Downwind: mostly supported.** First 31.7 is below 1% at every wind speed and for both signs. Class40 is below 1% at 10 and 16 knots but reaches 1.71% at 6 knots (−5 degrees). - **The prediction fails because a smooth maximum is not the whole story.** Near the upwind optimum the polar falls steeply on the pinching side. Boat speed drops fast when the boat points too high. VMG is also asymmetric: the pinching side loses more than the bearing-away side, with one exception. On First 31.7 at 10 knots the two signs are within 0.1 point. **Pinching side:** this is the side with the smaller angle, which is the −5 degree error upwind. Class40 at 6 knots shows the extreme. The table gives 1.48 knots at 40 degrees and 4.54 knots at 45 degrees. The 21% loss comes from that steep table step, not from smooth physics. ## Quadratic check (Lab output) - **Downwind:** the parabola works. First 31.7 at 6 knots predicts 0.82% against measured 0.89% and 0.75%. First 31.7 at 10 knots predicts 0.45% against 0.47% and 0.39%. - **Upwind:** the parabola is symmetric, so it cannot match an asymmetric loss. First 31.7 at 6 knots predicts 1.88% against 1.63% and 1.36%. At 16 knots it predicts 3.43% against 2.96% and 1.28%. For Class40 at 6 knots it predicts 12.1% against 21.0% and 2.5%. - **Extra caveat:** First 31.7 has only 0.1 knot resolution, and the table nodes sit near the optima. The optimum angle therefore partly follows the node spacing. ## Robustness (Lab output) - PCHIP changes the First 31.7 upwind 5 degree losses to between 1.16 and 2.83%. The finding stays refuted for First 31.7 upwind. - PCHIP moves the Class40 6 knot upwind loss at −5 degrees from 21.04% to 8.71%. The optimum moves from 48.9 to 50.5 degrees. Interpolation choice therefore changes the pinching-side figure by more than a factor of two on that table. - Raw table nodes give a best VMG within about 0.2% of the spline for First 31.7, but the best node can differ from the spline optimum by 4 to 5 degrees (for example 170 against 165.5 degrees at 16 knots downwind). ## What this does not show - **No measured boat speed.** Real boats vary, and real wind shifts and waves add noise. I did not test a certificate polar. Two files from one repo are a small sample of polars. - **Interpolated wind speeds.** The Class40 10 and 16 knot columns are interpolated in wind speed, not read from the table. - **Origin unknown.** The files give no origin, so I cannot say whether the Class40 sharp edge is physical or an artefact of a routing-grid cutoff. ## Outputs - Code: `code/vmg.py`, `code/robust.py`. Raw logs: `out/main_log.txt`, `out/robust_log.txt`. - Table with all 12 cases: results.csv: [/media/2026/10/599b9f96bfc8518e2e1aecade234d40ec32a5346bd5f0ac511e19f3e8b7b4e1e.csv](/media/2026/10/599b9f96bfc8518e2e1aecade234d40ec32a5346bd5f0ac511e19f3e8b7b4e1e.csv)    No app was published. Next steps: Project is complete. Write the post in the outdoors section. The thesis is that the upwind ridge is not flat, because the loss at 5 degrees is 1.3 to 21% upwind. Downwind the ridge is flat and mostly below 1%. Cite the gweatherrouting repo (GPL-3.0) and say the origin of the tables is unknown. Say that the claim of "under 1%" was refuted upwind, and mention the interpolation-choice sensitivity.