Exemplo n.º 1
0
            public override void Tick()
            {
                base.Tick();

                if (cockpit.GetNaturalGravity().Length() == 0)
                {
                    SetAction("disabled");
                }

                CalcWorldSpeed();
                CalcPitchAndRoll();
                PrintStatus();
                if (cockpit.GetNaturalGravity().Length() > 0)
                {
                    PrintVelocity();
                    PrintOrientation();
                }
                else
                {
                    PrintLine("\n\n   No Planetary Gravity");
                }

                if (action?.execute != null)
                {
                    action?.execute();
                }
                if (gyroController.gyroOverride)
                {
                    ExecuteManeuver();
                }
            }
            private double calculateGravityForce()
            {
                double gravityVectorLength = myShipController.GetNaturalGravity().Length();
                float  currentMass         = myShipController.CalculateShipMass().TotalMass;

                return(gravityVectorLength * currentMass);
            }
Exemplo n.º 3
0
            private double GetSpeedOnNaturalGravityVect()
            {
                Vector3D acceleration    = referenceBlock.GetNaturalGravity();
                Vector3D shipVelocityVec = referenceBlock.GetShipVelocities().LinearVelocity;

                return(VectorUtils.Projection(shipVelocityVec, acceleration).Length() * Math.Sign(shipVelocityVec.Dot(acceleration)));
            }
Exemplo n.º 4
0
 public static Planet GetBestGuessFromInitialData(IMyShipController remote)
 {
     if (!double.IsNaN(remote.GetNaturalGravity().Length()))
     {
         Planet   p = new Planet();
         Vector3D center;
         remote.TryGetPlanetPosition(out center);
         p.Center = center;
         double curdist = Vector3D.Distance(center, remote.GetPosition());
         double sealevelelevation;
         double curgrav = remote.GetNaturalGravity().Length();
         remote.TryGetPlanetElevation(MyPlanetElevation.Sealevel, out sealevelelevation);
         p.Radius            = curdist - sealevelelevation;
         p.GravityMathNumber = curgrav * Math.Pow(curdist, p.GravityExponent);
         if (curdist > p.Radius * (1 + p.HillParameter))
         {
             double mathvalue = curgrav * Math.Pow(curdist, p.GravityExponent);
             p.SurfaceGravity = mathvalue / Math.Pow(p.Radius * p.HillParameter + p.Radius, p.GravityExponent);
         }
         else
         {
             p.SurfaceGravity = curgrav;
         }
         return(p);
     }
     return(null);
 }
Exemplo n.º 5
0
            bool AdjustGyros_v2()
            {
                if (!ignoreGravity)
                {
                    alignVec = sc.GetNaturalGravity();
                }
                if (ignoreGravity || Vector3D.IsZero(alignVec))
                {
                    // When in zero-gravity, then use direction of ship-velocity instead
                    alignVec = sc.GetShipVelocities().LinearVelocity;
                    if (Vector3D.IsZero(alignVec))
                    {
                        // No usable velocity, reset all gyros
                        foreach (var g in gyros)
                        {
                            SetGyro(g);
                        }
                        return(false);
                    }
                }
                if (!isInverted)
                {
                    alignVec = Vector3D.Negate(alignVec);
                }
                alignVec.Normalize();

                sc.Orientation.GetMatrix(out or);                 //Get orientation from reference-block
                //down = (isRocket ? or.Backward : or.Down);
                localDown = Vector3D.Transform((isRocket ? or.Backward : or.Down), MatrixD.Transpose(or));
                localGrav = Vector3D.TransformNormal(alignVec, MatrixD.Transpose(sc.WorldMatrix));

                rot = Vector3D.Cross(localDown, localGrav);
                ang = rot.Length() + forceRotation;                               // Naive fix for "Gimbal lock"
                ang = Math.Atan2(ang, Math.Sqrt(Math.Max(0.0, 1.0 - ang * ang))); //More numerically stable than: ang=Math.Asin(ang)
                if (0.01 > ang)
                {
                    foreach (var g in gyros)
                    {
                        SetGyro(g);
                    }
                    return(false);
                }

                //Control speed to be proportional to distance (angle) we have left
                ctrl_vel = Math.Max(0.01, Math.Min(maxYaw, (maxYaw * (ang / Math.PI) * ctrl_Coeff)));
                rot.Normalize();
                rot *= -ctrl_vel;

                foreach (var g in gyros)
                {
                    var gyroRot = Vector3D.TransformNormal(rot, MatrixD.Transpose(g.WorldMatrix));
                    SetGyroRad(g, 1, true, (float)gyroRot.X, (float)gyroRot.Y, (float)gyroRot.Z);
                }
                return(true);
            }
