示例#1
0
 public bool getMass(out double mass)
 {
     mass = -1;
     if (_init())
     {
         return(true);
     }
     mass = (double)rc.CalculateShipMass().BaseMass + (
         (
             rc.CalculateShipMass().TotalMass -
             rc.CalculateShipMass().BaseMass
         ) / 10
         );
     return(false);
 }
        ///
        /// обновляем вектор гравитации с учетом массы корабля
        ///
        private void updateWeightVector()
        {
            Vector3D gravityVector = remoteControl.GetNaturalGravity();
            float    shipMass      = remoteControl.CalculateShipMass().PhysicalMass;

            Vector3D.Multiply(ref gravityVector, shipMass, out weightVector);
        }
示例#3
0
            void UpdateHitPosition(IMyRemoteControl control, int tick)
            {
                if (ticks != 1)
                {
                    //RayCast not long enough, no new information acquired
                    return;
                }
                double relativeVelocity = lastDistance - predictedPositionAngles.X;
                double timeFactor       = 60D / (double)tick;

                relativeVelocity = relativeVelocity * timeFactor;


                if (TotalMass == -1)
                {
                    TotalMass = (int)control.CalculateShipMass().TotalMass;
                }
                if (MaxThrust == -1)
                {
                    MaxThrust = 0;
                    List <IMyThrust> thruster = new List <IMyThrust>();
                    parent.GridTerminalSystem.GetBlocksOfType(thruster);
                    foreach (IMyThrust thrust in thruster)
                    {
                        if (thrust.WorldMatrix.Forward == control.WorldMatrix.Backward)
                        {
                            MaxThrust += thrust.MaxThrust;
                        }
                    }
                }
                if (MaxAcceleration == -1)
                {
                    MaxAcceleration = MaxThrust / TotalMass;
                }


                double ownSpeed = control.GetShipSpeed();
                double timeToMax;
                double distanceAtMaxSpeed;

                if (ownSpeed <= 99)
                {
                    timeToMax          = (100 - ownSpeed) / MaxAcceleration;
                    distanceAtMaxSpeed = predictedPositionAngles.X - (relativeVelocity + (MaxAcceleration * timeToMax) / 2) * timeToMax;
                }
                else
                {
                    timeToMax          = 0;
                    distanceAtMaxSpeed = predictedPositionAngles.X;
                }
                timeToTarget      = (float)(distanceAtMaxSpeed / (relativeVelocity + (100 - ownSpeed)) + timeToMax);
                predictedHitPoint = TargetInfo.Position + timeToTarget * TargetInfo.Velocity;
                lastDistance      = predictedPositionAngles.X;
            }
示例#4
0
            public void SetThrust(Vector3D deltaV, bool align)
            {
                Base6Directions.Direction direction         = Base6Directions.GetClosestDirection(deltaV);
                Base6Directions.Direction oppositeDirection = Base6Directions.GetOppositeDirection(direction);
                //Program.Echo($"\nDirection: {direction.ToString()}");
                //Program.Echo($"\nOpposite: {oppositeDirection.ToString()}");
                float maxThrust = MaxThrusters[direction];

                //double decayFactor = 0.8;
                //if (align && direction != Base6Directions.Direction.Forward || direction != Base6Directions.Direction.Backward)
                //    decayFactor = 0.25;

                //double acceleration = MathHelper.Clamp(maxThrust / Remote.CalculateShipMass().TotalMass, 0.1, Math.Pow(deltaV.Length(), decayFactor));
                //Drone.LogToLcd($"{direction.ToString()} {acceleration.ToString()}m/s/s");

                double acceleration = 0;
                var    freq         = this.Program.Runtime.TimeSinceLastRun.TotalMilliseconds / 1000;

                if (direction == Base6Directions.Direction.Left || direction == Base6Directions.Direction.Right)
                {
                    acceleration = XPID.CorrectError(deltaV.Length(), freq);
                }
                else if (direction == Base6Directions.Direction.Up || direction == Base6Directions.Direction.Down)
                {
                    acceleration = YPID.CorrectError(deltaV.Length(), freq);
                }
                else if (direction == Base6Directions.Direction.Forward || direction == Base6Directions.Direction.Backward)
                {
                    acceleration = ZPID.CorrectError(deltaV.Length(), freq);
                }

                double force = Remote.CalculateShipMass().TotalMass *acceleration;

                foreach (IMyThrust thruster in Thrusters[direction])
                {
                    thruster.Enabled        = true;
                    thruster.ThrustOverride = (float)force;
                }

                foreach (IMyThrust thruster in Thrusters[oppositeDirection])
                {
                    thruster.ThrustOverride = 0f;
                    thruster.Enabled        = false;
                }
            }
示例#5
0
            public void OnFlightUpdateFrame()
            {
                if (is_enabled)
                {
                    desired   = Vector3D.Zero;
                    velocity  = control.GetShipVelocities().LinearVelocity;
                    gravity   = control.GetNaturalGravity();
                    ship_mass = control.CalculateShipMass();
                    effective_breaking_distance = Settings.ARRIVAL_DIST * (ship_mass.TotalMass / ship_mass.BaseMass);

                    tasks.OnUpdateFrame();

                    if ((flags & SpaceshipFlags.CAS) == SpaceshipFlags.CAS)
                    {
                        cas.OnUpdateFrame();
                    }
                    if ((flags & SpaceshipFlags.FD) == SpaceshipFlags.FD)
                    {
                        fd.OnUpdateFrame();
                    }

                    Vector3DLimit(ref desired, Settings.MAX_SPEED);

                    if ((flags & SpaceshipFlags.AP) == SpaceshipFlags.AP)
                    {
                        autopilot.OnUpdateFrame();
                    }

                    if ((flags & SpaceshipFlags.TM) == SpaceshipFlags.TM)
                    {
                        thrusters.OnUpdateFrame();
                    }
                    else
                    {
                        thrusters.Disable();
                    }

                    CheckConnector();
                    if (fd.prev == fd.next)
                    {
                        fd.SetFlightPlan(null);
                    }
                }
            }
                public void CalculateThrust(Vector3D target_velocity, IMyRemoteControl control)
                {
                    float mass = control.CalculateShipMass().TotalMass;

                    for (int i = 0; i < 6; i++)
                    {
                        Vector3D thruster_vector = Settings.ManagedThrusterDirections[i];
                        required_thrust[i] = 0.0f;
                        if (Vector3D.Dot(target_velocity, thruster_vector) > 0.0f)
                        {
                            Vector3D projected_vector = Vector3D.ProjectOnVector(ref target_velocity, ref thruster_vector);
                            required_thrust[i] = (float)(projected_vector.Length() * mass);
                            if (required_thrust[i] < Settings.EPSILON)
                            {
                                required_thrust[i] = 0.0f;
                            }
                        }
                    }
                }
