コード例 #1
0
        //Standard Guidance Routine
        #region RdavNav Missile Guidance #RFC#

        /*=================================================
         * RdavNav
         * ---------------------------------------     */
        void STD_GUIDANCE(MISSILE This_Missile)
        {
            //Targeting Module
            //-----------------------------------------------

            //Retrieves Target Position
            var This_Missile_Director = This_Missile.TURRET as IMyLargeTurretBase;
            var ENEMY_POS             = new Vector3D();

            //Logical Determination Of Enemy Position
            if (This_Missile_Director.GetTargetedEntity().IsEmpty() == false)
            {
                ENEMY_POS = This_Missile_Director.GetTargetedEntity().Position;                 //Also based on position for critical hits
            }
            //else if (!(This_Missile.TARGET_PREV_POS == null)) //new Vector3D()
            //{ENEMY_POS = This_Missile.TARGET_PREV_POS;}
            else
            {
                ENEMY_POS = RC.GetPosition() + RC.WorldMatrix.Forward * ((This_Missile.GYRO.GetPosition() - Me.GetPosition()).Length() + 300);
            }

            //Sorts CurrentVelocities
            Vector3D MissilePosition     = This_Missile.GYRO.CubeGrid.WorldVolume.Center;
            Vector3D MissilePositionPrev = This_Missile.MIS_PREV_POS;
            Vector3D MissileVelocity     = (MissilePosition - MissilePositionPrev) / Global_Timestep;

            Vector3D TargetPosition     = ENEMY_POS;
            Vector3D TargetPositionPrev = This_Missile.TARGET_PREV_POS;
            Vector3D TargetVelocity     = (TargetPosition - This_Missile.TARGET_PREV_POS) / Global_Timestep;

            //Uses RdavNav Navigation APN Guidance System
            //-----------------------------------------------

            //Setup LOS rates and PN system
            Vector3D LOS_Old = Vector3D.Normalize(TargetPositionPrev - MissilePositionPrev);
            Vector3D LOS_New = Vector3D.Normalize(TargetPosition - MissilePosition);
            Vector3D Rel_Vel = Vector3D.Normalize(TargetVelocity - MissileVelocity);

            //And Assigners
            Vector3D am = new Vector3D(1, 0, 0); double LOS_Rate; Vector3D LOS_Delta;
            Vector3D MissileForwards = This_Missile.THRUSTERS[0].WorldMatrix.Backward;

            //Vector/Rotation Rates
            if (LOS_Old.Length() == 0)
            {
                LOS_Delta = new Vector3D(0, 0, 0); LOS_Rate = 0.0;
            }
            else
            {
                LOS_Delta = LOS_New - LOS_Old; LOS_Rate = LOS_Delta.Length() / Global_Timestep;
            }

            //-----------------------------------------------

            //Closing Velocity
            double Vclosing          = (TargetVelocity - MissileVelocity).Length();

            //If Under Gravity Use Gravitational Accel
            Vector3D GravityComp = -RC.GetNaturalGravity();

            //Calculate the final lateral acceleration
            Vector3D LateralDirection             = Vector3D.Normalize(Vector3D.Cross(Vector3D.Cross(Rel_Vel, LOS_New), Rel_Vel));
            Vector3D LateralAccelerationComponent = LateralDirection * PNGain * LOS_Rate * Vclosing + LOS_Delta * 9.8 * (0.5 * PNGain);             //Eases Onto Target Collision LOS_Delta * 9.8 * (0.5 * Gain)

            //If Impossible Solution (ie maxes turn rate) Use Drift Cancelling For Minimum T
            double OversteerReqt = (LateralAccelerationComponent).Length() / This_Missile.MissileAccel;

            if (OversteerReqt > 0.98)
            {
                LateralAccelerationComponent = This_Missile.MissileAccel * Vector3D.Normalize(LateralAccelerationComponent + (OversteerReqt * Vector3D.Normalize(-MissileVelocity)) * 40);
            }

            //Calculates And Applies Thrust In Correct Direction (Performs own inequality check)
            double ThrustPower = RdavUtils.Vector_Projection_Scalar(MissileForwards, Vector3D.Normalize(LateralAccelerationComponent));             //TESTTESTTEST

            ThrustPower = This_Missile.IsLargeGrid ? MathHelper.Clamp(ThrustPower, 0.9, 1) : ThrustPower;
            //MathHelper.Clamp(ThrustPower, 0.6, 1); //for improved thrust performance
            foreach (IMyThrust thruster in This_Missile.THRUSTERS)
            {
                if (thruster.ThrustOverride != (thruster.MaxThrust * ThrustPower))                 //12 increment inequality to help conserve on performance
                {
                    thruster.ThrustOverride = (float)(thruster.MaxThrust * ThrustPower);
                }
            }

            //Calculates Remaining Force Component And Adds Along LOS
            double RejectedAccel = Math.Sqrt(This_Missile.MissileAccel * This_Missile.MissileAccel - LateralAccelerationComponent.LengthSquared());             //Accel has to be determined whichever way you slice it

            if (double.IsNaN(RejectedAccel))
            {
                RejectedAccel = 0;
            }
            LateralAccelerationComponent = LateralAccelerationComponent + LOS_New * RejectedAccel;

            //-----------------------------------------------

            //Guides To Target Using Gyros
            am = Vector3D.Normalize(LateralAccelerationComponent + GravityComp);
            double Yaw; double Pitch;

            GyroTurn6(am, 18, 0.3, This_Missile.THRUSTERS[0], This_Missile.GYRO as IMyGyro, This_Missile.PREV_Yaw, This_Missile.PREV_Pitch, out Pitch, out Yaw);

            //Updates For Next Tick Round
            This_Missile.TARGET_PREV_POS = TargetPosition;
            This_Missile.MIS_PREV_POS    = MissilePosition;
            This_Missile.PREV_Yaw        = Yaw;
            This_Missile.PREV_Pitch      = Pitch;

            //Detonates warheads in close proximity
            if ((TargetPosition - MissilePosition).LengthSquared() < 20 * 20 && This_Missile.WARHEADS.Count > 0)             //Arms
            {
                foreach (var item in This_Missile.WARHEADS)
                {
                    (item as IMyWarhead).IsArmed = true;
                }
            }
            if ((TargetPosition - MissilePosition).LengthSquared() < This_Missile.FuseDistance * This_Missile.FuseDistance && This_Missile.WARHEADS.Count > 0)             //A mighty earth shattering kaboom
            {
                (This_Missile.WARHEADS[0] as IMyWarhead).Detonate();
            }
        }
