現バージョンではダンパーをオフにして前につけたセンサーが反応したところまで進み
その後ランディングギアがロックされるまで降下するだけのもの
必要なパーツ
センサー(プレイヤーはOFF、船等をONにする。範囲はお好みで)
スラスター
コックピット
タイマーブロック(1~2秒くらいがおすすめ、アクションにはプログラムブロックを指定)
使い方は""の部分を自分の船に合わせて書き換える(コードでもパーツ名をあわせてもOK)
static string FRONT_SENSOR = "Sensor";
前のセンサー名
static string THRUSTER_F = "Small Thruster 3";
前向きのスラスター名
static string THRUSTER_D = "Small Thruster 4";
下向きのスラスター名
static string COCKPIT ="Cockpit";
コックピット名
static string TIMER = "Timer Block";
タイマーブロック名
あとはコードを走らせるだけ(母艦は静止させること)
サポートできないので使用は自己責任で!
課題
旋回運動はしないので、そのあたりの姿勢制御をどうするかが悩みどころ
(上下のない宇宙だから、着地先の状態をどうやって取得するか・・・)
あとは自機の速度管理もしていないのでランディングギアが壊れるかも(レーザー測距ブロック実装希望)
//Automatic Landing ver0.1
static string FRONT_SENSOR = "Sensor";
static string THRUSTER_F = "Small Thruster 3";
static string THRUSTER_D = "Small Thruster 4";
static string COCKPIT ="Cockpit";
static string GYRO = "Gyroscope";
static string TIMER = "Timer Block";
static int GEARNUM = 1;
IMySensorBlock f_sensor;
IMyFunctionalBlock thrst_f;
IMyFunctionalBlock thrst_d;
IMyTextPanel textpanel;
IMyCockpit cockpit;
IMyTimerBlock timerb;
double x;
double y;
double z;
double oldx;
double oldy;
double oldz;
long CurrentTime;
long OldTime;
double speed;
string text = "";
static string mode;
void Main()
{
List<IMyTerminalBlock> TL = new List<IMyTerminalBlock>();
GridTerminalSystem.SearchBlocksOfName(THRUSTER_F,TL);
thrst_f = TL[0] as IMyThrust;
GridTerminalSystem.SearchBlocksOfName(THRUSTER_D,TL);
thrst_d = TL[0] as IMyThrust;
f_sensor = GridTerminalSystem.GetBlockWithName(FRONT_SENSOR) as IMySensorBlock;
textpanel = GridTerminalSystem.GetBlockWithName(TEXTBLOCKNAME) as IMyTextPanel;
//IMyGryo gyro = GridTerminalSystem.GetBlockWithName(GYRO) as IMyGyro;
cockpit = GridTerminalSystem.GetBlockWithName(COCKPIT) as IMyCockpit;
timerb = GridTerminalSystem.GetBlockWithName(TIMER) as IMyTimerBlock;
text = "";
getSpd();
if(!getSensorF())
{
mode = "Forward";
}
if (getSensorF() && speed > 0 && mode !="Down")
{
mode = "Stop";
}
if (mode != "Forward" && speed == 0)
{
mode = "Down";
}
text += "MODE : " + mode + "\n\n";
if(mode == "Forward")
{
getForward();
}
if(mode == "Stop")
{
getHold();
}
if (mode == "Down")
{
getDown();
}
if (!getLanding())
{
ITerminalAction action = timerb.GetActionWithName("Start");
action.Apply(timerb);
} else {
getHold();
damperOff();
}
}
void getSpd()
{
var Time1 = System.DateTime.Now;
OldTime = CurrentTime;
CurrentTime = Time1.ToBinary();
oldx = x;
oldy = y;
oldz = z;
x = Math.Round(f_sensor.GetPosition().GetDim(0),4);
y = Math.Round(f_sensor.GetPosition().GetDim(1),4);
z = Math.Round(f_sensor.GetPosition().GetDim(2),4);
double distance = 0;
distance = Math.Sqrt((x - oldx) * (x - oldx) + (y - oldy) * (y - oldy) + (z - oldz) * (z - oldz));
var Time0 = DateTime.FromBinary(OldTime);
var TimeDelta = (Time1 - Time0).TotalSeconds;
speed = 0.0;
speed = distance / TimeDelta;
text += "Distance : " + distance + "\n";
text += "Speed : " + speed + "\n";
text += "TimeDelta : " + TimeDelta + "\n";
}
void damperOn()
{
if (!cockpit.DampenersOverride)
{
ITerminalAction action = cockpit.GetActionWithName("DampenersOverride");
action.Apply(cockpit);
}
}
void damperOff()
{
if (cockpit.DampenersOverride)
{
ITerminalAction action = cockpit.GetActionWithName("DampenersOverride");
action.Apply(cockpit);
}
}
bool getSensorF()
{
if (f_sensor.IsActive)
{
text += "Sensor F is Active\n";
return true;
} else {
text += "Sensor F is not Active\n";
return false;
}
}
void getHold()
{
thrst_f.SetValueFloat("Override",0);
thrst_d.SetValueFloat("Override",0);
damperOn();
}
void getForward()
{
damperOff();
ITerminalAction action = thrst_f.GetActionWithName("IncreaseOverride");
if (speed == 0)
{
action.Apply(thrst_f);
} else {
thrst_f.SetValueFloat("Override",0);
}
}
void getDown()
{
damperOff();
ITerminalAction action = thrst_d.GetActionWithName("IncreaseOverride");
if (speed == 0)
{
action.Apply(thrst_d);
} else {
thrst_d.SetValueFloat("Override",0);
}
}
bool getLanding()
{
List<IMyTerminalBlock> TL = new List<IMyTerminalBlock>();
GridTerminalSystem.GetBlocksOfType<IMyLandingGear>(TL);
int prox = 0;
for (int i = 0; i < TL.Count; i++)
{
var lgvalue = new StringBuilder();
TL[i].GetActionWithName("SwitchLock").WriteValue(TL[i], lgvalue);
if (lgvalue.ToString() == "Locked")
{
prox++;
}
}
text += "LandingGear : " + prox.ToString() + "\n";
if (prox >= GEARNUM)
{
return true;
} else {
return false;
}
}
0 件のコメント:
コメントを投稿