示例#7
0
        public Program()
        {
            control             = GridTerminalSystem.GetBlockWithName("Control") as IMyRemoteControl;
            visor               = GridTerminalSystem.GetBlockWithName("Visor") as IMyCameraBlock;
            visor.EnableRaycast = true;
            for (int i = 0; i < 6; i++)
            {
                thruster.Add((Side)i, new List <IMyThrust>());
                maxThrust.Add((Side)i, 0);
            }
            List <IMyThrust> thrust = new List <IMyThrust>();

            GridTerminalSystem.GetBlocksOfType(thrust);
            allThruster = thrust;
            foreach (IMyThrust thr in thrust)
            {
                SortThruster(thr);
                thr.SetValueFloat("Override", 0);
            }
            List <IMyGyro> GyrosList = new List <IMyGyro>();

            GridTerminalSystem.GetBlocksOfType(GyrosList);
            foreach (IMyGyro gyro in GyrosList)
            {
                gyro.GyroOverride = true;
                gyros.Add(new Gyroscope(gyro, control));
            }
            SetGyros(0, 0, 0);
            GridTerminalSystem.GetBlocksOfType(grinder);
            IMyBlockGroup sensors = GridTerminalSystem.GetBlockGroupWithName("Sensor Grinder");

            sensors.GetBlocksOfType(mainGrinderSensors);
            sensors = GridTerminalSystem.GetBlockGroupWithName("Sensor Collision");
            sensors.GetBlocksOfType(mainCollisionSensors);
            List <IMyCargoContainer> container = new List <IMyCargoContainer>();

            GridTerminalSystem.GetBlocksOfType(container);
            baseMass = control.CalculateShipMass().TotalMass;
            Echo("Init completed");
        }
示例#8
0
            double CAF_DIST_TO_TARGET;                            //Outputs distance to target

            void CollectAndFire2(Vector3D INPUT_POINT, double INPUT_VELOCITY, double INPUT_MAX_VELOCITY, Vector3D REFPOS, IMyRemoteControl RC)
            {
                //Function Initialisation
                //--------------------------------------------------------------------
                if (C_A_F_HASRUN == false)
                {
                    //Initialise Classes And Basic System
                    CAF2_FORWARD = new Thrust_info(RC.WorldMatrix.Forward, myGridTerminal, RC.CubeGrid);
                    CAF2_UP      = new Thrust_info(RC.WorldMatrix.Up, myGridTerminal, RC.CubeGrid);
                    CAF2_RIGHT   = new Thrust_info(RC.WorldMatrix.Right, myGridTerminal, RC.CubeGrid);
                    CAFTHI       = new List <Thrust_info>()
                    {
                        CAF2_FORWARD, CAF2_UP, CAF2_RIGHT
                    };
                    myGridTerminal.GetBlocksOfType <IMyThrust>(CAF2_THRUST, block => block.CubeGrid == RC.CubeGrid);
                    C_A_F_HASRUN = true;

                    //Initialises Braking Component
                    foreach (var item in CAFTHI)
                    {
                        CAF2_BRAKING_COUNT = (item.PositiveMaxForce < CAF2_BRAKING_COUNT) ? item.PositiveMaxForce : CAF2_BRAKING_COUNT;
                        CAF2_BRAKING_COUNT = (item.NegativeMaxForce < CAF2_BRAKING_COUNT) ? item.PositiveMaxForce : CAF2_BRAKING_COUNT;
                    }
                }
                //Generating Maths To Point and decelleration information etc.
                //--------------------------------------------------------------------
                double   SHIPMASS     = Convert.ToDouble(RC.CalculateShipMass().PhysicalMass);
                Vector3D INPUT_VECTOR = Vector3D.Normalize(INPUT_POINT - REFPOS);
                double   VELOCITY     = RC.GetShipSpeed();

                CAF_DIST_TO_TARGET     = (REFPOS - INPUT_POINT).Length();
                CAF_SHIP_DECELLERATION = 0.75 * (CAF2_BRAKING_COUNT / SHIPMASS);
                CAF_STOPPING_DIST      = (((VELOCITY * VELOCITY) - (INPUT_VELOCITY * INPUT_VELOCITY))) / (2 * CAF_SHIP_DECELLERATION);

                //If Within Stopping Distance Halts Programme
                //--------------------------------------------
                if (!(CAF_DIST_TO_TARGET > (CAF_STOPPING_DIST + 0.25)) || CAF_DIST_TO_TARGET < 0.25 || VELOCITY > INPUT_MAX_VELOCITY)
                {
                    foreach (var thruster in CAF2_THRUST)
                    {
                        (thruster as IMyThrust).ThrustOverride = 0;
                    }
                    return;
                }
                //dev notes, this is the most major source of discontinuity between theorised system response

                //Reflects Vector To Cancel Orbiting
                //------------------------------------
                Vector3D DRIFT_VECTOR   = Vector3D.Normalize(RC.GetShipVelocities().LinearVelocity + RC.WorldMatrix.Forward * 0.00001);
                Vector3D R_DRIFT_VECTOR = -1 * Vector3D.Normalize(Vector3D.Reflect(DRIFT_VECTOR, INPUT_VECTOR));

                R_DRIFT_VECTOR = ((Vector3D.Dot(R_DRIFT_VECTOR, INPUT_VECTOR) < -0.3)) ? 0 * R_DRIFT_VECTOR : R_DRIFT_VECTOR;
                INPUT_VECTOR   = Vector3D.Normalize((4 * R_DRIFT_VECTOR) + INPUT_VECTOR);

                //Components Of Input Vector In FUR Axis
                //----------------------------------------
                double F_COMP_IN = Vector_Projection(INPUT_VECTOR, RC.WorldMatrix.Forward);
                double U_COMP_IN = Vector_Projection(INPUT_VECTOR, RC.WorldMatrix.Up);
                double R_COMP_IN = Vector_Projection(INPUT_VECTOR, RC.WorldMatrix.Right);

                //Calculate MAX Allowable in Each Axis & Length
                //-----------------------------------------------
                double F_COMP_MAX = (F_COMP_IN > 0) ? CAF2_FORWARD.PositiveMaxForce : -1 * CAF2_FORWARD.NegativeMaxForce;
                double U_COMP_MAX = (U_COMP_IN > 0) ? CAF2_UP.PositiveMaxForce : -1 * CAF2_UP.NegativeMaxForce;
                double R_COMP_MAX = (R_COMP_IN > 0) ? CAF2_RIGHT.PositiveMaxForce : -1 * CAF2_RIGHT.NegativeMaxForce;
                double MAX_FORCE  = Math.Sqrt(F_COMP_MAX * F_COMP_MAX + U_COMP_MAX * U_COMP_MAX + R_COMP_MAX * R_COMP_MAX);

                //Apply Length to Input Components and Calculates Smallest Multiplier
                //--------------------------------------------------------------------
                double F_COMP_PROJ = F_COMP_IN * MAX_FORCE;
                double U_COMP_PROJ = U_COMP_IN * MAX_FORCE;
                double R_COMP_PROJ = R_COMP_IN * MAX_FORCE;
                double MULTIPLIER  = 1;

                MULTIPLIER = (F_COMP_MAX / F_COMP_PROJ < MULTIPLIER) ? F_COMP_MAX / F_COMP_PROJ : MULTIPLIER;
                MULTIPLIER = (U_COMP_MAX / U_COMP_PROJ < MULTIPLIER) ? U_COMP_MAX / U_COMP_PROJ : MULTIPLIER;
                MULTIPLIER = (R_COMP_MAX / R_COMP_PROJ < MULTIPLIER) ? R_COMP_MAX / R_COMP_PROJ : MULTIPLIER;

                //Calculate Multiplied Components
                //---------------------------------
                CAF2_FORWARD.VCF = ((F_COMP_PROJ * MULTIPLIER) / F_COMP_MAX) * Math.Sign(F_COMP_MAX);
                CAF2_UP.VCF      = ((U_COMP_PROJ * MULTIPLIER) / U_COMP_MAX) * Math.Sign(U_COMP_MAX);
                CAF2_RIGHT.VCF   = ((R_COMP_PROJ * MULTIPLIER) / R_COMP_MAX) * Math.Sign(R_COMP_MAX);

                //Runs System Thrust Application
                //----------------------------------
                Dictionary <IMyThrust, float> THRUSTVALUES = new Dictionary <IMyThrust, float>();

                foreach (var thruster in CAF2_THRUST)
                {
                    THRUSTVALUES.Add((thruster as IMyThrust), 0f);
                }

                foreach (var THRUSTSYSTM in CAFTHI)
                {
                    List <IMyThrust> POSTHRUST = THRUSTSYSTM.PositiveThrusters;
                    List <IMyThrust> NEGTHRUST = THRUSTSYSTM.NegativeThrusters;
                    if (THRUSTSYSTM.VCF < 0)
                    {
                        POSTHRUST = THRUSTSYSTM.NegativeThrusters; NEGTHRUST = THRUSTSYSTM.PositiveThrusters;
                    }
                    foreach (var thruster in POSTHRUST)
                    {
                        THRUSTVALUES[thruster as IMyThrust] = (float)(Math.Abs(THRUSTSYSTM.VCF)) * (thruster as IMyThrust).MaxThrust;
                    }
                    foreach (var thruster in NEGTHRUST)
                    {
                        THRUSTVALUES[thruster as IMyThrust] = 1;
                    }                                                                               //(float)0.01001;}
                    foreach (var thruster in THRUSTVALUES)
                    {
                        thruster.Key.ThrustOverride = thruster.Value;
                    }                                                                                        //thruster.Key.ThrustOverride = thruster.Value;
                }
            }
示例#9
0
        public void Main(string argument, UpdateType updateType)
        {
            Vector3D homebase         = new Vector3D(coord[0], coord[1], coord[2]);
            Vector3D homebasevelocity = new Vector3D(velocityout[0], velocityout[1], velocityout[2]);
            MatrixD  m = brain.WorldMatrix;
            Matrix   test;



            switch (argument.ToLower())
            {
            case "auto":
                brain.SetAutoPilotEnabled(true);
                brain.SetCollisionAvoidance(true);
                brain.DampenersOverride = true;
                Echo("Auto Pilot Enabled.");
                break;

            case "stop":
                brain.SetAutoPilotEnabled(false);
                brain.SetCollisionAvoidance(false);
                brain.DampenersOverride = false;
                Echo("Auto Pilot Disabled.");
                break;
            }



            info.WritePublicText("");
            info.WritePublicText(brain.CalculateShipMass().TotalMass.ToString() + " : Mass \n", true);

            //calculate manhattan distance
            int dist = (int)Math.Ceiling(Math.Abs(homebase.X - brain.GetPosition().X) + Math.Abs(homebase.Y - brain.GetPosition().Y) + Math.Abs(homebase.Z - brain.GetPosition().Z));

            info.WritePublicText(dist.ToString() + " :Distance \n", true);
            //debugging to an lcd screen - used as a visual aid
            info.WritePublicText(m.Forward.X.ToString(), true);

            //found out how to use and turn gyro
            //if (dist < 20 && m.Forward.X < 0.1)
            //{
            //    gyro.SetValueFloat("Yaw", 2);
            //    gyro.GetActionWithName("Override").Apply(gyro);
            //}

            //check for new homebase coords
            if (listeners[0].HasPendingMessage)
            {
                packet = listeners[0].AcceptMessage();
                string messagetext = packet.Data.ToString();
                sentcord = messagetext;
            }

            //check for new homebase velocity
            if (listeners[1].HasPendingMessage)
            {
                packet = listeners[1].AcceptMessage();
                string messagetext1 = packet.Data.ToString();
                sentvelocity = messagetext1;
            }
            string[] coords = sentcord.Split(' ');
            if (coords[0] != "")
            {
                coord[0] = double.Parse(coords[0].Remove(0, 2));
                coord[1] = double.Parse(coords[1].Remove(0, 2));
                coord[2] = double.Parse(coords[2].Remove(0, 2));
            }

            string[] velocity = sentvelocity.Split(' ');
            if (velocity[0] != "")
            {
                velocityout[0] = double.Parse(velocity[0].Remove(0, 2));
                velocityout[1] = double.Parse(velocity[1].Remove(0, 2));
                velocityout[2] = double.Parse(velocity[2].Remove(0, 2));
            }
            GetPredictedTargetPosition(homebase, homebasevelocity);

            //add new thrusters to list
            for (int i = 0; i < term.Count; i++)
            {
                onGridThrust.Add((IMyThrust)term[i]);
            }
        }
示例#10
0
        public Program()
        {
            Runtime.UpdateFrequency = UpdateFrequency.Update10 | UpdateFrequency.Update100;
            ini.TryParse(Storage);

            antenna   = GridTerminalSystem.GetBlockWithName("Antenna Miner#1") as IMyRadioAntenna;
            rc        = GridTerminalSystem.GetBlockWithName("rc") as IMyRemoteControl;
            gyro      = GridTerminalSystem.GetBlockWithName("Gyroscope") as IMyGyro;
            connector = GridTerminalSystem.GetBlockWithName("Connector") as IMyShipConnector;
            connector.PullStrength = float.PositiveInfinity;

            if (connector.Status == MyShipConnectorStatus.Connected)
            {
                goodsetup = false;
            }

            shipMass = rc.CalculateShipMass().TotalMass;

            if (connector.Orientation.Forward == rc.Orientation.Forward)
            {
                rcDockingDir = Base6Directions.Direction.Forward;
            }
            else if (connector.Orientation.Forward == Base6Directions.GetFlippedDirection(rc.Orientation.Forward))
            {
                rcDockingDir = Base6Directions.Direction.Backward;
            }
            else if (connector.Orientation.Forward == rc.Orientation.Left)
            {
                rcDockingDir = Base6Directions.Direction.Left;
            }
            else if (connector.Orientation.Forward == Base6Directions.GetFlippedDirection(rc.Orientation.Left))
            {
                rcDockingDir = Base6Directions.Direction.Right;
            }
            else if (connector.Orientation.Forward == rc.Orientation.Up)
            {
                rcDockingDir = Base6Directions.Direction.Up;
            }
            else if (connector.Orientation.Forward == Base6Directions.GetFlippedDirection(rc.Orientation.Up))
            {
                rcDockingDir = Base6Directions.Direction.Down;
            }
            else
            {
                Echo("ERROR: ORIENTATION MATCHING FAILED");
            }

            BoundingBoxD boundingBox = rc.CubeGrid.WorldAABB;

            lengthOfShip = Vector3D.Distance(boundingBox.Max, boundingBox.Min);


            gyros = new List <IMyGyro>();
            GridTerminalSystem.GetBlocksOfType(gyros);

            foreach (IMyGyro gyro in gyros)
            {
                gyro.Pitch        = 0;
                gyro.Yaw          = 0;
                gyro.GyroOverride = false;
                gyro.ApplyAction("OnOff_On");
            }

            if (ini.ContainsKey("save", "password"))
            {
                password = ini.Get("save", "password").ToString();
            }
            else if (customPasswordMode)
            {
                password = customPassword;
            }
            else
            {
                Random r = new Random();
                password = r.Next(1000000, 9999999) + "";
            }

            allThrusters = new List <IMyThrust>();
            GridTerminalSystem.GetBlocksOfType(allThrusters);

            allThrustGroups.Add(leftThrusterGroup);
            allThrustGroups.Add(rightThrusterGroup);
            allThrustGroups.Add(upThrusterGroup);
            allThrustGroups.Add(downThrusterGroup);
            allThrustGroups.Add(backThrusterGroup);

            foreach (IMyThrust thruster in allThrusters)
            {
                if (thruster.Orientation.Forward == Base6Directions.GetFlippedDirection(connector.Orientation.Up))
                {
                    downThrusterGroup.Add(thruster);
                }
                else if (thruster.Orientation.Forward == connector.Orientation.Up)
                {
                    upThrusterGroup.Add(thruster);
                }
                else if (thruster.Orientation.Forward == connector.Orientation.Left)
                {
                    leftThrusterGroup.Add(thruster);
                }
                else if (thruster.Orientation.Forward == Base6Directions.GetFlippedDirection(connector.Orientation.Left))
                {
                    rightThrusterGroup.Add(thruster);
                }
                else if (thruster.Orientation.Forward == Base6Directions.GetFlippedDirection(connector.Orientation.Forward))
                {
                    backThrusterGroup.Add(thruster);
                    totalBackForce += thruster.MaxEffectiveThrust;
                }
            }

            if (ini.ContainsKey("save", "linkedConnectorName"))
            {
                linkedConnectorName = ini.Get("save", "linkedConnectorName").ToString();
            }
            if (ini.ContainsKey("save", "groupName"))
            {
                linkedConnectorName = ini.Get("save", "groupName").ToString();
            }
            if (ini.ContainsKey("save", "dockingConnectorPos"))
            {
                Vector3D.TryParse(ini.Get("save", "dockingConnectorPos").ToString(), out dockingConnectorPos);
            }
            if (ini.ContainsKey("save", "dockingDir"))
            {
                Vector3D.TryParse(ini.Get("save", "dockingDir").ToString(), out dockingDir);
            }

            if (ini.ContainsKey("save", "mode"))
            {
                Int32.TryParse(ini.Get("save", "mode").ToString(), out mode);
            }
            var            k = 0;
            MyWaypointInfo element;

            globalPath.Clear();
            while (ini.ContainsKey("save", "globalPath_" + k))
            {
                MyWaypointInfo.TryParse(ini.Get("save", "globalPath_" + k).ToString(), out element);
                globalPath.Add(element);
                k++;
            }

            reversePath.Clear();
            reversePath = globalPath;
            reversePath.Reverse();
        }
