Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Евро-табурет v0.0 by swagman
- //Управляющий скрипт для монокоптера
- //пассажирское сидение как IMyShipController
- //инструкция: https://youtu.be/0Eohqz4PXKw
- /*gts wrapper*/List<T> gts<T>(Func<T, bool>b=null) where T:class {b=b??(x=>true);List<T>l=new List<T>();Func<T,bool>f=x=>((IMyTerminalBlock)x).IsSameConstructAs(Me);GridTerminalSystem.GetBlocksOfType(l,k=>f(k)&&b(k));return l;}
- Vector3D o_pos; public Program() { o_pos = Me.CubeGrid.GetPosition(); Runtime.UpdateFrequency = UpdateFrequency.Update10; }
- bool forcer = false;
- bool damper = true;
- public void Main(string arg) {/*mon init*/var m = Me.GetSurface(0); m.ContentType = ContentType.TEXT_AND_IMAGE; m.FontSize = 26.4f/12; m.TextPadding = 0;m.Font = "Monospace"; m.FontColor = Color.Gray; m.BackgroundColor = new Color(0,0,7);
- var deg = (float)Math.PI / 180; //градус выраженный в радианах
- //берём нужные блоки
- var gy = gts<IMyGyro>(); // b.GridThrustDirection.Y == -1
- var tr = gts<IMyThrust>(b => b.IsWorking && b.Orientation.Forward == Base6Directions.Direction.Down);
- var sc = gts<IMyShipController>().First();
- //var sc = gts<IMyShipController>(b => b.CustomName.Contains("!")).First();
- //берем центр планеты и переводим его в целочисленный вектор в пространстве сетки
- var g_pos = Me.CubeGrid.GetPosition();
- var p_cen = g_pos; var g_ovr = sc.TryGetPlanetPosition(out p_cen);
- var cen = Me.CubeGrid.WorldToGridInteger( p_cen );
- var spd = Me.CubeGrid.WorldToGridInteger( o_pos ); o_pos = g_pos;
- //вычисляем углы отклонения (-pi..pi)
- var ax = (float) Math.Atan2( cen.X, -cen.Y );
- var az = (float) Math.Atan2( cen.Z, -cen.Y );
- //триггеры
- forcer = sc.MoveIndicator.Z==-1 ? sc.MoveIndicator.Y==1 ? true : forcer : false; //триггер усилителя разгона
- damper = sc.MoveIndicator.Z==1 && sc.MoveIndicator.Y==1 ? true:forcer?false:damper; //триггер демпфера
- //формируем управляющие сигналы (-2pi..2pi)
- var uv = new Vector3(0); uv.Y = sc.RollIndicator *deg*45;
- uv.Z = -(ax *2 - spd.X*deg*3 - sc.MoveIndicator.X *deg*20 );
- uv.X = (az *2 - (damper? spd.Z *deg*5: 0) - sc.MoveIndicator.Z *(forcer?deg*90:deg*20) );
- //учитываем фактор коллизии
- if ( Math.Abs(ax)>1 ) {uv.Z = 2 * Math.Sign(uv.Z); uv.X = 0;} else if ( Math.Abs(az)>1) {uv.X = 2 * Math.Sign(uv.X); uv.Z = 0;}
- //применяем сигналы к гироскопам
- for (int j = 0; j<gy.Count; j++) {
- Matrix ma; gy[j].Orientation.GetMatrix(out ma); var tv = Vector3.Transform( uv, Matrix.Transpose( ma ));
- if ( gy[j].Pitch != (float)tv.X || gy[j].Yaw != (float)tv.Y || gy[j].Roll != (float)tv.Z ) {
- gy[j].Pitch = (float)tv.X; gy[j].Yaw = (float)tv.Y; gy[j].Roll = (float)tv.Z;}
- gy[j].GyroOverride = g_ovr;
- }
- //Dampeners ассистент, включаем демпфирование на безопасной высоте
- double alt; sc.TryGetPlanetElevation( MyPlanetElevation.Surface, out alt );
- var tpow = 1f; foreach (var t in tr) tpow += t.MaxEffectiveThrust;
- var sh = sc.GetShipSpeed(); sh = sh*sh/(tpow/sc.CalculateShipMass().PhysicalMass-sc.GetNaturalGravity().Length());
- sc.DampenersOverride = sh>=alt | sc.DampenersOverride;
- //тяга зависания с учетом эффективности трастера
- //var p = (float)(sc.GetNaturalGravity().Length() * sc.CalculateShipMass().PhysicalMass * tr[0].MaxThrust / tr[0].MaxEffectiveThrust);
- //управление высотой при включенном общем демпфировании
- foreach (var t in tr) t.ThrustOverride = sc.MoveIndicator.Y==1?t.MaxThrust:sc.MoveIndicator.Y==-1 && sh<alt ?0.01f:0;
- m.WriteText($"{(sh<alt?0:1)} {System.DateTime.Now:T}\nALT:{alt:f2}\nFRZ:{(forcer?1:0)} DMP:{(damper?1:0)}\naz:{az,8:f4}\nax:{ax,8:f4}\n Y:{uv.Y,8:f4}\n Z:{uv.Z,8:f4}\n X:{uv.X,8:f4}");
- /*script monitor*/var і=Runtime;Echo($"{System.DateTime.Now}\nTime:{і.LastRunTimeMs:F2}:{і.TimeSinceLastRun.Milliseconds}ms\nInst:{і.CurrentInstructionCount}:{і.MaxInstructionCount}\nCall:{і.CurrentCallChainDepth}:{і.MaxCallChainDepth}\n"); }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement