AIを使って20年もののプログラムの間違いを修正した。試験片の見えない段差

# NC旋盤の試験片に出た「見えない段差」— 20年もののプログラムに潜んでいた1行
## 発端:径は合っているのに、境目だけおかしい
引張試験片を旋盤で削っていて、あるとき気づきました。R部(曲線)と平行部(直線)の**境目に、細い稜線のような段差**が出る。しかも試験部の径はきっちり出ている。寸法は正しいのに、境目だけ何かがおかしい——。
この「見えない段差」を追いかけたら、行き着いたのは**約20年前に書かれたGコード自動生成プログラムの、たった1行**でした。しかもそのバグは、20年間ずっと「ほぼ正しく」動いていたのです。
## そもそも「なめらかにつながる」とは
引張試験片は、太いつかみ部と細い試験部を、半径Rのフィレット(円弧)でつないだ形をしています。
このRと平行部が**なめらかに(接線で)つながる**には、幾何学的な条件があります。
> 円弧の中心のZ座標が、R部と平行部の境目のZ座標に一致していること。
これが満たされると、境目で円弧の接線がちょうど軸と平行になり、平行部となめらかに続きます。逆に中心がずれると、円弧が平行部に**角度をつけて突き当たり**、境目に角(稜線)ができます。これが正体でした。
実測すると、境目の角度は約**0.28°**。径にして数µm〜0.01mmの、まさに「見えるか見えないか」の段差です。
## 犯人は円弧開始位置の計算式
プログラムはC言語製で、各切削パスの円弧開始Z座標(ZZ)を計算していました。問題の行はこうです。
“`c
// 旧(バグ)
ZZ = y – sqrt(pow(RR,2) – pow(RR – (c*i + 1), 2));
“`
これは直角三角形(斜辺=円弧半径RR、縦辺=A、横辺=y−ZZ)から開始点を求める式です。ポイントは縦辺 A の中身。
**正しい A**`RR + XX/2 – x/2`(実際の径から決まる値)
**旧の A**`RR – (c*i + 1)`(パス番号 i と切り込み量 c から見積もった値)
旧プログラムは「本来は実際の径から測るべき落差」を、**回数と切り込みの掛け算で近似**していたのです。
## なぜ20年も気づかれなかったのか(ここが面白い)
普通、計算式が間違っていれば一目でおかしな結果になります。ところがこのバグは違いました。
**理由1:正しい式とほぼ一致する。**
両式の差を取ると、`(0.1 − c)` という小さな一定値だけでした。円弧半径RRは20mmもあるので、出てくる座標は「ほぼ正しい」。ズレは0.1〜0.2mm程度で、それが0.28°の微小な角としてしか現れませんでした。
**理由2:特定の条件では“完全に”正しくなる。**
切り込み量が **c = 0.1** のとき
削り回数 `t/c`**割り切れる(整数)** とき
これらのときは、近似式がたまたま真値と一致します。当時よく使う条件がこれにハマっていたのでしょう。実際、ある寸法の試験片では仕上げパスの座標が `Z-10.0 / Z-19.0 / Z-50.0` ときれいな整数で出て、完全に接線になっていました——**偶然に**
完全に間違ったコードは即バレます。でも「**惜しくも合っている**」コードは、20年でも生き延びる。これがいちばんの教訓かもしれません。
## 直し方はシンプル
近似をやめて、**実際の径から落差を直接引く**だけです。
“`c
// 新(修正)
ZZ = y – sqrt(pow(RR,2) – pow(RR + XX/2.0 – x/2.0, 2));
“`
`XX`(そのパスの試験部径)はもともとプログラム内で正しく計算されていました。皮肉なことに、**手元に正しい値があったのに、旧コードはそれを使わず i と c から作り直していた**のです。新コードは、あるものをそのまま使うだけ。
あわせて、出口円弧の半径が `%.1f`(小数1桁)で出力され、`R20.225``R20.2` に丸められて非接線を助長していたので、`%.3f` に修正しました。
## 検証結果
修正前後で、境目が接線からどれだけずれているかを全パス計算しました。
| | 修正前 | 修正後 |
|—|—|—|
| 入口の境目角度 | 約 0.279° | **0.000°** |
| 出口の境目角度 | 約 0.262° | **0.000°** |
全パスで角度0°、段差は解消。切り込み量を変えても常に接線になることも確認できました。
## 学んだこと
1. **「数えて足す」より「実際の値を引く」。** 累積回数から幾何量を再構成すると、前提が崩れた瞬間にずれる。測れる値は測って使う。
2. **過剰指定に注意。** 円弧を「端点+半径」で与えると幾何が過剰指定になり、わずかな不整合が角になる。中心を直接指定する(I/K)ほうが堅い場面も多い。
3. **“だいたい合う”バグがいちばん怖い。** 完全な誤りは即発覚するが、惜しく合うバグは長期間潜伏する。テストは境界条件(ここでは c≠0.1、割り切れない回数)で。
4. **古いコードには当時の前提が埋め込まれている。** 「切り込み0.1固定」のような暗黙の前提は、コメントにも書かれず残りがち。
20年動いていたコードでも、数式に立ち返れば原因は1行に絞れる。地味だけど、ものづくりの現場らしい小さな探偵劇でした。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

目次