Exemplo n.º 6
0
        void UpdateOrientationParameters()
        {
            Vector3D linearVelocity = Vector3D.Normalize(cockpit_.GetShipVelocities().LinearVelocity);
            Vector3D gravity        = -Vector3D.Normalize(cockpit_.GetNaturalGravity());

            pitch_ = Math.Acos(Vector3D.Dot(cockpit_.WorldMatrix.Forward, gravity)) * RadToDeg;
            roll_  = Math.Acos(Vector3D.Dot(cockpit_.WorldMatrix.Right, gravity)) * RadToDeg;

            worldSpeedForward_ = Vector3D.Dot(linearVelocity, Vector3D.Cross(gravity, cockpit_.WorldMatrix.Right)) * cockpit_.GetShipSpeed();
            worldSpeedRight_   = Vector3D.Dot(linearVelocity, Vector3D.Cross(gravity, cockpit_.WorldMatrix.Forward)) * cockpit_.GetShipSpeed();
            worldSpeedUp_      = Vector3D.Dot(linearVelocity, gravity) * cockpit_.GetShipSpeed();
        }
            public Vector2 CalculatePitchRollToAchiveVelocity(Vector3 targetVelocity)
            {
                Vector3 diffrence            = Vector3.Normalize(controller.GetShipVelocities().LinearVelocity - targetVelocity);
                Vector3 gravity              = -Vector3.Normalize(controller.GetNaturalGravity());
                float   velocity             = (float)controller.GetShipSpeed();
                float   proportionalModifier = (float)Math.Pow(Math.Abs(diffrence.Length()), 2);

                float pitch = NotNaN(Vector3.Dot(diffrence, Vector3.Cross(gravity, controller.WorldMatrix.Right)) * velocity) * proportionalModifier / dampeningFactor;
                float roll  = NotNaN(Vector3.Dot(diffrence, Vector3.Cross(gravity, controller.WorldMatrix.Forward)) * velocity) * proportionalModifier / dampeningFactor;

                pitch = MinAbs(pitch, 90.0f * degToRad);
                roll  = MinAbs(roll, 90.0f * degToRad);

                return(new Vector2(roll, pitch));
            }
Exemplo n.º 8
0
            bool GetBearing()
            {
                var gravityVec = sc.GetNaturalGravity();

                if (Vector3D.IsZero(gravityVec))
                {
                    return(false);
                }

                //get east vector
                var relativeEastVec = gravityVec.Cross(absNorthVec);

                //get relative north vector
                var relativeNorthVec = relativeEastVec.Cross(gravityVec);

                //project forward vector onto a plane comprised of the north and east vectors
                var forwardVec          = sc.WorldMatrix.Forward;
                var forwardProjPlaneVec = VectorProjection(forwardVec, relativeEastVec) + VectorProjection(forwardVec, relativeNorthVec);

                //find angle from abs north to projected forward vector measured clockwise
                var bearingAng = Math.Acos(forwardProjPlaneVec.Dot(relativeNorthVec) / forwardProjPlaneVec.Length() / relativeNorthVec.Length()) * (180 / Math.PI);

                //check direction of angle
                if (forwardVec.Dot(relativeEastVec) < 0)
                {
                    bearingAng = 360 - bearingAng;                     //because of how the angle is measured
                }
                var lne = compassStr.Substring(MathHelper.Clamp((int)Math.Round(bearingAng / 5), 0, 359), 20);

                lastAng    = ang;
                ang        = (int)Math.Round(bearingAng);
                bearingStr = $"\n{lne}\nBearing ^ {ang:000}    ";

                return(true);
            }
Exemplo n.º 9
0
        public void SpawnConvoyTransport(IMyShipController baseToSpawnAt)
        {
            var factionId       = baseToSpawnAt.OwnerId;
            var spawnerPosition = baseToSpawnAt.GetPosition();
            var gravity         = baseToSpawnAt.GetNaturalGravity();
            var unitType        = baseToSpawnAt.CustomName.Contains("GROUND") ? UnitType.Ground : UnitType.Air;
            var cargoSize       = heatSystem.GenerateCargoShipSize();

            if (unitType == UnitType.Air)
            {
                var positionToSpawn = spawnerPosition + gravity * -5f + baseToSpawnAt.WorldMatrix.Forward * 30;
                var transportPrefab = CalPrefabFactory.GetAirTransport(cargoSize);
                DuckUtils.SpawnInGravity(positionToSpawn, gravity, factionId, transportPrefab.PrefabName,
                                         transportPrefab.InitialBeaconName,
                                         Vector3D.Normalize(baseToSpawnAt.WorldMatrix.Forward));
            }
            else
            {
                var positionToSpawn = spawnerPosition + gravity * -1f + baseToSpawnAt.WorldMatrix.Forward * 35;
                var transportPrefab = CalPrefabFactory.GetGroundTransport(cargoSize);
                DuckUtils.SpawnInGravity(positionToSpawn, gravity, factionId, transportPrefab.PrefabName,
                                         transportPrefab.InitialBeaconName,
                                         Vector3D.Normalize(baseToSpawnAt.WorldMatrix.Forward));
            }
        }
