Пример #1
0
        void RegainEnergy(FlightCtrlState s)
        {
            debugString += "\nRegaining energy";
            steerMode    = SteerModes.Aiming;
            Vector3 planarDirection = Vector3.ProjectOnPlane(vessel.srf_velocity, upDirection);
            float   angle           = (Mathf.Clamp(MissileGuidance.GetRadarAltitude(vessel) - minAltitude, 0, 1500) / 1500) * 90;

            angle = Mathf.Clamp(angle, 0, 55) * Mathf.Deg2Rad;
            Vector3 targetDirection = Vector3.RotateTowards(planarDirection, -upDirection, angle, 0).normalized;

            AdjustThrottle(maxSpeed, false);
            FlyToPosition(s, vesselTransform.position + (targetDirection * 100));
        }
Пример #2
0
        void TakeOff(FlightCtrlState s)
        {
            threatLevel  = 1;
            debugString += "\nTaking off/Gaining altitude";

            if (vessel.Landed && vessel.srfSpeed < takeOffSpeed)
            {
                defaultOrbitCoords = VectorUtils.WorldPositionToGeoCoords(vessel.transform.position, vessel.mainBody);
                return;
            }

            steerMode = SteerModes.Aiming;

            float radarAlt = MissileGuidance.GetRadarAltitude(vessel);

            Vector3 forwardPoint = vessel.transform.position + Vector3.ProjectOnPlane(vesselTransform.up * 100, upDirection);
            float   terrainDiff  = MissileGuidance.GetRaycastRadarAltitude(forwardPoint) - radarAlt;

            terrainDiff = Mathf.Max(terrainDiff, 0);

            float rise = Mathf.Clamp((float)vessel.srfSpeed * 0.3f, 5, 100);

            if (radarAlt > 70)
            {
                vessel.ActionGroups.SetGroup(KSPActionGroup.Gear, false);
            }
            else
            {
                vessel.ActionGroups.SetGroup(KSPActionGroup.Gear, true);
            }

            FlyToPosition(s, forwardPoint + (upDirection * (rise + terrainDiff)));

            if (radarAlt > minAltitude)
            {
                startedLanded = false;
            }
        }
Пример #3
0
        void FlyToTargetVessel(FlightCtrlState s, Vessel v)
        {
            Vector3 target = v.CoM;
            MissileLauncher missile = null;
            Vector3 vectorToTarget = v.transform.position - vesselTransform.position;
            float distanceToTarget = vectorToTarget.magnitude;
            if(weaponManager)
            {
                missile = weaponManager.currentMissile;
                if(missile != null)
                {
                    if(missile.GetWeaponClass() == WeaponClasses.Missile)
                    {
                        if(missile.targetingMode == MissileLauncher.TargetingModes.Heat && !weaponManager.heatTarget.exists)
                        {
                            target += v.srf_velocity.normalized * 10;
                        }
                        else
                        {
                            target = MissileGuidance.GetAirToAirFireSolution(missile, v);
                        }

                        if(Vector3.Angle(target - vesselTransform.position, vesselTransform.forward) < 20f)
                        {
                            steerMode = SteerModes.Aiming;
                        }
                    }
                    else //bombing
                    {
                        if(Vector3.Angle(target - vesselTransform.position, vesselTransform.up) < 45f)
                        {
                            /*
                            target = GetSurfacePosition(target) + (vessel.upAxis * vessel.altitude);
                            Vector3 fixedTDir = Quaternion.FromToRotation(Vector3.ProjectOnPlane(vessel.srf_velocity, vessel.upAxis), target - vesselTransform.position) * (target - vesselTransform.position);
                            target = FlightPosition(vesselTransform.position + fixedTDir, Mathf.Max(defaultAltitude - 500f, minAltitude));
                            */

                            target = target+(Mathf.Max(defaultAltitude - 500f, minAltitude)*upDirection);
                            Vector3 tDir = (target-vesselTransform.position).normalized;
                            tDir = (1000 * tDir) - (vessel.srf_velocity.normalized * 600);
                            target = vesselTransform.position + tDir;

                        }
                        else
                        {
                            target = target+(Mathf.Max(defaultAltitude - 500f, minAltitude)*upDirection);
                        }
                    }
                }
                else
                {
                    ModuleWeapon weapon = weaponManager.currentGun;
                    if(weapon!=null)
                    {
                        //target -= 1.30f*weapon.GetLeadOffset();
                        Vector3 leadOffset = weapon.GetLeadOffset();

                        float targetAngVel = 1.65f * Vector3.Angle(v.transform.position - vessel.transform.position, v.transform.position + (vessel.srf_velocity) - vessel.transform.position);
                        debugString += "\ntargetAngVel: " + targetAngVel;
                        float magnifier = Mathf.Clamp(targetAngVel, 1.25f, 3);
                        magnifier += (0.5f * Mathf.Sin(Time.time / 2));
                        target -= magnifier * leadOffset;
                        float angleToLead = Vector3.Angle(vesselTransform.up, target - vesselTransform.position);
                        if(distanceToTarget < weaponManager.gunRange &&  angleToLead < 20)
                        {
                            steerMode = SteerModes.Aiming; //steer to aim
                        }

                        if(v.LandedOrSplashed)
                        {
                            if(distanceToTarget > defaultAltitude * 2.2f)
                            {
                                target = FlightPosition(target, defaultAltitude);
                            }
                            else
                            {
                                steerMode = SteerModes.Aiming;
                            }
                        }
                        else if(distanceToTarget > weaponManager.gunRange * 1.5f || Vector3.Dot(target-vesselTransform.position, vesselTransform.up) < 0)
                        {
                            target = v.CoM;
                        }
                    }
                }
            }

            float targetDot = Vector3.Dot(vesselTransform.up, v.transform.position-vessel.transform.position);

            //manage speed when close to enemy
            float finalMaxSpeed = maxSpeed;
            if(targetDot > 0)
            {
                finalMaxSpeed = Mathf.Max((distanceToTarget - 100) / 8, 0) + (float)v.srfSpeed;
                finalMaxSpeed = Mathf.Max(finalMaxSpeed, minSpeed);
            }
            AdjustThrottle(finalMaxSpeed, true);

            if((targetDot < 0 && vessel.srfSpeed > finalMaxSpeed)
                && distanceToTarget < 300 && vessel.srfSpeed < v.srfSpeed * 1.25f && Vector3.Dot(vessel.srf_velocity, v.srf_velocity) > 0) //distance is less than 800m
            {
                debugString += ("\nEnemy on tail. Braking");
                AdjustThrottle(minSpeed, true);
            }
            if(missile!=null
                && targetDot > 0
                && distanceToTarget < 300
               && vessel.srfSpeed > 130)
            {
                extending = true;
                lastTargetPosition = v.transform.position;
            }

            FlyToPosition(s, target);
        }
Пример #4
0
        void FlyToPosition(FlightCtrlState s, Vector3 targetPosition)
        {
            if(!startedLanded)
            {
                targetPosition = FlightPosition(targetPosition, minAltitude);
                targetPosition = vesselTransform.position + ((targetPosition - vesselTransform.position).normalized * 100);
            }

            Vector3d srfVel = vessel.srf_velocity;
            if(srfVel != Vector3d.zero)
            {
                velocityTransform.rotation = Quaternion.LookRotation(srfVel, -vesselTransform.forward);
            }
            velocityTransform.rotation = Quaternion.AngleAxis(90, velocityTransform.right) * velocityTransform.rotation;
            Vector3 localAngVel = vessel.angularVelocity;

            if(BDArmorySettings.DRAW_DEBUG_LINES)
            {
                flyingToPosition = targetPosition;
            }

            //test poststall
            float AoA = Vector3.Angle(vessel.ReferenceTransform.up, vessel.srf_velocity);
            if(AoA > 30f)
            {
                steerMode = SteerModes.Aiming;
            }

            //slow down for tighter turns
            float velAngleToTarget = Vector3.Angle(targetPosition-vesselTransform.position, vessel.srf_velocity);
            float normVelAngleToTarget = Mathf.Clamp(velAngleToTarget, 0, 90)/90;
            float speedReductionFactor = 1.25f;
            float finalSpeed = Mathf.Min(speedController.targetSpeed, Mathf.Clamp(maxSpeed - (speedReductionFactor * normVelAngleToTarget), idleSpeed, maxSpeed));
            debugString += "\nFinal Target Speed: " + finalSpeed.ToString("0.0");
            AdjustThrottle(finalSpeed, useBrakes, useAB);

            Vector3 targetDirection;
            Vector3 targetDirectionYaw;
            float yawError;
            float pitchError;
            float postYawFactor;
            float postPitchFactor;
            if(steerMode == SteerModes.NormalFlight)
            {
                targetDirection = velocityTransform.InverseTransformDirection(targetPosition - velocityTransform.position).normalized;
                targetDirection = Vector3.RotateTowards(Vector3.up, targetDirection, 45 * Mathf.Deg2Rad, 0);

                targetDirectionYaw = vesselTransform.InverseTransformDirection(vessel.srf_velocity).normalized;
                targetDirectionYaw = Vector3.RotateTowards(Vector3.up, targetDirectionYaw, 45 * Mathf.Deg2Rad, 0);

                postYawFactor = 0.5f;
                postPitchFactor = 1;

            }
            else//(steerMode == SteerModes.Aiming)
            {
                targetDirection = vesselTransform.InverseTransformDirection(targetPosition-vesselTransform.position).normalized;
                targetDirection = Vector3.RotateTowards(Vector3.up, targetDirection, 25 * Mathf.Deg2Rad, 0);
                targetDirectionYaw = targetDirection;

                if(command == PilotCommands.Follow)
                {
                    postYawFactor = 0.45f;
                    postPitchFactor = 1f;
                }
                else
                {
                    postYawFactor = 1.75f;
                    postPitchFactor = 2f;
                }
            }

            pitchError = VectorUtils.SignedAngle(Vector3.up, Vector3.ProjectOnPlane(targetDirection, Vector3.right), Vector3.back);
            yawError = VectorUtils.SignedAngle(Vector3.up, Vector3.ProjectOnPlane(targetDirectionYaw, Vector3.forward), Vector3.right);

            float finalMaxSteer = threatLevel * maxSteer;

            float steerPitch = (postPitchFactor * 0.015f * steerMult * pitchError) - (postPitchFactor * steerDamping * -localAngVel.x);
            float steerYaw = (postYawFactor * 0.020f * steerMult * yawError) - (postYawFactor * steerDamping * 0.6f * -localAngVel.z);

            s.yaw = Mathf.Clamp(steerYaw, -finalMaxSteer, finalMaxSteer);
            s.pitch = Mathf.Clamp(steerPitch, Mathf.Min(-finalMaxSteer, -0.2f), finalMaxSteer);

            //roll
            Vector3 currentRoll = -vesselTransform.forward;
            Vector3 rollTarget;

            //if(steerMode == SteerModes.Aiming || angleToTarget > 2)
            //{
                rollTarget = (targetPosition + ((steerMode == SteerModes.Aiming ? 10f : 25f) * upDirection)) - vesselTransform.position;
            //}
            //else
            //{
            //	rollTarget = upDirection;
            //}

            if(command == PilotCommands.Follow && useRollHint)
            {
                rollTarget = -commandLeader.vessel.ReferenceTransform.forward;
            }

            rollTarget = Vector3.ProjectOnPlane(rollTarget, vesselTransform.up);

            float rollError = Misc.SignedAngle(currentRoll, rollTarget, vesselTransform.right);
            debugString += "\nRoll offset: "+rollError;
            float steerRoll = (steerMult * 0.0015f * rollError);
            debugString += "\nSteerRoll: "+steerRoll;
            float rollDamping = (.10f * steerDamping * -localAngVel.y);
            steerRoll -= rollDamping;
            debugString += "\nRollDamping: "+rollDamping;

            float roll = Mathf.Clamp(steerRoll, -maxSteer, maxSteer);
            s.roll = roll;
            //
        }
Пример #5
0
        void AutoPilot(FlightCtrlState s)
        {
            if(!vessel || !vessel.transform || vessel.packed || !vessel.mainBody)
            {
                return;
            }
            vesselTransform = vessel.ReferenceTransform;

            //default brakes off full throttle
            //s.mainThrottle = 1;

            //vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, false);
            AdjustThrottle(maxSpeed, true);
            useAB = true;
            useBrakes = true;
            vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true);

            steerMode = SteerModes.NormalFlight;

            GetGuardTarget();
            if(vessel.LandedOrSplashed && standbyMode && weaponManager && (BDATargetManager.TargetDatabase[BDATargetManager.BoolToTeam(weaponManager.team)].Count == 0||BDArmorySettings.PEACE_MODE))
            {
                //s.mainThrottle = 0;
                //vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, true);
                AdjustThrottle(0, true);
                return;
            }
            //upDirection = -FlightGlobals.getGeeForceAtPosition(transform.position).normalized;
            upDirection = VectorUtils.GetUpDirection(vessel.transform.position);
            debugString = string.Empty;

            CalculateAccelerationAndTurningCircle();
            if (MissileGuidance.GetRadarAltitude(vessel) < MinAltitudeNeeded())
            {
                startedLanded = true;
            }

            if (startedLanded)
            {
                if(command != PilotCommands.Follow)
                {
                    currentStatus = "Gain Alt.";
                }
                TakeOff(s);
                turningTimer = 0;
            }
            else
            {
                if(FlyAvoidCollision(s))
                {
                    turningTimer = 0;
                }
                else if(command != PilotCommands.Free)
                {
                    UpdateCommand(s);
                }
                else
                {
                    UpdateAI(s);
                }
            }
            UpdateGAndAoALimits(s);
            AdjustPitchForGAndAoALimits(s);
            //brake and cut throttle if exceeding max speed
            /*
            if(vessel.srfSpeed > maxSpeed)
            {
                vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, true);
                s.mainThrottle = 0;
            }
            */

            debugString += "\nthreatLevel: " + threatLevel;
        }
Пример #6
0
        void UpdateFollowCommand(FlightCtrlState s)
        {
            threatLevel = 1;
            steerMode = SteerModes.NormalFlight;
            //s.mainThrottle = 1;
            vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, false);

            commandSpeed = commandLeader.vessel.srfSpeed;
            commandHeading = commandLeader.vessel.srf_velocity.normalized;

            //formation position
            commandPosition = GetFormationPosition();

            float distanceToPos = Vector3.Distance(vesselTransform.position, commandPosition);

            //if(distanceToPos > 100)
            //{

            float dotToPos = Vector3.Dot(vesselTransform.up, commandPosition - vesselTransform.position);
            Vector3 flyPos;
            useRollHint = false;

            float ctrlModeThresh = 1000;

            if(distanceToPos < ctrlModeThresh)
            {
                flyPos = commandPosition + (ctrlModeThresh * commandHeading);

                Vector3 vectorToFlyPos = flyPos - vessel.ReferenceTransform.position;
                Vector3 projectedPosOffset = Vector3.ProjectOnPlane(commandPosition - vessel.ReferenceTransform.position, commandHeading);
                float posOffsetMag = projectedPosOffset.magnitude;
                float adjustAngle = (Mathf.Clamp(posOffsetMag * 0.27f, 0, 25));
                Vector3 projVel = Vector3.Project(vessel.srf_velocity - commandLeader.vessel.srf_velocity, projectedPosOffset);
                adjustAngle -= Mathf.Clamp(Mathf.Sign(Vector3.Dot(projVel, projectedPosOffset)) * projVel.magnitude * 0.12f, -10, 10);

                adjustAngle *= Mathf.Deg2Rad;

                vectorToFlyPos = Vector3.RotateTowards(vectorToFlyPos, projectedPosOffset, adjustAngle, 0);

                flyPos = vessel.ReferenceTransform.position + vectorToFlyPos;

                if(distanceToPos < 400)
                {
                    steerMode = SteerModes.Aiming;
                }
                else
                {
                    steerMode = SteerModes.NormalFlight;
                }
                /*
                if(dotToPos < 0)
                {
                    flyPos = commandPosition + (315 * commandHeading);
                    s.mainThrottle = 0;
                    vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, true);

                    steerMode = SteerModes.NormalFlight;
                }
                */
                if(distanceToPos < 10)
                {
                    useRollHint = true;
                }
            }
            else
            {
                steerMode = SteerModes.NormalFlight;
                flyPos = commandPosition;
            }

            double finalMaxSpeed = commandSpeed;
            if(dotToPos > 0)
            {
                finalMaxSpeed += (distanceToPos / 8);
            }
            else
            {
                finalMaxSpeed -= (distanceToPos / 2);
            }

            AdjustThrottle((float)finalMaxSpeed, true);

            FlyToPosition(s, flyPos);
        }
Пример #7
0
        void TakeOff(FlightCtrlState s)
        {
            threatLevel = 1;
            debugString += "\nTaking off/Gaining altitude";

            if(vessel.LandedOrSplashed && vessel.srfSpeed < takeOffSpeed)
            {
                defaultOrbitCoords = VectorUtils.WorldPositionToGeoCoords(vessel.transform.position, vessel.mainBody);
                return;
            }

            steerMode = SteerModes.Aiming;

            float radarAlt = MissileGuidance.GetRadarAltitude(vessel);

            Vector3 forwardPoint = vessel.transform.position + Vector3.ProjectOnPlane(vesselTransform.up * 100, upDirection);
            float terrainDiff = MissileGuidance.GetRaycastRadarAltitude(forwardPoint) - radarAlt;
            terrainDiff = Mathf.Max(terrainDiff, 0);

            float rise = Mathf.Clamp((float)vessel.srfSpeed * 0.3f, 5, 100);

            if(radarAlt > 70)
            {
                vessel.ActionGroups.SetGroup(KSPActionGroup.Gear, false);
            }
            else
            {
                vessel.ActionGroups.SetGroup(KSPActionGroup.Gear, true);
            }

            FlyToPosition(s, forwardPoint + (upDirection * (rise+terrainDiff)));

            if(radarAlt > minAltitude)
            {
                startedLanded = false;
            }
        }
Пример #8
0
        void RegainEnergy(FlightCtrlState s)
        {
            debugString += "\nRegaining energy";
            steerMode = SteerModes.Aiming;
            Vector3 planarDirection = Vector3.ProjectOnPlane(vessel.srf_velocity, upDirection);
            float angle = (Mathf.Clamp(MissileGuidance.GetRadarAltitude(vessel) - minAltitude, 0, 1500) / 1500) * 90;
            angle = Mathf.Clamp(angle, 0, 55) * Mathf.Deg2Rad;
            Vector3 targetDirection = Vector3.RotateTowards(planarDirection, -upDirection, angle, 0).normalized;

            AdjustThrottle(maxSpeed, false);
            FlyToPosition(s, vesselTransform.position + (targetDirection*100));
        }
Пример #9
0
        void FlyToTargetVessel(FlightCtrlState s, Vessel v)
        {
            Vector3         target           = v.CoM;
            MissileLauncher missile          = null;
            Vector3         vectorToTarget   = v.transform.position - vesselTransform.position;
            float           distanceToTarget = vectorToTarget.magnitude;

            if (weaponManager)
            {
                missile = weaponManager.currentMissile;
                if (missile != null)
                {
                    if (missile.targetingMode == MissileLauncher.TargetingModes.Heat && !weaponManager.heatTarget.exists)
                    {
                        target += v.srf_velocity.normalized * 10;
                    }
                    else
                    {
                        target = MissileGuidance.GetAirToAirFireSolution(missile, v);
                    }

                    if (Vector3.Angle(target - vesselTransform.position, vesselTransform.forward) < 15)
                    {
                        steerMode = SteerModes.Aiming;
                    }
                }
                else
                {
                    ModuleWeapon weapon = weaponManager.currentGun;
                    if (weapon != null)
                    {
                        //target -= 1.30f*weapon.GetLeadOffset();
                        Vector3 leadOffset = weapon.GetLeadOffset();

                        float targetAngVel = 1.65f * Vector3.Angle(v.transform.position - vessel.transform.position, v.transform.position + (vessel.srf_velocity) - vessel.transform.position);
                        debugString += "\ntargetAngVel: " + targetAngVel;
                        float magnifier = Mathf.Clamp(targetAngVel, 1.25f, 5);
                        target -= magnifier * leadOffset;
                        float angleToLead = Vector3.Angle(vesselTransform.up, target - vesselTransform.position);
                        if (distanceToTarget < 1600 && angleToLead < 20)
                        {
                            steerMode = SteerModes.Aiming;                             //steer to aim
                        }
                    }
                }
            }



            float targetDot = Vector3.Dot(vesselTransform.up, v.transform.position - vessel.transform.position);

            //manage speed when close to enemy
            float finalMaxSpeed = ((distanceToTarget - 100) / 8) + (float)v.srfSpeed;

            AdjustThrottle(finalMaxSpeed, true);

            if ((targetDot < 0 || vessel.srfSpeed > finalMaxSpeed) &&
                distanceToTarget < 800)                    //distance is less than 800m
            {
                debugString += ("\nEnemy on tail. Braking");
                AdjustThrottle(minSpeed, true);
            }
            if (missile != null &&
                targetDot > 0 &&
                distanceToTarget < 300 &&
                vessel.srfSpeed > 130)
            {
                extending          = true;
                lastTargetPosition = v.transform.position;
            }


            FlyToPosition(s, target);
        }
