歯車について勉強する4 の変更点

更新


#author("2025-03-20T00:55:50+00:00;2025-03-20T00:54:11+00:00","default:administrator","administrator")
#author("2025-03-31T17:16:28+00:00;2025-03-20T00:54:11+00:00","default:administrator","administrator")
[[工作/歯車について勉強する]]

* 歯車について勉強するシリーズ [#dd0be2de]

- [[工作/歯車について勉強する]] 歯車の形状についての基礎
- [[工作/歯車について勉強する2]] 仮想的なラックを使って実用的な歯車形状を切り出す話
- [[工作/歯車について勉強する3]] 歯車に関するいろいろな計算機
- [[工作/歯車について勉強する4]] 転位歯車の中心間距離と逆インボリュート関数
- [[工作/歯車について勉強する5]] ウォームホイールの歯形計算について
- [[工作/歯車について勉強する6]] かさ歯車は球面インボリュート曲線を持つ
- [[工作/歯車について勉強する/ゼネバ歯車]] 間欠歯車の一種です
- [[工作/Fusion360歯車スクリプト]] 勉強した結果を使って作ってみました
- [[工作/Fusion360歯車切削スクリプト]] Fusion 360 内で歯車の歯切りを行うスクリプトです
- [[工作/Fusion360曲面生成スクリプト]] 歯切り結果の表面をきれいにするスクリプトです
- [[工作/Fusion360ジョイント駆動スクリプト]] ジョイントを動かしてアニメーションさせるスクリプトです

* 噛み合い圧力角と中心距離修整係数 [#xbd9e7e1]
&katex();

** 概容 [#j9f40790]

転位歯車やはすば歯車では基準円半径を足しただけでは2つの歯車の中心間の距離を求められない。

かなり複雑な計算が必要になるのだそうだ。

** 目次 [#ba6aac7b]

#contents

* 転位平歯車の場合 [#q65abe09]

KHK 小原歯車工業さんの 歯車技術資料 の 転位平歯車 のページを見ると、~
https://www.khkgears.co.jp/gear_technology/pdf/gijutu.pdf#page=16

&ref(shifted-spur.png);

~
中心距離 $a$ は

$$
a=\underbrace{\frac{z_1m+z_2m}{2}}_{\text{基準円半径の和}}+\underbrace{ym}_{\text{修正}}
$$

とされていて、基準円半径の和に修正項 $ym$ が加算されている。

この修正係数 $y$ は、

$$
y=\frac{z_1+z_2}{2}\Big(\frac{\cos\alpha}{\cos\alpha_w}-1\Big)
$$

なので、実のところ $y$ ではなく、

$$
a=\underbrace{\frac{z_1m+z_2m}{2}}_{\text{基準円半径の和}}\times \frac{\cos\alpha}{\cos\alpha_w}
=\underbrace{\frac{z_1m+z_2m}{2}}_{\text{基準円半径の和}}\times y'
$$

として、

$$
y'=\frac{\cos\alpha}{\cos\alpha_w}
$$

を文字通り修正のための係数とみなすのもいいのかもしれない。

$y$ や $y'$ に含まれる $\alpha_\mathrm{w}$ は かみ合い圧力角 と呼ばれ、

$$
\mathrm{inv} \alpha_\mathrm{w}=2\tan\alpha\Big(\frac{x_1+x_2}{z_1+z_2}+\mathrm{inv}\alpha\Big)
$$

という方程式を解いて得られる。

ここでインボリュート関数は $\mathrm{inv} x = \tan(x) - x$ で与えられる。

インボリュート関数は $x$ を与えれば値を求めるのはたやすいものの、その逆関数は簡単な形で書けるものでないため近似式や漸化式を用いて計算することになる。

* インボリュート関数 [#db932ba8]

そもそもインボリュート関数とは何なのか?

歯車の計算では、歯車が $\theta$ 回転する間にラックが $r_p\theta$ だけ移動するのを歯車から見ることで、ラックにより切削される歯車歯形を求めたりする。

この「$\theta$ 回転する間に $r_p\theta$ だけ移動」を表すのがインボリュート曲線なのだそうだ。

&ref(involute.png,,40%);

ラックが $(r,0)$ から $(r,-r\theta)$ へ移動する間に歯車が $-\theta$ 回転したとして、歯車に固定した座標から見たラック位置がどうなるかを考えたのが上の図である。

歯車が回転したことでラックが始めにいた点 $(r,0)$ は $\bm q$ に、ラックの現在位置 $(r,-r\theta)$ は $\bm p$ に見えることになる。求めたいのは $\bm p$ の座標だ。

三角形 $\bm O\bm q\bm p$ は直角三角形なので、

$$
\tan \alpha = \frac{r\theta}r = \theta
$$

である。これを使うと点 $\bm p$ から原点までの距離は、

$$
|\bm p| = \frac r{\cos\alpha}
$$

ベクトル $\bm p$ の $x$ 軸からの角度は

$$
\theta-\alpha=\tan\alpha - \alpha
$$

であるから、

$$
\bm p=\frac r{\cos\alpha}\begin{pmatrix}
\cos(\tan\alpha - \alpha)\\
\sin(\tan\alpha - \alpha)
\end{pmatrix}
$$

と表せることになる。

ここに現れる $\tan\alpha - \alpha$ の形をインボリュート関数と呼び、

$$
\mathrm{inv}\,\alpha=\tan\alpha - \alpha
$$

と書く。

&ref(involute2.png,,50%);

横軸をラジアンで取った関数形がこちら。

$\alpha$ の小さいところで $\tan \alpha \sim \alpha$ であるためこの関数は傾きゼロで始まり、$\alpha$ が大きくなると $\tan\alpha$ の増加が勝るのためほぼ $\tan\alpha$ になって $\alpha=\pi/2$ で発散する。

* 逆インボリュート関数 [#le168f21]

既存の三角関数などを組み合わせて求めることはできないので漸化式を使う。

https://opeo.jp/library/onepoint/mech_elem/gear/inv_involute/

によると $a_1=1.441 (\mathrm{inv}\,\alpha)^{1/3}-0.374\mathrm{inv}\,\alpha$ から始めて

$$
a_{n+1}=a_n+\frac{\mathrm{inv}\,\alpha - \tan a_n}{\tan^2 a_n}
$$

の漸化式を進めると $\lim_{n\to\infty}a_n = \mathrm{inv}\,\alpha$ となるそうだ。~

ただやってみると、求めたい $\mathrm{inv}\,\alpha$ の値が $2$ よりいくらか大きいとき、
初期値が悪くて発散してしまう。

$\alpha$ が大きいときの $\mathrm{inv}\,\alpha$ はほぼ $\tan\alpha$ なので、
$\tan^{-1}\mathrm{inv}\alpha$ から開始することで $\mathrm{inv}\,\alpha$ 
がとても大きいときにも正しく収束するみたいだった。

奇関数なので、$\mathrm{inv}\,\alpha<0$ の時は $-\mathrm{inv}\,\alpha$ に対して解いた結果の符号を反転すれば求まる。

下のテキストボックスに $\mathrm{inv}\,\alpha$ の値を入れるとこの計算を試せる。

----
''逆インボリュート計算機:''

 LANG: p5js_live
 p.setup = () => {
   p.createCanvas(1,1);
   p.createSpan('inv(a): ');
   const invAlpha = p.createInput();
   invAlpha.value(0.1);
   const answer = p.createDiv();
   const handler = () => {
     let inva = Number(invAlpha.value());
     const s = inva < 0 ? -1 : 1;
     inva = Math.abs(inva)
     let a = 1.441 * inva ** (1/3) - 0.374*inva;
     if (inva > 2) a = Math.atan(inva);
     let str = '';
     for (let i = 0; i < 10; i++) {
       str += `&nbsp; &nbsp; ${i} : ${a}<br/>`;
       if(a!=0) {
         const tana = Math.tan(a);
         a += (inva - tana + a) / tana ** 2;
       }
     }
     str += `<br>inv(${a}) = ${Math.tan(s*a) - s*a}`;
     answer.html(str);
   }
   handler();
   invAlpha.input(handler);
 }

----

python ならこうかな?

 LANG:python
 from math import tan, atan
 def inverse_inv(inva: float):
     if inva == 0:
         return 0
     if inva < 0:
         return -inverse_inv(-inva)
     a = 1.441 * inva ** (1/3) - 0.374 * inva if inva < 2.4 else atan(inva)
     a_prev = 2
     while True:
         tana = tan(a)
         a += (inva - tana + a) / tana ** 2
         if abs(a_prev - a) < 1e-15:
             return a
         a_prev = a

Counter: 113 (from 2010/06/03), today: 2, yesterday: 1