Example #1
0
 public void Rotate()
 {
     if (OrbitEntity == null)
     {
         m_flyTo = true;
         m_mover.StopRotate();
     }
     else if (OrbitEntity is MyPlanet)
     {
         m_flyTo = false;
         m_mover.CalcRotate(m_navBlock, RelativeDirection3F.FromWorld(m_navBlock.Grid, m_faceDirection));
     }
     else if (m_navSet.DistanceLessThan(OrbitSpeed))
     {
         if (m_flyTo)
         {
             CalcFakeOrbitSpeedForce();
             m_flyTo = false;
         }
         m_mover.CalcRotate(m_navBlock, RelativeDirection3F.FromWorld(m_navBlock.Grid, m_faceDirection));
     }
     else
     {
         m_flyTo = true;
         m_mover.CalcRotate();
     }
 }
Example #2
0
        public void Rotate()
        {
            //Log.DebugLog("entered");

            if (m_enemy == null)
            {
                m_mover.StopRotate();
                return;
            }

            if (m_approaching)
            {
                //Log.DebugLog("approaching");
                m_mover.CalcRotate();
            }
            else
            {
                //Log.DebugLog("ramming");
                if (m_navSet.DistanceLessThan(100f))
                {
                    // just before impact, face the target
                    Vector3 targetDirection = m_enemy.GetPosition() - m_controlBlock.CubeBlock.GetPosition();
                    targetDirection.Normalize();
                    m_mover.CalcRotate(m_mover.Thrust.Standard, RelativeDirection3F.FromWorld(m_mover.Block.CubeGrid, targetDirection));
                }
                else
                {
                    m_mover.CalcRotate_Accel();
                }
            }
        }
Example #3
0
        public override void Rotate()
        {
            if (m_gridFinder.Grid == null)
            {
                m_mover.StopRotate();
                return;
            }

            if (m_landingState == LandingState.None)
            {
                if (m_targetBlock != null && m_targetBlock.Forward.HasValue)
                {
                    m_navSet.GetSettingsLevel(m_settingLevel).NavigatorRotator = this;
                    //Log.DebugLog("matching target direction", "Rotate()");
                    m_mover.CalcRotate(m_navBlock, m_gridFinder.Block, m_targetBlock.Forward, m_targetBlock.Upward);
                    return;
                }
                else
                {
                    m_mover.CalcRotate();
                }
                return;
            }

            if (m_landingState == LandingState.Approach)
            {
                //Log.DebugLog("facing controller towards target : " + m_targetPosition, "Rotate()");
                m_mover.CalcRotate();
                return;
            }

            if (m_gridFinder.Block == null)
            {
                if (m_landGearWithoutTargetBlock)
                {
                    m_mover.CalcRotate(m_navBlock, RelativeDirection3F.FromWorld(m_navBlock.Grid, m_destination.WorldPosition() - m_navBlock.WorldPosition));
                    return;
                }

                m_mover.CalcRotate();
                return;
            }

            //Log.DebugLog("rotating for landing", "Rotate()");
            if (IsLocked())
            {
                Log.DebugLog("already landed");
                return;
            }
            m_mover.CalcRotate(m_navBlock, m_gridFinder.Block, m_landingDirection, m_targetBlock.Upward);
            return;
        }
Example #4
0
 public override void Rotate()
 {
     switch (m_stage)
     {
     case Stage.Mine:
     case Stage.Tunnel:
     {
         Vector3 direction = Vector3.Normalize(m_target.WorldPosition() - m_navBlock.WorldPosition);
         m_mover.CalcRotate(m_navBlock, RelativeDirection3F.FromWorld(m_grid, direction));
         break;
     }
     }
 }
Example #5
0
        /// <summary>
        /// Match orientation with the target block.
        /// </summary>
        /// <param name="block">The navigation block</param>
        /// <param name="destBlock">The destination block</param>
        /// <param name="forward">The direction of destBlock that will be matched to navigation block's forward</param>
        /// <param name="upward">The direction of destBlock that will be matched to navigation block's upward</param>
        /// <returns>True iff localMatrix is facing the same direction as destBlock's forward</returns>
        public void CalcRotate(PseudoBlock block, IMyCubeBlock destBlock, Base6Directions.Direction?forward, Base6Directions.Direction?upward)
        {
            //Log.DebugLog("entered CalcRotate(PseudoBlock block, IMyCubeBlock destBlock, Base6Directions.Direction? forward, Base6Directions.Direction? upward)", "CalcRotate()");

            if (forward == null)
            {
                forward = Base6Directions.Direction.Forward;
            }

            RelativeDirection3F faceForward = RelativeDirection3F.FromWorld(block.Grid, destBlock.WorldMatrix.GetDirectionVector(forward.Value));
            RelativeDirection3F faceUpward  = upward.HasValue ? RelativeDirection3F.FromWorld(block.Grid, destBlock.WorldMatrix.GetDirectionVector(upward.Value)) : null;

            CalcRotate(block.LocalMatrix, faceForward, faceUpward);
        }
Example #6
0
        public void Rotate()
        {
            switch (m_stage)
            {
            case Stage.Approach:
                m_mover.CalcRotate();
                return;

            case Stage.Rotate:
            case Stage.Land:
                m_mover.CalcRotate(m_landBlock, RelativeDirection3F.FromWorld(m_landBlock.Grid, m_targetPostion.WorldPosition() - m_landBlock.WorldPosition));
                return;
            }
        }
Example #7
0
        // necessary wrapper for main CalcRotate, should always be called.
        private void CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, bool gravityAdjusted = false, IMyEntity targetEntity = null)
        {
            //Log.DebugLog("entered CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, bool levelingOff = false, IMyEntity targetEntity = null)", "CalcRotate()");

            CheckGrid();
            Thrust.Update();

            if (!gravityAdjusted && ThrustersOverWorked())
            {
                CalcRotate_InGravity(Direction);
                return;
            }

            in_CalcRotate(localMatrix, Direction, UpDirect, targetEntity);
        }
Example #8
0
        public override void Rotate()
        {
            Vector3 linearVelocity = m_grid.Physics.LinearVelocity;
            float   speedSquared   = linearVelocity.LengthSquared();

            if (speedSquared < 1f)
            {
                m_mover.CalcRotate();
                m_navSet.Settings_Current.DistanceAngle = 0f;
            }
            else
            {
                m_mover.CalcRotate(m_navBlock, RelativeDirection3F.FromWorld(m_grid, linearVelocity));
            }
        }
Example #9
0
        public void Rotate()
        {
            if (m_enemy == null || (m_navSet.DistanceLessThan(1f) && m_navSet.Settings_Current.DistanceAngle <= MaxAngleRotate))
            {
                m_mover.CalcRotate_Stop();
                return;
            }
            if (m_stage == Stage.Intercept)
            {
                m_mover.CalcRotate();
                return;
            }

            //Log.DebugLog("rotating to " + m_targetPosition);
            m_mover.CalcRotate(m_navGrind, RelativeDirection3F.FromWorld(m_navGrind.Grid, m_targetPosition - m_navGrind.WorldPosition));
        }
Example #10
0
        /// <summary>
        /// Rotate to face the acceleration direction. If acceleration is zero, invokes CalcRotate_Stop.
        /// </summary>
        public void CalcRotate_Accel()
        {
            if (m_moveAccel == Vector3.Zero)
            {
                CalcRotate_Stop();
                return;
            }

            if (SignificantGravity())
            {
                CalcRotate_InGravity(RelativeDirection3F.FromBlock(Block.CubeBlock, m_moveAccel));
            }
            else
            {
                CalcRotate(Thrust.Standard.LocalMatrix, RelativeDirection3F.FromBlock(Block.CubeBlock, m_moveAccel));
            }
        }
Example #11
0
        public override void Rotate()
        {
            switch (m_stage)
            {
            case Stage.Backout:
            {
                Vector3 direction = Vector3.Normalize(m_navBlock.WorldPosition - m_target.WorldPosition());
                m_mover.CalcRotate(m_navBlock, RelativeDirection3F.FromWorld(m_grid, direction));
                break;
            }

            case Stage.FromCentre:
            {
                m_mover.StopRotate();
                break;
            }
            }
        }
Example #12
0
        public void Rotate()
        {
            if (!m_weaponArmed)
            {
                m_mover.StopRotate();
                return;
            }

            if (m_weapon_primary == null || m_weapon_primary.CubeBlock.Closed)
            {
                Log.DebugLog("no primary weapon");
                Disarm();
                m_mover.StopRotate();
                return;
            }
            Vector3?FiringDirection = m_weapon_primary.CurrentTarget.FiringDirection;

            if (!FiringDirection.HasValue)
            {
                if (m_orbiter != null)
                {
                    m_orbiter.Rotate();
                }
                else
                {
                    m_mover.CalcRotate();
                }
                return;
            }
            //Log.DebugLog("facing target at " + firingDirection.Value, "Rotate()");

            RelativeDirection3F upDirect = null;

            if (m_mover.SignificantGravity())
            {
                upDirect = RelativeDirection3F.FromWorld(m_controlBlock.CubeGrid, -m_mover.Thrust.WorldGravity.vector);
            }

            m_mover.CalcRotate(m_weapon_primary_pseudo, RelativeDirection3F.FromWorld(m_weapon_primary_pseudo.Grid, FiringDirection.Value), UpDirect: upDirect, targetEntity: m_weapon_primary.CurrentTarget.Entity);
        }
Example #13
0
        /// <summary>
        /// When in space, stops rotation. When in gravity, rotate to hover.
        /// </summary>
        private void CalcRotate_Hover()
        {
            if (SignificantGravity())
            {
                float accel = Thrust.SecondaryForce / Block.Physics.Mass;
                if (accel > Thrust.GravityStrength)
                {
                    Log.DebugLog("facing secondary away from gravity, secondary: " + Thrust.Gravity.LocalMatrix.Forward + ", away from gravity: " + (-Thrust.LocalGravity.vector));
                    CalcRotate(Thrust.Gravity.LocalMatrix, RelativeDirection3F.FromLocal(Block.CubeGrid, -Thrust.LocalGravity.vector), gravityAdjusted: true);
                }
                else
                {
                    Log.DebugLog("facing primary away from gravity, primary: " + Thrust.Standard.LocalMatrix.Forward + ", away from gravity: " + (-Thrust.LocalGravity.vector));
                    CalcRotate(Thrust.Standard.LocalMatrix, RelativeDirection3F.FromLocal(Block.CubeGrid, -Thrust.LocalGravity.vector), gravityAdjusted: true);
                }

                return;
            }

            //Log.DebugLog("stopping rotation");
            StopRotate();
        }
Example #14
0
        /// <summary>
        /// Calculate the best rotation to stop the ship.
        /// </summary>
        /// TODO: if ship cannot rotate quickly, find a reasonable alternative to facing primary
        public void CalcRotate_Stop()
        {
            //Log.DebugLog("entered CalcRotate_Stop()", "CalcRotate_Stop()");

            Vector3 linearVelocity = LinearVelocity;

            if (!Thrust.CanMoveAnyDirection() || linearVelocity.LengthSquared() > 1f)
            {
                //Log.DebugLog("rotate to stop");

                if (SignificantGravity())
                {
                    CalcRotate_InGravity(RelativeDirection3F.FromWorld(Block.CubeGrid, -linearVelocity));
                }
                else
                {
                    CalcRotate(Thrust.Standard.LocalMatrix, RelativeDirection3F.FromWorld(Block.CubeGrid, -linearVelocity));
                }

                return;
            }

            CalcRotate_Hover();
        }
Example #15
0
        /// <summary>
        /// Calculates the force necessary to rotate the grid.
        /// </summary>
        /// <param name="Direction">The direction to face the localMatrix in.</param>
        /// <param name="block"></param>
        /// <returns>True iff localMatrix is facing Direction</returns>
        public void CalcRotate(PseudoBlock block, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, IMyEntity targetEntity = null)
        {
            //m_logger.debugLog("entered CalcRotate(PseudoBlock block, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, IMyEntity targetEntity = null)", "CalcRotate()");

            CalcRotate(block.LocalMatrix, Direction, UpDirect, targetEntity: targetEntity);
        }