Пример #10
0
        void UpdateFollowCommand(FlightCtrlState s)
        {
            threatLevel = 1;
            steerMode   = SteerModes.NormalFlight;
            //s.mainThrottle = 1;
            vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, false);

            commandSpeed   = commandLeader.vessel.srfSpeed;
            commandHeading = commandLeader.vessel.srf_velocity.normalized;

            //formation position
            commandPosition = GetFormationPosition();

            float distanceToPos = Vector3.Distance(vesselTransform.position, commandPosition);

            //if(distanceToPos > 100)
            //{

            float   dotToPos = Vector3.Dot(vesselTransform.up, commandPosition - vesselTransform.position);
            Vector3 flyPos;

            useRollHint = false;

            float ctrlModeThresh = 1000;

            if (distanceToPos < ctrlModeThresh)
            {
                flyPos = commandPosition + (ctrlModeThresh * commandHeading);

                Vector3 vectorToFlyPos     = flyPos - vessel.ReferenceTransform.position;
                Vector3 projectedPosOffset = Vector3.ProjectOnPlane(commandPosition - vessel.ReferenceTransform.position, commandHeading);
                float   posOffsetMag       = projectedPosOffset.magnitude;
                float   adjustAngle        = (Mathf.Clamp(posOffsetMag * 0.27f, 0, 25));
                Vector3 projVel            = Vector3.Project(vessel.srf_velocity - commandLeader.vessel.srf_velocity, projectedPosOffset);
                adjustAngle -= Mathf.Clamp(Mathf.Sign(Vector3.Dot(projVel, projectedPosOffset)) * projVel.magnitude * 0.12f, -10, 10);

                adjustAngle *= Mathf.Deg2Rad;

                vectorToFlyPos = Vector3.RotateTowards(vectorToFlyPos, projectedPosOffset, adjustAngle, 0);

                flyPos = vessel.ReferenceTransform.position + vectorToFlyPos;

                if (distanceToPos < 400)
                {
                    steerMode = SteerModes.Aiming;
                }
                else
                {
                    steerMode = SteerModes.NormalFlight;
                }

                /*
                 * if(dotToPos < 0)
                 * {
                 *      flyPos = commandPosition + (315 * commandHeading);
                 *      s.mainThrottle = 0;
                 *      vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, true);
                 *
                 *      steerMode = SteerModes.NormalFlight;
                 * }
                 */
                if (distanceToPos < 15)
                {
                    useRollHint = true;
                }
            }
            else
            {
                steerMode = SteerModes.NormalFlight;
                flyPos    = commandPosition;
            }

            double finalMaxSpeed = commandSpeed;

            if (dotToPos > 0)
            {
                finalMaxSpeed += (distanceToPos / 8);
            }
            else
            {
                finalMaxSpeed -= (distanceToPos / 2);
            }


            AdjustThrottle((float)finalMaxSpeed, true);


            FlyToPosition(s, flyPos);
        }
Пример #11
0
        void AutoPilot(FlightCtrlState s)
        {
            if (!vessel || !vessel.transform || vessel.packed || !vessel.mainBody)
            {
                return;
            }
            vesselTransform = vessel.ReferenceTransform;

            //default brakes off full throttle
            //s.mainThrottle = 1;

            //vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, false);
            AdjustThrottle(maxSpeed, true);
            useAB     = true;
            useBrakes = true;
            vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true);

            steerMode = SteerModes.NormalFlight;


            GetGuardTarget();
            if (vessel.Landed && standbyMode && weaponManager && BDATargetManager.TargetDatabase[BDATargetManager.BoolToTeam(weaponManager.team)].Count == 0)
            {
                //s.mainThrottle = 0;
                //vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, true);
                AdjustThrottle(0, true);
                return;
            }
            //upDirection = -FlightGlobals.getGeeForceAtPosition(transform.position).normalized;
            upDirection = VectorUtils.GetUpDirection(vessel.transform.position);
            debugString = string.Empty;
            if (MissileGuidance.GetRadarAltitude(vessel) < minAltitude)
            {
                startedLanded = true;
            }



            if (startedLanded)
            {
                TakeOff(s);
                turningTimer = 0;
            }
            else
            {
                if (FlyAvoidCollision(s))
                {
                    turningTimer = 0;
                }
                else if (command != PilotCommands.Free)
                {
                    UpdateCommand(s);
                }
                else
                {
                    UpdateAI(s);
                }
            }

            //brake and cut throttle if exceeding max speed

            /*
             * if(vessel.srfSpeed > maxSpeed)
             * {
             *      vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, true);
             *      s.mainThrottle = 0;
             * }
             */

            debugString += "\nthreatLevel: " + threatLevel;
        }
Пример #12
0
        void Evasive(FlightCtrlState s)
        {
            currentStatus = "Evading";
            debugString += "\nEvasive";
            debugString += "\n Threat Distance: " + weaponManager.incomingMissileDistance;

            collisionDetectionTicker += 2;

            if(weaponManager)
            {
                if(weaponManager.isFlaring)
                {
                    useAB = vessel.srfSpeed < minSpeed;
                    useBrakes = false;
                    float targetSpeed = minSpeed;
                    if(weaponManager.isChaffing)
                    {
                        targetSpeed = maxSpeed;
                    }
                    AdjustThrottle(targetSpeed, false, useAB);
                }

                if((weaponManager.isChaffing || weaponManager.isFlaring) && (weaponManager.incomingMissileDistance > 2000))
                {
                    debugString += "\nBreaking from missile threat!";
                    Vector3 axis = -Vector3.Cross(vesselTransform.up, threatRelativePosition);
                    Vector3 breakDirection = Quaternion.AngleAxis(90, axis) * threatRelativePosition;
                    //Vector3 breakTarget = vesselTransform.position + breakDirection;
                    RegainEnergy(s, breakDirection);
                    return;
                }
                else if(weaponManager.underFire)
                {
                    debugString += "\nDodging gunfire";
                    float threatDirectionFactor = Vector3.Dot(vesselTransform.up, threatRelativePosition.normalized);
                    //Vector3 axis = -Vector3.Cross(vesselTransform.up, threatRelativePosition);

                    Vector3 breakTarget = threatRelativePosition * 2f;       //for the most part, we want to turn _towards_ the threat in order to increase the rel ang vel and get under its guns

                    if (threatDirectionFactor > 0.9f)     //within 28 degrees in front
                    {
                        breakTarget += Vector3.Cross(threatRelativePosition.normalized, Mathf.Sign(Mathf.Sin((float)vessel.missionTime / 2)) * vessel.upAxis);
                        debugString += " from directly ahead!";
                    }
                    else if (threatDirectionFactor < -0.9) //within ~28 degrees behind
                    {
                        float threatDistance = threatRelativePosition.magnitude;
                        if(threatDistance > 400)
                        {
                            breakTarget = vesselTransform.position + vesselTransform.up * 1500 - 500 * vessel.upAxis;
                            breakTarget += Mathf.Sin((float)vessel.missionTime / 2) * vesselTransform.right * 1000 - Mathf.Cos((float)vessel.missionTime / 2) * vesselTransform.forward * 1000;
                            if(threatDistance > 800)
                                debugString += " from behind afar; engaging barrel roll";
                            else
                            {
                                debugString += " from behind moderate distance; engaging aggressvie barrel roll and braking";
                                steerMode = SteerModes.Aiming;
                                AdjustThrottle(minSpeed, true, false);
                            }
                        }
                        else
                        {
                            breakTarget = threatRelativePosition;
                            if (evasiveTimer < 1.5f)
                                breakTarget += Mathf.Sin((float)vessel.missionTime * 2) * vesselTransform.right * 500;
                            else
                                breakTarget += -Math.Sign(Mathf.Sin((float)vessel.missionTime * 2)) * vesselTransform.right * 150;
                            debugString += " from directly behind and close; breaking hard";
                            steerMode = SteerModes.Aiming;
                        }
                    }
                    else
                    {
                        float threatDistance = threatRelativePosition.magnitude;
                        if(threatDistance < 400)
                        {
                            breakTarget += Mathf.Sin((float)vessel.missionTime * 2) * vesselTransform.right * 100;
                            debugString += " from the side; breaking in";
                            steerMode = SteerModes.Aiming;
                        }
                        else
                        {
                            breakTarget = vesselTransform.position + vesselTransform.up * 1500;
                            breakTarget += Mathf.Sin((float)vessel.missionTime / 2) * vesselTransform.right * 1000 - Mathf.Cos((float)vessel.missionTime / 2) * vesselTransform.forward * 1000;
                            debugString += " from far side; engaging barrel roll";
                        }
                    }

                    float threatAltitudeDiff = Vector3.Dot(threatRelativePosition, vessel.upAxis);
                    if (threatAltitudeDiff > 500)
                        breakTarget += threatAltitudeDiff * vessel.upAxis;      //if it's trying to spike us from below, don't go crazy trying to dive below it
                    else
                        breakTarget += - 150 * vessel.upAxis;   //dive a bit to escape

                    FlyToPosition(s, breakTarget);
                    return;

                }
                else if(weaponManager.incomingMissileVessel)
                {
                    float mSqrDist = Vector3.SqrMagnitude(weaponManager.incomingMissileVessel.transform.position - vesselTransform.position);
                    if(mSqrDist < 810000) //900m
                    {
                        debugString += "\nMissile about to impact! pull away!";
                        AdjustThrottle(maxSpeed, false, false);
                        Vector3 cross = Vector3.Cross(weaponManager.incomingMissileVessel.transform.position - vesselTransform.position, vessel.srf_velocity).normalized;
                        if(Vector3.Dot(cross, -vesselTransform.forward) < 0)
                        {
                            cross = -cross;
                        }
                        FlyToPosition(s, vesselTransform.position +(50*vessel.srf_velocity/vessel.srfSpeed)+ (100 * cross));
                        return;
                    }

                }
            }

            Vector3 target = (vessel.srfSpeed < 200) ? FlightPosition(vessel.transform.position, minAltitude) : vesselTransform.position;
            float angleOff = Mathf.Sin(Time.time * 0.75f) * 180;
            angleOff = Mathf.Clamp(angleOff, -45, 45);
            target +=
                (Quaternion.AngleAxis(angleOff, upDirection) * Vector3.ProjectOnPlane(vesselTransform.up * 500, upDirection));
            //+ (Mathf.Sin (Time.time/3) * upDirection * minAltitude/3);

            FlyToPosition(s, target);
        }
