Exemplo n.º 1
0
        public string GetNetworkInfo()
        {
            if (!(HighLogic.LoadedSceneIsFlight || HighLogic.LoadedSceneIsEditor))
            {
                return("Empty");
            }

            string info = FlightGlobals.GetHomeBody().displayName + " Relay Constellation\n";

            homeworldRadius    = FlightGlobals.GetHomeBody().Radius;
            homeworldTopOfAtmo = FlightGlobals.GetHomeBody().atmosphereDepth;
            double rp        = FlightGlobals.GetHomeBody().rotationPeriod;
            double GM        = FlightGlobals.GetHomeBody().gravParameter;
            double geoAlt    = Math.Pow(Math.Pow(rp / (2 * Math.PI), 2) * GM, 1.0 / 3.0) - homeworldRadius;
            double commPower = 0;

            //info += "Radius: " + (homeworldRadius / 1000).ToString("n0") + "km" + "\n";
            //info += "Atmosphere Height: " + (homeworldTopOfAtmo / 1000).ToString("n0") + "km" + "\n";

            // CommNet Math https://wiki.kerbalspaceprogram.com/wiki/CommNet
            double       combStrongestPower      = 0;
            double       combSumOfPowers         = 0;
            double       combWeightedSumOfPowers = 0;
            double       strongestPower          = 0;
            ICommAntenna strongestAntenna        = null;
            bool         thisPartCombinable      = false;
            bool         combinableNotStrongest  = false;

            List <ICommAntenna> antennas;

            if (HighLogic.LoadedSceneIsFlight)
            {
                antennas = vessel.FindPartModulesImplementing <ICommAntenna>();
            }
            else
            {
                antennas = new List <ICommAntenna>();
                foreach (Part p in EditorLogic.fetch.ship.parts)
                {
                    antennas.AddRange(p.FindModulesImplementing <ICommAntenna>());
                }
            }

            foreach (ICommAntenna antenna in antennas)
            {
                if (antenna.CommType == AntennaType.RELAY)
                {
                    if (antenna.CommPower > strongestPower)
                    {
                        strongestAntenna = antenna;
                        strongestPower   = antenna.CommPower;
                    }

                    if (antenna.CommCombinable)
                    {
                        if (antenna.CommPower > combStrongestPower)
                        {
                            combStrongestPower = antenna.CommPower;
                        }
                        combSumOfPowers         += antenna.CommPower;
                        combWeightedSumOfPowers += antenna.CommPower * antenna.CommCombinableExponent;
                    }
                }
            }
            if (combStrongestPower > 0)
            {
                double combAvgCombExponent = combWeightedSumOfPowers / combSumOfPowers;
                commPower = combStrongestPower * Math.Pow(combSumOfPowers / combStrongestPower, combAvgCombExponent);
            }

            if (commPower < strongestPower)
            {
                combinableNotStrongest = true;
                commPower = strongestPower;
            }

            if (commPower > 0)
            {
                // Right triangle
                // a = 1/2 power
                // b = homeworld core to midpoint between sats
                // c = homeworldRadius + sat altitude
                //
                double a = commPower / 2 * 0.8042; // 10% signal strength
                double b = homeworldRadius;
                double c = Math.Sqrt(Math.Pow(b, 2) + Math.Pow(a, 2));
                if (c < homeworldRadius + homeworldTopOfAtmo)
                {
                    c = homeworldRadius + homeworldTopOfAtmo;
                    b = Math.Sqrt(Math.Pow(a, 2) + Math.Pow(c, 2));
                }

                double angleA     = Math.Asin(a / c);
                int    minSats    = (int)Math.Ceiling(Math.PI / angleA);
                double basicPower = 500000 * (homeworldRadius / 600000); // Scaled Communotron 16

                info += "\n<b>Min Sats:</b> " + minSats.ToString("n0") + "\n";
                info += "<b>Best* Alt:</b> " + FormatAltitudeKM(c - homeworldRadius) + "km\n";
                info += "<b>Signal loss to " + FormatAltitudeKM(basicPower) + "K ant:</b> " + FormatAltitudeKM(Math.Sqrt(basicPower * commPower)) + "km\n";
                info += "<b>Geosync:</b> " + Math.Round(geoAlt / 1000, 3).ToString("n3") + "km\n\n";

                c      = homeworldRadius + commPower * 0.8042;
                angleA = Math.Asin(a / c);
                int maxSats = (int)Math.Ceiling(Math.PI / angleA);

                info += "<color=green># Sats: Min / Max Alt / Signal to " + FormatAltitudeKM(basicPower) + "K antenna</color>\n";
                for (int i = minSats; i <= maxSats + 1; i++)
                {
                    //info += "\n";
                    info += GetNetworkInfoLine(i, commPower, basicPower) + "\n";
                }
                info += "\n<i>*Best alt is the altitude where a constellation member can connect to any other member that is over the horizon.</i>";
            }
            else
            {
                info += "No relay antennas found!\n";
                info += "commPower: " + commPower.ToString("n") + "\n";
                info += "antennas: " + antennas.Count.ToString("n") + "\n";
            }

            return(info);
        }
        /// <summary>
        /// Read the part data of an unloaded/loaded vessel and store in data structures
        /// </summary>
        protected List <CNCAntennaPartInfo> readAntennaData()
        {
            List <CNCAntennaPartInfo> antennas = new List <CNCAntennaPartInfo>();
            int numParts = (!this.vessel.loaded) ? this.vessel.protoVessel.protoPartSnapshots.Count : this.vessel.Parts.Count;

            //inspect each part
            for (int partIndex = 0; partIndex < numParts; partIndex++)
            {
                Part thisPart;
                ProtoPartSnapshot partSnapshot = null;

                if (this.Vessel.loaded)
                {
                    thisPart = this.vessel.Parts[partIndex];
                }
                else
                {
                    partSnapshot = this.vessel.protoVessel.protoPartSnapshots[partIndex];
                    thisPart     = partSnapshot.partInfo.partPrefab;
                }

                bool populatedAntennaInfo = false;
                CNCAntennaPartInfo      newAntennaPartInfo = new CNCAntennaPartInfo();;
                ProtoPartModuleSnapshot partModuleSnapshot = null;

                //inspect each module of the part
                for (int moduleIndex = 0; moduleIndex < thisPart.Modules.Count; moduleIndex++)
                {
                    PartModule thisPartModule = thisPart.Modules[moduleIndex];

                    if (thisPartModule is CNConstellationAntennaModule) // is it CNConstellationAntennaModule?
                    {
                        if (!this.Vessel.loaded)
                        {
                            partModuleSnapshot = partSnapshot.FindModule(thisPartModule, moduleIndex);

                            newAntennaPartInfo.frequency = short.Parse(partModuleSnapshot.moduleValues.GetValue("Frequency"));
                            string oname = partModuleSnapshot.moduleValues.GetValue("OptionalName");
                            newAntennaPartInfo.name     = (oname.Length == 0) ? partSnapshot.partInfo.title : oname;
                            newAntennaPartInfo.inUse    = bool.Parse(partModuleSnapshot.moduleValues.GetValue("InUse"));
                            newAntennaPartInfo.CosAngle = double.Parse(partModuleSnapshot.moduleValues.GetValue("CosAngle"));
                        }
                        else
                        {
                            CNConstellationAntennaModule antennaMod = (CNConstellationAntennaModule)thisPartModule;
                            newAntennaPartInfo.frequency = antennaMod.Frequency;
                            newAntennaPartInfo.name      = antennaMod.Name;
                            newAntennaPartInfo.inUse     = antennaMod.InUse;
                        }

                        populatedAntennaInfo = true;
                    }
                    else if (thisPartModule is ICommAntenna) // is it ModuleDataTransmitter?
                    {
                        ICommAntenna thisAntenna = thisPartModule as ICommAntenna;

                        if (!this.Vessel.loaded)
                        {
                            partModuleSnapshot = partSnapshot.FindModule(thisPartModule, moduleIndex);
                        }

                        newAntennaPartInfo.antennaPower              = (!this.vessel.loaded) ? thisAntenna.CommPowerUnloaded(partModuleSnapshot) : thisAntenna.CommPower;
                        newAntennaPartInfo.antennaCombinable         = thisAntenna.CommCombinable;
                        newAntennaPartInfo.antennaCombinableExponent = thisAntenna.CommCombinableExponent;
                        newAntennaPartInfo.antennaType           = thisAntenna.CommType;
                        newAntennaPartInfo.partReference         = thisPart; //unique ID for part is not available
                        newAntennaPartInfo.partSnapshotReference = partSnapshot;
                        newAntennaPartInfo.canComm = (!this.vessel.loaded) ? thisAntenna.CanCommUnloaded(partModuleSnapshot) : thisAntenna.CanComm();

                        populatedAntennaInfo = true;
                    }
                }

                if (populatedAntennaInfo) // valid info?
                {
                    antennas.Add(newAntennaPartInfo);
                    CNCLog.Debug("CommNet Vessel '{0}' has antenna '{1}' of {2} and {3} power (w/o range modifier)", this.Vessel.GetName(), newAntennaPartInfo.name, newAntennaPartInfo.frequency, newAntennaPartInfo.antennaPower);
                }
            }

            return(antennas);
        }
Exemplo n.º 3
0
        public Antenna_Info(Vessel v)
        {
            List <AntennaPartInfo> adaptorsInfoList = new List <AntennaPartInfo>();

            int numParts = (!v.loaded) ? v.protoVessel.protoPartSnapshots.Count : v.Parts.Count;

            for (int partIndex = 0; partIndex < numParts; partIndex++)
            {
                Part part;
                ProtoPartSnapshot protoPart = null;

                if (v.loaded)
                {
                    part = v.Parts[partIndex];
                }
                else
                {
                    protoPart = v.protoVessel.protoPartSnapshots[partIndex];
                    part      = PartLoader.getPartInfoByName(protoPart.partName).partPrefab;
                }

                bool                    hasInfo         = false;
                AntennaPartInfo         antennaPartInfo = new AntennaPartInfo();
                ProtoPartModuleSnapshot protoPartModule = null;

                // Inspect each module of the part
                for (int moduleIndex = 0; moduleIndex < part.Modules.Count; moduleIndex++)
                {
                    NetworkAdaptor antennaMod = new NetworkAdaptor();
                    PartModule     pModule    = part.Modules[moduleIndex];
                    if (pModule is NetworkAdaptor)
                    {
                        if (v.loaded)
                        {
                            antennaMod = (NetworkAdaptor)pModule;
                            antennaPartInfo.frequency = antennaMod.frequency;
                            antennaPartInfo.ecCost    = antennaMod.ecCost;
                            antennaPartInfo.rate      = antennaMod.rate;
                            antennaPartInfo.name      = part.partInfo.title;
                        }
                        else
                        {
                            ProtoPartModuleSnapshot netAdaptor = FlightGlobals.FindProtoPartByID(protoPart.flightID).FindModule("NetworkAdaptor");
                            antennaPartInfo.frequency = Lib.Proto.GetShort(netAdaptor, "frequency");
                            antennaPartInfo.ecCost    = Lib.Proto.GetDouble(netAdaptor, "ecCost");
                            antennaPartInfo.rate      = Lib.Proto.GetDouble(netAdaptor, "rate");
                            antennaPartInfo.name      = protoPart.partInfo.title;
                        }

                        hasInfo = true;
                    }
                    else if (pModule is ICommAntenna)
                    {
                        ICommAntenna antenna = pModule as ICommAntenna;

                        // This method only works when v.Loaded, otherwise this brings a wrong deployState
                        ModuleDeployableAntenna anim = part.FindModuleImplementing <ModuleDeployableAntenna>();

                        // Assume extended if there is no animator
                        if (anim != null)
                        {
                            if (!v.loaded)
                            {
                                // This method works to !v.Loaded
                                ProtoPartModuleSnapshot deployState = FlightGlobals.FindProtoPartByID(protoPart.flightID).FindModule("ModuleDeployableAntenna");
                                antennaPartInfo.deployState = Lib.KCOMMNET.String_to_DeployState(Lib.Proto.GetString(deployState, "deployState"));
                            }
                            else
                            {
                                antennaPartInfo.deployState = anim.deployState;
                            }
                        }
                        else
                        {
                            antennaPartInfo.deployState = ModuleDeployablePart.DeployState.EXTENDED;
                        }

                        if (!v.loaded)
                        {
                            protoPartModule = protoPart.FindModule(pModule, moduleIndex);
                        }

                        antennaPartInfo.antennaPower              = (!v.loaded) ? antenna.CommPowerUnloaded(protoPartModule) : antenna.CommPower;
                        antennaPartInfo.antennaCombinable         = antenna.CommCombinable;
                        antennaPartInfo.antennaCombinableExponent = antenna.CommCombinableExponent;
                        antennaPartInfo.antennaType = antenna.CommType;
                        //antennaPartInfo.partReference = part;
                        //antennaPartInfo.partSnapshotReference = protoPart;
                        antennaPartInfo.canComm = (!v.loaded) ? antenna.CanCommUnloaded(protoPartModule) : antenna.CanComm();

                        hasInfo = true;
                    }
                }

                if (hasInfo)
                {
                    adaptorsInfoList.Add(antennaPartInfo);
                }
            }

            freqSortedList     = adaptorsInfoList.OrderBy(a => a.frequency).ToList(); // order by frequency
            adaptorsSortedList = adaptorsInfoList.OrderBy(a => a.name).ToList();      // order by device name

            AntennaCalc(freqSortedList);
        }