Advertisement
Whiplash141

Some Thing

Jul 30th, 2017
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.52 KB | None | 0 0
  1. #region pre-script
  2. #if DEBUG
  3. using System;
  4. using System.Collections.Generic;
  5. using VRageMath;
  6. using VRage.Game;
  7. using VRage.Library;
  8. using System.Text;
  9. using Sandbox.ModAPI.Interfaces;
  10. using Sandbox.ModAPI.Ingame;
  11. using Sandbox.Common;
  12. using Sandbox.Game;
  13. using VRage.Collections;
  14. using VRage.Game.ModAPI.Ingame;
  15. using SpaceEngineers.Game.ModAPI.Ingame;
  16.  
  17. namespace SE_Scripting
  18. {
  19.     public class Program : MyGridProgram
  20.     {
  21. #endif
  22.         #endregion
  23.         //=======================================================================================
  24.         //////////////////////////START//////////////////////////////////////////
  25.         //=======================================================================================
  26.  
  27.         string shipControllerNameTag = "Reference";
  28.  
  29.         double desiredSpeed = 5; // meters per second
  30.  
  31.         //PID Controller constants
  32.         double proportionalGain = 5;
  33.         double integralGain = 0;
  34.         double derivativeGain = 2;
  35.  
  36.         PID frontBackPID;
  37.         PID leftRightPID;
  38.         PID upDownPID;
  39.  
  40.         Vector3D desiredDirection = new Vector3D(0, 0, 0);
  41.  
  42.         Program()
  43.         {
  44.             frontBackPID = new PID(proportionalGain, integralGain, derivativeGain, -10, 10, 1d/60d);
  45.             leftRightPID = new PID(proportionalGain, integralGain, derivativeGain, -10, 10, 1d / 60d);
  46.             upDownPID = new PID(proportionalGain, integralGain, derivativeGain, -10, 10, 1d / 60d);
  47.         }
  48.  
  49.         void Main(string arg)
  50.         {
  51.             bool isSetup = GrabBlocks();
  52.             if (!isSetup)
  53.                 return;
  54.  
  55.             Echo("It's workingggg!!!");
  56.  
  57.             switch (arg.ToLower())
  58.             {
  59.                 case "front":
  60.                     desiredDirection = controller.WorldMatrix.Forward;
  61.                     break;
  62.                 case "back":
  63.                     desiredDirection = controller.WorldMatrix.Backward;
  64.                     break;
  65.                 case "left":
  66.                     desiredDirection = controller.WorldMatrix.Left;
  67.                     break;
  68.                 case "right":
  69.                     desiredDirection = controller.WorldMatrix.Right;
  70.                     break;
  71.                 case "up":
  72.                     desiredDirection = controller.WorldMatrix.Up;
  73.                     break;
  74.                 case "down":
  75.                     desiredDirection = controller.WorldMatrix.Down;
  76.                     break;
  77.                 case "stop":
  78.                     desiredDirection = Vector3D.Zero;
  79.                     break;
  80.                 default:
  81.                     ParseArgument(arg);
  82.                     break;
  83.             }
  84.  
  85.             MoveInDirection(desiredDirection, desiredSpeed, controller);
  86.         }
  87.  
  88.         void ParseArgument(string arg)
  89.         {
  90.             //do stuff
  91.         }
  92.  
  93.         void MoveInDirection(Vector3D desiredDirection, double desiredSpeed, IMyShipController controller)
  94.         {
  95.             var currentVelocity = controller.GetShipVelocities().LinearVelocity;
  96.             var desiredVelocity = desiredDirection * desiredSpeed;
  97.             var relativeVelocity = desiredVelocity - currentVelocity; Echo($"RelVel: {relativeVelocity.Length()}");
  98.  
  99.             var forwardError = ScalarProjection(relativeVelocity, controller.WorldMatrix.Forward);
  100.             var leftError = ScalarProjection(relativeVelocity, controller.WorldMatrix.Left);
  101.             var upError = ScalarProjection(relativeVelocity, controller.WorldMatrix.Up);
  102.  
  103.             var forwardOutput = frontBackPID.Control(forwardError);
  104.             var leftOutput = leftRightPID.Control(leftError);
  105.             var upOutput = upDownPID.Control(upError);
  106.  
  107.             Echo($"Forward: {forwardOutput}\nLeft: {leftOutput}\nUp: {upOutput}");
  108.  
  109.             ThrustToTargetSpeed(forwardThrust, backwardThrust, forwardOutput);
  110.             ThrustToTargetSpeed(leftThrust, rightThrust, leftOutput);
  111.             ThrustToTargetSpeed(upThrust, downThrust, upOutput);
  112.         }
  113.  
  114.         void ThrustToTargetSpeed(List<IMyThrust> positiveThrust, List<IMyThrust> negativeThrust, double desiredThrust)
  115.         {
  116.             if (desiredThrust < 0)
  117.                 ApplyThrust(negativeThrust, -desiredThrust);
  118.             else
  119.                 ApplyThrust(positiveThrust, desiredThrust);
  120.         }
  121.  
  122.         void ApplyThrust(List<IMyThrust> thrusters, double thrust)
  123.         {
  124.             foreach (var block in thrusters)
  125.             {
  126.                 block.SetValue("Override", (float)thrust);
  127.                 Echo($"{block.CustomName}\nThrust: {thrust}");
  128.             }
  129.         }
  130.  
  131.         Vector3D VectorProjection(Vector3D a, Vector3D b)
  132.         {
  133.             if (Vector3D.IsZero(b))
  134.                 return Vector3D.Zero;
  135.  
  136.             return a.Dot(b) / b.LengthSquared() * b;
  137.         }
  138.  
  139.         double ScalarProjection(Vector3D a, Vector3D b)
  140.         {
  141.             if (Vector3D.IsZero(b))
  142.                 return 0;
  143.  
  144.             return a.Dot(b) / b.Length() * Math.Sign(a.Dot(b));
  145.         }
  146.  
  147.         List<IMyShipController> shipControllers = new List<IMyShipController>();
  148.         List<IMyThrust> allThrust = new List<IMyThrust>();
  149.         List<IMyThrust> upThrust = new List<IMyThrust>();
  150.         List<IMyThrust> downThrust = new List<IMyThrust>();
  151.         List<IMyThrust> leftThrust = new List<IMyThrust>();
  152.         List<IMyThrust> rightThrust = new List<IMyThrust>();
  153.         List<IMyThrust> forwardThrust = new List<IMyThrust>();
  154.         List<IMyThrust> backwardThrust = new List<IMyThrust>();
  155.         IMyShipController controller;
  156.  
  157.         bool GrabBlocks()
  158.         {
  159.             upThrust.Clear();
  160.             downThrust.Clear();
  161.             leftThrust.Clear();
  162.             rightThrust.Clear();
  163.             forwardThrust.Clear();
  164.             backwardThrust.Clear();
  165.  
  166.             GridTerminalSystem.GetBlocksOfType(shipControllers, x => x.CustomName.Contains(shipControllerNameTag));
  167.             GridTerminalSystem.GetBlocksOfType(allThrust);
  168.  
  169.             if (shipControllers.Count == 0)
  170.             {
  171.                 Echo($"Error: No ship controllers named \"{shipControllerNameTag}\" found");
  172.                 return false;
  173.             }
  174.  
  175.             controller = shipControllers[0];
  176.  
  177.             foreach (var block in allThrust)
  178.             {
  179.                 if (controller.WorldMatrix.Forward == block.WorldMatrix.Backward)
  180.                     forwardThrust.Add(block);
  181.                 else if (controller.WorldMatrix.Backward == block.WorldMatrix.Backward)
  182.                     backwardThrust.Add(block);
  183.                 else if (controller.WorldMatrix.Left == block.WorldMatrix.Backward)
  184.                     leftThrust.Add(block);
  185.                 else if (controller.WorldMatrix.Right == block.WorldMatrix.Backward)
  186.                     rightThrust.Add(block);
  187.                 else if (controller.WorldMatrix.Up == block.WorldMatrix.Backward)
  188.                     upThrust.Add(block);
  189.                 else if (controller.WorldMatrix.Down == block.WorldMatrix.Backward)
  190.                     downThrust.Add(block);
  191.             }
  192.             return true;
  193.         }
  194.  
  195.         //Whip's PID controller class v2 - 7/29/17
  196.         public class PID
  197.         {
  198.             double _kP = 0;
  199.             double _kI = 0;
  200.             double _kD = 0;
  201.             double _lowerBound = 0;
  202.             double _upperBound = 0;
  203.             double _timeStep = 0;
  204.             double _errorSum = 0;
  205.             double _lastError = 0;
  206.             bool _firstRun = true;
  207.  
  208.             public PID(double kP, double kI, double kD, double lowerBound, double upperBound, double timeStep)
  209.             {
  210.                 _kP = kP;
  211.                 _kI = kI;
  212.                 _kD = kD;
  213.                 _lowerBound = lowerBound;
  214.                 _upperBound = upperBound;
  215.                 _timeStep = timeStep;
  216.             }
  217.  
  218.             public PID(float kP, float kI, float kD, float lowerBound, float upperBound, float timeStep)
  219.             {
  220.                 _kP = kP;
  221.                 _kI = kI;
  222.                 _kD = kD;
  223.                 _lowerBound = lowerBound;
  224.                 _upperBound = upperBound;
  225.                 _timeStep = timeStep;
  226.             }
  227.  
  228.             public double Control(double error)
  229.             {
  230.                 //Compute derivative term
  231.                 var errorDerivative = (error - _lastError) / _timeStep;
  232.  
  233.                 if (_firstRun)
  234.                 {
  235.                     errorDerivative = 0;
  236.                     _firstRun = false;
  237.                 }
  238.  
  239.                 //Compute integral term
  240.                 _errorSum += error * _timeStep;
  241.  
  242.                 //Clamp integral term
  243.                 if (_errorSum > _upperBound)
  244.                     _errorSum = _upperBound;
  245.                 else if (_errorSum < _lowerBound)
  246.                     _errorSum = _lowerBound;
  247.  
  248.                 //Store this error as last error
  249.                 _lastError = error;
  250.  
  251.                 //Construct output
  252.                 return _kP * error + _kI * _errorSum + _kD * errorDerivative;
  253.             }
  254.  
  255.             public void Reset()
  256.             {
  257.                 _errorSum = 0;
  258.                 _lastError = 0;
  259.                 _firstRun = true;
  260.             }
  261.         }
  262.  
  263.         //=======================================================================================
  264.         //////////////////////////END//////////////////////////////////////////
  265.         //=======================================================================================
  266.         #region post-script
  267. #if DEBUG
  268.     }
  269. }
  270. #endif
  271. #endregion
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement