Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.05 KB | None | 0 0
  1. static IMyGridTerminalSystem MyGTS;
  2. static List<IMyGyro> Gyros = new List<IMyGyro>();
  3. static IMyCockpit MyCockpit;
  4. static Vector3D G;
  5. static double g;
  6. static double maxrpm = 60;
  7. static double tickspersecond = 6.0;
  8. static PID PitchControl;
  9. static double gyrobias = 0;
  10. static List<IMyTextSurface> CockpitScreens = new List<IMyTextSurface>();
  11. static List<IMyCockpit> Cockpits = new List<IMyCockpit>();
  12. Matrix CockpitOr;
  13.  
  14. public Program()
  15. {
  16. MyGTS = GridTerminalSystem;
  17. MyGTS.GetBlocksOfType(Gyros,block => block.CubeGrid==Me.CubeGrid);
  18. MyGTS.GetBlocksOfType(Cockpits,block => block.CubeGrid==Me.CubeGrid);
  19. MyCockpit = Cockpits[0];
  20. // Rotation matrix relative to grid
  21. MyCockpit.Orientation.GetMatrix(out CockpitOr);
  22.  
  23. CockpitScreens.Add( MyCockpit.GetSurface(0));
  24. CockpitScreens.Add(MyCockpit.GetSurface(1));
  25.  
  26. // Configure the gyros for override/manual control at recompile
  27. foreach (IMyGyro gyro in Gyros){
  28. if (!gyro.CustomData.Contains("leave"))gyro.GyroOverride = true;
  29. else gyro.GyroOverride=false;
  30. }
  31. // Get new pitch conroller
  32. PitchControl = new PID(50,0.0,0);
  33.  
  34. // Update every 10 ticks
  35. Runtime.UpdateFrequency = UpdateFrequency.Update10;
  36. }
  37.  
  38. public void Main(string argument, UpdateType updateSource)
  39. {
  40.  
  41. // Get the gravity vector and convert to unit quantity
  42. G = MyCockpit.GetNaturalGravity();
  43. G.Normalize();
  44.  
  45. // Get the component of gravity acting in the forward direction of the cockpit
  46. g = G.Dot(MyCockpit.WorldMatrix.Forward);
  47.  
  48. // if the forward direction gravity is 0, then the vehicle is level in pitch. regulate the gravity to 0 = regulate pitch to 0
  49. double output = PitchControl.GetSignal(-g,tickspersecond);
  50. // if the forward gravity component is negative (pitching up) then make sure the output rotation is positve (pitching down)
  51. if (g >0)output = -Math.Abs(output);
  52. // if the forward gravity component is positive (pitching down) then make sure the output rotation is negative (pitching up)
  53. else output = Math.Abs(output);
  54.  
  55. // bound the commanded angular velocity magnitude to 60 RPM
  56. output = Math.Max(output,-maxrpm*2*Math.PI/60);
  57. output = Math.Min(output,maxrpm*2*Math.PI/60);
  58. // if there is a bias add it in here (radians/sec)
  59. output+=gyrobias;
  60.  
  61. // create the bodyfixed angular rotation vector
  62. Vector3D bodyrot = new Vector3D(0.0,output,0.0);
  63.  
  64. // make sure the magnitude is stored
  65. double bodymag = bodyrot.Length();
  66.  
  67. // scale the bodyrotation vector to unit
  68. bodyrot.Normalize();
  69.  
  70. // decompose commanded body angular velocity into each gyroscope
  71. foreach(IMyGyro gyro in Gyros) {
  72.  
  73. Echo(gyro.DisplayNameText);
  74.  
  75. // get the rotation of the gyroscope
  76. Matrix gyroor;
  77. gyro.Orientation.GetMatrix(out gyroor);
  78.  
  79. // for some reason, I don't know why, the gyroscope orientation is presented as PitchRollYaw Euler Transformation...
  80. Vector3 XYZ;
  81. Matrix.GetEulerAnglesXYZ(ref gyroor, out XYZ);
  82. String test = string.Format("TF {0:0.00} {1:0.00} {2:0.00}", XYZ.X, XYZ.Y, XYZ.Z);
  83. Echo(test);
  84.  
  85. // Get the commanded rotation relative to the gyroscope's local axes
  86. Vector3D localCmd = Vector3D.Transform(bodyrot,gyroor);
  87.  
  88. // Scale the command vector to radian/s
  89. localCmd = Vector3D.Multiply(localCmd,bodymag*2*Math.PI/60.0);
  90.  
  91. gyro.Yaw = (float)(localCmd.GetDim(0));
  92. gyro.Pitch = (float)(localCmd.GetDim(1));
  93. gyro.Roll = (float)(localCmd.GetDim(2));
  94.  
  95. string OutputStr = string.Format("CMD {0:0.00} {1:0.00} {2:0.00}\n",localCmd.GetDim(0),localCmd.GetDim(1),localCmd.GetDim(2));
  96. Echo(OutputStr);
  97. }
  98.  
  99. }
  100.  
  101. class PID
  102.     {
  103.     public double Kp {get;set;}
  104.     public double Ki {get;set;}
  105.     public double Kd {get;set;}
  106.     public double Signal {get;set;}
  107.     double Iscale = 1;
  108.     double ValuePrev;
  109.     double Integral;
  110.     public PID(double kp=1,double ki=1,double kd=1)
  111.     {
  112.     Kp=kp;
  113.     Ki=ki;
  114.     Kd=kd;
  115.     }
  116.     public void Reset()
  117.     {
  118.     ValuePrev=0;
  119.     Integral=0;
  120.     Signal=0;
  121.     }
  122.     public double GetSignal(double value,double dt=1.0/60.0)
  123.     {
  124.     if(Ki!=0)
  125.     Integral += value*Iscale;
  126.     Signal=Kp*value+Ki*Integral*dt+Kd*(value-ValuePrev)/dt;
  127.     ValuePrev=value;
  128.     return Signal;
  129.     }
  130.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement