こんにちは、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を使えば一瞬で完了し、さらにその結果をグラフで直感的に理解することができます。これこそが、ものづくりの世界におけるプログラミングの、最も強力な活用法の一つです。
このシミュレーターを元に、ぜひあなたも色々なパラメータを試してみてください!
コメント