Пример #13
0
        void FlyToTargetVessel(FlightCtrlState s, Vessel v)
        {
            Vector3 target = v.CoM;
            MissileLauncher missile = null;
            Vector3 vectorToTarget = v.transform.position - vesselTransform.position;
            float distanceToTarget = vectorToTarget.magnitude;
            float planarDistanceToTarget = Vector3.ProjectOnPlane(vectorToTarget, upDirection).magnitude;
            float angleToTarget = Vector3.Angle(target - vesselTransform.position, vesselTransform.up);
            if(weaponManager)
            {
                missile = weaponManager.currentMissile;
                if(missile != null)
                {
                    if(missile.GetWeaponClass() == WeaponClasses.Missile)
                    {
                        if(distanceToTarget > 5500f)
                        {
                            finalMaxSteer = GetSteerLimiterForSpeedAndPower();
                        }

                        if(missile.targetingMode == MissileLauncher.TargetingModes.Heat && !weaponManager.heatTarget.exists)
                        {
                            debugString += "\nAttempting heat lock";
                            target += v.srf_velocity.normalized * 10;
                        }
                        else
                        {
                            target = MissileGuidance.GetAirToAirFireSolution(missile, v);
                        }

                        if(angleToTarget < 20f)
                        {
                            steerMode = SteerModes.Aiming;
                        }
                    }
                    else //bombing
                    {
                        if(distanceToTarget > 4500f)
                        {
                            finalMaxSteer = GetSteerLimiterForSpeedAndPower();
                        }

                        if(angleToTarget < 45f)
                        {
                            /*
                            target = GetSurfacePosition(target) + (vessel.upAxis * vessel.altitude);
                            Vector3 fixedTDir = Quaternion.FromToRotation(Vector3.ProjectOnPlane(vessel.srf_velocity, vessel.upAxis), target - vesselTransform.position) * (target - vesselTransform.position);
                            target = FlightPosition(vesselTransform.position + fixedTDir, Mathf.Max(defaultAltitude - 500f, minAltitude));
                            */

                            target = target + (Mathf.Max(defaultAltitude - 500f, minAltitude) * upDirection);
                            Vector3 tDir = (target - vesselTransform.position).normalized;
                            tDir = (1000 * tDir) - (vessel.srf_velocity.normalized * 600);
                            target = vesselTransform.position + tDir;

                        }
                        else
                        {
                            target = target + (Mathf.Max(defaultAltitude - 500f, minAltitude) * upDirection);
                        }
                    }
                }
                else if(weaponManager.currentGun)
                {
                    ModuleWeapon weapon = weaponManager.currentGun;
                    if(weapon != null)
                    {
                        Vector3 leadOffset = weapon.GetLeadOffset();

                        float targetAngVel = Vector3.Angle(v.transform.position - vessel.transform.position, v.transform.position + (vessel.srf_velocity) - vessel.transform.position);
                        debugString += "\ntargetAngVel: " + targetAngVel;
                        float magnifier = Mathf.Clamp(targetAngVel, 1f, 2f);
                        magnifier += ((magnifier-1f) * Mathf.Sin(Time.time *0.75f));
                        target -= magnifier * leadOffset;

                        angleToTarget = Vector3.Angle(vesselTransform.up, target - vesselTransform.position);
                        if(distanceToTarget < weaponManager.gunRange && angleToTarget < 20)
                        {
                            steerMode = SteerModes.Aiming; //steer to aim
                        }
                        else
                        {
                            if(distanceToTarget > 3500f || vessel.srfSpeed < takeOffSpeed)
                            {
                                finalMaxSteer = GetSteerLimiterForSpeedAndPower();
                            }
                            else
                            {
                                //figuring how much to lead the target's movement to get there after its movement assuming we can manage a constant speed turn
                                //this only runs if we're not aiming and not that far from the target
                                float curVesselMaxAccel = Math.Min(maxDynPresGRecorded * (float)vessel.dynamicPressurekPa, maxAllowedGForce * 9.81f);
                                if (curVesselMaxAccel > 0)
                                {
                                    float timeToTurn = (float)vessel.srfSpeed * angleToTarget * Mathf.Deg2Rad / curVesselMaxAccel;
                                    target += v.srf_velocity * timeToTurn;
                                    //target += 0.5f * v.acceleration * timeToTurn * timeToTurn;
                                }
                            }
                        }

                        if(v.LandedOrSplashed)
                        {
                            if(distanceToTarget > defaultAltitude * 2.2f)
                            {
                                target = FlightPosition(target, defaultAltitude);
                            }
                            else
                            {
                                steerMode = SteerModes.Aiming;
                            }
                        }
                        else if(distanceToTarget > weaponManager.gunRange * 1.5f || Vector3.Dot(target - vesselTransform.position, vesselTransform.up) < 0)
                        {
                            target = v.CoM;
                        }
                    }
                }
                else if(planarDistanceToTarget > weaponManager.gunRange * 1.25f && (vessel.altitude < targetVessel.altitude || MissileGuidance.GetRadarAltitude(vessel) < defaultAltitude)) //climb to target vessel's altitude if lower and still too far for guns
                {
                    finalMaxSteer = GetSteerLimiterForSpeedAndPower();
                    target = vesselTransform.position + GetLimitedClimbDirectionForSpeed(vectorToTarget);
                }
                else
                {
                    finalMaxSteer = GetSteerLimiterForSpeedAndPower();
                }
            }

            float targetDot = Vector3.Dot(vesselTransform.up, v.transform.position-vessel.transform.position);

            //manage speed when close to enemy
            float finalMaxSpeed = maxSpeed;
            if(targetDot > 0)
            {
                finalMaxSpeed = Mathf.Max((distanceToTarget - 100) / 8, 0) + (float)v.srfSpeed;
                finalMaxSpeed = Mathf.Max(finalMaxSpeed, minSpeed+25f);
            }
            AdjustThrottle(finalMaxSpeed, true);

            if((targetDot < 0 && vessel.srfSpeed > finalMaxSpeed)
                && distanceToTarget < 300 && vessel.srfSpeed < v.srfSpeed * 1.25f && Vector3.Dot(vessel.srf_velocity, v.srf_velocity) > 0) //distance is less than 800m
            {
                debugString += ("\nEnemy on tail. Braking");
                AdjustThrottle(minSpeed, true);
            }
            if(missile!=null
                && targetDot > 0
                && distanceToTarget < MissileLaunchParams.GetDynamicLaunchParams(missile, v.srf_velocity, v.transform.position).minLaunchRange
                && vessel.srfSpeed > idleSpeed)
            {
                //extending = true;
                //lastTargetPosition = v.transform.position;
                RequestExtend(lastTargetPosition);
            }

            if(regainEnergy && angleToTarget > 30f)
            {
                RegainEnergy(s, target - vesselTransform.position);
                return;
            }
            else
            {
                useVelRollTarget = true;
                FlyToPosition(s, target);
                return;
            }
        }
