virt_flyのブログ -165ページ目

virt_flyのブログ

フライトシミュレーターソフトのFlightGearで仮想飛行を楽しむブログです。

イメージ 1
↑みごと大空に向けて突進していくSAM。Nasalで打ち上げができました。

 

AIミサイルに位置座標を与えるNasalプログラム

 

  未解決のまま放置していて気になっているもののひとつが、コンピュータまかせで自動的に発射されるAIミサイルをつくることです。

  Flightearでは、ballisticがsubmodels.xmlに記述する以外は使えなくなり、またtranslateが動かないというかtranslate用のpropertyが効かなくなって、コンピュータにプログラムを実行させて地上からAIロケットを打ち上げることができなくなっていたものです。

 
  考えられるのは、以前作成したdrifting_ship.nasのようなNasalプログラムをつくってみること、としたまま時間だけが経過していました。
 
  drifting_ship.nasでは、水上機が風に吹かれて水面を流される様子を擬似的に再現していました。これを応用して、新たに高度を考慮し刻々と変化するミサイルの位置座標を与えてやる、しかも風の影響は考えなくていいのですから、より簡単なプログラムが書けるのでと考え、挑戦してみることにしました。
 
  ここでは問題を単純化するため、あえてFGルート下のNasalディレクトリにrocket_launch.nasというnasファイルをもうけることにします。
  もちろんここにもうけると、対象となるobjectすべてに影響を及ぼすことになりますので、とりあえずtankerに限定。後日別な対応を検討することにします。
 
  ここでの基本は、ミサイルの発射角、向き、速度から、垂直方向の移動量、また水平方向の移動量を計算し、それぞれ高度と緯度、経度として現在位置の座標をだそうという、簡略なものです。無学な者が自己流に球面座標を平面座標から計算させようとしていますので、明らかに極地点では破綻をきたす擬似的なもので、数学的知識を少しでもお持ちの方からすればとても堪えられない不愉快なものでしょう。国土地理院あたりの計算式からプログラムを書いてくださる方がいらっしゃれば、すごくありがたいのですが。
 
  さて、波に揺られるくらいならいいのですが、一定距離を飛行するとなると、同じ距離の移動でも、経度の変化は緯度により異なってくることを考慮する必要があります。滑走路の端からまっすぐに発射したミサイルが、見る間に滑走路をはずれていくくらいのずれになりますから、無視できません。
 
  移動距離から角度を求めるにあたっては、それでもかなり大雑把ですが、地球の円周を4万キロメートルとしました。高度はフィートですから、メートルからの換算を計算式に含めなければなりません。
 
  できあがったプログラムは以下のとおり。恥ずかしながら、いたってシンプルなものです。なお、ミサイル自体の発射角(pitch)や向き(heading)、速度の値を取り込む方法を今のところ知らずにいますので、プログラムの先頭で改めて値を与えるようにしています。
 
###########################################################
# rocket_launch.nas by virt_fly
# 2014/04/03
#
###########################################################

var rocket_speed = 70;
var rocket_pitch =30;
var rocket_dir =70;

print ("rocket_speed:" , rocket_speed);
print ("rocket_pitch:" , rocket_pitch);

var vertical_change =math.sin(rocket_pitch*math.pi / 180.0)*rocket_speed;
var horizontal_change =math.cos(rocket_pitch*math.pi / 180.0)*rocket_speed;
print ("vertical_change:" , vertical_change);
print ("horizontal_change:" , horizontal_change);
print ("rocket_dir:" , rocket_dir);
var latche = math.cos(rocket_dir*math.pi / 180.0)*horizontal_change;
var lonche = math.sin(rocket_dir*math.pi / 180.0)*horizontal_change;