コード例 #2
0
        void Guidance(Missile missile)
        {
            //Finds Current Target
            Vector3D ENEMY_POS = EnemyScan(missile);

            //---------------------------------------------------------------------------------------------------------------------------------

            //Sorts CurrentVelocities
            Vector3D MissilePosition     = missile.m_gyroBlock.CubeGrid.WorldVolume.Center;
            Vector3D MissilePositionPrev = missile.MIS_PREV_POS;
            Vector3D MissileVelocity     = (MissilePosition - MissilePositionPrev) / m_program.m_globalTimestep;

            Vector3D TargetPosition     = ENEMY_POS;
            Vector3D TargetPositionPrev = missile.TARGET_PREV_POS;
            Vector3D TargetVelocity     = (TargetPosition - missile.TARGET_PREV_POS) / m_program.m_globalTimestep;

            //Uses RdavNav Navigation APN Guidance System
            //-----------------------------------------------

            //Setup LOS rates and PN system
            Vector3D LOS_Old = Vector3D.Normalize(TargetPositionPrev - MissilePositionPrev);
            Vector3D LOS_New = Vector3D.Normalize(TargetPosition - MissilePosition);
            Vector3D Rel_Vel = Vector3D.Normalize(TargetVelocity - MissileVelocity);

            //And Assigners
            Vector3D am = new Vector3D(1, 0, 0); double LOS_Rate; Vector3D LOS_Delta;
            Vector3D MissileForwards = missile.m_thrusterBlockList[0].WorldMatrix.Backward;

            //Vector/Rotation Rates
            if (LOS_Old.Length() == 0)
            {
                LOS_Delta = new Vector3D(0, 0, 0); LOS_Rate = 0.0;
            }
            else
            {
                LOS_Delta = LOS_New - LOS_Old; LOS_Rate = LOS_Delta.Length() / m_program.m_globalTimestep;
            }

            //-----------------------------------------------

            //Closing Velocity
            double Vclosing          = (TargetVelocity - MissileVelocity).Length();

            //If Under Gravity Use Gravitational Accel
            Vector3D GravityComp = -m_program.m_RC.GetNaturalGravity();

            //Calculate the final lateral acceleration
            Vector3D LateralDirection             = Vector3D.Normalize(Vector3D.Cross(Vector3D.Cross(Rel_Vel, LOS_New), Rel_Vel));
            Vector3D LateralAccelerationComponent = LateralDirection * m_program.m_PNGain * LOS_Rate * Vclosing + LOS_Delta * 9.8 * (0.5 * m_program.m_PNGain); //Eases Onto Target Collision LOS_Delta * 9.8 * (0.5 * Gain)

            //If Impossible Solution (ie maxes turn rate) Use Drift Cancelling For Minimum T
            double OversteerReqt = (LateralAccelerationComponent).Length() / missile.MissileAccel;

            if (OversteerReqt > 0.98)
            {
                LateralAccelerationComponent = missile.MissileAccel * Vector3D.Normalize(LateralAccelerationComponent + (OversteerReqt * Vector3D.Normalize(-MissileVelocity)) * 40);
            }

            //Calculates And Applies Thrust In Correct Direction (Performs own inequality check)
            double ThrustPower = RdavUtils.Vector_Projection_Scalar(MissileForwards, Vector3D.Normalize(LateralAccelerationComponent)); //TESTTESTTEST

            ThrustPower = missile.IsLargeGrid ? MathHelper.Clamp(ThrustPower, 0.9, 1) : ThrustPower;

            ThrustPower = MathHelper.Clamp(ThrustPower, 0.4, 1); //for improved thrust performance on the get-go
            foreach (IMyThrust thruster in missile.m_thrusterBlockList)
            {
                if (thruster.ThrustOverride != (thruster.MaxThrust * ThrustPower)) //12 increment inequality to help conserve on performance
                {
                    thruster.ThrustOverride = (float)(thruster.MaxThrust * ThrustPower);
                }
            }

            //Calculates Remaining Force Component And Adds Along LOS
            double RejectedAccel = Math.Sqrt(missile.MissileAccel * missile.MissileAccel - LateralAccelerationComponent.LengthSquared()); //Accel has to be determined whichever way you slice it

            if (double.IsNaN(RejectedAccel))
            {
                RejectedAccel = 0;
            }
            LateralAccelerationComponent = LateralAccelerationComponent + LOS_New * RejectedAccel;

            //-----------------------------------------------

            //Guides To Target Using Gyros
            am = Vector3D.Normalize(LateralAccelerationComponent + GravityComp);
            double Yaw; double Pitch;

            GyroTurn6(am, 18, 0.3, missile.m_thrusterBlockList[0], missile.m_gyroBlock as IMyGyro, missile.PREV_Yaw, missile.PREV_Pitch, out Pitch, out Yaw);

            //Updates For Next Tick Round
            missile.TARGET_PREV_POS = TargetPosition;
            missile.MIS_PREV_POS    = MissilePosition;
            missile.PREV_Yaw        = Yaw;
            missile.PREV_Pitch      = Pitch;

            //Detonates warheads in close proximity
            if ((TargetPosition - MissilePosition).LengthSquared() < 20 * 20 && missile.m_warheadBlockList.Count > 0) //Arms
            {
                foreach (var item in missile.m_warheadBlockList)
                {
                    (item as IMyWarhead).IsArmed = true;
                }
            }
            if ((TargetPosition - MissilePosition).LengthSquared() < missile.FuseDistance * missile.FuseDistance && missile.m_warheadBlockList.Count > 0) //A mighty earth shattering kaboom
            {
                (missile.m_warheadBlockList[0] as IMyWarhead).Detonate();
            }
        }