Exemplo n.º 10
0
            private IEnumerator <bool> TargetingRoutine()
            {
                if (control.GetNaturalGravity() == Vector3D.Zero && control.GetShipSpeed() < 2)         // Easy
                {
                    quartic = new QuarticTargeting(control.GetVelocityVector(), control.GetPosition(), maxProjectileVel);

                    Vector3D?result = quartic.CalculateTrajectory(target);
                    if (result.HasValue)
                    {
                        onRoutineFinish?.Invoke(result.Value);
                    }
                    else
                    {
                        onRoutineFail?.Invoke();
                    }

                    yield return(false);
                }
                else                                                                                  // This may take a while...
                {
                    double timescale      = 0.1;
                    var    projectileInfo = new AdvancedSimTargeting.ProjectileInfo(200, maxProjectileVel, timescale, control.GetPosition(), control.GetVelocityVector());
                    simTargeting = new AdvancedSimTargeting(projectileInfo, target, control, ingameTime, 25, true, maxProjectileVel, timescale);
                    simTargeting.onSimComplete += OnSimValid;
                    simTargeting.onSimFail     += OnSimFail;

                    yield return(true);

                    while (keepRunning)
                    {
                        simTargeting.Tick();
                        yield return(true);
                    }
                }
            }
            public void StabelizeUpwards(Vector3D groundUpVector)
            {
                Vector3D velocity = rc.GetShipVelocities().LinearVelocity;

                velocity.Normalize();

                Vector3D upVector      = groundUpVector;
                Vector3D forwardVector = VectorUtils.ProjectOnPlanePerpendiculair(rc.WorldMatrix.Left, rc.WorldMatrix.Forward, velocity);

                if (groundUpVector == Vector3D.Zero)
                {
                    upVector = Vector3D.Normalize(-rc.GetNaturalGravity());
                }

                upVector += pitchUpBias * rc.WorldMatrix.Backward;

                var refLeft    = rc.WorldMatrix.Left;
                var refUp      = rc.WorldMatrix.Backward;
                var refForward = rc.WorldMatrix.Up;

                double dotUp      = 1 - Vector3D.Dot(upVector, refForward);
                double multiplier = MyMath.Clamp((float)(dotUp * 2 * dotUp), 1, 10);

                MatrixD rotationMatrix = MatrixD.CreateFromDir(refForward, refUp);

                Vector3D moveindicatorUP = VectorUtils.Project(VectorUtils.TransformDirLocalToWorld(rc.WorldMatrix, rc.MoveIndicator), rc.WorldMatrix.Right);

                forwardVector += moveindicatorUP * userInputMultiplier;

                GyroUtils.PointInDirection(gyros, rotationMatrix, upVector, -forwardVector, multiplier * upwardStabelizationMultiplier);
            }
Exemplo n.º 12
0
        public Vector3D GetGravity(IMyShipController dataBlock)
        {
            var worldLocalGravity        = dataBlock.GetNaturalGravity();
            var worldToAnchorLocalMatrix = Matrix.Transpose(dataBlock.WorldMatrix.GetOrientation());

            return(Vector3D.Transform(worldLocalGravity, worldToAnchorLocalMatrix));
        }
Exemplo n.º 13
0
    //Стабилизатор горизонта для гироскопа.
    public void GyroStab(bool on_off)
    {
        //Находим все гироскопы и закидываем их в gyroList.
        gyroList = new List <IMyGyro>();
        GridTerminalSystem.GetBlocksOfType <IMyGyro>(gyroList);

        if (on_off)
        {
            Display("GyroStab - on", nameStateLCD);
            //Поиск блока Remote Control и получение векторов.
            if (FindBlockByPartOfName(nameRemCon).Count == 1)
            {
                //IMyRemoteControl remCon = FindBlockByPartOfName(nameRemCon) as IMyRemoteControl; - В игре вызвает исключение, поэтому использовал foreach.
                //Но потом понял, что в списках можно как и в массивах вытаскивать значение по индексу: listName[], и запихивать его в обычную переменную.
                remCon = FindBlockByPartOfName(nameRemCon)[0] as IMyRemoteControl;

                //Получаем и нормализуем вектор гравитации. Это наше направление "вниз" на планете.
                Vector3D GravityVector = remCon.GetNaturalGravity();
                Vector3D GravNorm      = Vector3D.Normalize(GravityVector);

                //Получаем проекции вектора прицеливания на все три оси блока ДУ.
                double gF = GravNorm.Dot(remCon.WorldMatrix.Forward);
                double gL = GravNorm.Dot(remCon.WorldMatrix.Left);
                double gU = GravNorm.Dot(remCon.WorldMatrix.Up);

                //Получаем сигналы по тангажу и крены операцией atan2
                RollInput  = (float)Math.Atan2(gL, -gU);
                PitchInput = -(float)Math.Atan2(gF, -gU);

                //На рыскание просто отправляем сигнал рыскания с контроллера. Им мы будем управлять вручную.
                YawInput = remCon.RotationIndicator.Y;

                //для каждого гироскопа устанавливаем текущие значения по тангажу, крену, рысканию.
                foreach (IMyGyro gyro in gyroList)
                {
                    gyro.GyroOverride = true;
                    gyro.Roll         = RollInput;
                    gyro.Pitch        = PitchInput;
                    gyro.Yaw          = YawInput;
                }
            }
            else if (FindBlockByPartOfName(nameRemCon).Count > 1)
            {
                Display("Warning! \r\n We find more than \r\n 1 blocks Remote control:", nameDebugLCD);
                foreach (IMyRemoteControl remCon in FindBlockByPartOfName(nameRemCon))
                {
                    string data = remCon.CustomName;
                    Display(data, nameDebugLCD);
                }
            }
            else
            {
                Display("Warning! \r\n You don't have remote control blocks!", nameDebugLCD);
            }
        }
        else if (!on_off)
        {
            Display("GyroStab - off", nameStateLCD);
        }
    }
Exemplo n.º 14
0
        private void SpawnConvoy(IMyShipController baseToSpawnAt)
        {
            var factionId       = baseToSpawnAt.OwnerId;
            var spawnerPosition = baseToSpawnAt.GetPosition();
            var gravity         = baseToSpawnAt.GetNaturalGravity();
            var unitType        = baseToSpawnAt.CustomName.Contains("GROUND") ? UnitType.Ground : UnitType.Air;
            var cargoSize       = heatSystem.GenerateCargoShipSize();

            //TODO: Should let base define the convoy spawn points
            //TODO: gravity is not normalized and is being used to scale the spawn point...  It should be normalized and then meters used to modify.
            // NOTE: The .Forward IS normalized, so the scalar is in meters.
            if (unitType == UnitType.Air)
            {
                var positionToSpawn = spawnerPosition + gravity * -5f + baseToSpawnAt.WorldMatrix.Forward * 30;
                var transportPrefab = PrefabGrid.GetAirTransport(cargoSize);
                DuckUtils.SpawnInGravity(positionToSpawn, gravity, factionId, transportPrefab.PrefabName,
                                         transportPrefab.InitialBeaconName,
                                         Vector3D.Normalize(baseToSpawnAt.WorldMatrix.Forward));
            }
            else
            {
                var positionToSpawn = spawnerPosition + gravity * -1f + baseToSpawnAt.WorldMatrix.Forward * 35;
                var transportPrefab = PrefabGrid.GetGroundTransport(cargoSize);
                DuckUtils.SpawnInGravity(positionToSpawn, gravity, factionId, transportPrefab.PrefabName,
                                         transportPrefab.InitialBeaconName,
                                         Vector3D.Normalize(baseToSpawnAt.WorldMatrix.Forward));
            }
        }
Exemplo n.º 15
0
        public Vector3D FindCrossVector(Vector3D NorthVectorNorm)
        {
            IMyShipController CockpitBlock   = FindCockpitBlock();
            Vector3D          GravVector     = CockpitBlock.GetNaturalGravity();
            Vector3D          GravVectorNorm = Vector3D.Normalize(GravVector);

            return(Vector3D.Cross(NorthVectorNorm, GravVectorNorm));
        }
Exemplo n.º 16
0
        public void UpdateVectors()
        {
            GravVector     = CockpitBlock.GetNaturalGravity();
            GravVectorNorm = Vector3D.Normalize(GravVector);

            ShipVector     = ReferenceBlock.GetPosition();
            ShipVectorNorm = Vector3D.Normalize(ShipVector);
        }
Exemplo n.º 17
0
        public void DetectRunwayHeadings()
        {
            string ZoneAString = config.Get("TouchdownZone", "GPSA").ToString();
            string ZoneBString = config.Get("TouchdownZone", "GPSB").ToString();

            string   ZoneAName;
            Vector3D ZoneA = CreateVectorFromGPSCoordinateString(ZoneAString, out ZoneAName);

            string   ZoneBName;
            Vector3D ZoneB = CreateVectorFromGPSCoordinateString(ZoneBString, out ZoneBName);

            Vector3D ResultA = (ZoneA * -1) + ZoneB;
            Vector3D ResultB = ResultA * -1;

            Vector3D ResultANorm = Vector3D.Normalize(ResultA);
            Vector3D ResultBNorm = Vector3D.Normalize(ResultB);

            Vector3D GravVector     = CockpitBlock.GetNaturalGravity();
            Vector3D GravVectorNorm = Vector3D.Normalize(GravVector);

            Vector3D VectorNorth         = Vector3D.Reject(new Vector3D(0, -1, 0), GravVectorNorm);
            Vector3D VectorNorthNorm     = Vector3D.Normalize(VectorNorth);
            Vector3D VectorPerpendicular = Vector3D.Cross(VectorNorthNorm, GravVectorNorm); // Will always be west.

            double DotNorthA = Vector3D.Dot(ResultANorm, VectorNorthNorm);
            double DotNorthB = Vector3D.Dot(ResultBNorm, VectorNorthNorm);

            double AngleNorthA = ToDegrees(Math.Acos(DotNorthA));
            double AngleNorthB = ToDegrees(Math.Acos(DotNorthB));

            double DotEastA = Vector3D.Dot(ResultANorm, VectorPerpendicular);
            double DotEastB = Vector3D.Dot(ResultBNorm, VectorPerpendicular);

            double AngleEastA = ToDegrees(Math.Acos(DotEastA));
            double AngleEastB = ToDegrees(Math.Acos(DotEastB));


            double HDGA = AngleNorthA;

            if (AngleEastA < 90)
            {
                HDGA = 360 - AngleNorthA;
            }

            double HDGB = AngleNorthB;

            if (AngleEastB < 90)
            {
                HDGB = 360 - AngleNorthB;
            }

            HDGA = Math.Round(HDGA);
            HDGB = Math.Round(HDGB);

            config.Set("Runway", "HeadingA", HDGA.ToString());
            config.Set("Runway", "HeadingB", HDGB.ToString());
            Me.CustomData = config.ToString();
        }
Exemplo n.º 18
0
            public void Update()
            {
                // Calculate the needed thrust to get to velocity
                Vector3D myVel  = rc.GetShipVelocities().LinearVelocity;
                Vector3D deltaV = myVel - Velocity;

                if (Vector3D.IsZero(deltaV))
                {
                    return;
                }

                Vector3D gravity = rc.GetNaturalGravity();
                Vector3D thrust  = GetShipMass() * (2 * deltaV + gravity);

                // Apply the thrust
                for (int i = 0; i < thrusters.Count; i++)
                {
                    IMyThrust t = thrusters [i];
                    if (t == null)
                    {
                        thrusters.RemoveAtFast(i);
                        continue;
                    }


                    if (!t.IsFunctional)
                    {
                        continue;
                    }

                    if (Vector3D.Dot(t.WorldMatrix.Forward, thrust) > 0)
                    {
                        t.Enabled = true;
                        double outputThrust     = Vector3D.Dot(thrust, t.WorldMatrix.Forward);
                        double outputProportion = MathHelper.Clamp(outputThrust / t.MaxEffectiveThrust, 0, 1);
                        t.ThrustOverridePercentage = (float)outputProportion;
                        thrust -= t.WorldMatrix.Forward * outputProportion * t.MaxEffectiveThrust;
                    }
                    else
                    {
                        t.ThrustOverride = 0;
                        t.Enabled        = false;
                    }
                }
            }
Exemplo n.º 19
0
        //public void Update(ProjectorVisualization proj)
        public void Update()
        {
            if (!Enabled)
            {
                return;
            }

            Vector3D down     = controller.GetNaturalGravity();
            Vector3D shipDown = controller.WorldMatrix.Down;

            if (Vector3D.IsZero(down))
            {
                //gravity is zero, means we're not in gravity well.
                if (DisableOnNaturalGravityExit && startedInNaturalGravity)
                {
                    Stop();
                    return;
                }
                else
                {
                    //Align to velocity vector
                    down = controller.GetShipVelocities().LinearVelocity;
                }
            }

            Vector3D locationInGrid  = Vector3D.Transform(controller.GetPosition() + Vector3.Normalize(down), MatrixD.Invert(controller.WorldMatrix)) / controller.CubeGrid.GridSize;
            Vector3D locationInGrid2 = Vector3D.Transform(controller.GetPosition() + Vector3.Normalize(shipDown), MatrixD.Invert(controller.WorldMatrix)) / controller.CubeGrid.GridSize;

            //screen.WriteText(locationInGrid.ToString("n3"));
            //screen.WriteText("\n" + locationInGrid2.ToString("n3"), true);

            Vector3D striveForZero = locationInGrid - locationInGrid2;

            striveForZero *= 5;             //Increase speed in aligning

            //screen.WriteText("\n" + striveForZero.ToString("n3"), true);
            //screen.WriteText("\n" + controller.RotationIndicator.Y.ToString("n3"), true);

            ApplyGyroOverride(-striveForZero.Z, controller.RotationIndicator.Y, -striveForZero.X, gyros, controller as IMyTerminalBlock);


            //proj.UpdatePosition(controller.GetPosition() + (Vector3.Normalize(controller.GetNaturalGravity()) * 10));
            //proj.UpdatePosition(controller.GetPosition() + (Vector3.Normalize(controller.WorldMatrix.Down) * 10));
        }
Exemplo n.º 20
0
        public void Turn(MatrixD Reference, Vector3D target)
        {
            if (Reference == MatrixD.Zero)
            {
                return;
            }
            MatrixD orientationMatrix = MatrixD.Identity;

            orientationMatrix.Translation = Reference.Translation;
            Vector3D orientationForward = Controller.WorldMatrix.Forward + Controller.WorldMatrix.Down + Controller.WorldMatrix.Left;

            orientationForward.Normalize();
            orientationMatrix.Forward = orientationForward;
            Vector3D orientationUp = Reference.Forward;

            orientationUp -= VectorHelpers.VectorProjection(orientationUp, orientationForward);
            orientationUp.Normalize();
            orientationMatrix.Up = orientationUp;
            Vector3D OrientationRight = orientationForward.Cross(orientationUp);

            orientationMatrix.Right = OrientationRight;
            var gravDir = Controller.GetNaturalGravity();

            gravDir.Normalize();

            double yawAngle, pitchAngle, spinAngle;

            GravAngle = VectorHelpers.VectorAngleBetween(gravDir, orientationMatrix.Forward);

            if (target != Vector3D.Zero && GravAngle < Math.PI * 0.1)
            {
                Vector3D TargetDir = target - orientationMatrix.Translation;
                TargetDir.Normalize();
                var projectedTargetUp = TargetDir - VectorHelpers.VectorProjection(TargetDir, orientationForward);
                spinAngle = -1 * VectorHelpers.VectorAngleBetween(orientationMatrix.Up, projectedTargetUp) * Math.Sign(orientationMatrix.Left.Dot(TargetDir));
            }
            else
            {
                spinAngle = 0;
                SpinPID.Reset();
            }
            TrigHelpers.GetRotationAngles(gravDir, orientationMatrix.Forward, orientationMatrix.Left, orientationMatrix.Up, out yawAngle, out pitchAngle);
            TrigHelpers.ApplyGyroOverride(PitchPID.Control(pitchAngle), YawPID.Control(yawAngle), SpinPID.Control(spinAngle), Gyros, orientationMatrix);
        }
        private void Update()
        {
            //-Prepare data
            //  >get local gravity vector
            //  >normalise vector to simplify angle calculation
            Vector3D
                worldGravity = controller.GetNaturalGravity();

            worldGravity.Normalize();

            //Check each thruster to see if it is safe to enable
            //-only check thrusters on our grid
            //-check that we have access to the thruster
            //-disable any that are pointing down
            //  >(with safetyCutoff tolerance)
            //  >enable any others
            GridTerminalSystem.GetBlocksOfType <IMyThrust>(temp);
            int count = 0;

            for (int i = 0; i < temp.Count; i++)
            {
                IMyThrust thruster = (IMyThrust)temp[i];

                if (thruster.CubeGrid != controller.CubeGrid)
                {
                    continue;
                }

                count++;
                //Check if we can actually use the thruster
                if (ValidateBlock(thruster, callbackRequired: false))
                {
                    Vector3D
                        worldThruster = GridToWorld(
                        Base6Directions.GetIntVector(thruster.Orientation.Forward),
                        thruster.CubeGrid);
                    //Compare the dot product of gravity and thrust direction (normalised)
                    // 1.0 => 0 degrees
                    // 0.0 => 90 degrees
                    //-1.0 => 180 degrees
                    //safe iff angle <= safetyCutoffAngle
                    //=> safe iff dot product >= cos(safetyCutoffAngle)
                    bool
                        safe = Vector3D.Dot(worldGravity, worldThruster) >= safetyCutoff *worldThruster.Length();

                    if (thruster.Enabled != safe)
                    {
                        thruster.RequestEnable(safe);
                    }
                }
            }             //end for

            Echo(temp.Count.ToString() + " thrusters found.");
            Echo(count.ToString() + " processed.");
        }
Exemplo n.º 22
0
            private void CalculateLiftThrustUsage(IMyShipController controller, List <IMyThrust> thrusters)
            {
                float mass            = controller.CalculateShipMass().PhysicalMass;
                float gravityStrength = (float)(controller.GetNaturalGravity().Length() / 9.81);

                LiftThrustNeeded = (mass * (float)gravityStrength / 100) * 1000;

                Vector3 gravity = controller.GetNaturalGravity();


                LiftThrustAvailable = 0;
                thrusters.ForEach(thruster =>
                {
                    if (thruster.IsWorking)
                    {
                        Vector3D thrusterDirection = thruster.WorldMatrix.Forward;
                        double upDot         = Vector3D.Dot(thrusterDirection, Vector3.Normalize(gravity));
                        LiftThrustAvailable += (thruster.MaxEffectiveThrust * (float)upDot);
                    }
                });
            }
Exemplo n.º 23
0
 public ControllableThrusters(IMyShipController controller)
 {
     _thisIController = controller;
     _thisController  = (MyShipController)controller;
     _thisController.ControlThrusters = true;
     controller.GetNaturalGravity();
     _thrusters.Add(ThrustDirection.Forward, new ConcurrentCachingList <ControllableThruster>());
     _thrusters.Add(ThrustDirection.Back, new ConcurrentCachingList <ControllableThruster>());
     _thrusters.Add(ThrustDirection.Up, new ConcurrentCachingList <ControllableThruster>());
     _thrusters.Add(ThrustDirection.Down, new ConcurrentCachingList <ControllableThruster>());
     _thrusters.Add(ThrustDirection.Left, new ConcurrentCachingList <ControllableThruster>());
     _thrusters.Add(ThrustDirection.Right, new ConcurrentCachingList <ControllableThruster>());
 }
        void Attack(TimeSpan localTime)
        {
            FriendlyShipScratchpad.Clear();

            var intelItems = IntelProvider.GetFleetIntelligences(localTime);

            foreach (var kvp in intelItems)
            {
                if (kvp.Key.Item1 == IntelItemType.Friendly)
                {
                    var friendly = (FriendlyShipIntel)kvp.Value;
                    if (friendly.AgentClass == AgentClass.Fighter && (friendly.AgentStatus & AgentStatus.Docked) != 0 && (friendly.GetPositionFromCanonicalTime(localTime + IntelProvider.CanonicalTimeDiff) - Controller.GetPosition()).Length() < 100)
                    {
                        FriendlyShipScratchpad.Add(friendly);
                    }
                }
            }

            if (FriendlyShipScratchpad.Count == 0)
            {
                return;
            }

            for (int i = 0; i < FriendlyShipScratchpad.Count; i++)
            {
                var targetWaypoint = new Waypoint();

                var gravDir = Controller.GetNaturalGravity();
                targetWaypoint.Position = Controller.GetPosition();
                var angle = 2 * i * Math.PI / FriendlyShipScratchpad.Count;

                if (gravDir != Vector3D.Zero)
                {
                    gravDir.Normalize();
                    var flatForward = Controller.WorldMatrix.Forward - VectorHelpers.VectorProjection(Controller.WorldMatrix.Forward, gravDir);
                    flatForward.Normalize();
                    var flatLeftDir = Vector3D.Cross(flatForward, gravDir);
                    targetWaypoint.Position += (flatForward * TrigHelpers.FastCos(angle) + flatLeftDir * TrigHelpers.FastSin(angle)) * 500;
                    targetWaypoint.Position -= gravDir * 200;
                }
                else
                {
                    targetWaypoint.Position += (Controller.WorldMatrix.Forward * TrigHelpers.FastCos(angle) + Controller.WorldMatrix.Left * TrigHelpers.FastSin(angle)) * 500;
                }

                targetWaypoint.Position += Controller.GetShipVelocities().LinearVelocity * 3;
                IntelProvider.ReportFleetIntelligence(targetWaypoint, localTime);
                IntelProvider.ReportCommand(FriendlyShipScratchpad[i], TaskType.Attack, MyTuple.Create(IntelItemType.Waypoint, targetWaypoint.ID), localTime);
            }
        }
Exemplo n.º 25
0
            private void UdjustSuspensionStrength()
            {
                float gravityFactor            = (float)_controller.GetNaturalGravity().Length() / 9.81f;
                float truckCurrentMass         = _controller.CalculateShipMass().PhysicalMass *gravityFactor;
                float massToWheelsDifference   = truckCurrentMass / _suspensions.Count;
                float _truckSuspensionStrength = (float)Math.Sqrt(massToWheelsDifference / _suspensionSoftnessFactor);

                SuspensionStrengthChangedEventArgs args = new SuspensionStrengthChangedEventArgs
                {
                    Strength = _truckSuspensionStrength
                };

                ChangeTruckSuspensionStrength?.Invoke(this, args);
            }
Exemplo n.º 26
0
        public Vector3D FindNorthVector()
        {
            IMyShipController CockpitBlock   = FindCockpitBlock();
            Vector3D          GravVector     = CockpitBlock.GetNaturalGravity();
            Vector3D          GravVectorNorm = Vector3D.Normalize(GravVector);

            Vector3D NorthVector     = Vector3D.Reject(new Vector3D(0, -1, 0), GravVectorNorm);
            Vector3D NorthVectorNorm = Vector3D.Normalize(NorthVector);

            // Echo("DotN: " + Vector3D.Dot(NorthVector, GravVectorNorm));
            // Echo("DotNN: " + Vector3D.Dot(NorthVectorNorm, GravVectorNorm));

            return(NorthVectorNorm);
        }
Exemplo n.º 27
0
 string GyroMain(string argument) {
     autoLevelStatus.Clear();
     //autoLevelStatus.Append("Auto level is turned on");
     if (rc == null) { gyrosetup(); }
     if (rc == null) {
         autoLevelStatus.Append("Auto-Level:No Cockpit or Remote Control.");
         return autoLevelStatus.ToString() ;
     }
     Matrix or;
     rc.Orientation.GetMatrix(out or);
     Vector3D down;
     if (argument.ToLower().Contains("rocket")) { down = or.Backward; } else { down = or.Down; }
     Vector3D grav = rc.GetNaturalGravity();
     grav.Normalize();
     autoLevelStatus.Append("Auto-Level:");
     for (int i = 0; i < gyros.Count; ++i) {
         var g = gyros[i];
         g.Orientation.GetMatrix(out or);
         var localDown = Vector3D.Transform(down, MatrixD.Transpose(or));
         var localGrav = Vector3D.Transform(grav, MatrixD.Transpose(g.WorldMatrix.GetOrientation()));
         //Since the gyro ui lies, we are not trying to control yaw,pitch,roll but rather we  
         //need a rotation vector (axis around which to rotate)  
         var rot = Vector3D.Cross(localDown, localGrav);
         double ang = rot.Length();
         ang = Math.Atan2(ang, Math.Sqrt(Math.Max(0.0, 1.0 - ang * ang)));
         if (double.IsNaN(ang)) { // not in gravity
             g.GyroOverride = false;
             autoLevelStatus.Append("Auto-Level:Not in gravity well");
             return autoLevelStatus.ToString() ;
         }
         if (ang < minAngleRad) { // close enough  
             g.GyroOverride = false;
             autoLevelStatus.Append($" on level.");
             continue;
         }
         autoLevelStatus.Append($" Off level: {(MathHelper.ToDegrees(ang)).ToString("0.000")} deg.");
         double ctrl_vel = g.GetMaximum<float>("Yaw") * (ang / Math.PI) * CTRL_COEFF;
         ctrl_vel = Math.Min(g.GetMaximum<float>("Yaw"), ctrl_vel);
         ctrl_vel = Math.Max(0.01, ctrl_vel);
         rot.Normalize();
         rot *= ctrl_vel;
         g.SetValueFloat("Pitch", (float)rot.GetDim(0));
         g.SetValueFloat("Yaw", -(float)rot.GetDim(1));
         g.SetValueFloat("Roll", -(float)rot.GetDim(2));
         g.SetValueFloat("Power", 1.0f);
         g.SetValueBool("Override", true);
     }
     return autoLevelStatus.ToString();
 }
 public bool Update()
 {
     //Speed towards the center of nearest gravity well.
     if (Controller != null)
     {
         newValue = -Vector3.Dot(Controller.GetShipVelocities().LinearVelocity,
                                 Vector3D.Normalize(Controller.GetNaturalGravity()));
         if (newValue != Value)
         {
             Value = newValue;
             return(true);
         }
     }
     return(false);
 }
Exemplo n.º 29
0
            public Vector3D ControlVelocity(Vector3D targetVelocity)
            {
                // Calculate the needed thrust to get to velocity
                Vector3D myVel  = rc.GetShipVelocities().LinearVelocity;
                Vector3D deltaV = myVel - targetVelocity;

                if (Vector3D.IsZero(deltaV))
                {
                    return(Vector3D.Zero);
                }

                Vector3D gravity = rc.GetNaturalGravity();

                return(2 * deltaV + gravity);
            }
Exemplo n.º 30
0
        public bool Update()
        {
            if (Controller != null)
            {
                val = Controller.GetNaturalGravity().Length();
                val = val / 9.81;

                if (val != Value)
                {
                    Value = val;
                    return(true);
                }
            }
            return(false);
        }