var rocket_launch = func {
var sec = getprop("/sim/time/elapsed-sec");
var property_alt=getprop("/ai/models/tanker[0]/position/altitude-ft");
if (property_alt==nil){
var oldalt=0;
}else{
var oldalt=getprop("/ai/models/tanker[0]/position/altitude-ft");
}
var newalt = vertical_change*3.2808+oldalt;
var property_lat=getprop("/ai/models/tanker[0]/position/latitude-deg");
if (property_lat==nil){
var oldlat=0;
}else{
var oldlat=getprop("/ai/models/tanker[0]/position/latitude-deg");
}
var newlat = latche*360.0/40000000+oldlat;
var property_lon=getprop("/ai/models/tanker[0]/position/longitude-deg");
if (property_lon==nil){
var oldlon=0;
}else{
var oldlon=getprop("/ai/models/tanker[0]/position/longitude-deg");
}
var newlon = lonche*360.0/(math.cos(newlat*math.pi / 180.0)*40000000)+oldlon;
print ("newalt:" , newalt," newlat:" , newlat," newlon:" , newlon);
interpolate("/ai/models/tanker[0]/position/altitude-ft", newalt, 1);
interpolate("/ai/models/tanker[0]/position/latitude-deg", newlat, 1);
interpolate("/ai/models/tanker[0]/position/longitude-deg", newlon, 1);
settimer(func { rocket_launch(); }, 0.1 );
}

_setlistener("/sim/signals/fdm-initialized", func { rocket_launch(); });
 
イメージ 1

↑編隊を組むH6K。主翼前縁の翼端に近いところにあるのが航空灯。これと似た色の光を放つ主翼上面に見られるライトが、停泊灯。

 

H6Kにも灯火

 

   運良く97式飛行艇の灯火のことが、おおよそですがわかるサイトをみつけましたので、FlightGear用の我がH6Kにもライトをつけてみることにしました。

  おおよそと言うのも、そのブログに掲載されていたのはプラモの製作に関する記事と写真でしたから、ライトの種類と大体の位置がわかる程度ということ。従って、正確な再現が期待できるでわけでもなく、まったくいい加減な再現というほかはありません。

  そんな正確さにかけるものをまことしやかに公表するのは、犯罪的だなと思わぬわけでもないのですが、実はダウンロード用のファイルを更新したい事情があってのこと。左のエルロンのプログラムにあったミスをこそっと修正するのに、カモフラージュがわりにしようとしたものでした(^人^;)

  さて、航空機の灯火には、機体の上下にある赤色閃光の衝突防止灯、航空機の進行方向を示すための、右翼端に緑色,左翼端に赤色,尾部に白色の航空灯、着陸時に滑走路を照らす白色の着陸灯、タキシング中に誘導路を照らす白色のタクシー灯、翼端の白色閃光も衝突防止、くらいのことはよく見聞きしますから知らないわけではありませんが、それらの法的な細かな規定まではもちろん、編隊灯なるものが存在することも知りませんでした。

【編隊灯】
  夜間に爆撃することの多かった爆撃機のことを思えば、編隊を組むにあたりお互い接触することがないように、灯火を頼りにすることは思えばごく当たり前のこと。軍用でなければ不要と思われますが、プラモ作成のブログに従い、我がH6Kにも両翼上面に緑と赤のライトを一応は装備することにしました。

  ライト類の3Dモデル(acファイル)や対応する画像ファイル、xmlファイルは、多くの機体で使われているものを借用することにします。ここでは自作のJu EF128で借用したものを流用します。

【衝突防止灯】
  さて一方、ごく一般的と思われる衝突防止灯ですが、当該ブログの製作記事に記述はなく、やむなく省かざるをえませんでした。実際のところはどうだったのでしょう。

