世界情勢がきな臭くなってきました。
いざという時のために
いろいろ出来るようになっておきましょう。
本日は2km先の敵を狙撃するための
弾道計算です。
解説動画はこちら
本日はライフルの弾道計算です
計算方法は非常に複雑ですが
基本的な考えは放物線運動です。
ライフルの弾は水平に構えたとしても
真横には飛ばず、空気抵抗や
重力の影響を受けてどんどん下に落ちて行きます。
そのため、少し角度をつけてやらないと
遠くには飛びません。
計算の際に必要になってくるのは
・弾の質量(重さ)
・弾の断面積
・銃の角度
・弾の初速
・銃を打つ際の高度
になります。
これを可変に出来るように
簡易シミュレーターを作ってみました。
ソースコードはこちら
Widgetsを使ってシミュレーションするのは
こちらの関数です。
こんな感じで5つの変数を動かせるようにしています。
デフォルトでは一般的な狙撃にしようされる弾丸
2km先の敵を打つには
結構な角度をつけないと届かないようですね。
弾や角度条件を変えれば
色々な銃の狙撃をシミュレーション出来るので
狙撃の予定がある人は
参考にしてみて下さい。
本日はスナイパーに関する
ライフルの弾道計算のお話でした。
それでは。
いざという時のために
いろいろ出来るようになっておきましょう。
本日は2km先の敵を狙撃するための
弾道計算です。
解説動画はこちら
本日はライフルの弾道計算です
計算方法は非常に複雑ですが
基本的な考えは放物線運動です。
ライフルの弾は水平に構えたとしても
真横には飛ばず、空気抵抗や
重力の影響を受けてどんどん下に落ちて行きます。
そのため、少し角度をつけてやらないと
遠くには飛びません。
計算の際に必要になってくるのは
・弾の質量(重さ)
・弾の断面積
・銃の角度
・弾の初速
・銃を打つ際の高度
になります。
これを可変に出来るように
簡易シミュレーターを作ってみました。
ソースコードはこちら
from matplotlib import pyplot as plt import ipywidgets as widgets from IPython.display import display from ipywidgets import interact, FloatSlider, IntSlider from math import pi, cos, sin,atan,sqrt %matplotlib inline # 固定値 dt = 0.1# 時間刻み[s] gr = 9.80665 # 重力定数 [m/s2] 初期値 9.80665 cd = 0.3 # 空気抵抗係数(Cd) airRho = 1.22 # 空気密度 [kg/m3] 初期値 1.22 (1atm , 摂氏15, 湿度50%) w0 = 0 # 風速(地上) [m/s] w1 = 0 # 風速(毎100m) [m/s] # 微分計算用関数 def dvx( vx, vy, w, k): return -k * (vx - w) * sqrt((vx - w) * (vx - w) + vy*vy) def dvy( vx, vy, w, k, g): return -g - k * vy * sqrt((vx - w) * (vx - w) + vy*vy) # 弾道計算関数 def ballistic_calc(mas,area,deg0,vo,ht): deg = deg0 / 180 * pi # 角度 [ラジアン] _S = area / 10000 # 断面積 [m2] _K = 0.5 * _S * cd * airRho / mas *1000 # 抵抗力係数 _T , _X , _Y , _v = 0 , 0 , ht , vo _vx , _vy , _W = _v * cos( deg ) , _v * sin( deg ) , w0 + w1 * (_Y / 100) _y_max , _t_max = _Y , 0 k_x1, k_x2, k_x3, k_x4, k_y1, k_y2, k_y3, k_y4 = 0,0,0,0,0,0,0,0 vx_2 , vy_2 , x_n2 , y_n2 = 0,0,0,0 result_x , result_y = [0],[0] for i in range(1,101): k_x1 = dt * dvx( _vx, _vy, _W, _K ) k_y1 = dt * dvy( _vx, _vy, _W, _K, gr ) k_x2 = dt * dvx( _vx + k_x1 / 2, _vy + k_y1 / 2, _W, _K ) k_y2 = dt * dvy( _vx + k_x1 / 2, _vy + k_y1 / 2, _W, _K, gr ) k_x3 = dt * dvx( _vx + k_x2 / 2, _vy + k_y2 / 2, _W, _K ) k_y3 = dt * dvy( _vx + k_x2 / 2, _vy + k_y2 / 2, _W, _K, gr ) k_x4 = dt * dvx( _vx + k_x3, _vy + k_y3, _W, _K ) k_y4 = dt * dvy( _vx + k_x3, _vy + k_y3, _W, _K, gr ) vx_2 = _vx + (k_x1 + 2 * k_x2 + 2 * k_x3 + k_x4) / 6 vy_2 = _vy + (k_y1 + 2 * k_y2 + 2 * k_y3 + k_y4) / 6 x_n2 = _X + ( _vx + vx_2 ) / 2 * dt y_n2 = _Y + ( _vy + vy_2 ) / 2 * dt #print('経過秒数 : {0:.2} , 飛距離 : {1:.05}m , 到達高度 : {2:.05}m'.format(i*dt,x_n2 , y_n2) ) result_x.append(x_n2) result_y.append(y_n2) if y_n2<0: #print('break') break _T = i * dt _vx , _vy = vx_2 , vy_2 _X , _Y = x_n2 , y_n2 _v = sqrt( _vx * _vx + _vy * _vy ) deg = atan ( _vy / _vx ) _W = w0 + w1 * (_Y / 100) return result_x , result_y
Widgetsを使ってシミュレーションするのは
こちらの関数です。
mas = widgets.FloatSlider(value=25.4 , min=5 , max=50, step=0.1 , description='質量 [g] : ') area = widgets.FloatSlider(value=1.19, min=1 , max=5, step=0.01 , description='断面積[cm2] : ') deg0 = widgets.FloatSlider(value=2.0 , min=0.1 , max=90 , step=0.1 , description='打揚角度 [°] : ') vo = widgets.IntSlider(value=890, min=500, max=1200 , step=10 , description='初速 [m/s] : ') ht = widgets.IntSlider(value=0 , min=0 , max=100 , step=1 , description='発射時高度 [m] : ') @interact(mas=mas,area=area,deg0=deg0,vo=vo,ht=ht) def on_value_change(mas,area,deg0,vo,ht): ax = plt.gca() bx,by = ballistic_calc(mas,area,deg0,vo,ht) print('経過秒数 : {0:.2} , 飛距離 : {1:.05}m , 到達最高度 : {2:.05}m'.format((len(bx) - 1)*0.1 , bx[-1] , max(by))) plt.plot(bx , by , linestyle = "dashed") plt.hlines(0 , max(bx),5,color="red") plt.hlines(max(by) , max(bx),5,color="green") plt.show()
こんな感じで5つの変数を動かせるようにしています。
デフォルトでは一般的な狙撃にしようされる弾丸
7.62x51mm NATO弾の重量 : 25.4g
初速890 [m/s]
断面積1.19cm2 を入れています。2km先の敵を打つには
結構な角度をつけないと届かないようですね。
弾や角度条件を変えれば
色々な銃の狙撃をシミュレーション出来るので
狙撃の予定がある人は
参考にしてみて下さい。
本日はスナイパーに関する
ライフルの弾道計算のお話でした。
それでは。
コメント
コメント一覧 (5)
面白いコラムだったので1点お伺いします。
計算素材として参照している断面積について、どのように調べればいいでしょうか。
wikiで弾薬のデータを見に行ってもなんとなく不明瞭で何を参照しているのかわかりませんでした。
こちら、wikiや弾薬の資料サイトを周り、大体の推定値です
手元にあれば直ぐに測れるんですけどね
超詳細にやるなら、ハワイなどの射撃場で調べるしかないでしょうね。
推定値了解です。
断面積の方向は弾丸を側面から見たときの断面積でしょうか。
7.62mm弾丸の直径(進行方向から見た場合の断面積)からだと45mm^2なので側面かなと思われるのですがよくわからず。
あとdt=0.1刻みの設定部分についてですが、
より詳細を調べようと0.01や0.001を代入した際にfor文のループ数に関してエラーが発生しました。
おそらく要素の計算回数が足りなくなるのが原因と思って以下のような修正を組み込んで実行しております。
元:for i in range(1,101):
後:for i in range(1, int((1 / dt) * 10 + 1)):
こちら、断面積なので、前から見た際の面積ですが
実際の弾丸を見れてないので、測れてないので
結構適当な数値でやっちゃった感じです
for文はUIからいじれる部分では無いので
固定値以外ではテスト出来てません、すいません。
forの部分は別に大丈夫だと思います。ただ単に自分はその精度が欲しくて魔改造しただけですので。
ありがとうございました。
コメントする