Example #16
0
        /// <summary>
        /// Calculates the force necessary to rotate the grid.
        /// </summary>
        /// <param name="localMatrix">The matrix to rotate to face the direction, use a block's local matrix or result of GetMatrix()</param>
        /// <param name="Direction">The direction to face the localMatrix in.</param>
        /// <param name="angularVelocity">The local angular velocity of the controlling block.</param>
        private void CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect, out Vector3 angularVelocity)
        {
            CheckGrid();

            myLogger.debugLog(Direction == null, "Direction == null", "CalcRotate()", Logger.severity.ERROR);

            angularVelocity = -Vector3.Transform(Block.Physics.AngularVelocity, Block.CubeBlock.WorldMatrixNormalizedInv.GetOrientation());

            //myLogger.debugLog("angular: " + angularVelocity, "CalcRotate()");
            float gyroForce = myGyro.TotalGyroForce();

            const ulong UpdateFrequency = ShipController_Autopilot.UpdateFrequency;
            if (rotateForceRatio != Vector3.Zero)
                if (Globals.UpdateCount - updated_prevAngleVel == UpdateFrequency) // needs to be == because displacment is not divided by frequency
                {
                    Vector3 ratio = (angularVelocity - prevAngleVel) / (rotateForceRatio * gyroForce);

                    //myLogger.debugLog("rotateForceRatio: " + rotateForceRatio + ", ratio: " + ratio + ", accel: " + (angularVelocity - prevAngleVel) + ", torque: " + (rotateForceRatio * gyroForce), "CalcRotate()");

                    myGyro.Update_torqueAccelRatio(rotateForceRatio, ratio);
                }
                else
                    myLogger.debugLog("prevAngleVel is old: " + (Globals.UpdateCount - updated_prevAngleVel), "CalcRotate()", Logger.severity.DEBUG);

            localMatrix.M41 = 0; localMatrix.M42 = 0; localMatrix.M43 = 0; localMatrix.M44 = 1;
            Matrix inverted; Matrix.Invert(ref localMatrix, out inverted);

            localMatrix = localMatrix.GetOrientation();
            inverted = inverted.GetOrientation();

            //myLogger.debugLog("local matrix: right: " + localMatrix.Right + ", up: " + localMatrix.Up + ", back: " + localMatrix.Backward + ", trans: " + localMatrix.Translation, "CalcRotate()");
            //myLogger.debugLog("inverted matrix: right: " + inverted.Right + ", up: " + inverted.Up + ", back: " + inverted.Backward + ", trans: " + inverted.Translation, "CalcRotate()");
            //myLogger.debugLog("local matrix: " + localMatrix, "CalcRotate()");
            //myLogger.debugLog("inverted matrix: " + inverted, "CalcRotate()");

            Vector3 localDirect = Direction.ToLocal();
            Vector3 rotBlockDirect; Vector3.Transform(ref localDirect, ref inverted, out rotBlockDirect);

            rotBlockDirect.Normalize();

            float azimuth, elevation; Vector3.GetAzimuthAndElevation(rotBlockDirect, out azimuth, out elevation);

            Vector3 rotaRight = localMatrix.Right;
            Vector3 rotaUp = localMatrix.Up;

            Vector3 NFR_right = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaRight));
            Vector3 NFR_up = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaUp));

            Vector3 displacement = -elevation * NFR_right - azimuth * NFR_up;

            if (UpDirect != null)
            {
                Vector3 upLocal = UpDirect.ToLocal();
                Vector3 upRotBlock; Vector3.Transform(ref upLocal, ref inverted, out upRotBlock);
                float roll; Vector3.Dot(ref upRotBlock, ref Vector3.Right, out roll);

                Vector3 rotaBackward = localMatrix.Backward;
                Vector3 NFR_backward = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaBackward));

                myLogger.debugLog("roll: " + roll + ", displacement: " + displacement + ", NFR_backward: " + NFR_backward + ", change: " + (-roll * NFR_backward), "CalcRotate()");

                displacement += roll * NFR_backward;
            }

            NavSet.Settings_Task_NavWay.DistanceAngle = displacement.Length();

            if (NavSet.Settings_Current.CollisionAvoidance)
            {
                myPathfinder.TestRotate(displacement);
                if (!myPathfinder.CanRotate)
                {
                    Logger.debugNotify("Cannot Rotate", 50);
                    myLogger.debugLog("Pathfinder not allowing rotation", "CalcRotate()");
                    return;
                }
            }

            //myLogger.debugLog("localDirect: " + localDirect + ", rotBlockDirect: " + rotBlockDirect + ", elevation: " + elevation + ", NFR_right: " + NFR_right + ", azimuth: " + azimuth + ", NFR_up: " + NFR_up + ", disp: " + displacement, "CalcRotate()");

            if (myGyro.torqueAccelRatio == 0)
            {
                // do a test
                myLogger.debugLog("torqueAccelRatio == 0", "CalcRotate()");
                rotateForceRatio = new Vector3(0, 1f, 0);
                return;
            }

            Vector3 targetVelocity = MaxAngleVelocity(displacement);

            // Adjust for moving target by measuring changes in displacement. Part of the change in displacement is attributable to ship rotation.
            const float dispToVel = (float)Globals.UpdatesPerSecond / (float)ShipController_Autopilot.UpdateFrequency;

            Vector3 addVelocity = angularVelocity - (prevAngleDisp - displacement) * dispToVel;
            if (addVelocity.LengthSquared() < 0.1f)
            {
                myLogger.debugLog("Adjust for moving, adding to target velocity: " + addVelocity, "CalcRotate()");
                targetVelocity += addVelocity;
            }
            else
                myLogger.debugLog("Not adjusting for moving, assuming target changed: " + addVelocity, "CalcRotate()");
            prevAngleDisp = displacement;

            Vector3 diffVel = targetVelocity - angularVelocity;

            rotateForceRatio = diffVel / (myGyro.torqueAccelRatio * gyroForce);

            myLogger.debugLog("targetVelocity: " + targetVelocity + ", angularVelocity: " + angularVelocity + ", diffVel: " + diffVel, "CalcRotate()");
            //myLogger.debugLog("diffVel: " + diffVel + ", torque: " + (myGyro.torqueAccelRatio * gyroForce) + ", rotateForceRatio: " + rotateForceRatio, "CalcRotate()");

            // dampeners
            for (int i = 0; i < 3; i++)
            {
                // if targetVelocity is close to 0, use dampeners

                float target = targetVelocity.GetDim(i);
                if (target > -0.01f && target < 0.01f)
                {
                    myLogger.debugLog("target near 0 for " + i + ", " + target, "CalcRotate()");
                    rotateForceRatio.SetDim(i, 0f);
                    continue;
                }

                float velDim = angularVelocity.GetDim(i);
                if (velDim < 0.01f && velDim > -0.01f)
                    continue;

                // where rotateForceRatio opposes angularVelocity, use dampeners

                float dim = rotateForceRatio.GetDim(i);
                if (Math.Sign(dim) * Math.Sign(angularVelocity.GetDim(i)) < 0)
                    //{
                    //	myLogger.debugLog("force ratio(" + dim + ") opposes velocity(" + angularVelocity.GetDim(i) + "), index: " + i + ", " + Math.Sign(dim) + ", " + Math.Sign(angularVelocity.GetDim(i)), "CalcRotate()");
                    rotateForceRatio.SetDim(i, 0f);
                //}
                //else
                //	myLogger.debugLog("force ratio is aligned with velocity: " + i + ", " + Math.Sign(dim) + ", " + Math.Sign(angularVelocity.GetDim(i)), "CalcRotate()");
            }
        }
Example #17
0
        /// <summary>
        /// Calculates the force necessary to rotate the grid.
        /// </summary>
        /// <param name="Direction">The direction to face the localMatrix in.</param>
        /// <param name="block"></param>
        /// <returns>True iff localMatrix is facing Direction</returns>
        public void CalcRotate(PseudoBlock block, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null)
        {
            Vector3 angleVelocity;
            CalcRotate(block.LocalMatrix, Direction, UpDirect, out angleVelocity);
            updated_prevAngleVel = Globals.UpdateCount;
            prevAngleVel = angleVelocity;

            //myLogger.debugLog("displacement.LengthSquared(): " + displacement.LengthSquared(), "CalcRotate()");
            //return displacement.LengthSquared() < 0.01f;

            //if (NavSet.Settings_Current.CollisionAvoidance)
            //	myPathfinder.TestRotate(displacement);
        }
Example #18
0
		/// <summary>
		/// Calculates the force necessary to rotate the grid.
		/// </summary>
		/// <param name="Direction">The direction to face the localMatrix in.</param>
		/// <param name="block"></param>
		/// <returns>True iff localMatrix is facing Direction</returns>
		public void CalcRotate(PseudoBlock block, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, IMyEntity targetEntity = null)
		{
			CalcRotate(block.LocalMatrix, Direction, UpDirect, targetEntity: targetEntity);
		}
Example #19
0
		// necessary wrapper for main CalcRotate, should always be called.
		private void CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect, bool levelingOff = false, IMyEntity targetEntity = null)
		{
			CheckGrid();
			myThrust.Update();

			if (!levelingOff)
			{
				if (ThrustersOverWorked())
				{
					myLogger.debugLog("Thrusters overworked; overruling navigator, need to level off", "CalcRotate()");
					if (InGravity_LevelOff())
						return;
					else
						myLogger.alwaysLog("Failed gravity check!", "CalcRotate()", Logger.severity.FATAL);
				}
				if (NavSet.Settings_Current.CollisionAvoidance && !myPathfinder.CanMove && InGravity_LevelOff())
				{
					myLogger.debugLog("Pathfinder preventing movement; level off", "CalcRotate()");
					return;
				}
			}

			Vector3 angleVelocity;
			CalcRotate(localMatrix, Direction, UpDirect, out angleVelocity, targetEntity);
			prevAngleVel = angleVelocity;
		}
Example #20
0
        /// <summary>
        /// Calculates the force necessary to rotate the grid.
        /// </summary>
        /// <param name="Direction">The direction to face the localMatrix in.</param>
        /// <param name="block"></param>
        /// <returns>True iff localMatrix is facing Direction</returns>
        public void CalcRotate(PseudoBlock block, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, IMyEntity targetEntity = null)
        {
            //Log.DebugLog("entered CalcRotate(PseudoBlock block, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, IMyEntity targetEntity = null)", "CalcRotate()");

            CalcRotate(block.LocalMatrix, Direction, UpDirect, targetEntity: targetEntity);
        }
Example #21
0
        /// <summary>
        /// Calculates the force necessary to rotate the grid. Two degrees of freedom are used to rotate forward toward Direction; the remaining degree is used to face upward towards UpDirect.
        /// </summary>
        /// <param name="localMatrix">The matrix to rotate to face the direction, use a block's local matrix or result of GetMatrix()</param>
        /// <param name="Direction">The direction to face the localMatrix in.</param>
        private void in_CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect, IMyEntity targetEntity)
        {
            m_logger.debugLog(Direction == null, "Direction == null", Logger.severity.ERROR);

            m_gyro.Update();
            float minimumMoment = Math.Min(m_gyro.InvertedInertiaMoment.Min(), MaxInverseTensor);
            if (minimumMoment <= 0f)
            {
                // == 0f, not calculated yet. < 0f, we have math failure
                StopRotate();
                m_logger.debugLog(minimumMoment < 0f, "minimumMoment < 0f", Logger.severity.FATAL);
                return;
            }

            localMatrix.M41 = 0; localMatrix.M42 = 0; localMatrix.M43 = 0; localMatrix.M44 = 1;
            Matrix inverted; Matrix.Invert(ref localMatrix, out inverted);

            localMatrix = localMatrix.GetOrientation();
            inverted = inverted.GetOrientation();

            Vector3 localDirect = Direction.ToLocalNormalized();
            Vector3 rotBlockDirect; Vector3.Transform(ref localDirect, ref inverted, out rotBlockDirect);

            float azimuth, elevation; Vector3.GetAzimuthAndElevation(rotBlockDirect, out azimuth, out elevation);

            Vector3 rotaRight = localMatrix.Right;
            Vector3 rotaUp = localMatrix.Up;

            Vector3 NFR_right = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaRight));
            Vector3 NFR_up = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaUp));

            Vector3 displacement = -elevation * NFR_right - azimuth * NFR_up;

            if (UpDirect != null)
            {
                Vector3 upLocal = UpDirect.ToLocalNormalized();
                Vector3 upRotBlock; Vector3.Transform(ref upLocal, ref inverted, out upRotBlock);
                upRotBlock.Z = 0f;
                upRotBlock.Normalize();
                float roll = Math.Sign(upRotBlock.X) * (float)Math.Acos(MathHelper.Clamp(upRotBlock.Y, -1f, 1f));

                Vector3 rotaBackward = localMatrix.Backward;
                Vector3 NFR_backward = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaBackward));

                //m_logger.debugLog("upLocal: " + upLocal + ", upRotBlock: " + upRotBlock + ", roll: " + roll + ", displacement: " + displacement + ", NFR_backward: " + NFR_backward + ", change: " + roll * NFR_backward, "in_CalcRotate()");

                displacement += roll * NFR_backward;
            }

            m_lastMoveAttempt = Globals.UpdateCount;
            Pathfinder.TestRotate(displacement);

            switch (Pathfinder.m_rotateState)
            {
                case Autopilot.Pathfinder.Pathfinder.PathState.Not_Running:
                    m_logger.debugLog("Pathfinder not run yet: " + Pathfinder.m_rotateState);
                    m_lastMove = Globals.UpdateCount;
                    return;
                case Autopilot.Pathfinder.Pathfinder.PathState.No_Obstruction:
                    break;
                default:
                    m_logger.debugLog("Pathfinder not allowing rotation: " + Pathfinder.m_rotateState);
                    return;
            }

            float distanceAngle = displacement.Length();
            if (distanceAngle < m_bestAngle || float.IsNaN(m_navSet.Settings_Current.DistanceAngle))
            {
                m_bestAngle = distanceAngle;
                m_lastMove = Globals.UpdateCount;
            }
            m_navSet.Settings_Task_NavWay.DistanceAngle = distanceAngle;

            //myLogger.debugLog("localDirect: " + localDirect + ", rotBlockDirect: " + rotBlockDirect + ", elevation: " + elevation + ", NFR_right: " + NFR_right + ", azimuth: " + azimuth + ", NFR_up: " + NFR_up + ", disp: " + displacement, "in_CalcRotate()");

            m_rotateTargetVelocity = MaxAngleVelocity(displacement, minimumMoment, targetEntity != null);

            // adjustment to face a moving entity
            if (targetEntity != null)
            {
                Vector3 relativeLinearVelocity = targetEntity.GetLinearVelocity() - LinearVelocity;
                float distance = Vector3.Distance(targetEntity.GetCentre(), Block.CubeBlock.GetPosition());

                //myLogger.debugLog("relativeLinearVelocity: " + relativeLinearVelocity + ", tangentialVelocity: " + tangentialVelocity + ", localTangVel: " + localTangVel, "in_CalcRotate()");

                float RLV_pitch = Vector3.Dot(relativeLinearVelocity, Block.CubeBlock.WorldMatrix.Down);
                float RLV_yaw = Vector3.Dot(relativeLinearVelocity, Block.CubeBlock.WorldMatrix.Right);
                float angl_pitch = (float)Math.Atan2(RLV_pitch, distance);
                float angl_yaw = (float)Math.Atan2(RLV_yaw, distance);

                m_logger.debugLog("relativeLinearVelocity: " + relativeLinearVelocity + ", RLV_yaw: " + RLV_yaw + ", RLV_pitch: " + RLV_pitch + ", angl_yaw: " + angl_yaw + ", angl_pitch: " + angl_pitch + ", total adjustment: " + (NFR_right * angl_pitch + NFR_up * angl_yaw));

                m_rotateTargetVelocity += NFR_right * angl_pitch + NFR_up * angl_yaw;
            }
            //m_logger.debugLog("targetVelocity: " + m_rotateTargetVelocity, "in_CalcRotate()");

            // angular velocity is reversed
            Vector3 angularVelocity = AngularVelocity.ToBlock(Block.CubeBlock);// ((DirectionWorld)(-Block.Physics.AngularVelocity)).ToBlock(Block.CubeBlock);
            m_rotateForceRatio = (m_rotateTargetVelocity + angularVelocity) / (minimumMoment * m_gyro.GyroForce);

            m_logger.debugLog("targetVelocity: " + m_rotateTargetVelocity + ", angularVelocity: " + angularVelocity + ", accel: " + (m_rotateTargetVelocity + angularVelocity));
            m_logger.debugLog("minimumMoment: " + minimumMoment + ", force: " + m_gyro.GyroForce + ", rotateForceRatio: " + m_rotateForceRatio);

            // dampeners
            for (int index = 0; index < 3; index++)
            {
                // if targetVelocity is close to 0, use dampeners

                float target = m_rotateTargetVelocity.GetDim(index);
                if (target > -0.01f && target < 0.01f)
                {
                    //m_logger.debugLog("target near 0 for " + i + ", " + target, "in_CalcRotate()");
                    m_rotateTargetVelocity.SetDim(index, 0f);
                    m_rotateForceRatio.SetDim(index, 0f);
                    continue;
                }

            }
        }
