Whiplash141

GASP Guidance - Private

Nov 4th, 2015
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.13 KB | None | 0 0
  1. /*
  2. Whip's GASP Missile System v4 - revised: 11/3/15
  3. /// PROPRIETARY VERSION ///
  4.     Torpedo 1
  5. ___________________________________________________________________
  6. Description:
  7.  
  8. This script handles the launch of the GASP Missile System
  9.  
  10. - Whiplash141 :)  
  11. */
  12.  
  13. /*
  14. ___________________________________________________________________
  15.  
  16. ========== You can edit these variables to your liking ============
  17. ___________________________________________________________________
  18. */
  19.     static string torpedo_no = "1";        
  20.     string forwardThrustName = "Forward Thrust - Torpedo - " + torpedo_no; //name tag of forward thrust on the missile
  21.     string maneuveringThrustersName = "Thruster - Maneuvering - " + torpedo_no; //name tag of manevering thrusters on the missile
  22.     string mergeName = "Merge - Missile Main - " + torpedo_no; //name tag of missile merge          
  23.     string artMassName = "Artificial Mass - Detach - " + torpedo_no; //name tag of missile mass
  24.     string batteryName = "Battery - Torpedo - " + torpedo_no; //name tag of missile battery
  25.     string shooterReferenceName = "[Shooter]"; //name tag of shooter's remote
  26.     string missileReferenceName = "[Missile " + torpedo_no + "]"; //name tag of missile's remote
  27.     string gyroName = "[Control " + torpedo_no + "]"; //name of missile gyro    
  28.     double guidance_delay = 2; //time (in seconds) that the missile will delay guidance activation by
  29.     double max_rotation_degrees = 180; //in degrees per second (360 max for small ships, 180 max for large ships)
  30.     double max_distance = 10000; //maximum guidance distance in meters; don't enlarge it lol, 10km is super far
  31.     int tick_limit = 1; //change to higher for less precision
  32.  
  33. /*
  34. ___________________________________________________________________
  35.  
  36. ============= Don't touch anything below this :) ==================
  37. ___________________________________________________________________
  38. */
  39. //---So many lists...  
  40.     List<IMyTerminalBlock> forwardThrusters = new List<IMyTerminalBlock>();          
  41.     List<IMyTerminalBlock> artMasses = new List<IMyTerminalBlock>();        
  42.     List<IMyTerminalBlock> mergeBlocks = new List<IMyTerminalBlock>();        
  43.     List<IMyTerminalBlock> maneuveringThrusters = new List<IMyTerminalBlock>();      
  44.     List<IMyTerminalBlock> batteries = new List<IMyTerminalBlock>();
  45.     List<IMyTerminalBlock> remotes = new List<IMyTerminalBlock>();  
  46.     List<IMyTerminalBlock> shooterRefrenceList = new List<IMyTerminalBlock>();  
  47.     List<IMyTerminalBlock> missileRefrenceList = new List<IMyTerminalBlock>();  
  48.     List<IMyTerminalBlock> gyroList = new List<IMyTerminalBlock>();
  49.    
  50.     Vector3D targetVectorNorm = new Vector3D(0, 0, 0);
  51.     Vector3D originPos = new Vector3D(0, 0, 0);
  52.     IMyRemoteControl shooterRefrence;  
  53.     IMyRemoteControl missileRefrence;  
  54.     bool hasRun = false;
  55.     bool isFired = false;
  56.     bool shouldKill = false;
  57.     double delta_origin;
  58.     int current_tick = 0;  
  59.     int duration = 0;      
  60.     int timeElapsed = 0;      
  61.  
  62. void Main(string arg)  
  63. {  
  64.     if(arg == "kill" && isFired == true)
  65.     {
  66.         shouldKill = true;
  67.         max_distance = double.PositiveInfinity;
  68.     }
  69.        
  70.  
  71.     Echo("Tick: " + current_tick.ToString());
  72.     if (!hasRun)
  73.     {
  74.         GrabRemotes();
  75.     }        
  76.     else //will not run or release missile until has run setup succesfully
  77.     {
  78.         MissileSystems();
  79.        
  80.         if (duration < Math.Ceiling(guidance_delay * 60))
  81.         {
  82.             duration++;
  83.             return;
  84.         }
  85.         else
  86.         {
  87.             if((current_tick % tick_limit) == 0)
  88.             {
  89.                 Echo("Guidance Active");  
  90.                 GuideMissile();  
  91.                 current_tick = 0;  
  92.             }
  93.         }      
  94.         current_tick++;    
  95.     }
  96.     Echo("Has run?: " + hasRun);
  97. }      
  98.  
  99. void GrabRemotes()
  100. {
  101.     GridTerminalSystem.SearchBlocksOfName(gyroName, gyroList);
  102.     GridTerminalSystem.GetBlocksOfType<IMyRemoteControl>(remotes);
  103.     for(int i = 0 ; i < remotes.Count ; i++)  
  104.         {  
  105.             var thisRemote = remotes[i] as IMyRemoteControl;
  106.             if(thisRemote.CustomName.Contains(shooterReferenceName))  
  107.             {    
  108.                 shooterRefrenceList.Add(thisRemote as IMyRemoteControl);  
  109.                 Echo("Found Shooter");  
  110.             }  
  111.  
  112.             if(thisRemote.CustomName.Contains(missileReferenceName))  
  113.             {  
  114.                 missileRefrenceList.Add(thisRemote as IMyRemoteControl);  
  115.                 Echo("Found Missile");  
  116.             }  
  117.         }
  118.  
  119. //---Check if we do not have an shooter remote
  120.     if(shooterRefrenceList.Count == 0)  
  121.     {  
  122.         Echo("No shooter refrence block found");  
  123.         hasRun = false;  
  124.         return;  
  125.     }
  126. //---Check if we do not have a missile remote
  127.     else if(missileRefrenceList.Count == 0)  
  128.     {  
  129.         Echo("No missile refrence block found");  
  130.         hasRun = false;  
  131.         return;  
  132.     }  
  133.     else if(gyroList.Count == 0)
  134.     {
  135.         Echo("No control gyro found");
  136.         hasRun = false;
  137.         return;
  138.     }
  139.     else
  140.     {    
  141.         Echo("Ready to run");
  142.         shooterRefrence = shooterRefrenceList[0] as IMyRemoteControl;  
  143.         missileRefrence = missileRefrenceList[0] as IMyRemoteControl;  
  144.         hasRun = true;  
  145.     }
  146. }
  147.  
  148. void GuideMissile()  
  149. {  
  150. //---Get positions of our blocks with relation to world center
  151.     if(!shouldKill)
  152.         originPos = shooterRefrence.GetPosition();  
  153.    
  154.     var missilePos = missileRefrence.GetPosition();  
  155.  
  156. //---Find current distance from shooter to missile
  157.     delta_origin = Vector3D.Distance(originPos, missilePos);
  158.  
  159. //---Check if we are in range    
  160.     if(delta_origin < max_distance) //change this later to be larger
  161.     {
  162.     //---Get forward vector from our shooter vessel
  163.         if(!shouldKill)
  164.         {
  165.             var shooterForward = shooterRefrence.Position + Base6Directions.GetIntVector(shooterRefrence.Orientation.TransformDirection(Base6Directions.Direction.Forward));  
  166.             var targetVector = shooterRefrence.CubeGrid.GridIntegerToWorld(shooterForward);  
  167.             targetVectorNorm = Vector3D.Normalize(targetVector - shooterRefrence.GetPosition());
  168.         }
  169.          
  170.  
  171.     //---Find vector from shooter to missile
  172.         var missileVector = Vector3D.Subtract(missilePos, originPos);
  173.  
  174.     //---Calculate angle between shooter vector and missile vector
  175.         double dotProduct; Vector3D.Dot(ref targetVectorNorm, ref missileVector, out dotProduct);
  176.         double x = dotProduct / missileVector.Length();      
  177.         double rawDevAngle = Math.Acos(x) * 180f / Math.PI; //angle between shooter vector and missile
  178.  
  179.     //---Calculate perpendicular distance from shooter vector
  180.         var projectionVector = dotProduct * targetVectorNorm;
  181.         double deviationDistance = Vector3D.Distance(projectionVector,missileVector);
  182.         Echo("Angular Dev: " + rawDevAngle.ToString());
  183.  
  184.     //---Determine scaling factor
  185.         double scalingFactor;
  186.         if(rawDevAngle < 90)
  187.         {
  188.             if(deviationDistance > 200)
  189.             {
  190.                 scalingFactor = delta_origin; //if we are too far from the beam, dont add any more distance till we are closer
  191.             }
  192.             else
  193.             {
  194.                 scalingFactor = (delta_origin + 200); //travel approx. 100m from current position in direction of target vector
  195.             }
  196.         }
  197.         else
  198.         {
  199.             scalingFactor = 200; //if missile is behind the shooter, goes 200m directly infront of shooter for better accuracy
  200.         }
  201.         var destination = shooterRefrence.GetPosition() + scalingFactor * targetVectorNorm;  
  202.         Echo(destination.ToString()); //debug
  203.  
  204.     //---Find front left and top vectors of our missile
  205.         var missileGridX = missileRefrence.Position + Base6Directions.GetIntVector(missileRefrence.Orientation.TransformDirection(Base6Directions.Direction.Forward));
  206.         var missileWorldX = missileRefrence.CubeGrid.GridIntegerToWorld(missileGridX) - missilePos;
  207.  
  208.         var missileGridY = missileRefrence.Position + Base6Directions.GetIntVector(missileRefrence.Orientation.TransformDirection(Base6Directions.Direction.Left));
  209.         var missileWorldY = missileRefrence.CubeGrid.GridIntegerToWorld(missileGridY) - missilePos;
  210.  
  211.         var missileGridZ = missileRefrence.Position + Base6Directions.GetIntVector(missileRefrence.Orientation.TransformDirection(Base6Directions.Direction.Up));
  212.         var missileWorldZ = missileRefrence.CubeGrid.GridIntegerToWorld(missileGridZ) - missilePos;
  213.  
  214.     //---Find vector from missile to destination
  215.         var shipToTarget = Vector3D.Subtract(destination, missilePos);
  216.  
  217.     //---Project target vector onto our top left and up vectors
  218.         double dotX; Vector3D.Dot(ref shipToTarget, ref missileWorldX, out dotX);
  219.         double dotY; Vector3D.Dot(ref shipToTarget, ref missileWorldY, out dotY);
  220.         double dotZ; Vector3D.Dot(ref shipToTarget, ref missileWorldZ, out dotZ);
  221.         var projTargetX = dotX / (missileWorldX.Length() * missileWorldX.Length()) * missileWorldX;
  222.         var projTargetY = dotY / (missileWorldY.Length() * missileWorldY.Length()) * missileWorldY;
  223.         var projTargetZ = dotZ / (missileWorldZ.Length() * missileWorldZ.Length()) * missileWorldZ;
  224.         var projTargetXYplane = projTargetX + projTargetY;
  225.  
  226.     //---Get Yaw and Pitch Angles
  227.         double angleYaw = Math.Atan(projTargetY.Length() / projTargetX.Length());
  228.         double anglePitch = Math.Atan(projTargetZ.Length() / projTargetXYplane.Length());
  229.  
  230.     //---Check if x is positive or negative
  231.         double checkPositiveX; Vector3D.Dot(ref missileWorldX, ref projTargetX, out checkPositiveX); Echo("check x:" + checkPositiveX.ToString());
  232.         if(checkPositiveX < 0)
  233.         {
  234.             angleYaw += Math.PI/2; //we only change one value so it doesnt spaz
  235.         }
  236.  
  237.     //---Check if yaw angle is left or right
  238.         double checkYaw; Vector3D.Dot(ref missileWorldY, ref projTargetY, out checkYaw); Echo("check yaw:" + checkYaw.ToString());
  239.         if(checkYaw > 0) //yaw is backwards for what ever reason
  240.             angleYaw = -angleYaw;
  241.         Echo("yaw angle:" + angleYaw.ToString());
  242.  
  243.     //---Check if pitch angle is up or down
  244.         double checkPitch; Vector3D.Dot(ref missileWorldZ, ref projTargetZ, out checkPitch); Echo("check pitch:" + checkPitch.ToString());
  245.         if(checkPitch < 0)
  246.             anglePitch = -anglePitch;
  247.         Echo("pitch angle:" + anglePitch.ToString());
  248.  
  249.     //---Angle controller
  250.         double max_rotation_radians = max_rotation_degrees * (Math.PI / 180);
  251.         double yawSpeed = max_rotation_radians * angleYaw / Math.Abs(angleYaw);
  252.         double pitchSpeed = max_rotation_radians * anglePitch / Math.Abs(anglePitch);
  253.  
  254.         //Alt method 1: Proportional Control
  255.         //(small ship gyros too weak for this to be effective)
  256.         /*
  257.             double yawSpeed = angleYaw / Math.PI * max_rotation_radians;
  258.             double pitchSpeed = anglePitch / Math.PI * max_rotation_radians;
  259.         */
  260.        
  261.         //Alt method 2: Proportional Control with bounds
  262.         //(Small gyros still too weak :/)
  263.             /*if (angleYaw < Math.PI/4)
  264.             {
  265.                 yawSpeed = angleYaw * max_rotation_radians / (Math.PI/4);
  266.             }
  267.             else
  268.             {
  269.                 yawSpeed = max_rotation_radians;
  270.             }
  271.              
  272.             if (anglePitch < Math.PI/4)
  273.             {
  274.                 pitchSpeed = anglePitch * max_rotation_radians / (Math.PI/4);
  275.             }
  276.             else
  277.             {
  278.                 pitchSpeed = max_rotation_radians;
  279.             }*/
  280.  
  281.     //---Set appropriate gyro override
  282.         for(int i = 0; i < gyroList.Count; i++)
  283.         {
  284.             var thisGyro = gyroList[i] as IMyGyro;
  285.             thisGyro.SetValue<float>("Yaw", (float)yawSpeed);
  286.             thisGyro.SetValue<float>("Pitch", (float)pitchSpeed);
  287.             thisGyro.SetValue("Override", true);
  288.         }
  289.     }
  290.     else
  291.     {
  292.         Echo("Out of range");
  293.         shouldKill = true;
  294.     }
  295. }
  296.  
  297. void MissileSystems()              
  298. {            
  299.     GridTerminalSystem.SearchBlocksOfName(artMassName,artMasses);  
  300.     GridTerminalSystem.SearchBlocksOfName(mergeName,mergeBlocks);    
  301.     GridTerminalSystem.SearchBlocksOfName(batteryName,batteries);
  302.  
  303. //---Check for the required launch components
  304.     if(mergeBlocks.Count == 0)
  305.     {
  306.         Echo("No merges found");
  307.     }  
  308.     else if(artMasses.Count == 0)
  309.     {
  310.         Echo("No detach mass found");
  311.     }
  312.     else if(batteries.Count == 0)
  313.     {
  314.         Echo("No batteries found");
  315.     }
  316.  
  317.     if (timeElapsed == 0)        
  318.     {        
  319.         for(int i = 0 ; i < batteries.Count ; i++)  
  320.         {  
  321.             var thisBattery = batteries[i] as IMyBatteryBlock;
  322.             thisBattery.ApplyAction("OnOff_On"); //make sure our battery is on
  323.             thisBattery.SetValue("Recharge", false);    
  324.         }  
  325.    
  326.     }  
  327.     else if(timeElapsed == 60)  
  328.     {  
  329.         for(int i = 0 ; i < artMasses.Count ; i++)      
  330.         {      
  331.             var thisMass = artMasses[i] as IMyVirtualMass;      
  332.             thisMass.ApplyAction("OnOff_On");      
  333.         }
  334.         Echo("Detach Mass On");  
  335.  
  336.         for(int i = 0 ; i < mergeBlocks.Count ; i++)  
  337.         {  
  338.             var thisMerge = mergeBlocks[i] as IMyShipMergeBlock;  
  339.             thisMerge.ApplyAction("OnOff_Off");  
  340.         }
  341.     }  
  342.     else if(timeElapsed == 180)  
  343.     {        
  344.         for(int i = 0 ; i < artMasses.Count ; i++)      
  345.         {      
  346.             var thisMass = artMasses[i] as IMyVirtualMass;      
  347.             thisMass.ApplyAction("OnOff_Off");      
  348.         }          
  349.         ThrusterOverride();        
  350.         ManeuveringThrust();        
  351.         Echo("Detach Mass Off");        
  352.         Echo("Main Thruster Override On");
  353.         isFired = true;
  354.     }                  
  355.  
  356.     if (timeElapsed < 180)
  357.         timeElapsed++;        
  358. }
  359.  
  360. void ManeuveringThrust()        
  361. {        
  362.     if(maneuveringThrusters.Count == 0)
  363.         Echo("No maneivering thrust found");
  364.    
  365.     GridTerminalSystem.SearchBlocksOfName(maneuveringThrustersName,maneuveringThrusters);        
  366.     for(int i = 0 ; i < maneuveringThrusters.Count ; i++)        
  367.     {        
  368.         IMyThrust Thrust = maneuveringThrusters[i] as IMyThrust;
  369.         Thrust.ApplyAction("OnOff_On");        
  370.     }        
  371. }        
  372.              
  373. void ThrusterOverride()        
  374. {        
  375.     if(forwardThrusters.Count == 0)
  376.         Echo("No main thrust found");
  377.    
  378.     GridTerminalSystem.SearchBlocksOfName(forwardThrustName,forwardThrusters);              
  379.     for(int i = 0; i < forwardThrusters.Count;i++)              
  380.     {              
  381.         IMyThrust Thrust = forwardThrusters[i] as IMyThrust;
  382.         Thrust.ApplyAction("OnOff_On");
  383.         Thrust.SetValue<float>("Override", float.MaxValue);              
  384.     }          
  385. }
Advertisement
Add Comment
Please, Sign In to add comment