Пример #14
0
        void FlyToPosition(FlightCtrlState s, Vector3 targetPosition)
        {
            if(!belowMinAltitude)
            {
                if(weaponManager && Time.time - weaponManager.timeBombReleased < 1.5f)
                {
                    targetPosition = vessel.transform.position + vessel.srf_velocity;
                }

                targetPosition = FlightPosition(targetPosition, minAltitude);
                targetPosition = vesselTransform.position + ((targetPosition - vesselTransform.position).normalized * 100);
            }

            Vector3d srfVel = vessel.srf_velocity;
            if(srfVel != Vector3d.zero)
            {
                velocityTransform.rotation = Quaternion.LookRotation(srfVel, -vesselTransform.forward);
            }
            velocityTransform.rotation = Quaternion.AngleAxis(90, velocityTransform.right) * velocityTransform.rotation;

            //ang vel
            Vector3 localAngVel = vessel.angularVelocity;
            //test
            Vector3 currTargetDir = (targetPosition-vesselTransform.position).normalized;
            if(steerMode == SteerModes.NormalFlight)
            {
                float gRotVel = ((10f * maxAllowedGForce) / ((float)vessel.srfSpeed));
                //currTargetDir = Vector3.RotateTowards(prevTargetDir, currTargetDir, gRotVel*Mathf.Deg2Rad, 0);
            }
            Vector3 targetAngVel = Vector3.Cross(prevTargetDir, currTargetDir)/Time.fixedDeltaTime;
            Vector3 localTargetAngVel = vesselTransform.InverseTransformVector(targetAngVel);
            prevTargetDir = currTargetDir;
            targetPosition = vessel.transform.position + (currTargetDir * 100);

            if(BDArmorySettings.DRAW_DEBUG_LINES)
            {
                flyingToPosition = targetPosition;
            }

            //test poststall
            float AoA = Vector3.Angle(vessel.ReferenceTransform.up, vessel.srf_velocity);
            if(AoA > 30f)
            {
                steerMode = SteerModes.Aiming;
            }

            //slow down for tighter turns
            float velAngleToTarget = Vector3.Angle(targetPosition-vesselTransform.position, vessel.srf_velocity);
            float normVelAngleToTarget = Mathf.Clamp(velAngleToTarget, 0, 90)/90;
            float speedReductionFactor = 1.25f;
            float finalSpeed = Mathf.Min(speedController.targetSpeed, Mathf.Clamp(maxSpeed - (speedReductionFactor * normVelAngleToTarget), idleSpeed, maxSpeed));
            debugString += "\nFinal Target Speed: " + finalSpeed.ToString("0.0");
            AdjustThrottle(finalSpeed, useBrakes, useAB);

            if(steerMode == SteerModes.Aiming)
            {
                localAngVel -= localTargetAngVel;
            }

            Vector3 targetDirection;
            Vector3 targetDirectionYaw;
            float yawError;
            float pitchError;
            //float postYawFactor;
            //float postPitchFactor;
            if(steerMode == SteerModes.NormalFlight)
            {
                targetDirection = velocityTransform.InverseTransformDirection(targetPosition - velocityTransform.position).normalized;
                targetDirection = Vector3.RotateTowards(Vector3.up, targetDirection, 45 * Mathf.Deg2Rad, 0);

                targetDirectionYaw = vesselTransform.InverseTransformDirection(vessel.srf_velocity).normalized;
                targetDirectionYaw = Vector3.RotateTowards(Vector3.up, targetDirectionYaw, 45 * Mathf.Deg2Rad, 0);

                //postYawFactor = 0.25f;
                //postPitchFactor = 0.8f;
            }
            else//(steerMode == SteerModes.Aiming)
            {
                targetDirection = vesselTransform.InverseTransformDirection(targetPosition-vesselTransform.position).normalized;
                targetDirection = Vector3.RotateTowards(Vector3.up, targetDirection, 25 * Mathf.Deg2Rad, 0);
                targetDirectionYaw = targetDirection;

                /*
                if(command == PilotCommands.Follow)
                {
                    postYawFactor = 0.45f;
                    postPitchFactor = 1f;
                }
                else
                {
                    postYawFactor = 1f;
                    postPitchFactor = 1.2f;
                }
                */
            }

            pitchError = VectorUtils.SignedAngle(Vector3.up, Vector3.ProjectOnPlane(targetDirection, Vector3.right), Vector3.back);
            yawError = VectorUtils.SignedAngle(Vector3.up, Vector3.ProjectOnPlane(targetDirectionYaw, Vector3.forward), Vector3.right);

            //test
            debugString += "\n   finalMaxSteer: " + finalMaxSteer;

            //roll
            Vector3 currentRoll = -vesselTransform.forward;
            float rollUp = (steerMode == SteerModes.Aiming ? 5f : 10f);
            if(steerMode == SteerModes.NormalFlight)
            {
                rollUp += (1 - finalMaxSteer) * 10f;
            }
            rollTarget = (targetPosition + (rollUp * upDirection)) - vesselTransform.position;

            //test
            if(steerMode == SteerModes.Aiming && !belowMinAltitude)
            {
                angVelRollTarget = -140 * vesselTransform.TransformVector(Quaternion.AngleAxis(90f, Vector3.up) * localTargetAngVel);
                rollTarget += angVelRollTarget;
            }

            if(command == PilotCommands.Follow && useRollHint)
            {
                rollTarget = -commandLeader.vessel.ReferenceTransform.forward;
            }

            //
            if(belowMinAltitude)
            {
                rollTarget = vessel.upAxis * 100;

            }
            if(useVelRollTarget && !belowMinAltitude)
            {
                rollTarget = Vector3.ProjectOnPlane(rollTarget, vessel.srf_velocity);
                currentRoll = Vector3.ProjectOnPlane(currentRoll, vessel.srf_velocity);
            }
            else
            {
                rollTarget = Vector3.ProjectOnPlane(rollTarget, vesselTransform.up);
            }

            //v/q
            float dynamicAdjustment = Mathf.Clamp(16*(float)(vessel.srfSpeed/vessel.dynamicPressurekPa), 0, 1.2f);

            float rollError = Misc.SignedAngle(currentRoll, rollTarget, vesselTransform.right);
            float steerRoll = (steerMult * 0.0015f * rollError);
            float rollDamping = (.10f * steerDamping * -localAngVel.y);
            steerRoll -= rollDamping;
            steerRoll *= dynamicAdjustment;

            if(steerMode == SteerModes.NormalFlight)
            {
                //premature dive fix
                pitchError = pitchError * Mathf.Clamp01((21 - Mathf.Exp(Mathf.Abs(rollError) / 30)) / 20);
            }

            float steerPitch = (0.015f * steerMult * pitchError) - (steerDamping * -localAngVel.x);
            float steerYaw = (0.005f * steerMult * yawError) - (steerDamping * 0.2f * -localAngVel.z);

            pitchIntegral += pitchError;

            steerPitch *= dynamicAdjustment;
            steerYaw *= dynamicAdjustment;

            float pitchKi = 0.1f * (pitchKiAdjust/5); //This is what should be allowed to be tweaked by the player, just like the steerMult, it is very low right now
            pitchIntegral = Mathf.Clamp(pitchIntegral, -0.2f / (pitchKi * dynamicAdjustment), 0.2f / (pitchKi * dynamicAdjustment)); //0.2f is the limit of the integral variable, making it bigger increases overshoot
            steerPitch += pitchIntegral * pitchKi * dynamicAdjustment; //Adds the integral component to the mix

            float roll = Mathf.Clamp(steerRoll, -maxSteer, maxSteer);
            s.roll = roll;
            s.yaw = Mathf.Clamp(steerYaw, -finalMaxSteer, finalMaxSteer);
            s.pitch = Mathf.Clamp(steerPitch, Mathf.Min(-finalMaxSteer, -0.2f), finalMaxSteer);
        }
Пример #15
0
        void FlyToPosition(FlightCtrlState s, Vector3 targetPosition)
        {
            if(!belowMinAltitude)
            {
                if(weaponManager && Time.time - weaponManager.timeBombReleased < 1.5f)
                {
                    targetPosition = vessel.transform.position + vessel.srf_velocity;
                }

                targetPosition = FlightPosition(targetPosition, minAltitude);
                targetPosition = vesselTransform.position + ((targetPosition - vesselTransform.position).normalized * 100);
            }

            Vector3d srfVel = vessel.srf_velocity;
            if(srfVel != Vector3d.zero)
            {
                velocityTransform.rotation = Quaternion.LookRotation(srfVel, -vesselTransform.forward);
            }
            velocityTransform.rotation = Quaternion.AngleAxis(90, velocityTransform.right) * velocityTransform.rotation;

            //ang vel
            Vector3 localAngVel = vessel.angularVelocity;
            //test
            Vector3 currTargetDir = (targetPosition-vesselTransform.position).normalized;
            if(steerMode == SteerModes.NormalFlight)
            {
                float gRotVel = ((10f * maxAllowedGForce) / ((float)vessel.srfSpeed));
                //currTargetDir = Vector3.RotateTowards(prevTargetDir, currTargetDir, gRotVel*Mathf.Deg2Rad, 0);
            }
            Vector3 targetAngVel = Vector3.Cross(prevTargetDir, currTargetDir)/Time.fixedDeltaTime;
            Vector3 localTargetAngVel = vesselTransform.InverseTransformVector(targetAngVel);
            prevTargetDir = currTargetDir;
            targetPosition = vessel.transform.position + (currTargetDir * 100);

            if(BDArmorySettings.DRAW_DEBUG_LINES)
            {
                flyingToPosition = targetPosition;
            }

            //test poststall
            float AoA = Vector3.Angle(vessel.ReferenceTransform.up, vessel.srf_velocity);
            if(AoA > 30f)
            {
                steerMode = SteerModes.Aiming;
            }

            //slow down for tighter turns
            float velAngleToTarget = Vector3.Angle(targetPosition-vesselTransform.position, vessel.srf_velocity);
            float normVelAngleToTarget = Mathf.Clamp(velAngleToTarget, 0, 90)/90;
            float speedReductionFactor = 1.25f;
            float finalSpeed = Mathf.Min(speedController.targetSpeed, Mathf.Clamp(maxSpeed - (speedReductionFactor * normVelAngleToTarget), idleSpeed, maxSpeed));
            debugString += "\nFinal Target Speed: " + finalSpeed.ToString("0.0");
            AdjustThrottle(finalSpeed, useBrakes, useAB);

            if(steerMode == SteerModes.Aiming)
            {
                localAngVel -= localTargetAngVel;
            }

            Vector3 targetDirection;
            Vector3 targetDirectionYaw;
            float yawError;
            float pitchError;
            float postYawFactor;
            float postPitchFactor;
            if(steerMode == SteerModes.NormalFlight)
            {
                targetDirection = velocityTransform.InverseTransformDirection(targetPosition - velocityTransform.position).normalized;
                targetDirection = Vector3.RotateTowards(Vector3.up, targetDirection, 45 * Mathf.Deg2Rad, 0);

                targetDirectionYaw = vesselTransform.InverseTransformDirection(vessel.srf_velocity).normalized;
                targetDirectionYaw = Vector3.RotateTowards(Vector3.up, targetDirectionYaw, 45 * Mathf.Deg2Rad, 0);

                postYawFactor = 0.25f;
                postPitchFactor = 0.8f;
            }
            else//(steerMode == SteerModes.Aiming)
            {
                targetDirection = vesselTransform.InverseTransformDirection(targetPosition-vesselTransform.position).normalized;
                targetDirection = Vector3.RotateTowards(Vector3.up, targetDirection, 25 * Mathf.Deg2Rad, 0);
                targetDirectionYaw = targetDirection;

                if(command == PilotCommands.Follow)
                {
                    postYawFactor = 0.45f;
                    postPitchFactor = 1f;
                }
                else
                {
                    postYawFactor = 1.75f;
                    postPitchFactor = 2f;
                }
            }

            pitchError = VectorUtils.SignedAngle(Vector3.up, Vector3.ProjectOnPlane(targetDirection, Vector3.right), Vector3.back);
            yawError = VectorUtils.SignedAngle(Vector3.up, Vector3.ProjectOnPlane(targetDirectionYaw, Vector3.forward), Vector3.right);

            //test
            debugString += "\n   finalMaxSteer: " + finalMaxSteer;

            float steerPitch = (postPitchFactor * 0.015f * steerMult * pitchError) - (postPitchFactor * steerDamping * -localAngVel.x);
            float steerYaw = (postYawFactor * 0.020f * steerMult * yawError) - (postYawFactor * steerDamping * 0.64f * -localAngVel.z);

            s.yaw = Mathf.Clamp(steerYaw, -finalMaxSteer, finalMaxSteer);
            s.pitch = Mathf.Clamp(steerPitch, Mathf.Min(-finalMaxSteer, -0.2f), finalMaxSteer);

            //roll
            Vector3 currentRoll = -vesselTransform.forward;
            float rollUp = (steerMode == SteerModes.Aiming ? 5f : 10f);
            if(steerMode == SteerModes.NormalFlight)
            {
                rollUp += (1 - finalMaxSteer) * 10f;
            }
            rollTarget = (targetPosition + (rollUp * upDirection)) - vesselTransform.position;

            //test
            if(steerMode == SteerModes.Aiming && !belowMinAltitude)
            {
                angVelRollTarget = -140 * vesselTransform.TransformVector(Quaternion.AngleAxis(90f, Vector3.up) * localTargetAngVel);
                rollTarget += angVelRollTarget;
            }

            if(command == PilotCommands.Follow && useRollHint)
            {
                rollTarget = -commandLeader.vessel.ReferenceTransform.forward;
            }

            //
            if(belowMinAltitude)
            {
                rollTarget = vessel.upAxis * 100;

            }
            if(useVelRollTarget && !belowMinAltitude)
            {
                rollTarget = Vector3.ProjectOnPlane(rollTarget, vessel.srf_velocity);
                currentRoll = Vector3.ProjectOnPlane(currentRoll, vessel.srf_velocity);
            }
            else
            {
                rollTarget = Vector3.ProjectOnPlane(rollTarget, vesselTransform.up);
            }

            float rollError = Misc.SignedAngle(currentRoll, rollTarget, vesselTransform.right);
            float steerRoll = (steerMult * 0.0015f * rollError);
            float rollDamping = (.10f * steerDamping * -localAngVel.y);
            steerRoll -= rollDamping;

            float roll = Mathf.Clamp(steerRoll, -maxSteer, maxSteer);
            s.roll = roll;
        }
Пример #16
0
        void UpdateFollowCommand(FlightCtrlState s)
        {
            if (!commandLeader)
            {
                ReleaseCommand();
                return;
            }

            threatLevel    = 1;
            steerMode      = SteerModes.NormalFlight;
            s.mainThrottle = 1;
            vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, false);

            commandSpeed   = commandLeader.vessel.srfSpeed;
            commandHeading = commandLeader.vessel.srf_velocity.normalized;

            //formation position
            commandPosition = GetFormationPosition();

            float distanceToPos = Vector3.Distance(vesselTransform.position, commandPosition);

            //if(distanceToPos > 100)
            //{

            float   dotToPos = Vector3.Dot(vesselTransform.up, commandPosition - vesselTransform.position);
            Vector3 flyPos   = commandPosition + (15 * commandHeading);

            useRollHint = false;
            if (distanceToPos < 300)
            {
                steerMode = SteerModes.Aiming;

                if (dotToPos < 0)
                {
                    flyPos         = commandPosition + (315 * commandHeading);
                    s.mainThrottle = 0;
                    vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, true);

                    steerMode = SteerModes.NormalFlight;
                }

                if (distanceToPos < 15)
                {
                    useRollHint = true;
                }
            }

            double finalMaxSpeed = commandSpeed;

            if (dotToPos > 0)
            {
                finalMaxSpeed += (distanceToPos / 8);
            }
            if (vessel.srfSpeed > finalMaxSpeed)
            {
                s.mainThrottle = 0;
                vessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, true);
            }


            FlyToPosition(s, flyPos);
        }