Example #22
0
        private void CalcRotate_InGravity(RelativeDirection3F direction)
        {
            //m_logger.debugLog("entered CalcRotate_InGravity(RelativeDirection3F direction)", "CalcRotate_InGravity()");

            float secondaryAccel = Thrust.SecondaryForce / Block.Physics.Mass;

            RelativeDirection3F fightGrav = RelativeDirection3F.FromLocal(Block.CubeGrid, -Thrust.LocalGravity.vector);
            if (secondaryAccel > Thrust.GravityStrength)
            {
                // secondary thrusters are strong enough to fight gravity
                if (Vector3.Dot(direction.ToLocalNormalized(), fightGrav.ToLocalNormalized()) > 0f)
                {
                    // direction is away from gravity
                    m_logger.debugLog("Facing primary towards direction(" + direction.ToLocalNormalized() + "), rolling secondary away from gravity(" + fightGrav.ToLocalNormalized() + ")");
                    CalcRotate(Thrust.Standard.LocalMatrix, direction, fightGrav, gravityAdjusted: true);
                    return;
                }
                else
                {
                    // direction is towards gravity
                    m_logger.debugLog("Facing secondary away from gravity(" + fightGrav.ToLocalNormalized() + "), rolling primary towards direction(" + direction.ToLocalNormalized() + ")");
                    CalcRotate(Thrust.Gravity.LocalMatrix, fightGrav, direction, gravityAdjusted: true);
                    return;
                }
            }

            // secondary thrusters are not strong enough to fight gravity

            if (secondaryAccel > 1f)
            {
                m_logger.debugLog("Facing primary towards gravity(" + fightGrav.ToLocalNormalized() + "), rolling secondary towards direction(" + direction.ToLocalNormalized() + ")");
                CalcRotate(Thrust.Standard.LocalMatrix, fightGrav, direction, gravityAdjusted: true);
                return;
            }

            // helicopter

            float primaryAccel = Math.Max(Thrust.PrimaryForce / Block.Physics.Mass - Thrust.GravityStrength, 1f); // obviously less than actual value but we do not need maximum theoretical acceleration

            DirectionGrid moveAccel = m_moveAccel != Vector3.Zero ? ((DirectionBlock)m_moveAccel).ToGrid(Block.CubeBlock) : LinearVelocity.ToGrid(Block.CubeGrid) * -0.5f;

            if (moveAccel.vector.LengthSquared() > primaryAccel * primaryAccel)
            {
                //myLogger.debugLog("move accel is over available acceleration: " + moveAccel.vector.Length() + " > " + primaryAccel, "CalcRotate_InGravity()");
                moveAccel = Vector3.Normalize(moveAccel.vector) * primaryAccel;
            }

            m_logger.debugLog("Facing primary away from gravity and towards direction, moveAccel: " + moveAccel + ", fight gravity: " + fightGrav.ToLocal() + ", direction: " + direction.ToLocalNormalized() + ", new direction: " + (moveAccel + fightGrav.ToLocal()));

            Vector3 dirV = moveAccel + fightGrav.ToLocal();
            direction = RelativeDirection3F.FromLocal(Block.CubeGrid, dirV);
            CalcRotate(Thrust.Standard.LocalMatrix, direction, gravityAdjusted: true);

            Vector3 fightGravDirection = fightGrav.ToLocal() / Thrust.GravityStrength;

            // determine acceleration needed in forward direction to move to desired altitude or remain at current altitude
            float projectionMagnitude = Vector3.Dot(dirV, fightGravDirection) / Vector3.Dot(Thrust.Standard.LocalMatrix.Forward, fightGravDirection);
            Vector3 projectionDirection = ((DirectionGrid)Thrust.Standard.LocalMatrix.Forward).ToBlock(Block.CubeBlock);

            m_moveForceRatio = projectionDirection * projectionMagnitude * Block.CubeGrid.Physics.Mass / Thrust.PrimaryForce;
            m_logger.debugLog("changed moveForceRatio, projectionMagnitude: " + projectionMagnitude + ", projectionDirection: " + projectionDirection + ", moveForceRatio: " + m_moveForceRatio);
        }
Example #23
0
		/// <summary>
		/// Calculates the force necessary to rotate the grid.
		/// </summary>
		/// <param name="localMatrix">The matrix to rotate to face the direction, use a block's local matrix or result of GetMatrix()</param>
		/// <param name="Direction">The direction to face the localMatrix in.</param>
		/// <param name="angularVelocity">The local angular velocity of the controlling block.</param>
		private void CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect, out Vector3 angularVelocity, IMyEntity targetEntity)
		{
			myLogger.debugLog(Direction == null, "Direction == null", "CalcRotate()", Logger.severity.ERROR);

			angularVelocity = -Vector3.Transform(Block.Physics.AngularVelocity, Block.CubeBlock.WorldMatrixNormalizedInv.GetOrientation());

			//myLogger.debugLog("angular: " + angularVelocity, "CalcRotate()");
			float gyroForce = myGyro.TotalGyroForce();

			float secondsSinceLast = (float)(DateTime.UtcNow - updated_prevAngleVel).TotalSeconds;
			updated_prevAngleVel = DateTime.UtcNow;

			if (rotateForceRatio != Vector3.Zero)
			{
				if (secondsSinceLast <= MaxUpdateSeconds)
				{
					Vector3 ratio = (angularVelocity - prevAngleVel) / (rotateForceRatio * gyroForce * secondsSinceLast);

					//myLogger.debugLog("rotateForceRatio: " + rotateForceRatio + ", ratio: " + ratio + ", accel: " + (angularVelocity - prevAngleVel) + ", torque: " + (rotateForceRatio * gyroForce), "CalcRotate()");

					myGyro.Update_torqueAccelRatio(rotateForceRatio, ratio);
				}
				else
					myLogger.debugLog("prevAngleVel is old: " + secondsSinceLast, "CalcRotate()", Logger.severity.DEBUG);
			}

			localMatrix.M41 = 0; localMatrix.M42 = 0; localMatrix.M43 = 0; localMatrix.M44 = 1;
			Matrix inverted; Matrix.Invert(ref localMatrix, out inverted);

			localMatrix = localMatrix.GetOrientation();
			inverted = inverted.GetOrientation();

			//myLogger.debugLog("local matrix: right: " + localMatrix.Right + ", up: " + localMatrix.Up + ", back: " + localMatrix.Backward + ", trans: " + localMatrix.Translation, "CalcRotate()");
			//myLogger.debugLog("inverted matrix: right: " + inverted.Right + ", up: " + inverted.Up + ", back: " + inverted.Backward + ", trans: " + inverted.Translation, "CalcRotate()");
			//myLogger.debugLog("local matrix: " + localMatrix, "CalcRotate()");
			//myLogger.debugLog("inverted matrix: " + inverted, "CalcRotate()");

			Vector3 localDirect = Direction.ToLocal();
			Vector3 rotBlockDirect; Vector3.Transform(ref localDirect, ref inverted, out rotBlockDirect);

			rotBlockDirect.Normalize();

			float azimuth, elevation; Vector3.GetAzimuthAndElevation(rotBlockDirect, out azimuth, out elevation);

			Vector3 rotaRight = localMatrix.Right;
			Vector3 rotaUp = localMatrix.Up;

			Vector3 NFR_right = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaRight));
			Vector3 NFR_up = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaUp));

			Vector3 displacement = -elevation * NFR_right - azimuth * NFR_up;

			if (UpDirect != null)
			{
				Vector3 upLocal = UpDirect.ToLocal();
				Vector3 upRotBlock; Vector3.Transform(ref upLocal, ref inverted, out upRotBlock);
				float roll; Vector3.Dot(ref upRotBlock, ref Vector3.Right, out roll);

				Vector3 rotaBackward = localMatrix.Backward;
				Vector3 NFR_backward = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaBackward));

				myLogger.debugLog("roll: " + roll + ", displacement: " + displacement + ", NFR_backward: " + NFR_backward + ", change: " + (roll * NFR_backward), "CalcRotate()");

				displacement += roll * NFR_backward;
			}

			NavSet.Settings_Task_NavWay.DistanceAngle = displacement.Length();

			if (NavSet.Settings_Current.CollisionAvoidance)
			{
				myPathfinder.TestRotate(displacement);
				if (!myPathfinder.CanRotate)
				{
					// if cannot rotate and not calculating move, move away from obstruction
					if (myPathfinder.RotateObstruction != null && Globals.UpdateCount >= m_notCalcMove)
					{
						Vector3 position  = Block.CubeBlock.GetPosition();
						Vector3 away = position - myPathfinder.RotateObstruction.GetCentre();
						away.Normalize();
						myLogger.debugLog("Cannot rotate and not calculating move, creating GOLIS to move away from obstruction", "CalcRotate()", Logger.severity.INFO);
						new GOLIS(this, NavSet, position + away * (10f + NavSet.Settings_Current.DestinationRadius), true);
					}
					Logger.debugNotify("Cannot Rotate", 50);
					myLogger.debugLog("Pathfinder not allowing rotation", "CalcRotate()");
					return;
				}
			}

			//myLogger.debugLog("localDirect: " + localDirect + ", rotBlockDirect: " + rotBlockDirect + ", elevation: " + elevation + ", NFR_right: " + NFR_right + ", azimuth: " + azimuth + ", NFR_up: " + NFR_up + ", disp: " + displacement, "CalcRotate()");

			if (myGyro.torqueAccelRatio == 0)
			{
				// do a test
				myLogger.debugLog("torqueAccelRatio == 0", "CalcRotate()");
				rotateForceRatio = new Vector3(0, 1f, 0);
				return;
			}

			Vector3 targetVelocity = MaxAngleVelocity(displacement, secondsSinceLast);

			if (targetEntity != null)
			{
				Vector3 relativeLinearVelocity = targetEntity.GetLinearVelocity() - Block.Physics.LinearVelocity;
				float distance = Vector3.Distance(targetEntity.GetCentre(), Block.CubeBlock.GetPosition());
				//Vector3 tangentialVelocity = Vector3.Reject(relativeLinearVelocity, targetEntity.GetCentre() - Block.CubeBlock.GetPosition());
				//Vector3 localTangVel = Vector3.Transform(tangentialVelocity, Block.CubeBlock.WorldMatrixNormalizedInv.GetOrientation());

				//myLogger.debugLog("relativeLinearVelocity: " + relativeLinearVelocity + ", tangentialVelocity: " + tangentialVelocity + ", localTangVel: " + localTangVel, "CalcRotate()");

				float RLV_pitch = Vector3.Dot(relativeLinearVelocity, Block.CubeBlock.WorldMatrix.Up);
				float RLV_yaw = Vector3.Dot(relativeLinearVelocity, Block.CubeBlock.WorldMatrix.Left);
				float angl_pitch = (float)Math.Atan2(RLV_pitch, distance);
				float angl_yaw = (float)Math.Atan2(RLV_yaw, distance);

				myLogger.debugLog("relativeLinearVelocity: " + relativeLinearVelocity + ", RLV_yaw: " + RLV_yaw + ", RLV_pitch: " + RLV_pitch + ", angl_yaw: " + angl_yaw + ", angl_pitch: " + angl_pitch, "CalcRotate()");

				targetVelocity += new Vector3(angl_pitch, angl_yaw, 0f);
			}

			Vector3 accel = (targetVelocity - angularVelocity) / secondsSinceLast;

			rotateForceRatio = accel / (myGyro.torqueAccelRatio * secondsSinceLast * gyroForce);

			myLogger.debugLog("targetVelocity: " + targetVelocity + ", angularVelocity: " + angularVelocity + ", accel: " + accel, "CalcRotate()");
			myLogger.debugLog("accel: " + accel + ", torque: " + (myGyro.torqueAccelRatio * secondsSinceLast * gyroForce) + ", rotateForceRatio: " + rotateForceRatio, "CalcRotate()");

			// dampeners
			for (int i = 0; i < 3; i++)
			{
				// if targetVelocity is close to 0, use dampeners

				float target = targetVelocity.GetDim(i);
				if (target > -0.01f && target < 0.01f)
				{
					//myLogger.debugLog("target near 0 for " + i + ", " + target, "CalcRotate()");
					rotateForceRatio.SetDim(i, 0f);
					continue;
				}
			}
		}
Example #24
0
 public void Rotate()
 {
     m_mover.CalcRotate(m_welder, RelativeDirection3F.FromWorld(m_welder.Grid, m_targetWorld - m_welder.WorldPosition));
 }
Example #25
0
        /// <remarks>
        /// Must execute regularly on game thread.
        /// </remarks>
        protected override void Update1_GameThread()
        {
            if (!MyAPIGateway.Multiplayer.IsServer)
            {
                return;
            }

            if (CurrentControl == Control.Off)
            {
#if USE_AI
                if (!myTurret.AIEnabled)
#endif
                {
                    setElevation = myTurret.Elevation;
                    setAzimuth   = myTurret.Azimuth;
                }
                return;
            }

            // CurrentTarget may be changed by WeaponTargeting
            Target GotTarget = CurrentTarget;
            if (GotTarget.Entity == null)
            {
                //FireWeapon = false;
                return;
            }
            if (!GotTarget.FiringDirection.HasValue || !GotTarget.ContactPoint.HasValue)             // happens alot
            {
                return;
            }

#if USE_AI
            // broken in UNSTABLE
            if (myTurret.AIEnabled)
            {
                myTurret.SetTarget(ProjectilePosition() + GotTarget.FiringDirection.Value * 1000f);
                return;
            }
#endif

            //Vector3 RotateTo = RelativeVector3F.createFromWorld(GotTarget.FiringDirection.Value, weapon.CubeGrid).getBlock(weapon);
            Vector3 RotateToDirection = RelativeDirection3F.FromWorld(CubeBlock.CubeGrid, GotTarget.FiringDirection.Value).ToBlockNormalized(CubeBlock);
            //Log.DebugLog("FiringDirection = " + GotTarget.FiringDirection.Value + ", RotateToDirection = " + RotateToDirection, "Update()");

            float targetElevation, targetAzimuth;             // the position of the target
            Vector3.GetAzimuthAndElevation(RotateToDirection, out targetAzimuth, out targetElevation);
            if (!targetElevation.IsValid() || !targetAzimuth.IsValid())
            {
                //Log.DebugLog("cannot rotate, invalid el(" + targetElevation + ") or az(" + targetAzimuth + ")", "RotateAndFire()");
                return;
            }

            // should azimuth rotate past 180°?
            if (Can360 && Math.Abs(setAzimuth - targetAzimuth) > Math.PI)
            {
                if (targetAzimuth < 0)
                {
                    targetAzimuth += MathHelper.TwoPi;
                }
                else
                {
                    targetAzimuth -= MathHelper.TwoPi;
                }
            }

            // add amount based on speed
            float nextElevation, nextAzimuth;
            if (targetElevation > setElevation)
            {
                nextElevation = Math.Min(targetElevation, setElevation + speedElevation);
            }
            else if (targetElevation < setElevation)
            {
                nextElevation = Math.Max(targetElevation, setElevation - speedElevation);
            }
            else
            {
                nextElevation = setElevation;
            }

            if (targetAzimuth > setAzimuth)
            {
                nextAzimuth = Math.Min(targetAzimuth, setAzimuth + speedAzimuth);
            }
            else if (targetAzimuth < setAzimuth)
            {
                nextAzimuth = Math.Max(targetAzimuth, setAzimuth - speedAzimuth);
            }
            else
            {
                nextAzimuth = setAzimuth;
            }

            // impose limits
            if (nextElevation < minElevation)
            {
                nextElevation = minElevation;
            }
            else if (nextElevation > maxElevation)
            {
                nextElevation = maxElevation;
            }

            if (!Can360)
            {
                if (nextAzimuth < minAzimuth)
                {
                    nextAzimuth = minAzimuth;
                }
                else if (nextAzimuth > maxAzimuth)
                {
                    nextAzimuth = maxAzimuth;
                }
            }

            //Log.DebugLog("next elevation = " + nextElevation + ", next azimuth = " + nextAzimuth, "RotateAndFire()");

            // apply changes
            if (nextElevation != myTurret.Elevation)
            {
                myTurret.Elevation = nextElevation;
                myTurret.SyncElevation();
            }
            //else
            //	Log.DebugLog("not setting elevation", "RotateAndFire()");
            if (nextAzimuth != myTurret.Azimuth)
            {
                myTurret.Azimuth = nextAzimuth;
                myTurret.SyncAzimuth();
            }
            //else
            //	Log.DebugLog("not setting azimuth", "RotateAndFire()");

            setElevation = nextElevation;
            setAzimuth   = nextAzimuth;
        }
Example #26
0
        private void CalcRotate_InGravity(RelativeDirection3F direction)
        {
            //Log.DebugLog("entered CalcRotate_InGravity(RelativeDirection3F direction)", "CalcRotate_InGravity()");

            float secondaryAccel = Thrust.SecondaryForce / Block.Physics.Mass;

            RelativeDirection3F fightGrav = RelativeDirection3F.FromLocal(Block.CubeGrid, -Thrust.LocalGravity.vector);

            if (secondaryAccel > Thrust.GravityStrength)
            {
                // secondary thrusters are strong enough to fight gravity
                if (Vector3.Dot(direction.ToLocalNormalized(), fightGrav.ToLocalNormalized()) > 0f)
                {
                    // direction is away from gravity
                    Log.DebugLog("Facing primary towards direction(" + direction.ToLocalNormalized() + "), rolling secondary away from gravity(" + fightGrav.ToLocalNormalized() + ")");
                    CalcRotate(Thrust.Standard.LocalMatrix, direction, fightGrav, gravityAdjusted: true);
                    return;
                }
                else
                {
                    // direction is towards gravity
                    Log.DebugLog("Facing secondary away from gravity(" + fightGrav.ToLocalNormalized() + "), rolling primary towards direction(" + direction.ToLocalNormalized() + ")");
                    CalcRotate(Thrust.Gravity.LocalMatrix, fightGrav, direction, gravityAdjusted: true);
                    return;
                }
            }

            // secondary thrusters are not strong enough to fight gravity

            if (secondaryAccel > 1f)
            {
                Log.DebugLog("Facing primary towards gravity(" + fightGrav.ToLocalNormalized() + "), rolling secondary towards direction(" + direction.ToLocalNormalized() + ")");
                CalcRotate(Thrust.Standard.LocalMatrix, fightGrav, direction, gravityAdjusted: true);
                return;
            }

            // helicopter

            float primaryAccel = Math.Max(Thrust.PrimaryForce / Block.Physics.Mass - Thrust.GravityStrength, 1f);             // obviously less than actual value but we do not need maximum theoretical acceleration

            DirectionGrid moveAccel = m_moveAccel != Vector3.Zero ? ((DirectionBlock)m_moveAccel).ToGrid(Block.CubeBlock) : LinearVelocity.ToGrid(Block.CubeGrid) * -0.5f;

            if (moveAccel.vector.LengthSquared() > primaryAccel * primaryAccel)
            {
                //Log.DebugLog("move accel is over available acceleration: " + moveAccel.vector.Length() + " > " + primaryAccel, "CalcRotate_InGravity()");
                moveAccel = Vector3.Normalize(moveAccel.vector) * primaryAccel;
            }

            //Log.DebugLog("Facing primary away from gravity and towards direction, moveAccel: " + moveAccel + ", fight gravity: " + fightGrav.ToLocal() + ", direction: " + direction.ToLocalNormalized() + ", new direction: " + (moveAccel + fightGrav.ToLocal()));

            Vector3 dirV = moveAccel + fightGrav.ToLocal();

            direction = RelativeDirection3F.FromLocal(Block.CubeGrid, dirV);
            CalcRotate(Thrust.Standard.LocalMatrix, direction, gravityAdjusted: true);

            Vector3 fightGravDirection = fightGrav.ToLocal() / Thrust.GravityStrength;

            // determine acceleration needed in forward direction to move to desired altitude or remain at current altitude
            float   projectionMagnitude = Vector3.Dot(dirV, fightGravDirection) / Vector3.Dot(Thrust.Standard.LocalMatrix.Forward, fightGravDirection);
            Vector3 projectionDirection = ((DirectionGrid)Thrust.Standard.LocalMatrix.Forward).ToBlock(Block.CubeBlock);

            m_moveForceRatio = projectionDirection * projectionMagnitude * Block.CubeGrid.Physics.Mass / Thrust.PrimaryForce;
            Log.DebugLog("changed moveForceRatio, projectionMagnitude: " + projectionMagnitude + ", projectionDirection: " + projectionDirection + ", moveForceRatio: " + m_moveForceRatio);
        }
Example #27
0
        /// <summary>
        /// Calculates the force necessary to rotate the grid. Two degrees of freedom are used to rotate forward toward Direction; the remaining degree is used to face upward towards UpDirect.
        /// </summary>
        /// <param name="localMatrix">The matrix to rotate to face the direction, use a block's local matrix or result of GetMatrix()</param>
        /// <param name="Direction">The direction to face the localMatrix in.</param>
        private void in_CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect, IMyEntity targetEntity)
        {
            Log.DebugLog("Direction == null", Logger.severity.ERROR, condition: Direction == null);

            m_gyro.Update();
            float minimumMoment = Math.Min(m_gyro.InvertedInertiaMoment.Min(), MaxInverseTensor);

            if (minimumMoment <= 0f)
            {
                // == 0f, not calculated yet. < 0f, we have math failure
                StopRotate();
                Log.DebugLog("minimumMoment < 0f", Logger.severity.FATAL, condition: minimumMoment < 0f);
                return;
            }

            localMatrix.M41 = 0; localMatrix.M42 = 0; localMatrix.M43 = 0; localMatrix.M44 = 1;
            Matrix inverted; Matrix.Invert(ref localMatrix, out inverted);

            localMatrix = localMatrix.GetOrientation();
            inverted    = inverted.GetOrientation();

            Vector3 localDirect = Direction.ToLocalNormalized();
            Vector3 rotBlockDirect; Vector3.Transform(ref localDirect, ref inverted, out rotBlockDirect);

            float azimuth, elevation; Vector3.GetAzimuthAndElevation(rotBlockDirect, out azimuth, out elevation);

            Vector3 rotaRight = localMatrix.Right;
            Vector3 rotaUp    = localMatrix.Up;

            Vector3 NFR_right = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaRight));
            Vector3 NFR_up    = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaUp));

            Vector3 displacement = -elevation * NFR_right - azimuth * NFR_up;

            if (UpDirect != null)
            {
                Vector3 upLocal = UpDirect.ToLocalNormalized();
                Vector3 upRotBlock; Vector3.Transform(ref upLocal, ref inverted, out upRotBlock);
                upRotBlock.Z = 0f;
                upRotBlock.Normalize();
                float roll = Math.Sign(upRotBlock.X) * (float)Math.Acos(MathHelper.Clamp(upRotBlock.Y, -1f, 1f));

                Vector3 rotaBackward = localMatrix.Backward;
                Vector3 NFR_backward = Base6Directions.GetVector(Block.CubeBlock.LocalMatrix.GetClosestDirection(ref rotaBackward));

                //Log.DebugLog("upLocal: " + upLocal + ", upRotBlock: " + upRotBlock + ", roll: " + roll + ", displacement: " + displacement + ", NFR_backward: " + NFR_backward + ", change: " + roll * NFR_backward, "in_CalcRotate()");

                displacement += roll * NFR_backward;
            }

            m_lastMoveAttempt = Globals.UpdateCount;
            RotateCheck.TestRotate(displacement);

            float distanceAngle = displacement.Length();

            //if (distanceAngle < m_bestAngle || float.IsNaN(NavSet.Settings_Current.DistanceAngle))
            //{
            //	m_bestAngle = distanceAngle;
            //	if (RotateCheck.ObstructingEntity == null)
            //		m_lastAccel = Globals.UpdateCount;
            //}
            NavSet.Settings_Task_NavWay.DistanceAngle = distanceAngle;

            //Log.DebugLog("localDirect: " + localDirect + ", rotBlockDirect: " + rotBlockDirect + ", elevation: " + elevation + ", NFR_right: " + NFR_right + ", azimuth: " + azimuth + ", NFR_up: " + NFR_up + ", disp: " + displacement, "in_CalcRotate()");

            m_rotateTargetVelocity = MaxAngleVelocity(displacement, minimumMoment, targetEntity != null);

            // adjustment to face a moving entity
            if (targetEntity != null)
            {
                Vector3 relativeLinearVelocity = (targetEntity.GetLinearVelocity() - LinearVelocity) * 1.1f;
                float   distance = Vector3.Distance(targetEntity.GetCentre(), Block.CubeBlock.GetPosition());

                //Log.DebugLog("relativeLinearVelocity: " + relativeLinearVelocity + ", tangentialVelocity: " + tangentialVelocity + ", localTangVel: " + localTangVel, "in_CalcRotate()");

                float RLV_pitch  = Vector3.Dot(relativeLinearVelocity, Block.CubeBlock.WorldMatrix.Down);
                float RLV_yaw    = Vector3.Dot(relativeLinearVelocity, Block.CubeBlock.WorldMatrix.Right);
                float angl_pitch = (float)Math.Atan2(RLV_pitch, distance);
                float angl_yaw   = (float)Math.Atan2(RLV_yaw, distance);

                Log.DebugLog("relativeLinearVelocity: " + relativeLinearVelocity + ", RLV_yaw: " + RLV_yaw + ", RLV_pitch: " + RLV_pitch + ", angl_yaw: " + angl_yaw + ", angl_pitch: " + angl_pitch + ", total adjustment: " + (NFR_right * angl_pitch + NFR_up * angl_yaw));

                m_rotateTargetVelocity += NFR_right * angl_pitch + NFR_up * angl_yaw;
            }
            //Log.DebugLog("targetVelocity: " + m_rotateTargetVelocity, "in_CalcRotate()");

            if (RotateCheck.ObstructingEntity != null)
            {
                float maxVel = (float)Math.Atan2(1d, Block.CubeGrid.LocalVolume.Radius);
                float lenSq  = m_rotateTargetVelocity.LengthSquared();
                if (lenSq > maxVel)
                {
                    Log.DebugLog("Reducing target velocity from " + Math.Sqrt(lenSq) + " to " + maxVel);
                    Vector3 normVel; Vector3.Divide(ref m_rotateTargetVelocity, (float)Math.Sqrt(lenSq), out normVel);
                    Vector3.Multiply(ref normVel, maxVel, out m_rotateTargetVelocity);
                }
            }

            // angular velocity is reversed
            Vector3 angularVelocity = AngularVelocity.ToBlock(Block.CubeBlock);            // ((DirectionWorld)(-Block.Physics.AngularVelocity)).ToBlock(Block.CubeBlock);

            m_rotateForceRatio = (m_rotateTargetVelocity + angularVelocity) / (minimumMoment * m_gyro.GyroForce);

            //Log.DebugLog("targetVelocity: " + m_rotateTargetVelocity + ", angularVelocity: " + angularVelocity + ", accel: " + (m_rotateTargetVelocity + angularVelocity));
            //Log.DebugLog("minimumMoment: " + minimumMoment + ", force: " + m_gyro.GyroForce + ", rotateForceRatio: " + m_rotateForceRatio);

            // dampeners
            for (int index = 0; index < 3; index++)
            {
                // if targetVelocity is close to 0, use dampeners

                float target = m_rotateTargetVelocity.GetDim(index);
                if (target > -0.01f && target < 0.01f)
                {
                    //Log.DebugLog("target near 0 for " + i + ", " + target, "in_CalcRotate()");
                    m_rotateTargetVelocity.SetDim(index, 0f);
                    m_rotateForceRatio.SetDim(index, 0f);
                    continue;
                }
            }
        }
Example #28
0
        // necessary wrapper for main CalcRotate, should always be called.
        private void CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, bool gravityAdjusted = false, IMyEntity targetEntity = null)
        {
            //m_logger.debugLog("entered CalcRotate(Matrix localMatrix, RelativeDirection3F Direction, RelativeDirection3F UpDirect = null, bool levelingOff = false, IMyEntity targetEntity = null)", "CalcRotate()");

            CheckGrid();
            Thrust.Update();

            if (!gravityAdjusted && ThrustersOverWorked())
            {
                CalcRotate_InGravity(Direction);
                return;
            }

            in_CalcRotate(localMatrix, Direction, UpDirect, targetEntity);
        }
Example #29
0
        public void Rotate()
        {
            if (isMiningPlanet)
            {
                switch (m_state)
                {
                case State.Approaching:
                    m_mover.CalcRotate();
                    return;

                case State.Rotating:
                    if (m_navSet.DirectionMatched())
                    {
                        m_logger.debugLog("Finished rotating", Logger.severity.INFO);
                        m_state = State.MoveTo;
                        m_mover.StopRotate();
                        return;
                    }
                    break;
                }
                m_mover.Thrust.Update();
                m_mover.CalcRotate(m_navDrill, RelativeDirection3F.FromWorld(m_controlBlock.CubeGrid, m_mover.Thrust.WorldGravity.vector));
                return;
            }

            switch (m_state)
            {
            case State.Approaching:
                if (m_navSet.DistanceLessThan(m_longestDimension))
                {
                    m_logger.debugLog("closer to destination than longest dim");
                    m_mover.StopRotate();
                }
                else
                {
                    m_mover.CalcRotate();
                }
                return;

            case State.GetTarget:
            case State.Mining_Escape:
            case State.Move_Away:
                m_logger.debugLog("no rotation");
                m_mover.StopRotate();
                return;

            case State.MoveTo:
            case State.Mining:
            case State.Mining_Tunnel:
                if (m_navSet.DistanceLessThan(3f))
                {
                    m_mover.StopRotate();
                    return;
                }
                break;

            case State.Rotating:
                if (m_navSet.DirectionMatched())
                {
                    m_logger.debugLog("Finished rotating", Logger.severity.INFO);
                    m_state = State.MoveTo;
                    m_mover.StopRotate();
                    return;
                }
                break;

            default:
                throw new Exception("case not implemented: " + m_state);
            }

            if (m_navDrill.FunctionalBlocks == 0)
            {
                m_logger.debugLog("no functional blocks, cannot rotate");
                m_mover.StopRotate();
            }
            else
            {
                m_logger.debugLog("rotate to face " + m_currentTarget);
                m_mover.CalcRotate(m_navDrill, RelativeDirection3F.FromWorld(m_controlBlock.CubeGrid, m_currentTarget - m_navDrill.WorldPosition));
            }
        }
Example #30
0
 /// <summary>
 /// Calculates the rotation to face the rotation block towards the target.
 /// </summary>
 public override void Rotate()
 {
     m_mover.CalcRotate(m_pseudoBlock, RelativeDirection3F.FromWorld(m_pseudoBlock.Block.CubeGrid, TargetDirection()));
 }