【DIY設計の自動化】Pythonで衝撃吸収アブソーバの性能をシミュレーションしよう!

ALL

こんにちは、Tech Samuraiです!
前回の記事「【DIY設計記録】3Dプリンタでボート用アブソーバ自作」では、物理計算と工学的なアイデアを駆使して、衝撃吸収システムの基本設計を完成させました。

しかし、あの記事では多くの計算を手作業で行いました。「バネを7本並列から8本並列に変えたら、吸収エネルギーはどうなる?」「目標の360Jを達成するには、一体何本のバネが必要なんだ?」… このような無数の「もしも」を試すたびに、電卓を叩き直すのは大変です。

今回の探検では、この試行錯誤のプロセスを**Pythonで自動化**します。前回行った物理計算をPythonの関数に落とし込み、`NumPy`で効率的に計算し、`Matplotlib`で結果を可視化する**「アブソーバ性能シミュレーター」**を開発します。これぞ、プログラミングとものづくりが融合する、最高の瞬間です!


ステップ1:物理モデルをPython関数に落とし込む

まずは、前回行った計算を、再利用可能なPythonの関数として定義します。これにより、コードが整理され、見通しが良くなります。

import numpy as np
import matplotlib.pyplot as plt

# --- 物理定数 ---
G = 9.8  # 重力加速度 (m/s^2)

def calculate_spring_constant(load_kg, stroke_mm):
    """荷重とストロークからバネ定数(N/m)を計算する"""
    load_n = load_kg * G  # 荷重をkgfからニュートン(N)に変換
    stroke_m = stroke_mm / 1000.0  # ストロークをmmからメートル(m)に変換
    return load_n / stroke_m

def calculate_spring_energy(k, stroke_m):
    """バネ定数とストロークからバネが蓄えるエネルギー(J)を計算する"""
    # エネルギーの公式: E = 1/2 * k * x^2
    return 0.5 * k * (stroke_m ** 2)

def simulate_absorber(k_single, stroke_single_m, num_parallel, num_series):
    """
    バネの組み合わせから、アブソーバ全体の性能を計算するシミュレーション関数
    """
    # 並列・直列のバネ定数の計算
    k_total = k_single * num_parallel / num_series

    # 全体のストローク長
    stroke_total_m = stroke_single_m * num_series

    # 吸収できる総エネルギー
    energy_total_j = calculate_spring_energy(k_total, stroke_total_m)

    # 必要な最大荷重
    force_total_n = k_total * stroke_total_m
    force_total_kgf = force_total_n / G

    return {
        "total_energy_j": energy_total_j,
        "total_stroke_mm": stroke_total_m * 1000,
        "required_force_kgf": force_total_kgf
    }

ステップ2:シミュレーションの実行と検証

関数ができたので、前回の記事で手計算した「7本並列・2組直列」のケースをシミュレーションし、結果が一致するか検証してみましょう。

# --- 入力パラメータ ---
# 手元にあるバネのスペック
single_spring_load_kg = 2.0
single_spring_stroke_mm = 36.0 # (53mm - 17mm)

# バネの組み合わせ
parallel_count = 7
series_count = 2

# --- 計算実行 ---
# 1. まずはバネ1本の性能を計算
k_one_spring = calculate_spring_constant(single_spring_load_kg, single_spring_stroke_mm)
stroke_one_spring_m = single_spring_stroke_mm / 1000.0

# 2. シミュレーター関数に渡して全体の性能を計算
result = simulate_absorber(k_one_spring, stroke_one_spring_m, parallel_count, series_count)

print("--- シミュレーション結果 ---")
print(f"構成: {parallel_count}並列 x {series_count}直列 (計{parallel_count * series_count}本)")
print(f"吸収エネルギー: {result['total_energy_j']:.2f} J")
print(f"ストローク長: {result['total_stroke_mm']:.1f} mm")
print(f"最大必要荷重: {result['required_force_kgf']:.1f} kgf")

実行結果:

--- シミュレーション結果 ---
構成: 7並列 x 2直列 (計14本)
吸収エネルギー: 4.94 J
ストローク長: 72.0 mm
最大必要荷重: 14.0 kgf

前回の記事の手計算とほぼ一致しますね!これで、私たちのシミュレーターが正しく動作することが確認できました。


ステップ3:`Matplotlib`で結果を可視化する

シミュレーターの真価は、パラメータを変化させて多くの結果を比較検討できる点にあります。`Matplotlib`を使い、並列バネの本数を増やしていくと、吸収エネルギーがどのように変化するかを可視化してみましょう。

# 並列数を1から20まで変化させてシミュレーション
parallel_nums = np.arange(1, 21)
energies = []

for num in parallel_nums:
    # 直列数は2で固定
    sim_result = simulate_absorber(k_one_spring, stroke_one_spring_m, num, 2)
    energies.append(sim_result['total_energy_j'])

# --- グラフの描画 ---
plt.figure(figsize=(10, 6))
plt.bar(parallel_nums, energies, color='royalblue', label='吸収可能エネルギー (J)')
plt.axhline(y=360, color='red', linestyle='--', label='目標エネルギー (360 J)')

plt.title('並列バネ本数と吸収エネルギーの関係 (2直列固定)')
plt.xlabel('並列バネの本数')
plt.ylabel('吸収エネルギー (ジュール)')
plt.xticks(parallel_nums)
plt.grid(axis='y', linestyle=':')
plt.legend()
plt.show()

実行結果のグラフ:

このグラフは、私たちに多くのことを教えてくれます。並列バネの本数を増やせば、吸収エネルギーは線形に増えていくことが一目瞭然です。しかし同時に、目標である360Jには、この構成では全く届かないという厳しい現実も、視覚的に突きつけてきます。


まとめ:設計とプログラミングの融合

今回は、前回のDIY設計プロジェクトの物理計算をPythonに落とし込み、性能シミュレーターを開発しました。

  • 複雑な計算を**関数**にまとめることで、コードの見通しを良くする方法。
  • パラメータを変えて何度も試行錯誤する**シミュレーション**の考え方。
  • **`Matplotlib`**を使い、シミュレーション結果を可視化することで、設計上の洞察を得る方法。

手計算では一日かかっても終わらないような膨大なパラメータの試行錯誤も、Pythonを使えば一瞬で完了し、さらにその結果をグラフで直感的に理解することができます。これこそが、ものづくりの世界におけるプログラミングの、最も強力な活用法の一つです。

このシミュレーターを元に、ぜひあなたも色々なパラメータを試してみてください!

コメント

タイトルとURLをコピーしました