示例#11
0
        public void Main(string argument, UpdateType updateSource)
        {
            if (goodsetup)
            {
                Echo("LastR: " + lastReversePath);
                Echo("Mode: " + mode);
                Echo("DockingDir: " + rcDockingDir.ToString());
                Echo("Password: "******"Argument: " + argument);
                    string[] info = argument.Split(new string[] { "," }, StringSplitOptions.None);

                    if (updateSource != UpdateType.Antenna)
                    {
                        if (info[0].ToLower() == "dock")
                        {
                            if (info.Length == 1)
                            {
                                Boolean sent = antenna.TransmitMessage("requestdock," + password + ",default");
                                if (!sent)
                                {
                                    messageQue.Add("requestdock," + password + ",default");
                                }
                            }
                            else if (info.Length == 2)
                            {
                                Boolean sent = antenna.TransmitMessage("requestdock," + password + "," + info[1]);
                                if (!sent)
                                {
                                    messageQue.Add("requestdock," + password + "," + info[1]);
                                }
                                groupName = info[1];
                            }
                            else if (info.Length == 3)
                            {
                                Boolean sent = antenna.TransmitMessage("requestdock," + password + "," + groupName + "," + info[2]);
                                if (!sent)
                                {
                                    messageQue.Add("requestdock," + password + "," + groupName + "," + info[2]);
                                }
                            }
                            else
                            {
                                Echo("ERROR, ARGUMENT SIZE INVALID");
                            }
                        }
                        else if (info[0].ToLower() == "stop")
                        {
                            Storage             = "";
                            dockingConnectorPos = new Vector3D();
                            dockingDir          = new Vector3D();
                            mode = 0;
                            globalPath.Clear();
                            reversePath.Clear();
                            rc.ClearWaypoints();

                            foreach (IMyThrust thrust in allThrusters)
                            {
                                thrust.ThrustOverridePercentage = 0;
                            }

                            foreach (IMyGyro gyro in gyros)
                            {
                                gyro.GyroOverride = false;
                                gyro.Pitch        = 0;
                                gyro.Yaw          = 0;
                                gyro.Roll         = 0;
                            }

                            Boolean sent = antenna.TransmitMessage("canceldock," + password);
                            if (!sent)
                            {
                                messageQue.Add("canceldock," + password);
                            }
                        }

                        else if (info[0] == "depart")
                        {
                            if (mode == 5 && connector.Status == MyShipConnectorStatus.Connected)
                            {
                                Main("dock," + groupName + ",leaving", UpdateType.Mod);
                            }
                            else
                            {
                                Echo("ERROR, WRONG MODE OR ALREADY DISCONNECTED");
                            }
                        }

                        else if (info[0].ToLower() == "newpassword")
                        {
                            Random r = new Random();
                            password = r.Next(1000000, 9999999) + "";
                        }
                    }

                    else if (updateSource == UpdateType.Antenna && info[0] == password)
                    {
                        Echo("Message Received: " + argument);
                        if (info[1] == "received" && info.Length == 3) //info[2] is name of spaceport
                        {
                            Echo("Request to '" + info[2] + "' was received, awaiting further instruction.");
                        }
                        else if (info[1] == "fail")
                        {
                            Echo("Request to '" + info[3] + "' failed.");
                        }
                        else if (info[1] == "rejected")
                        {
                            Echo("TOOK TO LONG, DOCKING PERMISSION REJECTED");
                            mode = 0;
                            rc.SetAutoPilotEnabled(false);
                            antenna.CustomName += " ERROR";
                        }
                        else if (info[1] == "wait")
                        {
                            Echo("Request to '" + info[3] + "' success, but placed into waiting que");
                            waiting = true;
                        }
                        else if (info[1] == "dockinginfo")
                        {
                            if (mode == 5)
                            {
                                connector.Disconnect();
                                List <MyWaypointInfo> path = new List <MyWaypointInfo>();
                                string[] strWaypoints      = new string[info.Length - 5];

                                for (int i = 0; i < strWaypoints.Length; i++)
                                {
                                    strWaypoints[i] = info[i + 5];
                                }

                                foreach (string waypoint in strWaypoints)
                                {
                                    MyWaypointInfo newPoint;
                                    Boolean        pass = MyWaypointInfo.TryParse(waypoint, out newPoint);
                                    if (pass)
                                    {
                                        path.Add(newPoint);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                path.Reverse();
                                reversePath = path;
                                EnableRC(reversePath, out path);
                                mode = 6;
                            }
                            else if (info.Length == 5)
                            {
                                linkedConnectorName = info[2];
                                string strConnectorPos = info[3];
                                string strDockingDir   = info[4];

                                //parse str's into their proper values
                                Boolean pass1 = Vector3D.TryParse(strConnectorPos, out dockingConnectorPos);
                                Boolean pass2 = Vector3D.TryParse(strDockingDir, out dockingDir);

                                Dock2(dockingConnectorPos, dockingDir); mode = 2;
                            }
                            else if (info.Length > 5)
                            {
                                linkedConnectorName = info[2];
                                string   strConnectorPos = info[3];
                                string   strDockingDir   = info[4];
                                string[] strWaypoints    = new string[info.Length - 5];
                                for (int i = 0; i < strWaypoints.Length; i++)
                                {
                                    strWaypoints[i] = info[i + 5];
                                }

                                //parse str's into their proper values
                                Boolean pass1 = Vector3D.TryParse(strConnectorPos, out dockingConnectorPos);
                                Boolean pass2 = Vector3D.TryParse(strDockingDir, out dockingDir);
                                pass2 = false;

                                List <MyWaypointInfo> path = new List <MyWaypointInfo>();
                                Boolean pass3 = true;
                                foreach (string waypoint in strWaypoints)
                                {
                                    pass2 = true;
                                    MyWaypointInfo newPoint;
                                    pass3 = MyWaypointInfo.TryParse(waypoint, out newPoint);
                                    if (pass3)
                                    {
                                        path.Add(newPoint);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                if (pass1 && pass2 && pass3)
                                {
                                    EnableRC(path, out globalPath);
                                    reversePath.Reverse();
                                    mode = 1;
                                }
                                else
                                {
                                    Echo(pass1 + " " + pass2 + " " + pass3);
                                }
                            }
                        }
                    }
                    else if (info[0] == "antennapos" && info.Length == 2)
                    {
                        Boolean updated = Vector3D.TryParse(info[1], out antennaPos);
                        if (updated)
                        {
                            antenna.Radius = (float)(Vector3D.Distance(rc.GetPosition(), antennaPos) + 10);
                        }
                        else
                        {
                            Echo("Failed to update antenna position");
                        }
                    }
                    else if (mode == 2 && !rc.IsAutoPilotEnabled && Vector3D.Distance(rc.GetPosition(), rc.CurrentWaypoint.Coords) >= 5)
                    {
                        rc.SetAutoPilotEnabled(true);
                    }
                    else if (mode == 1 && globalPath.Count != 0)
                    {
                        FollowPath(globalPath, true);
                    }
                }
                else if (mode == 1)
                {
                    FollowPath(globalPath, true);
                }
                else if (mode == 2 && rc.IsAutoPilotEnabled && Vector3D.Distance(rc.GetPosition(), rc.CurrentWaypoint.Coords) < 5)
                {
                    Dock3();
                    Boolean sent = antenna.TransmitMessage("freepath," + groupName);
                    if (!sent)
                    {
                        messageQue.Add("freepath," + groupName);
                    }
                }
                else if (mode == 2 && !rc.IsAutoPilotEnabled && Vector3D.Distance(rc.GetPosition(), rc.CurrentWaypoint.Coords) >= 5)
                {
                    rc.SetAutoPilotEnabled(true);
                }
                else if (mode == 3 && Dock3())
                {
                    Echo("DOCKED!");
                }
                else if (mode == 6)
                {
                    FollowPath(reversePath, false);
                }
                else if (updateSource == UpdateType.Update100)
                {
                    shipMass = rc.CalculateShipMass().TotalMass;
                }

                if (waiting)
                {
                    Echo("Waiting for clearance");
                }
            }
            else
            {
                Echo("SETUP FAILED. DO NOT SETUP WHILE CONNECTED TO ANOTHER GRID");
            }
        }
示例#12
0
        public void Main(string argument)
        {
            switch (state)
            {
            case Mode.Idle:
                if (argument == "Wreck")
                {
                    state = Mode.Grinding;
                }
                if (argument == "Start")
                {
                    if (visor.AvailableScanRange >= 1000)
                    {
                        Echo("Search for target");
                        target = visor.Raycast(1000);
                    }
                }
                if (target.IsEmpty())
                {
                    Echo("Target not found");
                    return;
                }
                Echo("Target found!");
                Vector3D targetPos;
                if (target.HitPosition != null)
                {
                    targetPos = (Vector3D)target.HitPosition;
                    Vector3D targetVector = targetPos - control.GetPosition();
                    targetVector.Normalize();
                    targetPos = targetPos - 20 * targetVector;
                    control.ClearWaypoints();
                    control.AddWaypoint(targetPos, "Target");
                    control.GetActionWithName("CollisionAvoidance_On").Apply(control);
                    control.GetActionWithName("DockingMode_On").Apply(control);
                    //!!!Erst einstellungen, dann aktivieren!!!
                    control.GetActionWithName("AutoPilot_On").Apply(control);
                    state = Mode.Flying;
                }
                break;

            case Mode.Flying:
                break;

            case Mode.Grinding:
                List <string> activSensors = CheckSensors(mainGrinderSensors);
                Vector3D      instructions = CheckDirection(activSensors);
                instructions = CheckObstacles(instructions);
                float  massFactor   = control.CalculateShipMass().TotalMass / baseMass;
                double thrustFactor = Math.Pow(2, massFactor);
                foreach (IMyThrust thrust in allThruster)
                {
                    thrust.SetValueFloat("Override", 0);
                }
                SetGyros(0, 0, 0);
                Echo("Vector is: " + (int)instructions.X + " " + (int)instructions.Y + " " + (int)instructions.Z);
                if (activSensors.Count == 0 && CheckSensors(mainCollisionSensors).Count == 0)
                {
                    Echo("Going forward");
                    foreach (IMyThrust thrust in thruster[Side.Front])
                    {
                        thrust.SetValueFloat("Override", (float)(10 * thrustFactor));
                    }
                }
                else if (IsZero(instructions))
                {
                    Echo("Is zero");
                    foreach (IMyThrust thrust in thruster[Side.Back])
                    {
                        thrust.SetValueFloat("Override", (float)(5 * thrustFactor));
                    }
                }
                else
                {
                    Echo("Working");
                    int basethrust = 35;
                    if (instructions.Z == 0)
                    {
                        instructions.X = Math.Sign(instructions.X) * thrustFactor;
                        instructions.Y = Math.Sign(instructions.Y) * thrustFactor;
                        SetGyros((float)instructions.Y, (float)instructions.X, 0);
                        instructions.X = -instructions.X;
                        instructions.Y = -instructions.Y;
                        basethrust     = 5;
                    }
                    List <IMyThrust> neededThruster = instructions.X > 0 ? thruster[Side.Right] : thruster[Side.Left];
                    if (instructions.X != 0)
                    {
                        foreach (IMyThrust thrust in neededThruster)
                        {
                            thrust.SetValueFloat("Override", (float)(thrustFactor * basethrust));
                        }
                        foreach (IMyThrust thrust in thruster[Side.Front])
                        {
                            thrust.SetValueFloat("Override", (float)(5 * thrustFactor));
                        }
                    }
                    if (instructions.Y != 0)
                    {
                        neededThruster = instructions.Y > 0 ? thruster[Side.Up] : thruster[Side.Down];
                        foreach (IMyThrust thrust in neededThruster)
                        {
                            thrust.SetValueFloat("Override", (float)(thrustFactor * basethrust));
                        }
                        foreach (IMyThrust thrust in thruster[Side.Front])
                        {
                            thrust.SetValueFloat("Override", (float)(5 * thrustFactor));
                        }
                    }
                }
                break;
            }
        }
示例#13
0
    Vector3D _getApplyVal()
    {
        if (_checkOrInitRc())
        {
            return(zero);
        }
        Vector3D v       = targetVelocity;
        Vector3D gravity = _gravity();

        if (gravity.Length() == 0)
        {
            gravity = zero;
        }
        Vector3D velocity = _velocity();
        double   mass     = (double)rc.CalculateShipMass().BaseMass + (
            (rc.CalculateShipMass().TotalMass -
             // rc.CalculateShipMass().BaseMass) /10);
             rc.CalculateShipMass().BaseMass));

        Vector3D vn                   = Vector3D.Normalize(v);
        Vector3D accAlongVector       = tm.GetThrustAlongVector(vn);
        double   accAlongVectorLength = accAlongVector.Length();

        pg.Echo("accAlongVectorLength = \n" + accAlongVectorLength);

        Vector3D velocityProjection       = velocity * (velocity.Dot(vn) / velocity.Length());
        double   velocityProjectionLength = velocityProjection.Length();

        pg.Echo("velocityProjectionLength = \n" + velocityProjectionLength);

        double breakingTime = velocityProjectionLength / accAlongVectorLength;

        pg.Echo("breakingTime = \n" + breakingTime);
        double breakingDistance = 1.1 * breakingTime * velocityProjectionLength / 2;

        pg.Echo("breakingDistance = \n" + breakingDistance);

        if (v.Length() < breakingDistance)
        {
            // v = -v;
            v = vn * (velocityProjectionLength - accAlongVectorLength);
        }

        // if (tm.unobtainable (velocityProjection)) {
        //     vn = velocityProjection - velocity;
        // }

        // Vector3D correction = velocity+gravity;
        // double corrLen = 100-correction.Length();
        // double vLen = v.Length();
        // if (vLen > corrLen) {
        //     v *= (corrLen/vLen);
        // }
        Vector3D tv = Vector3D.TransformNormal(
            v - velocity - gravity,
            MatrixD.Transpose(pg.Me.CubeGrid.WorldMatrix)
            );

        refVelocity = v - velocity - gravity;
        return(tv * mass);
    }
示例#14
0
            } // Recalculate method

            public void SetThrust(IMyRemoteControl rc, int direction, float accel)
            {
                float power = 0; // thruster power level

                if ((direction & FORWARD) > 0)
                {
                    // calculate thrust percentage
                    //f=ma
                    //percent = (req force) / (total force)
                    if (accel == 0) // check if no acceleration
                    {
                        power = 0;
                    }              // set power to 0 (simplify calculations)
                    else
                    {
                        power  = rc.CalculateShipMass().TotalMass *accel / maxFwdThr;
                        power *= 99;
                        power += 1;
                        //power *= 100;
                    }


                    // set thrusters
                    PowerThruster(fwdThrList, power); // Set Thruster Power Level
                } // if FORWARD

                if ((direction & AFT) > 0)
                {
                    if (accel == 0) // check if no acceleration
                    {
                        power = 0;
                    }              // set power to 0 (simplify calculations)
                    else
                    {
                        power  = rc.CalculateShipMass().TotalMass *accel / maxFwdThr;
                        power *= 99;
                        power += 1;
                        //power *= 100;
                    }

                    PowerThruster(aftThrList, power); // Set Thruster Power Level
                } // if AFT

                if ((direction & STARBOARD) > 0)
                {
                    if (accel == 0) // check if no acceleration
                    {
                        power = 0;
                    }              // set power to 0 (simplify calculations)
                    else
                    {
                        power  = rc.CalculateShipMass().TotalMass *accel / maxFwdThr;
                        power *= 99;
                        power += 1;
                        //power *= 100;
                    }

                    PowerThruster(stbdThrList, power); // Set Thruster Power Level
                } // if STARBOARD

                if ((direction & PORT) > 0)
                {
                    if (accel == 0) // check if no acceleration
                    {
                        power = 0;
                    }              // set power to 0 (simplify calculations)
                    else
                    {
                        power  = rc.CalculateShipMass().TotalMass *accel / maxFwdThr;
                        power *= 99;
                        power += 1;
                        //power *= 100;
                    }

                    PowerThruster(portThrList, power); // Set Thruster Power Level
                } // if PORT

                if ((direction & VENTRAL) > 0)
                {
                    if (accel == 0) // check if no acceleration
                    {
                        power = 0;
                    }              // set power to 0 (simplify calculations)
                    else
                    {
                        power  = rc.CalculateShipMass().TotalMass *accel / maxFwdThr;
                        power *= 99;
                        power += 1;
                        //power *= 100;
                    }

                    PowerThruster(ventThrList, power); // Set Thruster Power Level
                } // if VENTRAL

                if ((direction & DORSAL) > 0)
                {
                    if (accel == 0) // check if no acceleration
                    {
                        power = 0;
                    }              // set power to 0 (simplify calculations)
                    else
                    {
                        power  = rc.CalculateShipMass().TotalMass *accel / maxFwdThr;
                        power *= 99;
                        power += 1;
                        //power *= 100;
                    }

                    PowerThruster(dorsThrList, power); // Set Thruster Power Level
                } // if DORSAL
            } // SetThrust method
示例#15
0
            public void Update(MyDetectedEntityInfo target, Vector3D T, Vector3D PointerPos, Vector3D PointerDir)
            {
                if (!Launched)
                {
                    foreach (IMyThrust thr in thrusters)
                    {
                        thr.Enabled = true;
                        thr.ThrustOverridePercentage = 1;
                    }
                    Launched = true;
                }
                else
                {
                    counter++;
                    if (remcon.IsFunctional && (counter > VerticalDelay))
                    {
                        double   currentVelocity = remcon.GetShipVelocities().LinearVelocity.Length();
                        Vector3D targetvector    = new Vector3D();
                        if (LASER_GUIDED)
                        {
                            targetvector = ((remcon.GetPosition() - PointerPos).Dot(PointerDir) + 700) * PointerDir + PointerPos - remcon.GetPosition();
                        }
                        else
                        {
                            targetvector = FindInterceptVector(remcon.GetPosition(),
                                                               currentVelocity * INTERCEPT_COURSE,
                                                               T,
                                                               target.Velocity);
                        }

                        Vector3D trgNorm = Vector3D.Normalize(targetvector);

                        if ((target.Position - remcon.GetPosition()).Length() < WH_ARM_DIST)
                        {
                            if (currentVelocity - MyVelocity < -ACCEL_DET)
                            {
                                foreach (IMyWarhead wh in warheads)
                                {
                                    wh.Detonate();
                                }
                            }

                            MyVelocity = currentVelocity;
                        }

                        Vector3D velNorm          = Vector3D.Normalize(remcon.GetShipVelocities().LinearVelocity);
                        Vector3D CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm;
                        Vector3D G = remcon.GetNaturalGravity();

                        if (G.LengthSquared() == 0)
                        {
                            CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm;
                        }
                        else
                        {
                            if (JAVELIN)
                            {
                                //trgNorm = Vector3D.Normalize(Vector3D.Reflect(-G, trgNorm));
                                trgNorm = Vector3D.Normalize(G.Dot(trgNorm) * trgNorm * JAVELIN_CURVE - G);
                            }
                            CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm;
                            double A = 0;
                            foreach (IMyThrust thr in thrusters)
                            {
                                A += thr.MaxEffectiveThrust;
                            }
                            A /= remcon.CalculateShipMass().PhysicalMass;

                            Vector3D CorrectionNorm = Vector3D.Normalize(CorrectionVector);
                            //CorrectionVector = CorrectionNorm * A - G;
                            Vector3D gr = Vector3D.Reject(remcon.GetNaturalGravity(), CorrectionNorm);
                            CorrectionVector = CorrectionNorm * Math.Sqrt(A * A + gr.LengthSquared()) - gr;
                        }


                        Vector3D Axis = Vector3D.Normalize(CorrectionVector).Cross(remcon.WorldMatrix.Forward);
                        if (Axis.LengthSquared() < 0.1)
                        {
                            Axis += remcon.WorldMatrix.Backward * ROLL;
                        }
                        Axis *= GyroMult;
                        foreach (IMyGyro gyro in gyros)
                        {
                            gyro.Pitch = (float)Axis.Dot(gyro.WorldMatrix.Right);
                            gyro.Yaw   = (float)Axis.Dot(gyro.WorldMatrix.Up);
                            gyro.Roll  = (float)Axis.Dot(gyro.WorldMatrix.Backward);
                        }
                    }
                    else
                    {
                        foreach (IMyGyro gyro in gyros)
                        {
                            gyro.Pitch = 0;
                            gyro.Yaw   = 0;
                            gyro.Roll  = 0;
                        }
                    }
                }
            }
        public void Main(string argument, UpdateType updateSource)
        {
            string[] argInfo = argument.Split(new string[] { "," }, StringSplitOptions.None);
            if (argument == "RUN")
            {
                //Check if can scan, and scan if can.
                if (cam.CanScan(rayCastDistance))
                {
                    detectedInfo = cam.Raycast(rayCastDistance);
                }
                else
                {
                    Echo("Can't scan yet!");
                }

                Echo("INITIATING");

                coordinate = Vector3D.Zero; //initating to zero value.

                Boolean found = false;
                if (detectedInfo.HitPosition != null)
                {
                    coordinate = detectedInfo.HitPosition.Value;
                    found      = true;
                }

                if (found)
                {
                    Vector3D currentCoords = rc.GetPosition();

                    //creating unit vector
                    double denominator = Math.Sqrt(Math.Pow(coordinate.X - currentCoords.X, 2)
                                                   + Math.Pow(coordinate.Y - currentCoords.Y, 2)
                                                   + Math.Pow(coordinate.Z - currentCoords.Z, 2));
                    double xMultiplier = (coordinate.X - currentCoords.X) / denominator;
                    double yMultiplier = (coordinate.Y - currentCoords.Y) / denominator;
                    double zMultiplier = (coordinate.Z - currentCoords.Z) / denominator;

                    //manipulating target coordinate with unit vector
                    coordinate.X -= finalDistFromTarget * xMultiplier;
                    coordinate.Y -= finalDistFromTarget * yMultiplier;
                    coordinate.Z -= finalDistFromTarget * zMultiplier;

                    //Setting up backward thrusters list
                    backwardThrusters = new List <IMyThrust>();

                    //Obtaining each thruster pointing backward
                    foreach (IMyThrust thruster in thrusters)
                    {
                        if (Base6Directions.GetFlippedDirection(rc.Orientation.Forward) == Base6Directions.GetFlippedDirection(thruster.Orientation.Forward))
                        {
                            backwardThrusters.Add(thruster);
                        }
                    }

                    //Obtaining max backward acceleration
                    MyShipMass myShipMass = rc.CalculateShipMass();
                    backwardsAcceleration = CalculateAcceleration(myShipMass.TotalMass, backwardThrusters);

                    //autopilot settings
                    rc.ClearWaypoints();
                    rc.AddWaypoint(coordinate, "AUTO DYNAMIC BRAKING SCRIPT COORDINATE");
                    rc.SetAutoPilotEnabled(true);
                    rc.SetCollisionAvoidance(false);
                    rc.SetDockingMode(false); //CHANGE??? or dont?
                    rc.FlightMode = FlightMode.OneWay;
                    rc.Direction  = Base6Directions.Direction.Forward;
                    blindMode     = false;
                }
            }
            else if (argInfo[0] == "blind".ToLower())
            {
                int     dist   = 0;
                Boolean passed = Int32.TryParse(argInfo[1], out dist);

                if (passed)
                {
                    Vector3D dir = rc.WorldMatrix.Forward;
                    coordinate    = rc.GetPosition();
                    coordinate.X += dir.X * dist;
                    coordinate.Y += dir.Y * dist;
                    coordinate.Z += dir.Z * dist;

                    Vector3D currentCoords = rc.GetPosition();

                    //Setting up backward thrusters list
                    backwardThrusters = new List <IMyThrust>();

                    //Obtaining each thruster pointing backward
                    foreach (IMyThrust thruster in thrusters)
                    {
                        if (Base6Directions.GetFlippedDirection(rc.Orientation.Forward) == Base6Directions.GetFlippedDirection(thruster.Orientation.Forward))
                        {
                            backwardThrusters.Add(thruster);
                        }
                    }

                    //Obtaining max backward acceleration
                    MyShipMass myShipMass = rc.CalculateShipMass();
                    backwardsAcceleration = CalculateAcceleration(myShipMass.TotalMass, backwardThrusters);

                    //autopilot settings
                    rc.ClearWaypoints();
                    rc.AddWaypoint(coordinate, "CAPTXAN'S SCRIPT COORDINATE");
                    rc.SetAutoPilotEnabled(true);
                    rc.SetCollisionAvoidance(false);
                    rc.SetDockingMode(false); //CHANGE??? or dont?
                    rc.FlightMode = FlightMode.OneWay;
                    rc.Direction  = Base6Directions.Direction.Forward;
                    blindMode     = true;
                    blindCounter  = 0;
                }
                else
                {
                    Echo("2nd parameter is not a number!");
                }
            }
            else
            {
                //User Feedback
                if (!cam.CanScan(rayCastDistance))
                {
                    float percentage = ((cam.TimeUntilScan(rayCastDistance) / 1000) / (rayCastDistance / 2000));
                    percentage = (1 - percentage) * 100;
                    Echo("Raycast is recharging " + percentage + "%");
                    if (!cam.EnableRaycast)
                    {
                        cam.EnableRaycast = true;
                    }
                }
                else
                {
                    Echo("Ready to Scan");
                    cam.EnableRaycast = false;
                }

                //Travelling CHANGE HERE FOR ENABLE / DISABLE AUTOPILOT
                if (rc.IsAutoPilotEnabled)
                {
                    travelling = true;
                    double currentDistanceFromTarget = Vector3D.Distance(coordinate, rc.GetPosition());
                    Echo("Travelling, ETA: " + (int)(currentDistanceFromTarget / rc.GetShipSpeed()) + "s");

                    //Calculating stopping distance to determine if thrusters need to be enabled.
                    Echo("Current Speed: " + (int)rc.GetShipSpeed() + "m/s");
                    Echo("Ship Speed Limit: " + rc.SpeedLimit + "m/s");
                    if (rc.GetShipSpeed() > rc.SpeedLimit - 1) //If ship at max speed
                    {
                        Vector3D currentTrajectory = Vector3D.Normalize(rc.GetPosition() - prevPosition);
                        prevPosition = rc.GetPosition();
                        Vector3D calculatedTrajectory = Vector3D.Normalize(rc.GetPosition() - coordinate);

                        double accuracyAmount;
                        if (currentDistanceFromTarget > 15000)
                        {
                            accuracyAmount = .99999;
                        }
                        else if (currentDistanceFromTarget > 5000)
                        {
                            accuracyAmount = .9999;
                        }
                        else
                        {
                            accuracyAmount = .999;
                        }

                        if (currentDistanceFromTarget * .90 > (Math.Pow(rc.GetShipSpeed(), 2) / (2 * backwardsAcceleration)) &&
                            Math.Abs(currentTrajectory.Dot(calculatedTrajectory)) > accuracyAmount)
                        {
                            foreach (IMyThrust thruster in thrusters)
                            {
                                thruster.ApplyAction("OnOff_Off");
                            }
                        }
                        else //Curr < stopp
                        {
                            foreach (IMyThrust thruster in thrusters)
                            {
                                thruster.ApplyAction("OnOff_On");
                            }
                        }
                    }

                    Echo("Blind Mode: " + blindMode);

                    if (blindMode)
                    {
                        Echo("Blind Counter: " + blindCounter);
                        Echo("Coll Avoid: " + rc.);
                        if (cam.CanScan(((Math.Pow(rc.GetShipSpeed(), 2) / (2 * backwardsAcceleration)) * 2)))
                        {
                            detectedInfo = cam.Raycast((Math.Pow(maxSpeed, 2) / (2 * backwardsAcceleration)) * 2);
                            if (detectedInfo.HitPosition != null)
                            {
                                rc.SpeedLimit = 3;
                                rc.SetCollisionAvoidance(true);
                                blindCounter = 0;
                            }
                            else
                            {
                                if (blindCounter > 500)
                                {
                                    rc.SpeedLimit = maxSpeed;
                                    rc.SetCollisionAvoidance(false);
                                    blindCounter = 0;
                                }
                                else
                                {
                                    blindCounter++;
                                }
                            }
                        }
                    }
                }
                else if (travelling)
                {
                    foreach (IMyThrust thruster in thrusters)
                    {
                        thruster.ApplyAction("OnOff_On");
                    }
                    travelling = false;
                    blindMode  = false;
                }
            }
            //Additional Arugment Commands
            if (argument == "ABORT")
            {
                rc.SetAutoPilotEnabled(false);
                rc.DampenersOverride = true;
            }
        }
        public void Main(string argument, UpdateType updateSource)//main is called once per pysics update, ideally 60Hz
        {
            if (argument.ToLower() == "reset")
            {
                stage = 0;
            }
            bool valid = controller.TryGetPlanetElevation(MyPlanetElevation.Surface, out currentAltitude);

            var parts = Storage.Split(';');

            stage = int.Parse(parts[0]);

            maxTotalEffectiveThrust = 0.0f;//have to recalculate every time because it increases with alt
            foreach (var thruster in thrusters)
            {
                maxTotalEffectiveThrust += thruster.MaxEffectiveThrust;
            }
            physicalMass          = controller.CalculateShipMass().PhysicalMass;
            currentNaturalGravity = controller.GetNaturalGravity();   //
            double gravityMagnitude = currentNaturalGravity.Length(); //what a weird thing to call magnitude of a vector

            Echo($"STAGE: {stage}\nSPEED: {controller.GetShipVelocities().LinearVelocity.Length()}\nALT: {currentAltitude}");
            antenna.HudText = stage.ToString();

            if (stage == 0)
            {
                if (Freefall()) //if we are in freefall. Freefall is defined as accelerating at a rate ~= gravity, this implies thrusters are not acive. Also should check if it's heading towards or away from the gravity well. Linear alg time yay
                {
                    foreach (var thruster in thrusters)
                    {
                        thruster.ThrustOverride = 0;
                    }
                    stage++;
                    Storage = stage + ";";
                }
            }

            else if (stage == 1)
            {
                if (!Freefall())
                {
                    stage = 0;
                }
                double a = maxTotalEffectiveThrust / physicalMass - currentNaturalGravity.Length(); //acceleration with full retro burn
                double b = -controller.GetShipVelocities().LinearVelocity.Length();                 //velocity
                double c = currentAltitude;
                double thrustStopTime = -b / (2 * a);                                               //y=ax^2+bx ->  dy = 2ax+b | 0 = 2*a*x+b -> -b/2a=x

                Func <double, double> altitudeFunc = delegate(double x) {                           //x=time, y=altitude assuming full retro thrust
                    return(a * x * x + b * x + c);
                };

                double minHeight = altitudeFunc(thrustStopTime);                  //the lowest point of the trajectory IF thrust is engaged instantly
                double calculatedStoppingDistance = currentAltitude - minHeight;
                double safetyBuffer           = Math.Abs(b) * 1.25 + craftHeight; //a coefficient in front of the safety buffer feels wrong
                double safetyStoppingDistance = calculatedStoppingDistance + safetyBuffer;

                if (!controller.DampenersOverride && currentAltitude <= safetyStoppingDistance)
                {
                    stage++;
                    Storage = stage + ";";
                    controller.DampenersOverride = true;
                }
            }

            else if (stage == 2)//descent burn has been initiated, goto stg 3 when a safe speed has been reached
            {
                antenna.HudText = stage.ToString();

                if (controller.GetShipVelocities().LinearVelocity.Length() < safeVelocity)
                {
                    stage++;
                    Storage = stage + ";";
                }
            }

            else if (stage == 3)//target safe descent speed has been reached, maintain low speed until touchdown to planet
            {
                float totalThrustNeededToHover = physicalMass * (float)currentNaturalGravity.Length();
                float idealThrustPerThruster   = (float)totalThrustNeededToHover / (float)numThrusters;
                float thrustRatio = thrusters[0].MaxThrust / thrusters[0].MaxEffectiveThrust;//actual output of thrust is similar to but different from the input set by code/user.
                float adjustedThrustPerThruster = idealThrustPerThruster * thrustRatio;

                foreach (var thruster in thrusters)
                {
                    thruster.ThrustOverride = adjustedThrustPerThruster;
                }

                if (currentAltitude < touchdownHeight)
                {
                    stage++;
                    Storage = stage + ";";

                    foreach (var thruster in thrusters)
                    {
                        controller.DampenersOverride = false;
                        thruster.ThrustOverride      = 0.0f;
                    }
                }
            }

            else if (stage == 4)//touchdown, turn stuff off pls
            {
                antenna.HudText = stage.ToString();
                Echo($"TOUCHDOWN");
                stage   = 0;
                Storage = stage + ";";
                Runtime.UpdateFrequency = UpdateFrequency.None;//stop running the script
            }
            lastVelocities = controller.GetShipVelocities();
        }