【碇泊灯(停泊灯)】
  このほか、ライトで知らなかったものには、碇泊灯(停泊灯)というものが、H6Kにはありました。両翼端下面の白色灯で、停泊時の他の飛行艇や船舶との衝突回避のためのもののようです。したがって、飛行中は点灯させる必要がありませんから、何らかの条件を付して点灯させないようにプログロミングしなければなりません。

  停泊灯の点灯は、海面に着水後のことですから、条件は高度0でもよさそうですが、湖面に着水の場合は高度が0とは限りません。よく条件に使用されるエンジンの回転も、停泊中ですから0とすればよさそうなものですが、エンジンの空吹かしのような場合、停泊灯は点灯していたようですから、難がないわけではありません。しかし、速度がうまく利用できれば、エンジンの回転とは無関係に、機体が止まっている間だけ、停泊灯を灯すことができます。Wingmanによる編隊飛行を想定すれば、こちらの方が都合がよいことはいうまでもありません。(注参照)

  なお、灯火の3Dモデル(acファイル)の大半がオブジェクト名に同じLightを使用しており、条件設定にあたっては、機体の3Dモデル設定xmlに記述すると他のライトにも影響してしまいます。やはりここはライトのxmlファイル、停泊灯用にもうけたxmlファイル(ライトの3Dモデルはもちろん共用にします)の方で対処するのが本筋でしょう。

【航空灯】
  赤と緑の翼端灯、尾部にH6Kは2個の尾灯を装備します。

【着陸灯(着水灯)】
  ここまできたら、最後は着陸灯です。夜間に飛行するなら、照明のない海上に着水するのに着水灯は欠かせないでしょう。

  その着陸灯については、光源のライトの光の再現にとどめてよいか、それともライトの光に前方が明るく照らし出される様まで再現するべきかが、悩ましい問題です。後者の場合、3Dモデルのlight-cone.acを使用した着陸灯は、まだいまいちでなじまないところがあるからです。とはいえ、照明設備の整った明るい空港の滑走路であればいざ知らず、何もない真っ暗な海上にあっては、ライトに照らしだされた海面が見えないのも不自然な気がしないでもありません。

  さて、着陸灯は10,000フィート以下では、点灯するのが規則のようです。高度を条件に10,000フィートを越えると、ライトが消えるようにしてみましたが、なかなか10,000フィートの高さまで到達できず、いつまでも着陸灯が点いているのは鬱陶しいので、勝手に条件を緩めて、3000フィートにしてみました。犯罪的!ですよね、実際なら。

  以上でH6Kに灯火を装備の概要はおしまいです。詳細を知りたい方は、ダウンロードのページにアップした機体の更新ファイル(H6K-20140321.zip)を確認ください。

注)停泊灯の点灯のための条件設定について、ダウンロードファイルでは対気速度1以下を指定していますが、10位の設定に修正してください。波間に揺られるNasalプログラムのせいで対気速度が1以下にならないのか、揺れとともに停泊灯が点いたり消えたりして一定しないもので。
 

イメージ 2

↑真ん中の白い2つの光は、H6Kの尾灯。翼端近くの両翼下面の光が停泊灯。扇状の2つの白っぽいものは着陸灯の光。
 

イメージ 1

 

AI機のM6Aのプロペラを回す

 

  I-400潜水艦の改造記録です。
  これまでの改造で、M6A晴嵐をカタパルトで射出が可能となりました。しかし、このままでは射出されたM6A晴嵐は、プロペラが回らないまま飛行するというおかしなことになります。

  プロペラが回っている様子は、これを擬似的に再現する3Dオブジェクトを使うのが通常ですが、なんとI-400の中にあるM6AのAI機の3Dモデルでは、これが省略されていて含まれていません。FlightGear用の本来のM6Aの機体から当該オブジェクトだけコピーしてくる必要があります。

  問題は、格納容器から引き出された直後のM6A晴嵐はプロペラが止まっているが、カタパルトで射出するときは、プロペラが高速回転している、この2つの状態を再現できなくてはなりません。

  2つの状態を分けて再現することのできる、都合のよい条件がなかなかみつけられず、それぞれに対応する3Dモデル設定xmlファイル、m6a.xmlとm6a-2.xmlとをもうけることにしました。

  なお、高速で動くプロペラの残像が半透明の扇形を描くのを模した3Dオブジェクトを表示させることで、回転するプロペラを擬似的に再現しているわけですが、いまいち動いている感じがしません。そこで、これを少し回転させることでリアリティが増さないかと、ゆっくり動かしてみたのですが、いかがでしょう。


●回転するプロペラを模した3DオブジェクトをI-400のAichi-M6Aに付け加える

 別途ダウンロードしたAichi-M6AのModelsフォルダ中にあるm6a.acを、Blenderなどの3Dモデリングソフトで開き、ここではpropblurのみを選択して、propか何かの名前のacファイルに書き出します。 

ついで、I-400内のModelsフォルダ内のAichi-M6Aフォルダにあるm6a.acを3Dモデリングソフトで開いた上、先のprop.acを読み込みます。

あらたに取り込まれたpropblurをはじめすべてをac形式で書き出し、新たなm6a.acの完成です。


●m6a.xmlへの追加ー格納容器から引き出された直後のプロペラの止まった状態

<?xml version="1.0" encoding="ISO-8859-1"?>

<PropertyList>

   <path>m6a.ac</path>
          ・
          ・
         (中略)
          ・
          ・
   <animation>
    <type>select</type>
    <object-name>propblur</object-name>
   <condition>
     <equals>
      <property>sim/model/door-positions/bay/position-norm</property>
      <value>0</value>
     </equals>
    </condition>
   </animation>


</PropertyList>  


●m6a.xmlの修正コピーでm6a-2.xmlを新規作成ー射出時のプロペラの回転

<?xml version="1.0" encoding="ISO-8859-1"?>

<PropertyList>

   <path>m6a.ac</path>

    <animation>
    <!-- draw these first (in no particular order) -->
          ・
          ・
         (中略)
          ・
          ・
     <object-name>m6a-flotteursB</object-name>
     <object-name>propblur</object-name>

     <!-- draw this at last (order critical!) -->
          ・
          ・
         (中略)
          ・
          ・
    </animation>

    <effect>
      <inherits-from>Aircraft/Generic/Effects/Fuselagereflect</inherits-from>
          ・
          ・
         (中略)
          ・
          ・
     <object-name>propblur</object-name> ←Rembrandt対策
    </effect>
          ・
          ・
         (中略)
          ・
          ・
    <animation>
     <type>select</type>
     <object-name>m6a-helice</object-name>
     <condition>
      <equals>
       <property>sim/model/door-positions/bay/position-norm</property>
       <value>1</value>
      </equals>
     </condition>
    </animation>

    <animation>
     <type>select</type>
     <object-name>propblur</object-name>
     <condition>
      <less-than>
       <property>velocities/true-airspeed-kt</property> ←dummy
       <value>1</value>
      </less-than>
     </condition>
    </animation>


    <animation>
     <type>rotate</type>
     <object-name>propblur</object-name>
     <property>/sim/time/elapsed-sec</property>
     <factor>20</factor> ←大きくすれば回転が大、小さくすれば小
     <center>
      <x-m> -4.44266 </x-m>
      <y-m>  0.00000 </y-m>
      <z-m>  0.22662 </z-m>
     </center>
     <axis>
      <x> -1 </x>
      <y>  0 </y>
      <z>  0 </z>
     </axis>
    </animation>


</PropertyList>


●submodels.xmlの修正

<?xml version="1.0" encoding="UTF-8"?> ←encordingは統一した方がよさそう

<PropertyList>



  <submodel>
    <name>M6A</name>
    <!--<model>Aircraft/I-400/Models/Aichi-M6A/m6a.xml</model>-->
    <model>Aircraft/I-400/Models/Aichi-M6A/m6a-2.xml</model>
 
        ・
         ・
         (中略)
         ・
         ・
  </submodel>

</PropertyList>