Advertisement
Whiplash141

Example Gyroscopic Control Code

Dec 28th, 2017
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.70 KB | None | 0 0
  1.  
  2. //Whip's Example Code for Gyroscopic Control - 12/28/17
  3.  
  4. double proportionalGain = 1; //modifier that changes how fast the ship will rotate
  5.  
  6. List<IMyGyro> gyros = new List<IMyGyro>();
  7.  
  8. void Main()
  9. {
  10.     GridTerminalSystem.GetBlocksOfType(gyros);
  11.  
  12.     IMyTerminalBlock referenceBlock = GridTerminalSystem.GetBlockWithName("Reference Block");
  13.     if (referenceBlock == null)
  14.         return;
  15.  
  16.     //this is a world direction vector that you wish to align the "forward" direction of the reference block to
  17.     Vector3D desiredVector = new Vector3D(1, 2, 3);
  18.  
  19.     //get pitch and yaw angles (radians) required to steer onto desiredVector
  20.     double pitch = 0; double yaw = 0;
  21.     GetRotationAngles(desiredVector, referenceBlock, out yaw, out pitch);
  22.  
  23.     //the angular speed is obtained with a simple proportional error controller
  24.     double pitchSpeed = proportionalGain * pitch;
  25.     double yawSpeed = proportionalGain * yaw;
  26.  
  27.     //apply pitch and yaw speed to gyros
  28.     ApplyGyroOverride(pitchSpeed, yawSpeed, 0, gyros, referenceBlock);
  29. }
  30.  
  31. /*
  32. /// Whip's Get Rotation Angles Method v10 - 12/27/17 ///
  33. Dependencies: VectorProjection() | VectorAngleBetween()
  34. * Fix to solve for zero cases when a vertical target vector is input
  35. * Fixed straight up case
  36. */
  37. void GetRotationAngles(Vector3D v_target, IMyTerminalBlock reference, out double yaw, out double pitch)
  38. {
  39.     var v_front = reference.WorldMatrix.Forward;
  40.     var v_left = reference.WorldMatrix.Left;
  41.     var v_up = reference.WorldMatrix.Up;
  42.  
  43.     var projectTargetUp = VectorProjection(v_target, v_up);
  44.     var projTargetFrontLeft = v_target - projectTargetUp;
  45.  
  46.     yaw = VectorAngleBetween(v_front, projTargetFrontLeft);
  47.  
  48.     if (Vector3D.IsZero(projTargetFrontLeft) && !Vector3D.IsZero(projectTargetUp)) //check for straight up case
  49.         pitch = MathHelper.PiOver2;
  50.     else
  51.         pitch = VectorAngleBetween(v_target, projTargetFrontLeft); //pitch should not exceed 90 degrees by nature of this definition
  52.  
  53.     //---Check if yaw angle is left or right  
  54.     //multiplied by -1 to convert from right hand rule to left hand rule
  55.     yaw = -1 * Math.Sign(v_left.Dot(v_target)) * yaw;
  56.  
  57.     //---Check if pitch angle is up or down    
  58.     pitch = Math.Sign(v_up.Dot(v_target)) * pitch;
  59.  
  60.     //---Check if target vector is pointing opposite the front vector
  61.     if (Math.Abs(yaw) <= 1E-6 && v_target.Dot(v_front) < 0)
  62.     {
  63.         yaw = Math.PI;
  64.     }
  65. }
  66.  
  67. Vector3D VectorProjection(Vector3D a, Vector3D b)
  68. {
  69.     if (Vector3D.IsZero(b))
  70.         return Vector3D.Zero;
  71.  
  72.     return a.Dot(b) / b.LengthSquared() * b;
  73. }
  74.  
  75. double VectorAngleBetween(Vector3D a, Vector3D b) //returns radians
  76. {
  77.     if (Vector3D.IsZero(a) || Vector3D.IsZero(b))
  78.         return 0;
  79.     else
  80.         return Math.Acos(MathHelper.Clamp(a.Dot(b) / Math.Sqrt(a.LengthSquared() * b.LengthSquared()), -1, 1));
  81. }
  82.  
  83. //Whip's ApplyGyroOverride Method v9 - 8/19/17
  84. void ApplyGyroOverride(double pitch_speed, double yaw_speed, double roll_speed, List<IMyGyro> gyro_list, IMyTerminalBlock reference)
  85. {
  86.     var rotationVec = new Vector3D(-pitch_speed, yaw_speed, roll_speed); //because keen does some weird stuff with signs
  87.     var shipMatrix = reference.WorldMatrix;
  88.     var relativeRotationVec = Vector3D.TransformNormal(rotationVec, shipMatrix);
  89.  
  90.     foreach (var thisGyro in gyro_list)
  91.     {
  92.         var gyroMatrix = thisGyro.WorldMatrix;
  93.         var transformedRotationVec = Vector3D.TransformNormal(relativeRotationVec, Matrix.Transpose(gyroMatrix));
  94.  
  95.         thisGyro.Pitch = (float)transformedRotationVec.X;
  96.         thisGyro.Yaw = (float)transformedRotationVec.Y;
  97.         thisGyro.Roll = (float)transformedRotationVec.Z;
  98.         thisGyro.GyroOverride = true;
  99.     }
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement