Beispiel #1
0
        private CEUtil(string ceUri, string osName, string ceUser, string password, LogMsg logMsg)
        {
#if (P8_451)
            // P8 4.5 authentication
            UsernameToken token = new UsernameToken(ceUser, password, PasswordOption.SendPlainText);
            UserContext.SetProcessSecurityToken(token);
#else
            // P8 5.0 authentication
            UsernameCredentials cred = new UsernameCredentials(ceUser, password);
            ClientContext.SetProcessCredentials(cred);
#endif
            conn = Factory.Connection.GetConnection(ceUri);
            isCredentialsEstablished = true;

            // Get domain name
            PropertyFilter pf = new PropertyFilter();
            pf.AddIncludeProperty(0, null, null, "Name", null);
            pf.AddIncludeProperty(0, null, null, "Id", null);
            domain = Factory.Domain.FetchInstance(conn, null, null);
            objStore = Factory.ObjectStore.FetchInstance(domain, osName, null);

            // Successfully initialized CEUtil object: save singleton instance
            this.logMsg = logMsg;
            gCEUtil = this;
        }
Beispiel #2
0
 public static CEUtil GetInstance (string ceUri, string osName, string ceUser, string password, LogMsg logMsg)
 {
     // Singleton
     if (gCEUtil == null)
         gCEUtil = new CEUtil (ceUri, osName, ceUser, password, logMsg);
     return gCEUtil;
 }
 public void DumpToLog(LogMsg log)
 {
     if (attachedPartSim == null)
     {
         log.Append("<staged>:<n>");
     }
     else
     {
         log.Append(attachedPartSim.name, ":", attachedPartSim.partId);
     }
     log.Append("#", nodeType, ":", id);
 }
Beispiel #4
0
        public void Dump(LogMsg log)
        {
            log.buf.AppendFormat("number        : {0:d}\n", this.number);
            log.buf.AppendFormat("cost          : {0:g6}\n", this.cost);
            log.buf.AppendFormat("totalCost     : {0:g6}\n", this.totalCost);
            log.buf.AppendFormat("time          : {0:g6}\n", this.time);
            log.buf.AppendFormat("totalTime     : {0:g6}\n", this.totalTime);
            log.buf.AppendFormat("mass          : {0:g6}\n", this.mass);
            log.buf.AppendFormat("totalMass     : {0:g6}\n", this.totalMass);
            log.buf.AppendFormat("isp           : {0:g6}\n", this.isp);
            log.buf.AppendFormat("thrust        : {0:g6}\n", this.thrust);
            log.buf.AppendFormat("actualThrust  : {0:g6}\n", this.actualThrust);
            log.buf.AppendFormat("thrustToWeight: {0:g6}\n", this.thrustToWeight);
            log.buf.AppendFormat("maxTWR        : {0:g6}\n", this.maxThrustToWeight);
            log.buf.AppendFormat("actualTWR     : {0:g6}\n", this.actualThrustToWeight);
            log.buf.AppendFormat("ThrustTorque  : {0:g6}\n", this.maxThrustTorque);
            log.buf.AppendFormat("ThrustOffset  : {0:g6}\n", this.thrustOffsetAngle);
            log.buf.AppendFormat("deltaV        : {0:g6}\n", this.deltaV);
            log.buf.AppendFormat("totalDeltaV   : {0:g6}\n", this.totalDeltaV);
            log.buf.AppendFormat("invTotDeltaV  : {0:g6}\n", this.inverseTotalDeltaV);

            log.Flush();
        }
Beispiel #5
0
        public bool SetResourceDrains(LogMsg log, List<PartSim> allParts, List<PartSim> allFuelLines, HashSet<PartSim> drainingParts)
        {
            //DumpSourcePartSets(log, "before clear");
            foreach (HashSet<PartSim> sourcePartSet in sourcePartSets.Values)
            {
                sourcePartSet.Clear();
            }
            //DumpSourcePartSets(log, "after clear");

            for (int index = 0; index < this.resourceConsumptions.Types.Count; index++)
            {
                int type = this.resourceConsumptions.Types[index];

                HashSet<PartSim> sourcePartSet;
                if (!sourcePartSets.TryGetValue(type, out sourcePartSet))
                {
                    sourcePartSet = new HashSet<PartSim>();
                    sourcePartSets.Add(type, sourcePartSet);
                }

                switch ((ResourceFlowMode)this.resourceFlowModes[type])
                {
                    case ResourceFlowMode.NO_FLOW:
                        if (partSim.resources[type] > SimManager.RESOURCE_MIN && partSim.resourceFlowStates[type] != 0)
                        {
                            sourcePartSet.Add(partSim);
                        }
                        break;

                    case ResourceFlowMode.ALL_VESSEL:
                    case ResourceFlowMode.ALL_VESSEL_BALANCE:
                        for (int i = 0; i < allParts.Count; i++)
                        {
                            PartSim aPartSim = allParts[i];
                            if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0)
                            {
                                sourcePartSet.Add(aPartSim);
                            }
                        }
                        break;

                    case ResourceFlowMode.STAGE_PRIORITY_FLOW:
                    case ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE:

                        if (log != null) log.Append("Find ", ResourceContainer.GetResourceName(type), " sources for ", partSim.name)
                                            .AppendLine(":" , partSim.partId);
                        foreach (HashSet<PartSim> stagePartSet in stagePartSets.Values)
                        {
                            stagePartSet.Clear();
                        }
                        var maxStage = -1;

                        for (int i = 0; i < allParts.Count; i++)
                        {
                            var aPartSim = allParts[i];
                            //if (log != null) log.Append(aPartSim.name, ":" + aPartSim.partId, " contains ", aPartSim.resources[type])
                            //                  .AppendLine((aPartSim.resourceFlowStates[type] == 0) ? " (disabled)" : "");
                            if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0)
                            {
                                continue;
                            }

                            int stage = aPartSim.inverseStage;
                            if (stage > maxStage)
                            {
                                maxStage = stage;
                            }

                            HashSet<PartSim> tempPartSet;
                            if (!stagePartSets.TryGetValue(stage, out tempPartSet))
                            {
                                tempPartSet = new HashSet<PartSim>();
                                stagePartSets.Add(stage, tempPartSet);
                            }
                            tempPartSet.Add(aPartSim);
                        }

                        for (int j = maxStage; j >= -1; j--)
                        {
                            //if (log != null) log.AppendLine("Testing stage ", j);
                            HashSet<PartSim> stagePartSet;
                            if (stagePartSets.TryGetValue(j, out stagePartSet) && stagePartSet.Count > 0)
                            {
                                //if (log != null) log.AppendLine("Not empty");
                                // We have to copy the contents of the set here rather than copying the set reference or
                                // bad things (tm) happen
                                foreach (PartSim aPartSim in stagePartSet)
                                {
                                    sourcePartSet.Add(aPartSim);
                                }
                                break;
                            }
                        }
                        break;

                    case ResourceFlowMode.STACK_PRIORITY_SEARCH:
                    case ResourceFlowMode.STAGE_STACK_FLOW:
                    case ResourceFlowMode.STAGE_STACK_FLOW_BALANCE:
                        visited.Clear();

                        if (log != null) log.Append("Find ", ResourceContainer.GetResourceName(type), " sources for ", partSim.name)
                                            .AppendLine(":", partSim.partId);

                        partSim.GetSourceSet(type, true, allParts, visited, sourcePartSet, log, "");
                        break;

                    default:
                        if (log != null) log.Append("SetResourceDrains(", partSim.name, ":", partSim.partId)
                                            .AppendLine(") Unexpected flow type for ", ResourceContainer.GetResourceName(type), ")");
                        break;
                }

                if (log != null && sourcePartSet.Count > 0)
                {
                    log.AppendLine("Source parts for ", ResourceContainer.GetResourceName(type), ":");
                    foreach (PartSim partSim in sourcePartSet)
                    {
                        log.AppendLine(partSim.name, ":", partSim.partId);
                    }
                }

                //DumpSourcePartSets(log, "after " + ResourceContainer.GetResourceName(type));
            }

            // If we don't have sources for all the needed resources then return false without setting up any drains
            for (int i = 0; i < this.resourceConsumptions.Types.Count; i++)
            {
                int type = this.resourceConsumptions.Types[i];
                HashSet<PartSim> sourcePartSet;
                if (!sourcePartSets.TryGetValue(type, out sourcePartSet) || sourcePartSet.Count == 0)
                {
                    if (log != null) log.AppendLine("No source of ", ResourceContainer.GetResourceName(type));
                    isActive = false;
                    return false;
                }
            }

            // Now we set the drains on the members of the sets and update the draining parts set
            for (int i = 0; i < this.resourceConsumptions.Types.Count; i++)
            {
                int type = this.resourceConsumptions.Types[i];
                HashSet<PartSim> sourcePartSet = sourcePartSets[type];
                ResourceFlowMode mode = (ResourceFlowMode)resourceFlowModes[type];
                double consumption = resourceConsumptions[type];
                double amount = 0d;
                double total = 0d;
                if (mode == ResourceFlowMode.ALL_VESSEL_BALANCE ||
                    mode == ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE ||
                    mode == ResourceFlowMode.STAGE_STACK_FLOW_BALANCE ||
                    mode == ResourceFlowMode.STACK_PRIORITY_SEARCH)
                {
                    foreach (PartSim partSim in sourcePartSet)
                        total += partSim.resources[type];
                }
                else
                    amount = consumption / sourcePartSet.Count;

                // Loop through the members of the set
                foreach (PartSim partSim in sourcePartSet)
                {
                    if (total != 0d)
                        amount = consumption * partSim.resources[type] / total;

                    if (log != null) log.Append("Adding drain of ", amount, " ", ResourceContainer.GetResourceName(type))
                                        .AppendLine(" to ", partSim.name, ":", partSim.partId);

                    partSim.resourceDrains.Add(type, amount);
                    drainingParts.Add(partSim);
                }
            }
            return true;
        }
Beispiel #6
0
 private void tCheckPathAlarm_Elapsed(object sender, ElapsedEventArgs e)
 {
     this.tCheckPathAlarm.Enabled = false;
     try
     {
         try
         {
             PlatformAlarmRegionAlarm platformAlarmRegionAlarm = new PlatformAlarmRegionAlarm();
             this.clearAlarmCar();
             this.dtConfigInfo = this.getConfigInfo();
             if (this.dtConfigInfo != null && this.dtConfigInfo.Rows.Count > 0)
             {
                 foreach (DataRow row in this.dtConfigInfo.Rows)
                 {
                     DateTime dateTime  = Convert.ToDateTime(row["BeginTime"]);
                     DateTime dateTime1 = Convert.ToDateTime(row["EndTime"]);
                     DateTime dateTime2 = Convert.ToDateTime(row["gpsTime"]);
                     if (!platformAlarmRegionAlarm.IsInConfigTime(dateTime, dateTime1, this.dtNow) || !platformAlarmRegionAlarm.IsInConfigTime(dateTime, dateTime1, dateTime2) || dateTime2.Date != this.dtNow.Date)
                     {
                         continue;
                     }
                     int num  = Convert.ToInt32(row["carid"]);
                     int num1 = Convert.ToInt32(row["PathID"]);
                     if (this.htCarPathInfo[num] == null)
                     {
                         this.htCarPathInfo[num] = "";
                     }
                     try
                     {
                         if (this.htAlarmList[num] != null)
                         {
                             this.htAlarmList[num] = (this.htAlarmList[num] as AlarmCarInfo).updateAlarmCar(num, num1, dateTime, dateTime1);
                         }
                         else
                         {
                             this.htAlarmList[num] = AlarmCarInfo.getAlarmCar(num, num1, dateTime, dateTime1);
                         }
                     }
                     catch (Exception exception1)
                     {
                         Exception exception = exception1;
                         ErrorMsg  errorMsg  = new ErrorMsg("PlatformAlarmPathAlarm", "tCheckPathAlarm_Elapsed", string.Concat("保存报警车辆信息,", exception.Message));
                         this.logHelper.WriteError(errorMsg);
                     }
                     if (row["Longitude"] == DBNull.Value || row["Latitude"] == DBNull.Value || double.Parse(row["Longitude"].ToString()) < 0.001 || double.Parse(row["Latitude"].ToString()) < 0.001)
                     {
                         if (this.htCarPathInfo.Contains(num))
                         {
                             this.htCarPathInfo.Remove(num);
                         }
                         LogMsg   logMsg = new LogMsg("PlatformAlarmPathAlarm", "tCheckPathAlarm_Elapsed", "");
                         object[] str    = new object[] { "carid:", num, ",pathId:", num1.ToString(), ",simnum:", row["simnum"].ToString(), ",轨迹不存在或为0" };
                         logMsg.Msg = string.Concat(str);
                         this.logHelper.WriteLog(logMsg);
                     }
                     else if (row["alarmpathdot"] == DBNull.Value || string.IsNullOrEmpty(row["alarmpathdot"].ToString()))
                     {
                         if (this.htCarPathInfo.Contains(num))
                         {
                             this.htCarPathInfo.Remove(num);
                         }
                         LogMsg   logMsg1  = new LogMsg("PlatformAlarmPathAlarm", "tCheckPathAlarm_Elapsed", "");
                         object[] objArray = new object[] { "carid:", num, ",pathId:", num1.ToString(), ",simnum:", row["simnum"].ToString(), ",路线不存在" };
                         logMsg1.Msg = string.Concat(objArray);
                         this.logHelper.WriteLog(logMsg1);
                     }
                     else
                     {
                         Hashtable hashtables  = this.htCarPathInfo;
                         Hashtable hashtables1 = hashtables;
                         object    obj         = num;
                         object    item        = hashtables1[obj];
                         object[]  str1        = new object[] { item, num1, ":", row["alarmpathdot"].ToString(), ";" };
                         hashtables[obj]        = string.Concat(str1);
                         this.htCarPosInfo[num] = string.Concat(row["Longitude"].ToString(), "*", row["Latitude"].ToString());
                     }
                 }
                 this.setInputXML();
                 this.CheckAndAnalysis();
             }
         }
         catch (Exception exception3)
         {
             Exception exception2 = exception3;
             ErrorMsg  errorMsg1  = new ErrorMsg("PlatformAlarmPathAlarm", "tCheckPathAlarm_Elapsed", string.Concat("检测偏移路线报警错误,", exception2.Message));
             this.logHelper.WriteError(errorMsg1);
         }
     }
     finally
     {
         this.htCarPathInfo.Clear();
         this.htCarPosInfo.Clear();
         this.xDoc = null;
         this.tCheckPathAlarm.Enabled = true;
     }
 }
Beispiel #7
0
        // All functions below this point must not rely on the part member (it may be null)
        //
        public void GetSourceSet(int type, bool includeSurfaceMountedParts, List<PartSim> allParts, HashSet<PartSim> visited, HashSet<PartSim> allSources, LogMsg log, String indent)
        {
            if (log != null)
            {
                log.buf.AppendLine(indent + "GetSourceSet(" + ResourceContainer.GetResourceName(type) + ") for " + name + ":" + partId);
                indent += "  ";
            }

            // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns as is.
            if (visited.Contains(this))
            {
                if (log != null) log.buf.AppendLine(indent + "Returning empty set, already visited (" + name + ":" + partId + ")");
                return;
            }

            if (log != null) log.buf.AppendLine(indent + "Adding this to visited");

            visited.Add(this);

            // Rule 2: Part performs scan on start of every fuel pipe ending in it. This scan is done in order in which pipes were installed.
            // Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result.
            //MonoBehaviour.print("for each fuel line");

            int lastCount = allSources.Count;

            for (int i = 0; i < this.fuelTargets.Count; i++)
            {
                PartSim partSim = this.fuelTargets[i];
                if (partSim != null)
                {
                    if (visited.Contains(partSim))
                    {
                        if (log != null) log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
                    }
                    else
                    {
                        if (log != null) log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");

                        partSim.GetSourceSet(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent);
                    }
                }
            }

            // check surface mounted fuel targets
            if (includeSurfaceMountedParts)
            {
                for (int i = 0; i < surfaceMountFuelTargets.Count; i++)
                {
                    PartSim partSim = this.surfaceMountFuelTargets[i];
                    if (partSim != null)
                    {
                        if (visited.Contains(partSim))
                        {
                            if (log != null) log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
                        }
                        else
                        {
                            if (log != null) log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");

                            partSim.GetSourceSet(type, true, allParts, visited, allSources, log, indent);
                        }
                    }
                }
            }

            if (allSources.Count > lastCount)
            {
                if (log != null) log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " fuel target sources (" + this.name + ":" + this.partId + ")");
                return;
            }

            // Rule 3: This rule has been removed and merged with rules 4 and 7 to fix issue with fuel tanks with disabled crossfeed

            // Rule 4: Part performs scan on each of its axially mounted neighbors.
            //  Couplers (bicoupler, tricoupler, ...) are an exception, they only scan one attach point on the single attachment side,
            //  skip the points on the side where multiple points are. [Experiment]
            //  Again, the part creates union of scan lists from each of its neighbor and if it is not empty, returns this list.
            //  The order in which mount points of a part are scanned appears to be fixed and defined by the part specification file. [Experiment]
            if (fuelCrossFeed)
            {
                lastCount = allSources.Count;
                //MonoBehaviour.print("for each attach node");
                for (int i = 0; i < this.attachNodes.Count; i++)
                {
                    AttachNodeSim attachSim = this.attachNodes[i];
                    if (attachSim.attachedPartSim != null)
                    {
                        if (attachSim.nodeType == AttachNode.NodeType.Stack)
                        {
                            if ((string.IsNullOrEmpty(noCrossFeedNodeKey) == false && attachSim.id.Contains(noCrossFeedNodeKey)) == false)
                            {
                                if (visited.Contains(attachSim.attachedPartSim))
                                {
                                    if (log != null) log.buf.AppendLine(indent + "Attached part already visited, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                                }
                                else
                                {
                                    if (log != null) log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");

                                    attachSim.attachedPartSim.GetSourceSet(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent);
                                }
                            }
                        }
                    }
                }

                if (allSources.Count > lastCount)
                {
                    if (log != null) log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " attached sources (" + this.name + ":" + this.partId + ")");
                    return;
                }
            }

            // Rule 5: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel
            // type was not disabled [Experiment]) and it contains fuel, it returns itself.
            // Rule 6: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel
            // type was not disabled) but it does not contain the requested fuel, it returns empty list. [Experiment]
            if (resources.HasType(type) && resourceFlowStates[type] > 0.0)
            {
                if (resources[type] > SimManager.RESOURCE_MIN)
                {
                    allSources.Add(this);

                    if (log != null) log.buf.AppendLine(indent + "Returning enabled tank as only source (" + name + ":" + partId + ")");
                }

                return;
            }
            else
            {
                if (log != null) log.buf.AppendLine(indent + "Not fuel tank or disabled. HasType = " + resources.HasType(type) + "  FlowState = " + resourceFlowStates[type]);
            }

            // Rule 7: If the part is radially attached to another part and it is child of that part in the ship's tree structure, it scans its
            // parent and returns whatever the parent scan returned. [Experiment] [Experiment]
            if (parent != null && parentAttach == AttachModes.SRF_ATTACH)
            {
                if (fuelCrossFeed)
                {
                    if (visited.Contains(parent))
                    {
                        if (log != null) log.buf.AppendLine(indent + "Parent part already visited, skipping (" + parent.name + ":" + parent.partId + ")");
                    }
                    else
                    {
                        lastCount = allSources.Count;
                        this.parent.GetSourceSet(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent);
                        if (allSources.Count > lastCount)
                        {
                            if (log != null) log.buf.AppendLine(indent + "Returning " + (allSources.Count  - lastCount) + " parent sources (" + this.name + ":" + this.partId + ")");
                            return;
                        }
                    }
                }
            }

            // Rule 8: If all preceding rules failed, part returns empty list.
            if (log != null) log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");

            return;
        }
Beispiel #8
0
        public double TimeToDrainResource(LogMsg log)
        {
            //if (log != null) log.AppendLine("TimeToDrainResource(", name, ":", partId, ")");
            double time = double.MaxValue;

            for (int i = 0; i < resourceDrains.Types.Count; ++i)
            {
                int type = resourceDrains.Types[i];

                if (resourceDrains[type] > 0)
                {
                    time = Math.Min(time, resources[type] / resourceDrains[type]);
                    //if (log != null) log.AppendLine("type = " + ResourceContainer.GetResourceName(type) + "  amount = " + resources[type] + "  rate = " + resourceDrains[type] + "  time = " + time);
                }
            }

            //if (time < double.MaxValue)
            //    if (log != null) log.Append("TimeToDrainResource(", name, ":", partId)
            //                        .AppendLine(") = ", time);
            return time;
        }
Beispiel #9
0
        public String DumpPartAndParentsToLog(LogMsg log, String prefix)
        {
            if (log != null)
            {
                if (parent != null)
                    prefix = parent.DumpPartAndParentsToLog(log, prefix) + " ";

                DumpPartToLog(log, prefix);
            }

            return prefix;
        }
Beispiel #10
0
        // This function runs the simulation and returns a newly created array of Stage objects
        public Stage[] RunSimulation()
        {
            if (SimManager.logOutput)
            {
                MonoBehaviour.print("RunSimulation started");
            }

            this._timer.Reset();
            this._timer.Start();

            LogMsg log = null;
            if (SimManager.logOutput)
            {
                log = new LogMsg();
            }

            // Start with the last stage to simulate
            // (this is in a member variable so it can be accessed by AllowedToStage and ActivateStage)
            this.currentStage = this.lastStage;
            // Work out which engines would be active if just doing the staging and if this is different to the 
            // currently active engines then generate an extra stage
            // Loop through all the engines
            bool anyActive = false;
            for (int i = 0; i < allEngines.Count; ++i)
            {
                EngineSim engine = allEngines[i];

                if (log != null)
                {
                    log.buf.AppendLine("Testing engine mod of " + engine.partSim.name + ":" + engine.partSim.partId);
                }
                bool bActive = engine.isActive;
                bool bStage = (engine.partSim.inverseStage >= this.currentStage);
                if (log != null)
                {
                    log.buf.AppendLine("bActive = " + bActive + "   bStage = " + bStage);
                }
                if (HighLogic.LoadedSceneIsFlight)
                {
                    if (bActive)
                    {
                        anyActive = true;
                    }
                    if (bActive != bStage)
                    {
                        // If the active state is different to the state due to staging
                        if (log != null)
                        {
                            log.buf.AppendLine("Need to do current active engines first");
                        }

                        this.doingCurrent = true;
                    }
                }
                else
                {
                    if (bStage)
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine("Marking as active");
                        }

                        engine.isActive = true;
                    }
                }
            }

            // If we need to do current because of difference in engine activation and there actually are active engines
            // then we do the extra stage otherwise activate the next stage and don't treat it as current
            if (this.doingCurrent && anyActive)
            {
                this.currentStage++;
            }
            else
            {
                this.ActivateStage();
                this.doingCurrent = false;
            }

            // Create a list of lists of PartSims that prevent decoupling
            BuildDontStageLists(log);

            if (log != null)
            {
                log.Flush();
            }

            // Create the array of stages that will be returned
            Stage[] stages = new Stage[this.currentStage + 1];

            int startStage = currentStage;

            // Loop through the stages
            while (this.currentStage >= 0)
            {
                if (log != null)
                {
                    log.buf.AppendLine("Simulating stage " + this.currentStage);
                    log.Flush();
                    this._timer.Reset();
                    this._timer.Start();
                }

                // Update active engines and resource drains
                this.UpdateResourceDrains();

                // Update the masses of the parts to correctly handle "no physics" parts
                this.stageStartMass = this.UpdatePartMasses();

                if (log != null)
                    this.allParts[0].DumpPartToBuffer(log.buf, "", this.allParts);

                // Create the Stage object for this stage
                Stage stage = new Stage();

                this.stageTime = 0d;
                this.vecStageDeltaV = Vector3.zero;

                this.stageStartCom = this.ShipCom;

                this.stepStartMass = this.stageStartMass;
                this.stepEndMass = 0;

                this.CalculateThrustAndISP();

                // Store various things in the Stage object
                stage.thrust = this.totalStageThrust;
                if (log != null) log.buf.AppendLine("stage.thrust = " + stage.thrust);
                stage.thrustToWeight = this.totalStageThrust / (this.stageStartMass * this.gravity);
                stage.maxThrustToWeight = stage.thrustToWeight;
                if (log != null) log.buf.AppendLine("StageMass = " + stageStartMass);
                if (log != null) log.buf.AppendLine("Initial maxTWR = " + stage.maxThrustToWeight);
                stage.actualThrust = this.totalStageActualThrust;
                stage.actualThrustToWeight = this.totalStageActualThrust / (this.stageStartMass * this.gravity);

                // calculate torque and associates
                stage.maxThrustTorque = this.totalStageThrustForce.TorqueAt(this.stageStartCom).magnitude;

                // torque divided by thrust. imagine that all engines are at the end of a lever that tries to turn the ship.
                // this numerical value, in meters, would represent the length of that lever.
                double torqueLeverArmLength = (stage.thrust <= 0) ? 0 : stage.maxThrustTorque / stage.thrust;

                // how far away are the engines from the CoM, actually?
                double thrustDistance = (this.stageStartCom - this.totalStageThrustForce.GetAverageForceApplicationPoint()).magnitude;

                // the combination of the above two values gives an approximation of the offset angle.
                double sinThrustOffsetAngle = 0;
                if (thrustDistance > 1e-7) {
                    sinThrustOffsetAngle = torqueLeverArmLength / thrustDistance;
                    if (sinThrustOffsetAngle > 1) {
                        sinThrustOffsetAngle = 1;
                    }
                }

                stage.thrustOffsetAngle = Math.Asin(sinThrustOffsetAngle) * 180 / Math.PI;

                // Calculate the total cost of the vessel at this point
                stage.totalCost = 0d;
                for (int i = 0; i < allParts.Count; ++i)
                {
                    if (this.currentStage > allParts[i].decoupledInStage)
                        stage.totalCost += allParts[i].GetCost(currentStage);
                }

                // The total mass is simply the mass at the start of the stage
                stage.totalMass = this.stageStartMass;

                // If we have done a previous stage
                if (currentStage < startStage)
                {
                    // Calculate what the previous stage's mass and cost were by subtraction
                    Stage prev = stages[currentStage + 1];
                    prev.cost = prev.totalCost - stage.totalCost;
                    prev.mass = prev.totalMass - stage.totalMass;
                }

                // The above code will never run for the last stage so set those directly
                if (currentStage == 0)
                {
                    stage.cost = stage.totalCost;
                    stage.mass = stage.totalMass;
                }

                this.dontStageParts = dontStagePartsLists[this.currentStage];

                if (log != null)
                {
                    log.buf.AppendLine("Stage setup took " + this._timer.ElapsedMilliseconds + "ms");

                    if (this.dontStageParts.Count > 0)
                    {
                        log.buf.AppendLine("Parts preventing staging:");
                        for (int i = 0; i < this.dontStageParts.Count; i++)
                        {
                            PartSim partSim = this.dontStageParts[i];
                            partSim.DumpPartToBuffer(log.buf, "");
                        }
                    }
                    else
                    {
                        log.buf.AppendLine("No parts preventing staging");
                    }

                    log.Flush();
                }


                // Now we will loop until we are allowed to stage
                int loopCounter = 0;
                while (!this.AllowedToStage())
                {
                    loopCounter++;
                    //MonoBehaviour.print("loop = " + loopCounter);
                    // Calculate how long each draining tank will take to drain and run for the minimum time
                    double resourceDrainTime = double.MaxValue;
                    PartSim partMinDrain = null;
                    foreach (PartSim partSim in this.drainingParts)
                    {
                        double time = partSim.TimeToDrainResource();
                        if (time < resourceDrainTime)
                        {
                            resourceDrainTime = time;
                            partMinDrain = partSim;
                        }
                    }

                    if (log != null)
                    {
                        MonoBehaviour.print("Drain time = " + resourceDrainTime + " (" + partMinDrain.name + ":" + partMinDrain.partId + ")");
                    }
                    foreach (PartSim partSim in this.drainingParts)
                    {
                        partSim.DrainResources(resourceDrainTime);
                    }

                    // Get the mass after draining
                    this.stepEndMass = this.ShipMass;
                    this.stageTime += resourceDrainTime;

                    double stepEndTWR = this.totalStageThrust / (this.stepEndMass * this.gravity);
                    //MonoBehaviour.print("After drain mass = " + stepEndMass);
                    //MonoBehaviour.print("currentThrust = " + totalStageThrust);
                    //MonoBehaviour.print("currentTWR = " + stepEndTWR);
                    if (stepEndTWR > stage.maxThrustToWeight)
                    {
                        stage.maxThrustToWeight = stepEndTWR;
                    }

                    //MonoBehaviour.print("newMaxTWR = " + stage.maxThrustToWeight);

                    // If we have drained anything and the masses make sense then add this step's deltaV to the stage total
                    if (resourceDrainTime > 0d && this.stepStartMass > this.stepEndMass && this.stepStartMass > 0d && this.stepEndMass > 0d)
                    {
                        this.vecStageDeltaV += this.vecThrust * (float)((this.currentisp * Units.GRAVITY * Math.Log(this.stepStartMass / this.stepEndMass)) / this.simpleTotalThrust);
                    }

                    // Update the active engines and resource drains for the next step
                    this.UpdateResourceDrains();

                    // Recalculate the current thrust and isp for the next step
                    this.CalculateThrustAndISP();
                    
                    // Check if we actually changed anything
                    if (this.stepStartMass == this.stepEndMass)
                    {
                        //MonoBehaviour.print("No change in mass");
                        break;
                    }

                    // Check to stop rampant looping
                    if (loopCounter == 1000)
                    {
                        MonoBehaviour.print("exceeded loop count");
                        MonoBehaviour.print("stageStartMass = " + this.stageStartMass);
                        MonoBehaviour.print("stepStartMass = " + this.stepStartMass);
                        MonoBehaviour.print("StepEndMass   = " + this.stepEndMass);
                        Logger.Log("exceeded loop count");
                        Logger.Log("stageStartMass = " + this.stageStartMass);
                        Logger.Log("stepStartMass = " + this.stepStartMass);
                        Logger.Log("StepEndMass   = " + this.stepEndMass);
                        break;
                    }

                    // The next step starts at the mass this one ended at
                    this.stepStartMass = this.stepEndMass;
                }


                // Store more values in the Stage object and stick it in the array

                // Store the magnitude of the deltaV vector
                stage.deltaV = this.vecStageDeltaV.magnitude;
                stage.resourceMass = this.stageStartMass - this.stepEndMass;

                // Recalculate effective stage isp from the stage deltaV (flip the standard deltaV calculation around)
                // Note: If the mass doesn't change then this is a divide by zero
                if (this.stageStartMass != this.stepStartMass)
                {
                    stage.isp = stage.deltaV / (Units.GRAVITY * Math.Log(this.stageStartMass / this.stepStartMass));
                    stage.resourceMass = this.stageStartMass - this.stepEndMass;
                }
                else
                {
                    stage.isp = 0;
                    stage.resourceMass = 0;
                }

                // Zero stage time if more than a day (this should be moved into the window code)
                stage.time = (this.stageTime < SECONDS_PER_DAY) ? this.stageTime : 0d;
                stage.number = this.doingCurrent ? -1 : this.currentStage; // Set the stage number to -1 if doing current engines
                stage.totalPartCount = this.allParts.Count;
                stage.maxMach = maxMach;
                stages[this.currentStage] = stage;

                // Now activate the next stage
                this.currentStage--;
                this.doingCurrent = false;

                if (log != null)
                {
                    // Log how long the stage took
                    this._timer.Stop();
                    MonoBehaviour.print("Simulating stage took " + this._timer.ElapsedMilliseconds + "ms");
                    stage.Dump();
                    this._timer.Reset();
                    this._timer.Start();
                }

                // Activate the next stage
                this.ActivateStage();

                if (log != null)
                {
                    // Log how long it took to activate
                    this._timer.Stop();
                    MonoBehaviour.print("ActivateStage took " + this._timer.ElapsedMilliseconds + "ms");
                }
            }

            // Now we add up the various total fields in the stages
            for (int i = 0; i < stages.Length; i++)
            {
                // For each stage we total up the cost, mass, deltaV and time for this stage and all the stages above
                for (int j = i; j >= 0; j--)
                {
                    stages[i].totalDeltaV += stages[j].deltaV;
                    stages[i].totalTime += stages[j].time;
                    stages[i].partCount = i > 0 ? stages[i].totalPartCount - stages[i - 1].totalPartCount : stages[i].totalPartCount;
                }
                // We also total up the deltaV for stage and all stages below
                for (int j = i; j < stages.Length; j++)
                {
                    stages[i].inverseTotalDeltaV += stages[j].deltaV;
                }

                // Zero the total time if the value will be huge (24 hours?) to avoid the display going weird
                // (this should be moved into the window code)
                if (stages[i].totalTime > SECONDS_PER_DAY)
                {
                    stages[i].totalTime = 0d;
                }
            }

            if (log != null)
            {
                this._timer.Stop();
                MonoBehaviour.print("RunSimulation: " + this._timer.ElapsedMilliseconds + "ms");
            }
            FreePooledObject();
            
            return stages;
        }
Beispiel #11
0
        public PartSim(Part thePart, int id, double atmosphere, LogMsg log)
        {
            part = thePart;
            partId = id;
            name = part.partInfo.name;

            if (log != null)
                log.buf.AppendLine("Create PartSim for " + name);

            parent = null;
            parentAttach = part.attachMode;
            fuelCrossFeed = part.fuelCrossFeed;
            noCrossFeedNodeKey = part.NoCrossFeedNodeKey;
            decoupledInStage = DecoupledInStage(part);
            isFuelLine = part is FuelLine;
            isFuelTank = part is FuelTank;
            isSepratron = IsSepratron();
            inverseStage = part.inverseStage;
            //MonoBehaviour.print("inverseStage = " + inverseStage);

            cost = part.partInfo.cost;
            foreach (PartResource resource in part.Resources)
            {
                cost -= (float)((resource.maxAmount - resource.amount) * resource.info.unitCost);
            }

            // Work out if the part should have no physical significance
            isNoPhysics = part.HasModule<LaunchClamp>() ||
                            part.physicalSignificance == Part.PhysicalSignificance.NONE ||
                            part.PhysicsSignificance == 1;

            if (!isNoPhysics)
                baseMass = part.mass;

            if (SimManager.logOutput)
                MonoBehaviour.print((isNoPhysics ? "Ignoring" : "Using") + " part.mass of " + part.mass);

            foreach (PartResource resource in part.Resources)
            {
                // Make sure it isn't NaN as this messes up the part mass and hence most of the values
                // This can happen if a resource capacity is 0 and tweakable
                if (!Double.IsNaN(resource.amount))
                {
                    if (SimManager.logOutput)
                        MonoBehaviour.print(resource.resourceName + " = " + resource.amount);

                    resources.Add(resource.info.id, resource.amount);
                    resourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0);
                }
                else
                {
                    MonoBehaviour.print(resource.resourceName + " is NaN. Skipping.");
                }
            }

            startMass = GetMass();

            hasVessel = (part.vessel != null);
            isLanded = hasVessel && part.vessel.Landed;
            if (hasVessel)
            {
                vesselName = part.vessel.vesselName;
                vesselType = part.vesselType;
            }
            initialVesselName = part.initialVesselName;

            hasMultiModeEngine = part.HasModule<MultiModeEngine>();
            hasModuleEnginesFX = part.HasModule<ModuleEnginesFX>();
            hasModuleEngines = part.HasModule<ModuleEngines>();

            isEngine = hasMultiModeEngine || hasModuleEnginesFX || hasModuleEngines;

            if (SimManager.logOutput)
                MonoBehaviour.print("Created " + name + ". Decoupled in stage " + decoupledInStage);
        }
Beispiel #12
0
        public void CreateEngineSims(List <EngineSim> allEngines, double atmosphere, double mach, bool vectoredThrust, bool fullThrust, LogMsg log)
        {
            if (log != null)
            {
                log.buf.AppendLine("CreateEngineSims for " + this.name);
                for (int i = 0; i < this.part.Modules.Count; i++)
                {
                    PartModule partMod = this.part.Modules[i];
                    log.buf.AppendLine("Module: " + partMod.moduleName);
                }
            }

            if (hasMultiModeEngine)
            {
                // A multi-mode engine has multiple ModuleEngines but only one is active at any point
                // The mode of the engine is the engineID of the ModuleEngines that is active
                string mode = part.GetModule <MultiModeEngine>().mode;

                List <ModuleEngines> engines = part.GetModules <ModuleEngines>();
                for (int i = 0; i < engines.Count; ++i)
                {
                    ModuleEngines engine = engines[i];
                    if (engine.engineID == mode)
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine("Module: " + engine.moduleName);
                        }

                        EngineSim engineSim = EngineSim.New(
                            this,
                            engine,
                            atmosphere,
                            (float)mach,
                            vectoredThrust,
                            fullThrust,
                            log);
                        allEngines.Add(engineSim);
                    }
                }
            }
            else if (hasModuleEngines)
            {
                List <ModuleEngines> engines = part.GetModules <ModuleEngines>();
                for (int i = 0; i < engines.Count; ++i)
                {
                    ModuleEngines engine = engines[i];
                    if (log != null)
                    {
                        log.buf.AppendLine("Module: " + engine.moduleName);
                    }

                    EngineSim engineSim = EngineSim.New(
                        this,
                        engine,
                        atmosphere,
                        (float)mach,
                        vectoredThrust,
                        fullThrust,
                        log);
                    allEngines.Add(engineSim);
                }
            }

            if (log != null)
            {
                log.Flush();
            }
        }
Beispiel #13
0
        public void CreateEngineSims(List <EngineSim> allEngines, double atmosphere, double mach, bool vectoredThrust, bool fullThrust, LogMsg log)
        {
            if (log != null)
            {
                log.buf.AppendLine("CreateEngineSims for " + this.name);
                for (int i = 0; i < this.part.Modules.Count; i++)
                {
                    PartModule partMod = this.part.Modules[i];
                    log.buf.AppendLine("Module: " + partMod.moduleName);
                }
            }

            if (hasMultiModeEngine)
            {
                // A multi-mode engine has multiple ModuleEngines but only one is active at any point
                // The mode of the engine is the engineID of the ModuleEngines that is active
                string mode = part.GetModule <MultiModeEngine>().mode;

                List <ModuleEngines> engines = part.GetModules <ModuleEngines>();
                for (int i = 0; i < engines.Count; ++i)
                {
                    ModuleEngines engine = engines[i];
                    if (engine.engineID == mode)
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine("Module: " + engine.moduleName);
                        }

                        Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);

                        EngineSim engineSim = EngineSim.New(
                            this,
                            atmosphere,
                            (float)mach,
                            engine.maxFuelFlow,
                            engine.minFuelFlow,
                            engine.thrustPercentage,
                            thrustvec,
                            engine.atmosphereCurve,
                            engine.atmChangeFlow,
                            engine.useAtmCurve ? engine.atmCurve : null,
                            engine.useVelCurve ? engine.velCurve : null,
                            engine.currentThrottle,
                            engine.g,
                            engine.throttleLocked || fullThrust,
                            engine.propellants,
                            engine.isOperational,
                            engine.resultingThrust,
                            engine.thrustTransforms,
                            log);
                        allEngines.Add(engineSim);
                    }
                }
            }
            else if (hasModuleEngines)
            {
                List <ModuleEngines> engines = part.GetModules <ModuleEngines>();
                for (int i = 0; i < engines.Count; ++i)
                {
                    ModuleEngines engine = engines[i];
                    if (log != null)
                    {
                        log.buf.AppendLine("Module: " + engine.moduleName);
                    }

                    Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);

                    EngineSim engineSim = EngineSim.New(
                        this,
                        atmosphere,
                        (float)mach,
                        engine.maxFuelFlow,
                        engine.minFuelFlow,
                        engine.thrustPercentage,
                        thrustvec,
                        engine.atmosphereCurve,
                        engine.atmChangeFlow,
                        engine.useAtmCurve ? engine.atmCurve : null,
                        engine.useVelCurve ? engine.velCurve : null,
                        engine.currentThrottle,
                        engine.g,
                        engine.throttleLocked || fullThrust,
                        engine.propellants,
                        engine.isOperational,
                        engine.resultingThrust,
                        engine.thrustTransforms,
                        log);
                    allEngines.Add(engineSim);
                }
            }

            if (log != null)
            {
                log.Flush();
            }
        }
Beispiel #14
0
        public static PartSim New(Part thePart, int id, double atmosphere, LogMsg log)
        {
            PartSim partSim = pool.Borrow();

            partSim.part         = thePart;
            partSim.centerOfMass = thePart.transform.TransformPoint(thePart.CoMOffset);
            partSim.partId       = id;
            partSim.name         = partSim.part.partInfo.name;

            if (log != null)
            {
                log.buf.AppendLine("Create PartSim for " + partSim.name);
            }

            partSim.parent             = null;
            partSim.parentAttach       = partSim.part.attachMode;
            partSim.fuelCrossFeed      = partSim.part.fuelCrossFeed;
            partSim.noCrossFeedNodeKey = partSim.part.NoCrossFeedNodeKey;
            partSim.decoupledInStage   = partSim.DecoupledInStage(partSim.part);
            partSim.isFuelLine         = partSim.part.HasModule <CModuleFuelLine>();
            partSim.isFuelTank         = partSim.part is FuelTank;
            partSim.isSepratron        = partSim.IsSepratron();
            partSim.isFairing          = partSim.IsFairing(partSim.part);
            partSim.inverseStage       = partSim.part.inverseStage;
            //MonoBehaviour.print("inverseStage = " + inverseStage);

            partSim.baseCost = partSim.part.GetCostDry();

            if (log != null)
            {
                log.buf.AppendLine("Parent part = " + (partSim.part.parent == null ? "null" : partSim.part.parent.partInfo.name));
                log.buf.AppendLine("physicalSignificance = " + partSim.part.physicalSignificance);
                log.buf.AppendLine("PhysicsSignificance = " + partSim.part.PhysicsSignificance);
            }

            // Work out if the part should have no physical significance
            // The root part is never "no physics"
            partSim.isNoPhysics = partSim.part.physicalSignificance == Part.PhysicalSignificance.NONE ||
                                  partSim.part.PhysicsSignificance == 1;

            if (partSim.part.HasModule <LaunchClamp>())
            {
                partSim.realMass = 0d;
                if (log != null)
                {
                    log.buf.AppendLine("Ignoring mass of launch clamp");
                }
            }
            else
            {
                partSim.realMass = partSim.part.mass;
                if (log != null)
                {
                    log.buf.AppendLine("Using part.mass of " + partSim.part.mass);
                }
            }

            if (partSim.isFairing)
            {
                partSim.fairingMass = partSim.part.GetModuleMass((float)partSim.realMass);
            }

            for (int i = 0; i < partSim.part.Resources.Count; i++)
            {
                PartResource resource = partSim.part.Resources[i];

                // Make sure it isn't NaN as this messes up the part mass and hence most of the values
                // This can happen if a resource capacity is 0 and tweakable
                if (!Double.IsNaN(resource.amount))
                {
                    if (log != null)
                    {
                        log.buf.AppendLine(resource.resourceName + " = " + resource.amount);
                    }

                    partSim.resources.Add(resource.info.id, resource.amount);
                    partSim.resourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0);
                }
                else
                {
                    if (log != null)
                    {
                        log.buf.AppendLine(resource.resourceName + " is NaN. Skipping.");
                    }
                }
            }

            partSim.hasVessel = (partSim.part.vessel != null);
            partSim.isLanded  = partSim.hasVessel && partSim.part.vessel.Landed;
            if (partSim.hasVessel)
            {
                partSim.vesselName = partSim.part.vessel.vesselName;
                partSim.vesselType = partSim.part.vesselType;
            }
            partSim.initialVesselName = partSim.part.initialVesselName;

            partSim.hasMultiModeEngine = partSim.part.HasModule <MultiModeEngine>();
            partSim.hasModuleEngines   = partSim.part.HasModule <ModuleEngines>();

            partSim.isEngine = partSim.hasMultiModeEngine || partSim.hasModuleEngines;

            if (log != null)
            {
                log.buf.AppendLine("Created " + partSim.name + ". Decoupled in stage " + partSim.decoupledInStage);
            }

            return(partSim);
        }
        // This function runs the simulation and returns a newly created array of Stage objects
        public Stage[] RunSimulation(LogMsg _log)
        {
            log = _log;
            if (log != null)
            {
                log.AppendLine("RunSimulation started");
            }

            _timer.Reset();
            _timer.Start();

            // Start with the last stage to simulate
            // (this is in a member variable so it can be accessed by AllowedToStage and ActivateStage)
            currentStage = lastStage;
            // Work out which engines would be active if just doing the staging and if this is different to the
            // currently active engines then generate an extra stage
            // Loop through all the engines
            bool anyActive = false;

            for (int i = 0; i < allEngines.Count; ++i)
            {
                EngineSim engine = allEngines[i];

                if (log != null)
                {
                    log.AppendLine("Testing engine mod of ", engine.partSim.name, ":", engine.partSim.partId);
                }

                bool bActive = engine.isActive;
                bool bStage  = (engine.partSim.inverseStage >= currentStage);
                if (log != null)
                {
                    log.AppendLine("bActive = ", bActive, "   bStage = ", bStage);
                }
                if (HighLogic.LoadedSceneIsFlight)
                {
                    if (bActive)
                    {
                        anyActive = true;
                    }
                    if (bActive != bStage)
                    {
                        // If the active state is different to the state due to staging
                        if (log != null)
                        {
                            log.AppendLine("Need to do current active engines first");
                        }
                        doingCurrent = true;
                    }
                }
                else
                {
                    if (bStage)
                    {
                        if (log != null)
                        {
                            log.AppendLine("Marking as active");
                        }
                        engine.isActive = true;
                    }
                }
            }

            // If we need to do current because of difference in engine activation and there actually are active engines
            // then we do the extra stage otherwise activate the next stage and don't treat it as current
            if (doingCurrent && anyActive)
            {
                currentStage++;
            }
            else
            {
                ActivateStage();
                doingCurrent = false;
            }

            // Create a list of lists of PartSims that prevent decoupling
            BuildDontStageLists(log);

            if (log != null)
            {
                log.Flush();
            }

            // Create the array of stages that will be returned
            Stage[] stages = new Stage[currentStage + 1];

            int startStage = currentStage;

            // Loop through the stages
            while (currentStage >= 0)
            {
                if (log != null)
                {
                    log.AppendLine("Simulating stage ", currentStage);
                    log.Flush();
                    _timer.Reset();
                    _timer.Start();
                }

                // Update active engines and resource drains
                UpdateResourceDrains();

                // Update the masses of the parts to correctly handle "no physics" parts
                stageStartMass = UpdatePartMasses();

                if (log != null)
                {
                    allParts[0].DumpPartToLog(log, "", allParts);
                }

                // Create the Stage object for this stage
                Stage stage = new Stage();

                stageTime      = 0d;
                vecStageDeltaV = Vector3.zero;

                stageStartCom = ShipCom;

                stepStartMass = stageStartMass;
                stepEndMass   = 0;

                CalculateThrustAndISP();


                // Store various things in the Stage object
                stage.thrust               = totalStageThrust;
                stage.thrustToWeight       = totalStageThrust / (stageStartMass * gravity);
                stage.maxThrustToWeight    = stage.thrustToWeight;
                stage.actualThrust         = totalStageActualThrust;
                stage.actualThrustToWeight = totalStageActualThrust / (stageStartMass * gravity);

                CalculateRCS(gravity, false);

                stage.RCSIsp         = RCSIsp;
                stage.RCSThrust      = RCSThrust;
                stage.RCSdeltaVStart = RCSDeltaV;
                stage.RCSTWRStart    = RCSTWR;
                stage.RCSBurnTime    = RCSBurnTime;

                if (log != null)
                {
                    log.AppendLine("stage.thrust = ", stage.thrust);
                    log.AppendLine("StageMass = ", stageStartMass);
                    log.AppendLine("Initial maxTWR = ", stage.maxThrustToWeight);
                }

                // calculate torque and associates
                stage.maxThrustTorque = totalStageThrustForce.TorqueAt(stageStartCom).magnitude;

                // torque divided by thrust. imagine that all engines are at the end of a lever that tries to turn the ship.
                // this numerical value, in meters, would represent the length of that lever.
                double torqueLeverArmLength = (stage.thrust <= 0) ? 0 : stage.maxThrustTorque / stage.thrust;

                // how far away are the engines from the CoM, actually?
                double thrustDistance = (stageStartCom - totalStageThrustForce.GetAverageForceApplicationPoint()).magnitude;

                // the combination of the above two values gives an approximation of the offset angle.
                double sinThrustOffsetAngle = 0;
                if (thrustDistance > 1e-7)
                {
                    sinThrustOffsetAngle = torqueLeverArmLength / thrustDistance;
                    if (sinThrustOffsetAngle > 1)
                    {
                        sinThrustOffsetAngle = 1;
                    }
                }

                stage.thrustOffsetAngle = Math.Asin(sinThrustOffsetAngle) * 180 / Math.PI;

                // Calculate the total cost of the vessel at this point
                stage.totalCost = 0d;
                for (int i = 0; i < allParts.Count; ++i)
                {
                    if (currentStage > allParts[i].decoupledInStage)
                    {
                        stage.totalCost += allParts[i].GetCost(currentStage);
                    }
                }

                // The total mass is simply the mass at the start of the stage
                stage.totalMass = stageStartMass;

                // If we have done a previous stage
                if (currentStage < startStage)
                {
                    // Calculate what the previous stage's mass and cost were by subtraction
                    Stage prev = stages[currentStage + 1];
                    prev.cost = prev.totalCost - stage.totalCost;
                    prev.mass = prev.totalMass - stage.totalMass;
                }

                // The above code will never run for the last stage so set those directly
                if (currentStage == 0)
                {
                    stage.cost = stage.totalCost;
                    stage.mass = stage.totalMass;
                }

                dontStageParts = dontStagePartsLists[currentStage];

                if (log != null)
                {
                    log.AppendLine("Stage setup took ", _timer.ElapsedMilliseconds, "ms");

                    if (dontStageParts.Count > 0)
                    {
                        log.AppendLine("Parts preventing staging:");
                        for (int i = 0; i < dontStageParts.Count; i++)
                        {
                            PartSim partSim = dontStageParts[i];
                            partSim.DumpPartToLog(log, "");
                        }
                    }
                    else
                    {
                        log.AppendLine("No parts preventing staging");
                    }

                    log.Flush();
                }


                // Now we will loop until we are allowed to stage
                int loopCounter = 0;
                while (!AllowedToStage())
                {
                    loopCounter++;
                    //if (log != null) log.AppendLine("loop = ", loopCounter);
                    // Calculate how long each draining tank will take to drain and run for the minimum time
                    double  resourceDrainTime = double.MaxValue;
                    PartSim partMinDrain      = null;

                    foreach (PartSim partSim in drainingParts)
                    {
                        double time = partSim.TimeToDrainResource(log);
                        if (time < resourceDrainTime)
                        {
                            resourceDrainTime = time;
                            partMinDrain      = partSim;
                        }
                    }

                    if (log != null)
                    {
                        log.Append("Drain time = ", resourceDrainTime, " (", partMinDrain.name)
                        .AppendLine(":", partMinDrain.partId, ")");
                    }

                    foreach (PartSim partSim in drainingParts)
                    {
                        partSim.DrainResources(resourceDrainTime, log);
                    }

                    // Get the mass after draining
                    stepEndMass = ShipMass;
                    stageTime  += resourceDrainTime;

                    double stepEndTWR = totalStageThrust / (stepEndMass * gravity);

                    /*if (log != null)
                     * {
                     *  log.AppendLine("After drain mass = ", stepEndMass);
                     *  log.AppendLine("currentThrust = ", totalStageThrust);
                     *  log.AppendLine("currentTWR = ", stepEndTWR);
                     * }*/
                    if (stepEndTWR > stage.maxThrustToWeight)
                    {
                        stage.maxThrustToWeight = stepEndTWR;
                    }

                    //if (log != null) log.AppendLine("newMaxTWR = ", stage.maxThrustToWeight);

                    // If we have drained anything and the masses make sense then add this step's deltaV to the stage total
                    if (resourceDrainTime > 0d && stepStartMass > stepEndMass && stepStartMass > 0d && stepEndMass > 0d)
                    {
                        vecStageDeltaV += vecThrust * (float)((currentisp * Units.GRAVITY * Math.Log(stepStartMass / stepEndMass)) / simpleTotalThrust);
                    }

                    // Update the active engines and resource drains for the next step
                    UpdateResourceDrains();

                    // Recalculate the current thrust and isp for the next step
                    CalculateThrustAndISP();

                    // Check if we actually changed anything
                    if (stepStartMass == stepEndMass)
                    {
                        //MonoBehaviour.print("No change in mass");
                        break;
                    }

                    // Check to stop rampant looping
                    if (loopCounter == 1000)
                    {
                        if (log != null)
                        {
                            log.AppendLine("exceeded loop count");
                            log.AppendLine("stageStartMass = " + stageStartMass);
                            log.AppendLine("stepStartMass = " + stepStartMass);
                            log.AppendLine("StepEndMass   = " + stepEndMass);
                        }
                        break;
                    }

                    // The next step starts at the mass this one ended at
                    stepStartMass = stepEndMass;
                }

                // Store more values in the Stage object and stick it in the array

                // Store the magnitude of the deltaV vector
                stage.deltaV       = vecStageDeltaV.magnitude;
                stage.resourceMass = stageStartMass - stepEndMass;

                if (HighLogic.LoadedSceneIsEditor) //this is only needed in the VAB.
                {
                    CalculateRCS(gravity, true);
                }

                stage.RCSdeltaVEnd = RCSDeltaV;
                stage.RCSTWREnd    = RCSTWR;

                // Recalculate effective stage isp from the stage deltaV (flip the standard deltaV calculation around)
                // Note: If the mass doesn't change then this is a divide by zero
                if (stageStartMass != stepStartMass)
                {
                    stage.isp = stage.deltaV / (Units.GRAVITY * Math.Log(stageStartMass / stepStartMass));
                }
                else
                {
                    stage.isp = 0;
                }

                // Zero stage time if more than a day (this should be moved into the window code)
                stage.time           = (stageTime < SECONDS_PER_DAY) ? stageTime : 0d;
                stage.number         = doingCurrent ? -1 : currentStage; // Set the stage number to -1 if doing current engines
                stage.totalPartCount = allParts.Count;
                stage.maxMach        = maxMach;
                stages[currentStage] = stage;

                // Now activate the next stage
                currentStage--;
                doingCurrent = false;

                if (log != null)
                {
                    // Log how long the stage took
                    _timer.Stop();
                    log.AppendLine("Simulating stage took ", _timer.ElapsedMilliseconds, "ms");
                    stage.Dump(log);
                    _timer.Reset();
                    _timer.Start();
                }

                // Activate the next stage
                ActivateStage();

                if (log != null)
                {
                    // Log how long it took to activate
                    _timer.Stop();
                    log.AppendLine("ActivateStage took ", _timer.ElapsedMilliseconds, "ms");
                }
            }

            // Now we add up the various total fields in the stages
            for (int i = 0; i < stages.Length; i++)
            {
                // For each stage we total up the cost, mass, deltaV and time for this stage and all the stages above
                for (int j = i; j >= 0; j--)
                {
                    stages[i].totalDeltaV += stages[j].deltaV;
                    stages[i].totalTime   += stages[j].time;
                    stages[i].partCount    = i > 0 ? stages[i].totalPartCount - stages[i - 1].totalPartCount : stages[i].totalPartCount;
                }
                // We also total up the deltaV for stage and all stages below
                for (int j = i; j < stages.Length; j++)
                {
                    stages[i].inverseTotalDeltaV += stages[j].deltaV;
                }

                // Zero the total time if the value will be huge (24 hours?) to avoid the display going weird
                // (this should be moved into the window code)
                if (stages[i].totalTime > SECONDS_PER_DAY)
                {
                    stages[i].totalTime = 0d;
                }
            }

            FreePooledObject();

            _timer.Stop();

            if (log != null)
            {
                log.AppendLine("RunSimulation: ", _timer.ElapsedMilliseconds, "ms");
                log.Flush();
            }
            log = null;

            return(stages);
        }
Beispiel #16
0
 private void AppendTextToLogMsg(object text)
 {
     LogMsg.AppendText(text.ToString());
 }
Beispiel #17
0
 //LogMsg窗口自动滚动到最后一行
 private void LogMsg_TextChanged(object sender, EventArgs e)
 {
     LogMsg.Select(LogMsg.Text.Length, 0);
     LogMsg.ScrollToCaret();
 }
Beispiel #18
0
 private void SendBroadCast(DataRow myRow)
 {
     try
     {
         string   str       = myRow["SimNum"].ToString();
         DateTime dateTime  = Convert.ToDateTime(myRow["BeginTime"]);
         DateTime dateTime1 = Convert.ToDateTime(myRow["EndTime"]);
         string   str1      = myRow["MsgContent"].ToString();
         string   str2      = myRow["MsgLevel"].ToString();
         int      num       = int.Parse(myRow["MsgId"].ToString());
         if (dateTime1.CompareTo(DateTime.Now) < 0)
         {
             string str3 = "普通信息";
             if ("1".Equals(str2))
             {
                 str3 = "即时信息";
             }
             LogMsg logMsg = new LogMsg()
             {
                 FunctionName = "播报信息"
             };
             string[] strArrays = new string[] { "超时:SimNum-", str, ",信息类型-", str3, ",开始时间-", dateTime.ToString("yyyy-MM-dd HH:mm:ss"), ",结束时间-", dateTime1.ToString("yyyy-MM-dd HH:mm:ss"), ",播报时间-", null, null, null, null };
             strArrays[9]  = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
             strArrays[10] = ",播报消息-";
             strArrays[11] = str1;
             strArrays[12] = "\r\n";
             logMsg.Msg    = string.Concat(strArrays);
             (new LogHelper()).WriteLog(logMsg);
         }
         else if (this.setParam(str1))
         {
             if (this.htBroadCast.ContainsKey(str))
             {
                 if (DateTime.Parse(this.htBroadCast[str].ToString()).AddSeconds((double)ReadDataFromXml.BroadCastMsgTime).CompareTo(DateTime.Now) < 0)
                 {
                     this.htBroadCast.Remove(str);
                 }
                 else
                 {
                     bool flag = true;
                     if (this.dtBroadCastError != null)
                     {
                         foreach (DataRow row in this.dtBroadCastError.Rows)
                         {
                             if (!(row["SimNum"].ToString() == myRow["SimNum"].ToString()) || !(row["BeginTime"].ToString() == myRow["BeginTime"].ToString()) || !(row["MsgLevel"].ToString() == myRow["MsgLevel"].ToString()))
                             {
                                 continue;
                             }
                             flag = false;
                             break;
                         }
                     }
                     if (flag)
                     {
                         if (!"1".Equals(myRow["MsgLevel"].ToString()))
                         {
                             this.AddBroadCastError(myRow);
                         }
                         else
                         {
                             this.AddBroadCastUrgent(myRow);
                         }
                     }
                     return;
                 }
             }
             if (this.myDownData.icar_SendTxtMsg(CmdParam.ParamType.SimNum, str, this.sPw, CmdParam.CommMode.未知方式, this.txtMsg, num, "播报信息") != (long)0)
             {
                 this.AddBroadCastError(myRow);
                 LogMsg logMsg1 = new LogMsg()
                 {
                     FunctionName = "播报信息"
                 };
                 string[] strArrays1 = new string[] { "失败:SimNum-", str, ",播报消息-", str1, ",开始时间-", dateTime.ToString("yyyy-MM-dd HH:mm:ss"), ",结束时间-", dateTime1.ToString("yyyy-MM-dd HH:mm:ss"), ",播报时间-", null, null };
                 strArrays1[9]  = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                 strArrays1[10] = "\r\n";
                 logMsg1.Msg    = string.Concat(strArrays1);
                 (new LogHelper()).WriteLog(logMsg1);
             }
             else if (!this.htBroadCast.ContainsKey(str))
             {
                 this.htBroadCast.Add(str, DateTime.Now);
             }
         }
     }
     catch (Exception exception1)
     {
         Exception exception = exception1;
         ErrorMsg  errorMsg  = new ErrorMsg()
         {
             ClassName    = "BussinessProcess",
             FunctionName = "SendBroadCast",
             ErrorText    = string.Concat("发送播报信息发生错误!", exception.ToString())
         };
         (new LogHelper()).WriteError(errorMsg);
     }
 }
Beispiel #19
0
 private void tGetConfigInfo_Elapsed(object sender, ElapsedEventArgs e)
 {
     this.tGetConfigInfo.Enabled  = false;
     this.tGetConfigInfo.Interval = (double)this.iGetConfigInfo;
     try
     {
         try
         {
             string str = ReadDataFromDB.GetSvrTime().ToString("HH:mm:ss");
             lock (this.infoList)
             {
                 List <int> nums = new List <int>();
                 foreach (KeyValuePair <int, CarBeBackTimeInfo> keyValuePair in this.infoList)
                 {
                     if (this.IsInConfigTime(keyValuePair.Value.BeginTime, keyValuePair.Value.EndTime, str))
                     {
                         continue;
                     }
                     nums.Add(keyValuePair.Key);
                     LogMsg   logMsg = new LogMsg("CarBeBackOnTime", "tGetConfigInfo_Elapsed", "");
                     object[] d      = new object[] { "删除设置时间段外的配置信息ID:", keyValuePair.Value.ID, ",simnum:", keyValuePair.Value.SimNum, ",起始时间:", keyValuePair.Value.BeginTime, ",终止时间: ", keyValuePair.Value.EndTime, ",区域ID:", keyValuePair.Value.RegionID };
                     logMsg.Msg = string.Concat(d);
                     this.logHelper.WriteLog(logMsg);
                 }
                 foreach (int num in nums)
                 {
                     this.infoList.Remove(num);
                 }
                 DataTable configInfo = this.getConfigInfo(str);
                 if (configInfo != null && configInfo.Rows.Count > 0)
                 {
                     foreach (DataRow row in configInfo.Rows)
                     {
                         int num1 = Convert.ToInt32(row["ID"]);
                         if (this.infoList.Keys.Contains <int>(num1))
                         {
                             continue;
                         }
                         CarBeBackTimeInfo carBeBackInfo = this.getCarBeBackInfo(row);
                         if (carBeBackInfo == null)
                         {
                             continue;
                         }
                         this.infoList.Add(num1, carBeBackInfo);
                         LogMsg   logMsg1 = new LogMsg("CarBeBackOnTime", "tGetConfigInfo_Elapsed", "");
                         object[] simNum  = new object[] { "增加配置信息ID:", num1, ",simnum:", carBeBackInfo.SimNum, ",起始时间:", carBeBackInfo.BeginTime, ",终止时间: ", carBeBackInfo.EndTime, ",区域ID:", carBeBackInfo.RegionID };
                         logMsg1.Msg = string.Concat(simNum);
                         this.logHelper.WriteLog(logMsg1);
                     }
                 }
             }
         }
         catch (Exception exception1)
         {
             Exception exception = exception1;
             ErrorMsg  errorMsg  = new ErrorMsg()
             {
                 ClassName    = "CarBeBackOnTime",
                 FunctionName = "tGetConfigInfo_Elapsed",
                 ErrorText    = string.Concat("获取配置信息错误,", exception.Message)
             };
             this.logHelper.WriteError(errorMsg);
         }
     }
     finally
     {
         this.tGetConfigInfo.Enabled = true;
     }
 }
Beispiel #20
0
        // All functions below this point must not rely on the part member (it may be null)
        //

        public void GetSourceSet(int type, bool includeSurfaceMountedParts, List <PartSim> allParts, HashSet <PartSim> visited, HashSet <PartSim> allSources, LogMsg log, String indent)
        {
            if (log != null)
            {
                log.buf.AppendLine(indent + "GetSourceSet(" + ResourceContainer.GetResourceName(type) + ") for " + name + ":" + partId);
                indent += "  ";
            }

            // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns as is.
            if (visited.Contains(this))
            {
                if (log != null)
                {
                    log.buf.AppendLine(indent + "Returning empty set, already visited (" + name + ":" + partId + ")");
                }
                return;
            }

            if (log != null)
            {
                log.buf.AppendLine(indent + "Adding this to visited");
            }

            visited.Add(this);

            // Rule 2: Part performs scan on start of every fuel pipe ending in it. This scan is done in order in which pipes were installed.
            // Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result.
            //MonoBehaviour.print("for each fuel line");

            int lastCount = allSources.Count;

            for (int i = 0; i < this.fuelTargets.Count; i++)
            {
                PartSim partSim = this.fuelTargets[i];
                if (partSim != null)
                {
                    if (visited.Contains(partSim))
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
                        }
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");
                        }

                        partSim.GetSourceSet(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent);
                    }
                }
            }

            // check surface mounted fuel targets
            if (includeSurfaceMountedParts)
            {
                for (int i = 0; i < surfaceMountFuelTargets.Count; i++)
                {
                    PartSim partSim = this.surfaceMountFuelTargets[i];
                    if (partSim != null)
                    {
                        if (visited.Contains(partSim))
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
                            }
                        }
                        else
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");
                            }

                            partSim.GetSourceSet(type, true, allParts, visited, allSources, log, indent);
                        }
                    }
                }
            }

            if (allSources.Count > lastCount)
            {
                if (log != null)
                {
                    log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " fuel target sources (" + this.name + ":" + this.partId + ")");
                }
                return;
            }


            // Rule 3: This rule has been removed and merged with rules 4 and 7 to fix issue with fuel tanks with disabled crossfeed

            // Rule 4: Part performs scan on each of its axially mounted neighbors.
            //  Couplers (bicoupler, tricoupler, ...) are an exception, they only scan one attach point on the single attachment side,
            //  skip the points on the side where multiple points are. [Experiment]
            //  Again, the part creates union of scan lists from each of its neighbor and if it is not empty, returns this list.
            //  The order in which mount points of a part are scanned appears to be fixed and defined by the part specification file. [Experiment]
            if (fuelCrossFeed)
            {
                lastCount = allSources.Count;
                //MonoBehaviour.print("for each attach node");
                for (int i = 0; i < this.attachNodes.Count; i++)
                {
                    AttachNodeSim attachSim = this.attachNodes[i];
                    if (attachSim.attachedPartSim != null)
                    {
                        if (attachSim.nodeType == AttachNode.NodeType.Stack)
                        {
                            if ((string.IsNullOrEmpty(noCrossFeedNodeKey) == false && attachSim.id.Contains(noCrossFeedNodeKey)) == false)
                            {
                                if (visited.Contains(attachSim.attachedPartSim))
                                {
                                    if (log != null)
                                    {
                                        log.buf.AppendLine(indent + "Attached part already visited, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                                    }
                                }
                                else
                                {
                                    if (log != null)
                                    {
                                        log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                                    }

                                    attachSim.attachedPartSim.GetSourceSet(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent);
                                }
                            }
                        }
                    }
                }

                if (allSources.Count > lastCount)
                {
                    if (log != null)
                    {
                        log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " attached sources (" + this.name + ":" + this.partId + ")");
                    }
                    return;
                }
            }

            // Rule 5: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel
            // type was not disabled [Experiment]) and it contains fuel, it returns itself.
            // Rule 6: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel
            // type was not disabled) but it does not contain the requested fuel, it returns empty list. [Experiment]
            if (resources.HasType(type) && resourceFlowStates[type] > 0.0)
            {
                if (resources[type] > SimManager.RESOURCE_MIN)
                {
                    allSources.Add(this);

                    if (log != null)
                    {
                        log.buf.AppendLine(indent + "Returning enabled tank as only source (" + name + ":" + partId + ")");
                    }
                }

                return;
            }
            else
            {
                if (log != null)
                {
                    log.buf.AppendLine(indent + "Not fuel tank or disabled. HasType = " + resources.HasType(type) + "  FlowState = " + resourceFlowStates[type]);
                }
            }

            // Rule 7: If the part is radially attached to another part and it is child of that part in the ship's tree structure, it scans its
            // parent and returns whatever the parent scan returned. [Experiment] [Experiment]
            if (parent != null && parentAttach == AttachModes.SRF_ATTACH)
            {
                if (fuelCrossFeed)
                {
                    if (visited.Contains(parent))
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine(indent + "Parent part already visited, skipping (" + parent.name + ":" + parent.partId + ")");
                        }
                    }
                    else
                    {
                        lastCount = allSources.Count;
                        this.parent.GetSourceSet(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent);
                        if (allSources.Count > lastCount)
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " parent sources (" + this.name + ":" + this.partId + ")");
                            }
                            return;
                        }
                    }
                }
            }

            // Rule 8: If all preceding rules failed, part returns empty list.
            if (log != null)
            {
                log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");
            }

            return;
        }
Beispiel #21
0
        public bool SetResourceDrains(List<PartSim> allParts, List<PartSim> allFuelLines, HashSet<PartSim> drainingParts)
        {
            LogMsg log = null;
            //DumpSourcePartSets("before clear");
            foreach (HashSet<PartSim> sourcePartSet in sourcePartSets.Values)
            {
                sourcePartSet.Clear();
            }
            //DumpSourcePartSets("after clear");

            for (int index = 0; index < this.resourceConsumptions.Types.Count; index++)
            {
                int type = this.resourceConsumptions.Types[index];

                HashSet<PartSim> sourcePartSet;
                if (!sourcePartSets.TryGetValue(type, out sourcePartSet))
                {
                    sourcePartSet = new HashSet<PartSim>();
                    sourcePartSets.Add(type, sourcePartSet);
                }

                switch ((ResourceFlowMode)this.resourceFlowModes[type])
                {
                    case ResourceFlowMode.NO_FLOW:
                        if (partSim.resources[type] > SimManager.RESOURCE_MIN && partSim.resourceFlowStates[type] != 0)
                        {
                            //sourcePartSet = new HashSet<PartSim>();
                            //MonoBehaviour.print("SetResourceDrains(" + name + ":" + partId + ") setting sources to just this");
                            sourcePartSet.Add(partSim);
                        }
                        break;

                    case ResourceFlowMode.ALL_VESSEL:
                        for (int i = 0; i < allParts.Count; i++)
                        {
                            PartSim aPartSim = allParts[i];
                            if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0)
                            {
                                sourcePartSet.Add(aPartSim);
                            }
                        }
                        break;

                    case ResourceFlowMode.STAGE_PRIORITY_FLOW:

                        foreach (HashSet<PartSim> stagePartSet in stagePartSets.Values)
                        {
                            stagePartSet.Clear();
                        }
                        var maxStage = -1;

                        //Logger.Log(type);
                        for (int i = 0; i < allParts.Count; i++)
                        {
                            var aPartSim = allParts[i];
                            if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0)
                            {
                                continue;
                            }

                            int stage = aPartSim.DecouplerCount();
                            if (stage > maxStage)
                            {
                                maxStage = stage;
                            }

                            HashSet<PartSim> tempPartSet;
                            if (!stagePartSets.TryGetValue(stage, out tempPartSet))
                            {
                                tempPartSet = new HashSet<PartSim>();
                                stagePartSets.Add(stage, tempPartSet);
                            }
                            tempPartSet.Add(aPartSim);
                        }

                        for (int j = maxStage; j >= 0; j--)
                        {
                            HashSet<PartSim> stagePartSet;
                            if (stagePartSets.TryGetValue(j, out stagePartSet) && stagePartSet.Count > 0)
                            {
                                // We have to copy the contents of the set here rather than copying the set reference or
                                // bad things (tm) happen
                                foreach (PartSim aPartSim in stagePartSet)
                                {
                                    sourcePartSet.Add(aPartSim);
                                }
                                break;
                            }
                        }
                        break;

                    case ResourceFlowMode.STACK_PRIORITY_SEARCH:
                        visited.Clear();

                        if (SimManager.logOutput)
                        {
                            log = new LogMsg();
                            log.buf.AppendLine("Find " + ResourceContainer.GetResourceName(type) + " sources for " + partSim.name + ":" + partSim.partId);
                        }
                        partSim.GetSourceSet(type, allParts, visited, sourcePartSet, log, "");
                        if (SimManager.logOutput)
                        {
                            MonoBehaviour.print(log.buf);
                        }
                        break;

                    default:
                        MonoBehaviour.print("SetResourceDrains(" + partSim.name + ":" + partSim.partId + ") Unexpected flow type for " + ResourceContainer.GetResourceName(type) + ")");
                        break;
                }

                if (SimManager.logOutput)
                {
                    if (sourcePartSet.Count > 0)
                    {
                        log = new LogMsg();
                        log.buf.AppendLine("Source parts for " + ResourceContainer.GetResourceName(type) + ":");
                        foreach (PartSim partSim in sourcePartSet)
                        {
                            log.buf.AppendLine(partSim.name + ":" + partSim.partId);
                        }
                        MonoBehaviour.print(log.buf);
                    }
                }

                //DumpSourcePartSets("after " + ResourceContainer.GetResourceName(type));
            }

            // If we don't have sources for all the needed resources then return false without setting up any drains
            for (int i = 0; i < this.resourceConsumptions.Types.Count; i++)
            {
                int type = this.resourceConsumptions.Types[i];
                HashSet<PartSim> sourcePartSet;
                if (!sourcePartSets.TryGetValue(type, out sourcePartSet) || sourcePartSet.Count == 0)
                {
                    if (SimManager.logOutput)
                    {
                        MonoBehaviour.print("No source of " + ResourceContainer.GetResourceName(type));
                    }

                    isActive = false;
                    return false;
                }
            }

            // Now we set the drains on the members of the sets and update the draining parts set
            for (int i = 0; i < this.resourceConsumptions.Types.Count; i++)
            {
                int type = this.resourceConsumptions.Types[i];
                HashSet<PartSim> sourcePartSet = sourcePartSets[type];
                // Loop through the members of the set
                double amount = resourceConsumptions[type] / sourcePartSet.Count;
                foreach (PartSim partSim in sourcePartSet)
                {
                    if (SimManager.logOutput)
                    {
                        MonoBehaviour.print(
                            "Adding drain of " + amount + " " + ResourceContainer.GetResourceName(type) + " to " + partSim.name + ":" +
                            partSim.partId);
                    }

                    partSim.resourceDrains.Add(type, amount);
                    drainingParts.Add(partSim);
                }
            }
            return true;
        }
Beispiel #22
0
        private static Vector3 CalculateThrustVector(List <Transform> thrustTransforms, List <float> thrustTransformMultipliers, LogMsg log)
        {
            if (thrustTransforms == null)
            {
                return(Vector3.forward);
            }

            Vector3 thrustvec = Vector3.zero;

            for (int i = 0; i < thrustTransforms.Count; ++i)
            {
                Transform trans = thrustTransforms[i];

                if (log != null)
                {
                    log.buf.AppendFormat("Transform = ({0:g6}, {1:g6}, {2:g6})   length = {3:g6}\n", trans.forward.x, trans.forward.y, trans.forward.z, trans.forward.magnitude);
                }

                thrustvec -= (trans.forward * thrustTransformMultipliers[i]);
            }

            if (log != null)
            {
                log.buf.AppendFormat("ThrustVec  = ({0:g6}, {1:g6}, {2:g6})   length = {3:g6}\n", thrustvec.x, thrustvec.y, thrustvec.z, thrustvec.magnitude);
            }

            thrustvec.Normalize();

            if (log != null)
            {
                log.buf.AppendFormat("ThrustVecN = ({0:g6}, {1:g6}, {2:g6})   length = {3:g6}\n", thrustvec.x, thrustvec.y, thrustvec.z, thrustvec.magnitude);
            }

            return(thrustvec);
        }
Beispiel #23
0
        public void CreateEngineSims(List<EngineSim> allEngines, double atmosphere, double mach, bool vectoredThrust, bool fullThrust, LogMsg log)
        {
            if (log != null) log.AppendLine("CreateEngineSims for ", this.name);
            var partMods = this.part.Modules;
            var numMods = partMods.Count;

            if (hasMultiModeEngine)
            {
                // A multi-mode engine has multiple ModuleEngines but only one is active at any point
                // The mode of the engine is the engineID of the ModuleEngines that is (are?) active
                string mode = part.GetModule<MultiModeEngine>().mode;

                for (int i = 0; i < numMods; i++)
                {
                    //log.AppendLine("Module: ", partMods[i].moduleName);
                    var engine = partMods[i] as ModuleEngines;
                    if (engine != null && engine.engineID == mode)
                    {
                        if (log != null) log.AppendLine("Module: ", engine.moduleName);

                        EngineSim engineSim = EngineSim.New(
                            this,
                            engine,
                            atmosphere,
                            (float)mach,
                            vectoredThrust,
                            fullThrust,
                            log);
                        allEngines.Add(engineSim);
                    }
                }
            }
            else if (hasModuleEngines)
            {
                for (int i = 0; i < numMods; i++)
                {
                    //log.AppendLine("Module: ", partMods[i].moduleName);
                    var engine = partMods[i] as ModuleEngines;
                    if (engine != null)
                    {
                        if (log != null) log.AppendLine("Module: ", engine.moduleName);

                        EngineSim engineSim = EngineSim.New(
                            this,
                            engine,
                            atmosphere,
                            (float)mach,
                            vectoredThrust,
                            fullThrust,
                            log);
                        allEngines.Add(engineSim);
                    }
                }
            }
        }
Beispiel #24
0
        public bool SetResourceDrains(LogMsg log, List <PartSim> allParts, List <PartSim> allFuelLines, HashSet <PartSim> drainingParts)
        {
            //DumpSourcePartSets(log, "before clear");
            foreach (HashSet <PartSim> sourcePartSet in sourcePartSets.Values)
            {
                sourcePartSet.Clear();
            }
            //DumpSourcePartSets(log, "after clear");

            for (int index = 0; index < this.resourceConsumptionsForMass.Types.Count; index++)
            {
                int type = this.resourceConsumptionsForMass.Types[index];

                HashSet <PartSim> sourcePartSet;
                if (!sourcePartSets.TryGetValue(type, out sourcePartSet))
                {
                    sourcePartSet = new HashSet <PartSim>();
                    sourcePartSets.Add(type, sourcePartSet);
                }

                switch ((ResourceFlowMode)this.resourceFlowModes[type])
                {
                case ResourceFlowMode.NO_FLOW:
                    if (partSim.resources[type] > SimManager.RESOURCE_MIN && partSim.resourceFlowStates[type] != 0)
                    {
                        sourcePartSet.Add(partSim);
                    }
                    break;

                case ResourceFlowMode.ALL_VESSEL:
                case ResourceFlowMode.ALL_VESSEL_BALANCE:
                    for (int i = 0; i < allParts.Count; i++)
                    {
                        PartSim aPartSim = allParts[i];
                        if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0)
                        {
                            sourcePartSet.Add(aPartSim);
                        }
                    }
                    break;

                case ResourceFlowMode.STAGE_PRIORITY_FLOW:
                case ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE:

                    if (log != null)
                    {
                        log.Append("Find ", ResourceContainer.GetResourceName(type), " sources for ", partSim.name)
                        .AppendLine(":", partSim.partId);
                    }
                    foreach (HashSet <PartSim> stagePartSet in stagePartSets.Values)
                    {
                        stagePartSet.Clear();
                    }
                    var maxStage = -1;

                    for (int i = 0; i < allParts.Count; i++)
                    {
                        var aPartSim = allParts[i];
                        //if (log != null) log.Append(aPartSim.name, ":" + aPartSim.partId, " contains ", aPartSim.resources[type])
                        //                  .AppendLine((aPartSim.resourceFlowStates[type] == 0) ? " (disabled)" : "");
                        if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0)
                        {
                            continue;
                        }

                        int stage = aPartSim.inverseStage;
                        if (stage > maxStage)
                        {
                            maxStage = stage;
                        }

                        HashSet <PartSim> tempPartSet;
                        if (!stagePartSets.TryGetValue(stage, out tempPartSet))
                        {
                            tempPartSet = new HashSet <PartSim>();
                            stagePartSets.Add(stage, tempPartSet);
                        }
                        tempPartSet.Add(aPartSim);
                    }

                    for (int j = maxStage; j >= -1; j--)
                    {
                        //if (log != null) log.AppendLine("Testing stage ", j);
                        HashSet <PartSim> stagePartSet;
                        if (stagePartSets.TryGetValue(j, out stagePartSet) && stagePartSet.Count > 0)
                        {
                            //if (log != null) log.AppendLine("Not empty");
                            // We have to copy the contents of the set here rather than copying the set reference or
                            // bad things (tm) happen
                            foreach (PartSim aPartSim in stagePartSet)
                            {
                                sourcePartSet.Add(aPartSim);
                            }
                            break;
                        }
                    }
                    break;

                case ResourceFlowMode.STACK_PRIORITY_SEARCH:
                case ResourceFlowMode.STAGE_STACK_FLOW:
                case ResourceFlowMode.STAGE_STACK_FLOW_BALANCE:
                    visited.Clear();

                    if (log != null)
                    {
                        log.Append("Find ", ResourceContainer.GetResourceName(type), " sources for ", partSim.name)
                        .AppendLine(":", partSim.partId);
                    }

                    partSim.GetSourceSet(type, allParts, visited, sourcePartSet, log, "");
                    break;

                default:
                    if (log != null)
                    {
                        log.Append("SetResourceDrains(", partSim.name, ":", partSim.partId)
                        .AppendLine(") Unexpected flow type for ", ResourceContainer.GetResourceName(type), ")");
                    }
                    break;
                }

                if (log != null && sourcePartSet.Count > 0)
                {
                    log.AppendLine("Source parts for ", ResourceContainer.GetResourceName(type), ":");
                    foreach (PartSim partSim in sourcePartSet)
                    {
                        log.AppendLine(partSim.name, ":", partSim.partId);
                    }
                }

                //DumpSourcePartSets(log, "after " + ResourceContainer.GetResourceName(type));
            }

            // If we don't have sources for all the needed resources then return false without setting up any drains
            for (int i = 0; i < this.resourceConsumptionsForMass.Types.Count; i++)
            {
                int type = this.resourceConsumptionsForMass.Types[i];
                HashSet <PartSim> sourcePartSet;
                if (!sourcePartSets.TryGetValue(type, out sourcePartSet) || sourcePartSet.Count == 0)
                {
                    if (log != null)
                    {
                        log.AppendLine("No source of ", ResourceContainer.GetResourceName(type));
                    }
                    isActive = false;
                    return(false);
                }
            }

            // Now we set the drains on the members of the sets and update the draining parts set
            for (int i = 0; i < this.resourceConsumptionsForMass.Types.Count; i++)
            {
                int type = this.resourceConsumptionsForMass.Types[i];
                HashSet <PartSim> sourcePartSet = sourcePartSets[type];
                ResourceFlowMode  mode          = (ResourceFlowMode)resourceFlowModes[type];
                double            consumption   = resourceConsumptionsForMass[type];
                double            amount        = 0d;
                double            total         = 0d;
                if (mode == ResourceFlowMode.ALL_VESSEL_BALANCE ||
                    mode == ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE ||
                    mode == ResourceFlowMode.STAGE_STACK_FLOW_BALANCE ||
                    mode == ResourceFlowMode.STACK_PRIORITY_SEARCH)
                {
                    foreach (PartSim partSim in sourcePartSet)
                    {
                        total += partSim.resources[type];
                    }
                }
                else
                {
                    amount = consumption / sourcePartSet.Count;
                }

                // Loop through the members of the set
                foreach (PartSim partSim in sourcePartSet)
                {
                    if (total != 0d)
                    {
                        amount = consumption * partSim.resources[type] / total;
                    }

                    if (log != null)
                    {
                        log.Append("Adding drain of ", amount, " ", ResourceContainer.GetResourceName(type))
                        .AppendLine(" to ", partSim.name, ":", partSim.partId);
                    }

                    partSim.resourceDrains.Add(type, amount);
                    drainingParts.Add(partSim);
                }
            }
            return(true);
        }
Beispiel #25
0
        // This is a new function for STAGE_STACK_FLOW(_BALANCE)
        public void GetSourceSet(int type, bool includeSurfaceMountedParts, List<PartSim> allParts, HashSet<PartSim> visited, HashSet<PartSim> allSources, LogMsg log, String indent)
        {
            // Initial version of support for new flow mode

            // Call a modified version of the old GetSourceSet code that adds all potential sources rather than stopping the recursive scan
            // when certain conditions are met
            int priMax = int.MinValue;
            GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, ref priMax, log, indent);
            if (log != null) log.AppendLine(allSources.Count, " parts with priority of ", priMax);
        }
Beispiel #26
0
        public static EngineSim New(PartSim theEngine,
                                    ModuleEngines engineMod,
                                    double atmosphere,
                                    float machNumber,
                                    bool vectoredThrust,
                                    bool fullThrust,
                                    LogMsg log)
        {
            float            maxFuelFlow                = engineMod.maxFuelFlow;
            float            minFuelFlow                = engineMod.minFuelFlow;
            float            thrustPercentage           = engineMod.thrustPercentage;
            List <Transform> thrustTransforms           = engineMod.thrustTransforms;
            List <float>     thrustTransformMultipliers = engineMod.thrustTransformMultipliers;
            Vector3          vecThrust = CalculateThrustVector(vectoredThrust ? thrustTransforms : null,
                                                               vectoredThrust ? thrustTransformMultipliers : null,
                                                               log);
            FloatCurve        atmosphereCurve  = engineMod.atmosphereCurve;
            bool              atmChangeFlow    = engineMod.atmChangeFlow;
            FloatCurve        atmCurve         = engineMod.useAtmCurve ? engineMod.atmCurve : null;
            FloatCurve        velCurve         = engineMod.useVelCurve ? engineMod.velCurve : null;
            FloatCurve        thrustCurve      = engineMod.useThrustCurve ? engineMod.thrustCurve : null;
            float             currentThrottle  = engineMod.currentThrottle;
            float             IspG             = engineMod.g;
            bool              throttleLocked   = engineMod.throttleLocked || fullThrust;
            List <Propellant> propellants      = engineMod.propellants;
            float             thrustCurveRatio = engineMod.thrustCurveRatio;

            foreach (Propellant p in propellants)
            {
                if (p.ignoreForThrustCurve)
                {
                    continue;
                }
                double ratio = p.totalResourceAvailable / p.totalResourceCapacity;
                if (ratio < thrustCurveRatio)
                {
                    thrustCurveRatio = (float)ratio;
                }
            }

            bool active = engineMod.isOperational;

            //I do not know if this matters. RF and stock always have finalThrust. But stock uses resultingThrust in the mass flow calculations, so keep it.
            float resultingThrust = SimManager.hasInstalledRealFuels ? engineMod.finalThrust : engineMod.resultingThrust;

            bool isFlamedOut = engineMod.flameout;

            EngineSim engineSim = pool.Borrow();

            engineSim.isp          = 0.0;
            engineSim.maxMach      = 0.0f;
            engineSim.actualThrust = 0.0;
            engineSim.partSim      = theEngine;
            engineSim.isActive     = active;
            engineSim.thrustVec    = vecThrust;
            engineSim.isFlamedOut  = isFlamedOut;
            engineSim.resourceConsumptionsForMass.Reset();
            engineSim.resourceConsumptionsForIsp.Reset();
            engineSim.resourceFlowModes.Reset();
            engineSim.appliedForces.Clear();



            double flowRate = 0.0;

            if (engineSim.partSim.hasVessel)
            {
                if (log != null)
                {
                    log.AppendLine("hasVessel is true");
                }
                float flowModifier = GetFlowModifier(atmChangeFlow, atmCurve, engineSim.partSim.part.atmDensity, velCurve, machNumber, thrustCurve, thrustCurveRatio, ref engineSim.maxMach, engineMod.flowMultCap, engineMod.flowMultCapSharpness);
                engineSim.isp          = atmosphereCurve.Evaluate((float)atmosphere);
                engineSim.thrust       = GetThrust(Mathf.Lerp(minFuelFlow, maxFuelFlow, GetThrustPercent(thrustPercentage)) * flowModifier, engineSim.isp);
                engineSim.actualThrust = engineSim.isActive ?  resultingThrust : 0.0;
                if (log != null)
                {
                    log.buf.AppendFormat("flowMod = {0:g6}\n", flowModifier);
                    log.buf.AppendFormat("isp     = {0:g6}\n", engineSim.isp);
                    log.buf.AppendFormat("thrust  = {0:g6}\n", engineSim.thrust);
                    log.buf.AppendFormat("actual  = {0:g6}\n", engineSim.actualThrust);
                    log.buf.AppendFormat("final  = {0:g6}\n", engineMod.finalThrust);
                    log.buf.AppendFormat("resulting  = {0:g6}\n", engineMod.resultingThrust);
                }

                if (throttleLocked)
                {
                    if (log != null)
                    {
                        log.AppendLine("throttleLocked is true, using thrust for flowRate");
                    }
                    flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
                }
                else
                {
                    if (currentThrottle > 0.0f && engineSim.partSim.isLanded == false)
                    {
                        if (log != null)
                        {
                            log.AppendLine("throttled up and not landed, using actualThrust for flowRate");
                        }
                        flowRate = GetFlowRate(engineSim.actualThrust, engineSim.isp);
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.AppendLine("throttled down or landed, using thrust for flowRate");
                        }
                        flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
                    }
                }
            }
            else
            {
                if (log != null)
                {
                    log.buf.AppendLine("hasVessel is false");
                }
                float flowModifier = GetFlowModifier(atmChangeFlow, atmCurve, CelestialBodies.SelectedBody.GetDensity(BuildAdvanced.Altitude), velCurve, machNumber, thrustCurve, thrustCurveRatio, ref engineSim.maxMach, engineMod.flowMultCap, engineMod.flowMultCapSharpness);
                engineSim.isp          = atmosphereCurve.Evaluate((float)atmosphere);
                engineSim.thrust       = GetThrust(Mathf.Lerp(minFuelFlow, maxFuelFlow, GetThrustPercent(thrustPercentage)) * flowModifier, engineSim.isp);
                engineSim.actualThrust = 0d;
                if (log != null)
                {
                    log.buf.AppendFormat("flowMod = {0:g6}\n", flowModifier);
                    log.buf.AppendFormat("isp     = {0:g6}\n", engineSim.isp);
                    log.buf.AppendFormat("thrust  = {0:g6}\n", engineSim.thrust);
                    log.buf.AppendFormat("actual  = {0:g6}\n", engineSim.actualThrust);
                    log.AppendLine("no vessel, using thrust for flowRate");
                }

                flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
            }

            if (log != null)
            {
                log.buf.AppendFormat("flowRate = {0:g6}\n", flowRate);
            }

            float flowMass = 0f;

            for (int i = 0; i < propellants.Count; ++i)
            {
                Propellant propellant = propellants[i];
                if (propellant.name == "ElectricCharge" || propellant.name == "IntakeAir")
                {
                    continue;
                }
                flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id);
            }

            if (log != null)
            {
                log.buf.AppendFormat("flowMass = {0:g6}\n", flowMass);
            }

            for (int i = 0; i < propellants.Count; ++i)
            {
                Propellant propellant = propellants[i];

                if (propellant.name == "ElectricCharge" || propellant.name == "IntakeAir")
                {
                    continue;
                }

                double consumptionRate = propellant.ratio * flowRate / flowMass;
                if (log != null)
                {
                    log.buf.AppendFormat(
                        "Add consumption({0}, {1}:{2:d}) = {3:g6}\n",
                        ResourceContainer.GetResourceName(propellant.id),
                        theEngine.name,
                        theEngine.partId,
                        consumptionRate);
                }
                // Add all for mass
                engineSim.resourceConsumptionsForMass.Add(propellant.id, consumptionRate);
                if (!propellant.ignoreForIsp)
                {
                    engineSim.resourceConsumptionsForIsp.Add(propellant.id, consumptionRate);
                }
                engineSim.resourceFlowModes.Add(propellant.id, (double)propellant.GetFlowMode());
            }

            for (int i = 0; i < thrustTransforms.Count; i++)
            {
                Transform thrustTransform = thrustTransforms[i];
                Vector3d  direction       = thrustTransform.forward.normalized;
                Vector3d  position        = thrustTransform.position;

                AppliedForce appliedForce = AppliedForce.New(direction * engineSim.thrust * thrustTransformMultipliers[i], position);
                engineSim.appliedForces.Add(appliedForce);
            }

            return(engineSim);
        }
Beispiel #27
0
        public static PartSim New(Part p, int id, double atmosphere, LogMsg log)
        {
            PartSim partSim = pool.Borrow();

            partSim.part = p;
            partSim.centerOfMass = p.transform.TransformPoint(p.CoMOffset);
            partSim.partId = id;
            partSim.name = p.partInfo.name;

            if (log != null) log.buf.AppendLine("Create PartSim for " + partSim.name);

            partSim.parent = null;
            partSim.parentAttach = p.attachMode;
            partSim.fuelCrossFeed = p.fuelCrossFeed;
            partSim.noCrossFeedNodeKey = p.NoCrossFeedNodeKey;
            partSim.decoupledInStage = partSim.DecoupledInStage(p);
            partSim.isFuelLine = p.HasModule<CModuleFuelLine>();
            partSim.isFuelTank = p is FuelTank;
            partSim.isSepratron = partSim.IsSepratron();
            partSim.inverseStage = p.inverseStage;
            //MonoBehaviour.print("inverseStage = " + inverseStage);

            partSim.baseCost = p.GetCostDry();

            if (log != null)
            {
                log.buf.AppendLine("Parent part = " + (p.parent == null ? "null" : p.parent.partInfo.name));
                log.buf.AppendLine("physicalSignificance = " + p.physicalSignificance);
                log.buf.AppendLine("PhysicsSignificance = " + p.PhysicsSignificance);
            }

            // Work out if the part should have no physical significance
            // The root part is never "no physics"
            partSim.isNoPhysics = p.physicalSignificance == Part.PhysicalSignificance.NONE ||
                                    p.PhysicsSignificance == 1;

            if (p.HasModule<LaunchClamp>())
            {
                partSim.realMass = 0d;
                if (log != null) log.buf.AppendLine("Ignoring mass of launch clamp");
            }
            else
            {
                partSim.realMass = p.mass;
                if (log != null) log.buf.AppendLine("Using part.mass of " + p.mass);
            }

            partSim.postStageMassAdjust = 0f;
            if (log != null) log.buf.AppendLine("Calculating postStageMassAdjust, prefabMass = " + p.prefabMass);
            int count = p.Modules.Count;
            for (int i = 0; i < count; i++)
            {
                if (log != null) log.buf.AppendLine("Module: " + p.Modules[i].moduleName);
                IPartMassModifier partMassModifier = p.Modules[i] as IPartMassModifier;
                if (partMassModifier != null)
                {
                    if (log != null) log.buf.AppendLine("ChangeWhen = " + partMassModifier.GetModuleMassChangeWhen());
                    if (partMassModifier.GetModuleMassChangeWhen() == ModifierChangeWhen.STAGED)
                    {
                        float preStage = partMassModifier.GetModuleMass(p.prefabMass, ModifierStagingSituation.UNSTAGED);
                        float postStage = partMassModifier.GetModuleMass(p.prefabMass, ModifierStagingSituation.STAGED);
                        if (log != null) log.buf.AppendLine("preStage = " + preStage + "   postStage = " + postStage);
                        partSim.postStageMassAdjust += (postStage - preStage);
                    }
                }
            }
            if (log != null) log.buf.AppendLine("postStageMassAdjust = " + partSim.postStageMassAdjust);

            for (int i = 0; i < p.Resources.Count; i++)
            {
                PartResource resource = p.Resources[i];

                // Make sure it isn't NaN as this messes up the part mass and hence most of the values
                // This can happen if a resource capacity is 0 and tweakable
                if (!Double.IsNaN(resource.amount))
                {
                    if (log != null)
                        log.buf.AppendLine(resource.resourceName + " = " + resource.amount);

                    partSim.resources.Add(resource.info.id, resource.amount);
                    partSim.resourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0);
                }
                else
                {
                    if (log != null) log.buf.AppendLine(resource.resourceName + " is NaN. Skipping.");
                }
            }

            partSim.hasVessel = (p.vessel != null);
            partSim.isLanded = partSim.hasVessel && p.vessel.Landed;
            if (partSim.hasVessel)
            {
                partSim.vesselName = p.vessel.vesselName;
                partSim.vesselType = p.vesselType;
            }
            partSim.initialVesselName = p.initialVesselName;

            partSim.hasMultiModeEngine = p.HasModule<MultiModeEngine>();
            partSim.hasModuleEngines = p.HasModule<ModuleEngines>();

            partSim.isEngine = partSim.hasMultiModeEngine || partSim.hasModuleEngines;

            if (log != null) log.buf.AppendLine("Created " + partSim.name + ". Decoupled in stage " + partSim.decoupledInStage);

            return partSim;
        }
Beispiel #28
0
        public static PartSim New(Part p, int id, double atmosphere, LogMsg log)
        {
            PartSim partSim = pool.Borrow();

            partSim.part         = p;
            partSim.centerOfMass = p.transform.TransformPoint(p.CoMOffset);
            partSim.partId       = id;
            partSim.name         = p.partInfo.name;

            if (log != null)
            {
                log.AppendLine("Create PartSim for ", partSim.name);
            }

            partSim.parent             = null;
            partSim.parentAttach       = p.attachMode;
            partSim.fuelCrossFeed      = p.fuelCrossFeed;
            partSim.noCrossFeedNodeKey = p.NoCrossFeedNodeKey;
            partSim.isEnginePlate      = IsEnginePlate(p);
            if (partSim.isEnginePlate)
            {
                partSim.noCrossFeedNodeKey = "bottom";
            }
            partSim.decoupledInStage = partSim.DecoupledInStage(p);
            partSim.isFuelLine       = p.HasModule <CModuleFuelLine>();
            partSim.isSepratron      = p.IsSepratron();
            partSim.inverseStage     = p.inverseStage;
            if (log != null)
            {
                log.AppendLine("inverseStage = ", partSim.inverseStage);
            }
            partSim.resPriorityOffset = p.resourcePriorityOffset;
            partSim.resPriorityUseParentInverseStage = p.resourcePriorityUseParentInverseStage;
            partSim.resRequestRemainingThreshold     = p.resourceRequestRemainingThreshold;

            partSim.baseCost = p.GetCostDry();

            if (log != null)
            {
                log.AppendLine("Parent part = ", (p.parent == null ? "null" : p.parent.partInfo.name))
                .AppendLine("physicalSignificance = ", p.physicalSignificance)
                .AppendLine("PhysicsSignificance = ", p.PhysicsSignificance);
            }

            // Work out if the part should have no physical significance
            // The root part is never "no physics"
            partSim.isNoPhysics = p.physicalSignificance == Part.PhysicalSignificance.NONE ||
                                  p.PhysicsSignificance == 1;

            if (p.HasModule <LaunchClamp>())
            {
                partSim.realMass = 0d;
                if (log != null)
                {
                    log.AppendLine("Ignoring mass of launch clamp");
                }
            }
            else
            {
                partSim.crewMassOffset = p.getCrewAdjustment();
                partSim.realMass       = p.mass + partSim.crewMassOffset;
                if (log != null)
                {
                    log.AppendLine("Using part.mass of ", partSim.realMass);
                }
            }

            partSim.postStageMassAdjust = 0f;
            if (log != null)
            {
                log.AppendLine("Calculating postStageMassAdjust, prefabMass = ", p.prefabMass);
            }
            int count = p.Modules.Count;

            for (int i = 0; i < count; i++)
            {
                if (log != null)
                {
                    log.AppendLine("Module: ", p.Modules[i].moduleName);
                }
                IPartMassModifier partMassModifier = p.Modules[i] as IPartMassModifier;
                if (partMassModifier != null)
                {
                    if (log != null)
                    {
                        log.AppendLine("ChangeWhen = ", partMassModifier.GetModuleMassChangeWhen());
                    }
                    if (partMassModifier.GetModuleMassChangeWhen() == ModifierChangeWhen.STAGED)
                    {
                        float preStage  = partMassModifier.GetModuleMass(p.prefabMass, ModifierStagingSituation.UNSTAGED);
                        float postStage = partMassModifier.GetModuleMass(p.prefabMass, ModifierStagingSituation.STAGED);
                        if (log != null)
                        {
                            log.AppendLine("preStage = ", preStage, "   postStage = ", postStage);
                        }
                        partSim.postStageMassAdjust += (postStage - preStage);
                    }
                }
            }
            if (log != null)
            {
                log.AppendLine("postStageMassAdjust = ", partSim.postStageMassAdjust);
            }
            if (log != null)
            {
                log.AppendLine("crewMassOffset = ", partSim.crewMassOffset);
            }

            for (int i = 0; i < p.Resources.Count; i++)
            {
                PartResource resource = p.Resources[i];

                // Make sure it isn't NaN as this messes up the part mass and hence most of the values
                // This can happen if a resource capacity is 0 and tweakable
                if (!Double.IsNaN(resource.amount))
                {
                    if (log != null)
                    {
                        log.AppendLine(resource.resourceName, " = ", resource.amount);
                    }

                    partSim.resources.Add(resource.info.id, resource.amount);
                    partSim.resourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0);
                }
                else
                {
                    if (log != null)
                    {
                        log.AppendLine(resource.resourceName, " is NaN. Skipping.");
                    }
                }

                if (!Double.IsNaN(resource.maxAmount))
                {
                    partSim.maxResources.Add(resource.info.id, resource.maxAmount);
                    partSim.maxResourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0);
                }
            }

            partSim.hasVessel = (p.vessel != null);
            partSim.isLanded  = partSim.hasVessel && p.vessel.Landed;
            if (partSim.hasVessel)
            {
                partSim.vesselName = p.vessel.vesselName;
                partSim.vesselType = p.vesselType;
            }
            partSim.initialVesselName = p.initialVesselName;

            partSim.hasMultiModeEngine = p.HasModule <MultiModeEngine>();
            partSim.hasModuleEngines   = p.HasModule <ModuleEngines>();

            partSim.isEngine = partSim.hasMultiModeEngine || partSim.hasModuleEngines;

            if (log != null)
            {
                log.AppendLine("Created ", partSim.name, ". Decoupled in stage ", partSim.decoupledInStage);
            }

            return(partSim);
        }
Beispiel #29
0
 public void SetupParent(Dictionary<Part, PartSim> partSimLookup, LogMsg log)
 {
     if (part.parent != null)
     {
         parent = null;
         if (partSimLookup.TryGetValue(part.parent, out parent))
         {
             if (log != null) log.buf.AppendLine("Parent part is " + parent.name + ":" + parent.partId);
             if (part.attachMode == AttachModes.SRF_ATTACH && part.attachRules.srfAttach && part.fuelCrossFeed && part.parent.fuelCrossFeed)
             {
                 if (log != null) log.buf.AppendLine("Added " + name + " to " + parent.name + " surface mounted fuel targets.");
                 parent.surfaceMountFuelTargets.Add(this);
             }
         }
         else
         {
             if (log != null) log.buf.AppendLine("No PartSim for parent part (" + part.parent.partInfo.name + ")");
         }
     }
 }
Beispiel #30
0
        public void CreateEngineSims(List <EngineSim> allEngines, double atmosphere, double mach, bool vectoredThrust, bool fullThrust, LogMsg log)
        {
            if (log != null)
            {
                log.AppendLine("CreateEngineSims for ", this.name);
            }
            List <ModuleEngines> cacheModuleEngines = part.FindModulesImplementing <ModuleEngines>();

            try
            {
                if (cacheModuleEngines.Count > 0)
                {
                    //find first active engine, assuming that two are never active at the same time
                    foreach (ModuleEngines engine in cacheModuleEngines)
                    {
                        if (engine.isEnabled)
                        {
                            if (log != null)
                            {
                                log.AppendLine("Module: ", engine.moduleName);
                            }
                            EngineSim engineSim = EngineSim.New(
                                this,
                                engine,
                                atmosphere,
                                (float)mach,
                                vectoredThrust,
                                fullThrust,
                                log);
                            allEngines.Add(engineSim);
                        }
                    }
                }
            }
            catch
            {
                Debug.Log("[KER] Error Catch in CreateEngineSims");
            }
        }
Beispiel #31
0
        public void DumpSourcePartSets(LogMsg log, String msg)
        {
            if (log == null)
                return;

            log.AppendLine("DumpSourcePartSets ", msg);
            foreach (int type in sourcePartSets.Keys)
            {
                log.AppendLine("SourcePartSet for ", ResourceContainer.GetResourceName(type));
                HashSet<PartSim> sourcePartSet = sourcePartSets[type];
                if (sourcePartSet.Count > 0)
                {
                    foreach (PartSim partSim in sourcePartSet)
                    {
                        log.AppendLine("Part ", partSim.name, ":", partSim.partId);
                    }
                }
                else
                {
                    log.AppendLine("No parts");
                }
            }
        }
Beispiel #32
0
        public void DumpPartToLog(LogMsg log, String prefix, List <PartSim> allParts = null)
        {
            if (log == null)
            {
                return;
            }

            log.Append(prefix);
            log.Append(name);
            log.Append(":[id = ", partId, ", decouple = ", decoupledInStage);
            log.Append(", invstage = ", inverseStage);

            //log.Append(", vesselName = '", vesselName, "'");
            //log.Append(", vesselType = ", SimManager.GetVesselTypeString(vesselType));
            //log.Append(", initialVesselName = '", initialVesselName, "'");

            log.Append(", isNoPhys = ", isNoPhysics);
            log.buf.AppendFormat(", baseMass = {0}", baseMass);
            log.buf.AppendFormat(", baseMassForCoM = {0}", baseMassForCoM);

            log.Append(", fuelCF = {0}", fuelCrossFeed);
            log.Append(", noCFNKey = '{0}'", noCrossFeedNodeKey);

            log.Append(", isSep = {0}", isSepratron);

            try
            {
                for (int i = 0; i < resources.Types.Count; i++)
                {
                    int type = resources.Types[i];
                    log.buf.AppendFormat(", {0} = {1:g6}", ResourceContainer.GetResourceName(type), resources[type]);
                }
            }
            catch (Exception e)
            {
                log.Append("error dumping part resources " + e.ToString());
            }

            try
            {
                if (attachNodes.Count > 0)
                {
                    log.Append(", attached = <");
                    attachNodes[0].DumpToLog(log);
                    for (int i = 1; i < attachNodes.Count; i++)
                    {
                        log.Append(", ");
                        if (attachNodes[i] != null)
                        {
                            attachNodes[i].DumpToLog(log);                         //its u, isn't it?
                        }
                    }
                    log.Append(">");
                }
            }
            catch (Exception e)
            {
                log.Append("error dumping part nodes" + e.ToString());
            }

            try
            {
                if (surfaceMountFuelTargets.Count > 0)
                {
                    log.Append(", surface = <");
                    if (surfaceMountFuelTargets[0] != null)
                    {
                        log.Append(surfaceMountFuelTargets[0].name, ":", surfaceMountFuelTargets[0].partId);
                    }
                    for (int i = 1; i < surfaceMountFuelTargets.Count; i++)
                    {
                        if (surfaceMountFuelTargets[i] != null)
                        {
                            log.Append(", ", surfaceMountFuelTargets[i].name, ":", surfaceMountFuelTargets[i].partId);                                     //no it was u.
                        }
                    }
                    log.Append(">");
                }
            }
            catch (Exception e)
            {
                log.Append("error dumping part surface fuels " + e.ToString());
            }

            // Add more info here

            log.AppendLine("]");

            if (allParts != null)
            {
                String newPrefix = prefix + " ";
                for (int i = 0; i < allParts.Count; i++)
                {
                    PartSim partSim = allParts[i];
                    if (partSim.parent == this)
                    {
                        partSim.DumpPartToLog(log, newPrefix, allParts);
                    }
                }
            }
        }
Beispiel #33
0
        public static PartSim New(Part thePart, int id, double atmosphere, LogMsg log)
        {
            PartSim partSim = pool.Borrow();

            partSim.part = thePart;
            partSim.centerOfMass = thePart.transform.TransformPoint(thePart.CoMOffset);
            partSim.partId = id;
            partSim.name = partSim.part.partInfo.name;

            if (log != null) log.buf.AppendLine("Create PartSim for " + partSim.name);

            partSim.parent = null;
            partSim.parentAttach = partSim.part.attachMode;
            partSim.fuelCrossFeed = partSim.part.fuelCrossFeed;
            partSim.noCrossFeedNodeKey = partSim.part.NoCrossFeedNodeKey;
            partSim.decoupledInStage = partSim.DecoupledInStage(partSim.part);
            partSim.isFuelLine = partSim.part.HasModule<CModuleFuelLine>();
            partSim.isFuelTank = partSim.part is FuelTank;
            partSim.isSepratron = partSim.IsSepratron();
            partSim.inverseStage = partSim.part.inverseStage;
            //MonoBehaviour.print("inverseStage = " + inverseStage);

            partSim.baseCost = partSim.part.GetCostDry();

            if (log != null)
            {
                log.buf.AppendLine("Parent part = " + (partSim.part.parent == null ? "null" : partSim.part.parent.partInfo.name));
                log.buf.AppendLine("physicalSignificance = " + partSim.part.physicalSignificance);
                log.buf.AppendLine("PhysicsSignificance = " + partSim.part.PhysicsSignificance);
            }

            // Work out if the part should have no physical significance
            // The root part is never "no physics"
            partSim.isNoPhysics = partSim.part.physicalSignificance == Part.PhysicalSignificance.NONE ||
                                    partSim.part.PhysicsSignificance == 1;

            if (partSim.part.HasModule<LaunchClamp>())
            {
                partSim.realMass = 0d;
                if (log != null) log.buf.AppendLine("Ignoring mass of launch clamp");
            }
            else
            {
                partSim.realMass = partSim.part.mass;
                if (log != null) log.buf.AppendLine("Using part.mass of " + partSim.part.mass);
            }

            partSim.moduleMass = partSim.part.GetModuleMass((float)partSim.realMass);

            for (int i = 0; i < partSim.part.Resources.Count; i++)
            {
                PartResource resource = partSim.part.Resources[i];

                // Make sure it isn't NaN as this messes up the part mass and hence most of the values
                // This can happen if a resource capacity is 0 and tweakable
                if (!Double.IsNaN(resource.amount))
                {
                    if (log != null)
                        log.buf.AppendLine(resource.resourceName + " = " + resource.amount);

                    partSim.resources.Add(resource.info.id, resource.amount);
                    partSim.resourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0);
                }
                else
                {
                    if (log != null) log.buf.AppendLine(resource.resourceName + " is NaN. Skipping.");
                }
            }

            partSim.hasVessel = (partSim.part.vessel != null);
            partSim.isLanded = partSim.hasVessel && partSim.part.vessel.Landed;
            if (partSim.hasVessel)
            {
                partSim.vesselName = partSim.part.vessel.vesselName;
                partSim.vesselType = partSim.part.vesselType;
            }
            partSim.initialVesselName = partSim.part.initialVesselName;

            partSim.hasMultiModeEngine = partSim.part.HasModule<MultiModeEngine>();
            partSim.hasModuleEnginesFX = partSim.part.HasModule<ModuleEnginesFX>();
            partSim.hasModuleEngines = partSim.part.HasModule<ModuleEngines>();

            partSim.isEngine = partSim.hasMultiModeEngine || partSim.hasModuleEnginesFX || partSim.hasModuleEngines;

            if (log != null) log.buf.AppendLine("Created " + partSim.name + ". Decoupled in stage " + partSim.decoupledInStage);

            return partSim;
        }
Beispiel #34
0
        public void CreateEngineSims(List<EngineSim> allEngines, double atmosphere, double velocity, bool vectoredThrust, LogMsg log)
        {
            bool correctThrust = SimManager.DoesEngineUseCorrectedThrust(part);
            if (log != null)
            {
                log.buf.AppendLine("CreateEngineSims for " + name);

                foreach (PartModule partMod in part.Modules)
                {
                    log.buf.AppendLine("Module: " + partMod.moduleName);
                }

                log.buf.AppendLine("correctThrust = " + correctThrust);
            }

            if (hasMultiModeEngine)
            {
                // A multi-mode engine has multiple ModuleEnginesFX but only one is active at any point
                // The mode of the engine is the engineID of the ModuleEnginesFX that is active
                string mode = part.GetModule<MultiModeEngine>().mode;

                foreach (ModuleEnginesFX engine in part.GetModules<ModuleEnginesFX>())
                {
                    if (engine.engineID == mode)
                    {
                        if (log != null)
                            log.buf.AppendLine("Module: " + engine.moduleName);

                        Vector3 thrustvec = CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);

                        EngineSim engineSim = new EngineSim(this,
                                                            atmosphere,
                                                            velocity,
                                                            engine.maxThrust,
                                                            engine.minThrust,
                                                            engine.thrustPercentage,
                                                            engine.requestedThrust,
                                                            thrustvec,
                                                            engine.realIsp,
                                                            engine.atmosphereCurve,
                                                            engine.useVelocityCurve ? engine.velocityCurve : null,
                                                            engine.throttleLocked,
                                                            engine.propellants,
                                                            engine.isOperational,
                                                            correctThrust);
                        allEngines.Add(engineSim);
                    }
                }
            }
            else
            {
                if (hasModuleEnginesFX)
                {
                    foreach (ModuleEnginesFX engine in part.GetModules<ModuleEnginesFX>())
                    {
                        if (log != null)
                            log.buf.AppendLine("Module: " + engine.moduleName);

                        Vector3 thrustvec = CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);

                        EngineSim engineSim = new EngineSim(this,
                                                            atmosphere,
                                                            velocity,
                                                            engine.maxThrust,
                                                            engine.minThrust,
                                                            engine.thrustPercentage,
                                                            engine.requestedThrust,
                                                            thrustvec,
                                                            engine.realIsp,
                                                            engine.atmosphereCurve,
                                                            engine.useVelocityCurve ? engine.velocityCurve : null,
                                                            engine.throttleLocked,
                                                            engine.propellants,
                                                            engine.isOperational,
                                                            correctThrust);
                        allEngines.Add(engineSim);
                    }
                }

                if (hasModuleEngines)
                {
                    foreach (ModuleEngines engine in part.GetModules<ModuleEngines>())
                    {
                        if (log != null)
                            log.buf.AppendLine("Module: " + engine.moduleName);

                        Vector3 thrustvec = CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);

                        EngineSim engineSim = new EngineSim(this,
                                                            atmosphere,
                                                            velocity,
                                                            engine.maxThrust,
                                                            engine.minThrust,
                                                            engine.thrustPercentage,
                                                            engine.requestedThrust,
                                                            thrustvec,
                                                            engine.realIsp,
                                                            engine.atmosphereCurve,
                                                            engine.useVelocityCurve ? engine.velocityCurve : null,
                                                            engine.throttleLocked,
                                                            engine.propellants,
                                                            engine.isOperational,
                                                            correctThrust);
                        allEngines.Add(engineSim);
                    }
                }
            }

            if (log != null)
                log.Flush();
        }
Beispiel #35
0
        // This is a new function for STAGE_STACK_FLOW(_BALANCE)
        public void GetSourceSet(int type, bool includeSurfaceMountedParts, List <PartSim> allParts, HashSet <PartSim> visited, HashSet <PartSim> allSources, bool checkMax, LogMsg log, String indent)
        {
            // Initial version of support for new flow mode

            // Call a modified version of the old GetSourceSet code that adds all potential sources rather than stopping the recursive scan
            // when certain conditions are met
            int priMax = int.MinValue;

            GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, checkMax, ref priMax, log, indent);
            if (log != null)
            {
                log.AppendLine(allSources.Count, " parts with priority of ", priMax);
            }
        }
Beispiel #36
0
        public bool SetResourceDrains(List <PartSim> allParts, List <PartSim> allFuelLines, HashSet <PartSim> drainingParts)
        {
            LogMsg log = null;

            //DumpSourcePartSets("before clear");
            foreach (HashSet <PartSim> sourcePartSet in sourcePartSets.Values)
            {
                sourcePartSet.Clear();
            }
            //DumpSourcePartSets("after clear");

            for (int index = 0; index < this.resourceConsumptions.Types.Count; index++)
            {
                int type = this.resourceConsumptions.Types[index];

                HashSet <PartSim> sourcePartSet;
                if (!sourcePartSets.TryGetValue(type, out sourcePartSet))
                {
                    sourcePartSet = new HashSet <PartSim>();
                    sourcePartSets.Add(type, sourcePartSet);
                }

                switch ((ResourceFlowMode)this.resourceFlowModes[type])
                {
                case ResourceFlowMode.NO_FLOW:
                    if (partSim.resources[type] > SimManager.RESOURCE_MIN && partSim.resourceFlowStates[type] != 0)
                    {
                        //sourcePartSet = new HashSet<PartSim>();
                        //MonoBehaviour.print("SetResourceDrains(" + name + ":" + partId + ") setting sources to just this");
                        sourcePartSet.Add(partSim);
                    }
                    break;

                case ResourceFlowMode.ALL_VESSEL:
                case ResourceFlowMode.ALL_VESSEL_BALANCE:
                    for (int i = 0; i < allParts.Count; i++)
                    {
                        PartSim aPartSim = allParts[i];
                        if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0)
                        {
                            sourcePartSet.Add(aPartSim);
                        }
                    }
                    break;

                case ResourceFlowMode.STAGE_PRIORITY_FLOW:
                case ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE:

                    foreach (HashSet <PartSim> stagePartSet in stagePartSets.Values)
                    {
                        stagePartSet.Clear();
                    }
                    var maxStage = -1;

                    //Logger.Log(type);
                    for (int i = 0; i < allParts.Count; i++)
                    {
                        var aPartSim = allParts[i];
                        if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0)
                        {
                            continue;
                        }

                        int stage = aPartSim.DecouplerCount();
                        if (stage > maxStage)
                        {
                            maxStage = stage;
                        }

                        HashSet <PartSim> tempPartSet;
                        if (!stagePartSets.TryGetValue(stage, out tempPartSet))
                        {
                            tempPartSet = new HashSet <PartSim>();
                            stagePartSets.Add(stage, tempPartSet);
                        }
                        tempPartSet.Add(aPartSim);
                    }

                    for (int j = maxStage; j >= 0; j--)
                    {
                        HashSet <PartSim> stagePartSet;
                        if (stagePartSets.TryGetValue(j, out stagePartSet) && stagePartSet.Count > 0)
                        {
                            // We have to copy the contents of the set here rather than copying the set reference or
                            // bad things (tm) happen
                            foreach (PartSim aPartSim in stagePartSet)
                            {
                                sourcePartSet.Add(aPartSim);
                            }
                            break;
                        }
                    }
                    break;

                case ResourceFlowMode.STACK_PRIORITY_SEARCH:
                    visited.Clear();

                    if (SimManager.logOutput)
                    {
                        log = new LogMsg();
                        log.buf.AppendLine("Find " + ResourceContainer.GetResourceName(type) + " sources for " + partSim.name + ":" + partSim.partId);
                    }
                    partSim.GetSourceSet(type, PhysicsGlobals.Stack_PriUsesSurf, allParts, visited, sourcePartSet, log, "");
                    if (SimManager.logOutput && log != null)
                    {
                        MonoBehaviour.print(log.buf);
                    }
                    break;

                case ResourceFlowMode.STAGE_STACK_FLOW:
                case ResourceFlowMode.STAGE_STACK_FLOW_BALANCE:
                    visited.Clear();

                    if (SimManager.logOutput)
                    {
                        log = new LogMsg();
                        log.buf.AppendLine("Find " + ResourceContainer.GetResourceName(type) + " sources for " + partSim.name + ":" + partSim.partId);
                    }
                    partSim.GetSourceSet(type, true, allParts, visited, sourcePartSet, log, "");
                    if (SimManager.logOutput && log != null)
                    {
                        MonoBehaviour.print(log.buf);
                    }
                    break;

                default:
                    MonoBehaviour.print("SetResourceDrains(" + partSim.name + ":" + partSim.partId + ") Unexpected flow type for " + ResourceContainer.GetResourceName(type) + ")");
                    break;
                }

                if (SimManager.logOutput)
                {
                    if (sourcePartSet.Count > 0)
                    {
                        log = new LogMsg();
                        log.buf.AppendLine("Source parts for " + ResourceContainer.GetResourceName(type) + ":");
                        foreach (PartSim partSim in sourcePartSet)
                        {
                            log.buf.AppendLine(partSim.name + ":" + partSim.partId);
                        }
                        MonoBehaviour.print(log.buf);
                    }
                }

                //DumpSourcePartSets("after " + ResourceContainer.GetResourceName(type));
            }

            // If we don't have sources for all the needed resources then return false without setting up any drains
            for (int i = 0; i < this.resourceConsumptions.Types.Count; i++)
            {
                int type = this.resourceConsumptions.Types[i];
                HashSet <PartSim> sourcePartSet;
                if (!sourcePartSets.TryGetValue(type, out sourcePartSet) || sourcePartSet.Count == 0)
                {
                    if (SimManager.logOutput)
                    {
                        MonoBehaviour.print("No source of " + ResourceContainer.GetResourceName(type));
                    }

                    isActive = false;
                    return(false);
                }
            }

            // Now we set the drains on the members of the sets and update the draining parts set
            for (int i = 0; i < this.resourceConsumptions.Types.Count; i++)
            {
                int type = this.resourceConsumptions.Types[i];
                HashSet <PartSim> sourcePartSet = sourcePartSets[type];
                // Loop through the members of the set
                double amount = resourceConsumptions[type] / sourcePartSet.Count;
                foreach (PartSim partSim in sourcePartSet)
                {
                    if (SimManager.logOutput)
                    {
                        MonoBehaviour.print(
                            "Adding drain of " + amount + " " + ResourceContainer.GetResourceName(type) + " to " + partSim.name + ":" +
                            partSim.partId);
                    }

                    partSim.resourceDrains.Add(type, amount);
                    drainingParts.Add(partSim);
                }
            }
            return(true);
        }
Beispiel #37
0
        public void CreateEngineSims(List<EngineSim> allEngines, double atmosphere, double mach, bool vectoredThrust, bool fullThrust, LogMsg log)
        {
            bool correctThrust = SimManager.DoesEngineUseCorrectedThrust(part);
            if (log != null)
            {
                log.buf.AppendLine("CreateEngineSims for " + this.name);
                for (int i = 0; i < this.part.Modules.Count; i++)
                {
                    PartModule partMod = this.part.Modules[i];
                    log.buf.AppendLine("Module: " + partMod.moduleName);
                }

                log.buf.AppendLine("correctThrust = " + correctThrust);
            }

            if (hasMultiModeEngine)
            {
                // A multi-mode engine has multiple ModuleEnginesFX but only one is active at any point
                // The mode of the engine is the engineID of the ModuleEnginesFX that is active
                string mode = part.GetModule<MultiModeEngine>().mode;

                List<ModuleEnginesFX> engines = part.GetModules<ModuleEnginesFX>();
                for (int i = 0; i < engines.Count; ++i)
                {
                    ModuleEnginesFX engine = engines[i];
                    if (engine.engineID == mode)
                    {
                        if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);

                        Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);

                        EngineSim engineSim = EngineSim.New(
                            this,
                            atmosphere,
                            (float)mach,
                            engine.maxFuelFlow,
                            engine.minFuelFlow,
                            engine.thrustPercentage,
                            thrustvec,
                            engine.atmosphereCurve,
                            engine.atmChangeFlow,
                            engine.useAtmCurve ? engine.atmCurve : null,
                            engine.useVelCurve ? engine.velCurve : null,
                            fullThrust ? 0.0f : engine.currentThrottle,
                            engine.g,
                            engine.throttleLocked,
                            engine.propellants,
                            engine.isOperational,
                            engine.resultingThrust,
                            engine.thrustTransforms,
                            log);
                        allEngines.Add(engineSim);
                    }
                }
            }
            else
            {
                if (hasModuleEngines)
                {
                    List<ModuleEngines> engines = part.GetModules<ModuleEngines>();
                    for (int i = 0; i < engines.Count; ++i)
                    {
                        ModuleEngines engine = engines[i];
                        if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);

                        Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);

                        EngineSim engineSim = EngineSim.New(
                            this,
                            atmosphere,
                            (float)mach,
                            engine.maxFuelFlow,
                            engine.minFuelFlow,
                            engine.thrustPercentage,
                            thrustvec,
                            engine.atmosphereCurve,
                            engine.atmChangeFlow,
                            engine.useAtmCurve ? engine.atmCurve : null,
                            engine.useVelCurve ? engine.velCurve : null,
                            fullThrust ? 0.0f : engine.currentThrottle,
                            engine.g,
                            engine.throttleLocked,
                            engine.propellants,
                            engine.isOperational,
                            engine.resultingThrust,
                            engine.thrustTransforms,
                            log);
                        allEngines.Add(engineSim);
                    }
                }
            }

            if (log != null)
            {
                log.Flush();
            }
        }
Beispiel #38
0
        public void GetSourceSet_Internal(int type, bool includeSurfaceMountedParts, List <PartSim> allParts, HashSet <PartSim> visited, HashSet <PartSim> allSources, bool checkMax, ref int priMax, LogMsg log, String indent)
        {
            if (log != null)
            {
                log.Append(indent, "GetSourceSet_Internal(", ResourceContainer.GetResourceName(type), ") for ")
                .AppendLine(name, ":", partId);
                indent += "  ";
            }

            // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns as is.
            if (visited.Contains(this))
            {
                if (log != null)
                {
                    log.Append(indent, "Nothing added, already visited (", name, ":")
                    .AppendLine(partId + ")");
                }
                return;
            }

            if (log != null)
            {
                log.AppendLine(indent, "Adding this to visited");
            }

            visited.Add(this);

            // Rule 2: Part performs scan on start of every fuel pipe ending in it. This scan is done in order in which pipes were installed.
            // Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result.
            //MonoBehaviour.print("for each fuel line");

            int lastCount = allSources.Count;

            for (int i = 0; i < this.fuelTargets.Count; i++)
            {
                PartSim partSim = this.fuelTargets[i];
                if (partSim != null)
                {
                    if (visited.Contains(partSim))
                    {
                        if (log != null)
                        {
                            log.Append(indent, "Fuel target already visited, skipping (", partSim.name, ":")
                            .AppendLine(partSim.partId, ")");
                        }
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.Append(indent, "Adding fuel target as source (", partSim.name, ":")
                            .AppendLine(partSim.partId, ")");
                        }

                        partSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, checkMax, ref priMax, log, indent);
                    }
                }
            }

            if (fuelCrossFeed)
            {
                if (includeSurfaceMountedParts)
                {
                    // check surface mounted fuel targets
                    for (int i = 0; i < surfaceMountFuelTargets.Count; i++)
                    {
                        PartSim partSim = this.surfaceMountFuelTargets[i];
                        if (partSim != null)
                        {
                            if (visited.Contains(partSim))
                            {
                                if (log != null)
                                {
                                    log.Append(indent, "Surface part already visited, skipping (", partSim.name, ":")
                                    .AppendLine(partSim.partId, ")");
                                }
                            }
                            else
                            {
                                if (log != null)
                                {
                                    log.Append(indent, "Adding surface part as source (", partSim.name, ":")
                                    .AppendLine(partSim.partId, ")");
                                }

                                partSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, checkMax, ref priMax, log, indent);
                            }
                        }
                    }
                }

                lastCount = allSources.Count;
                //MonoBehaviour.print("for each attach node");
                for (int i = 0; i < this.attachNodes.Count; i++)
                {
                    AttachNodeSim attachSim = this.attachNodes[i];
                    if (attachSim.attachedPartSim != null)
                    {
                        if (attachSim.nodeType == AttachNode.NodeType.Stack)
                        {
                            if ((string.IsNullOrEmpty(noCrossFeedNodeKey) == false && attachSim.id.Contains(noCrossFeedNodeKey)) == false)
                            {
                                if (visited.Contains(attachSim.attachedPartSim))
                                {
                                    if (log != null)
                                    {
                                        log.Append(indent, "Attached part already visited, skipping (", attachSim.attachedPartSim.name, ":")
                                        .AppendLine(attachSim.attachedPartSim.partId, ")");
                                    }
                                }
                                else
                                {
                                    bool flg = true;

                                    if (attachSim.attachedPartSim.isEnginePlate) //y u make me do dis.
                                    {
                                        foreach (AttachNodeSim att in attachSim.attachedPartSim.attachNodes)
                                        {
                                            if (att.attachedPartSim == this && att.id == "bottom")
                                            {
                                                flg = false;
                                            }
                                        }
                                    }

                                    if (flg)
                                    {
                                        if (log != null)
                                        {
                                            log.Append(indent, "Adding attached part as source  (", attachSim.attachedPartSim.name, ":")
                                            .AppendLine(attachSim.attachedPartSim.partId, ")");
                                        }

                                        attachSim.attachedPartSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, checkMax, ref priMax, log, indent);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel
            // type was not disabled) and it contains fuel, it adds itself.
            if (checkMax ? (maxResources.HasType(type)) : (resources.HasType(type) && resourceFlowStates[type] > 0.0))
            {
                if (checkMax ? (maxResources[type] > SimManager.RESOURCE_MIN) : (resources[type] > resRequestRemainingThreshold))
                {
                    // Get the priority of this tank
                    int pri = GetResourcePriority();
                    if (pri > priMax)
                    {
                        // This tank is higher priority than the previously added ones so we clear the sources
                        // and set the priMax to this priority
                        allSources.Clear();
                        priMax = pri;
                    }
                    // If this is the correct priority then add this to the sources
                    if (pri == priMax)
                    {
                        if (log != null)
                        {
                            log.Append(indent, "Adding enabled tank as source (", name, ":")
                            .AppendLine(partId, ")");
                        }

                        allSources.Add(this);
                    }
                }
            }
            else
            {
                if (log != null)
                {
                    log.Append(indent, "Not fuel tank or disabled. HasType = ", resources.HasType(type))
                    .AppendLine("  FlowState = " + resourceFlowStates[type]);
                }
            }
        }
Beispiel #39
0
 public void SetupParent(Dictionary<Part, PartSim> partSimLookup, LogMsg log)
 {
     if (part.parent != null)
     {
         parent = null;
         if (partSimLookup.TryGetValue(part.parent, out parent))
         {
             if (log != null)
                 log.buf.AppendLine("Parent part is " + parent.name + ":" + parent.partId);
         }
         else
         {
             if (log != null)
                 log.buf.AppendLine("No PartSim for parent part (" + part.parent.partInfo.name + ")");
         }
     }
 }
Beispiel #40
0
        public void SetupAttachNodes(Dictionary <Part, PartSim> partSimLookup, LogMsg log)
        {
            if (log != null)
            {
                log.AppendLine("SetupAttachNodes for ", name, ":", partId);
            }

            attachNodes.Clear();

            for (int i = 0; i < part.attachNodes.Count; ++i)
            {
                AttachNode attachNode = part.attachNodes[i];

                if (log != null)
                {
                    log.AppendLine("AttachNode ", attachNode.id, " = ", (attachNode.attachedPart != null ? attachNode.attachedPart.partInfo.name : "null"));
                }

                if (attachNode.attachedPart != null && attachNode.id != "Strut")
                {
                    PartSim attachedSim;
                    if (partSimLookup.TryGetValue(attachNode.attachedPart, out attachedSim))
                    {
                        if (log != null)
                        {
                            log.AppendLine("Adding attached node ", attachedSim.name, ":", attachedSim.partId);
                        }

                        attachNodes.Add(AttachNodeSim.New(attachedSim, attachNode.id, attachNode.nodeType));
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.AppendLine("No PartSim for attached part (", attachNode.attachedPart.partInfo.name, ")");
                        }
                    }
                }
            }

            for (int i = 0; i < part.fuelLookupTargets.Count; ++i)
            {
                Part p = part.fuelLookupTargets[i];

                if (p != null)
                {
                    PartSim targetSim;
                    if (partSimLookup.TryGetValue(p, out targetSim))
                    {
                        if (log != null)
                        {
                            log.AppendLine("Fuel target: ", targetSim.name, ":", targetSim.partId);
                        }

                        fuelTargets.Add(targetSim);
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.AppendLine("No PartSim for fuel target (", p.name, ")");
                        }
                    }
                }
            }
        }
Beispiel #41
0
        public static EngineSim New(PartSim theEngine,
                         double atmosphere,
                         float machNumber,
                         float maxFuelFlow,
                         float minFuelFlow,
                         float thrustPercentage,
                         Vector3 vecThrust,
                         FloatCurve atmosphereCurve,
                         bool atmChangeFlow,
                         FloatCurve atmCurve,
                         FloatCurve velCurve,
                         float currentThrottle,
                         float IspG,
                         bool throttleLocked,
                         List<Propellant> propellants,
                         bool active,
                         float resultingThrust,
                         List<Transform> thrustTransforms,
                        LogMsg log)
        {
            EngineSim engineSim = pool.Borrow();

            engineSim.isp = 0.0;
            engineSim.maxMach = 0.0f;
            engineSim.actualThrust = 0.0;
            engineSim.partSim = theEngine;
            engineSim.isActive = active;
            engineSim.thrustVec = vecThrust;
            engineSim.resourceConsumptions.Reset();
            engineSim.resourceFlowModes.Reset();
            engineSim.appliedForces.Clear();

            double flowRate = 0.0;
            if (engineSim.partSim.hasVessel)
            {
                if (log != null) log.buf.AppendLine("hasVessel is true");

                float flowModifier = GetFlowModifier(atmChangeFlow, atmCurve, engineSim.partSim.part.atmDensity, velCurve, machNumber, ref engineSim.maxMach);
                engineSim.isp = atmosphereCurve.Evaluate((float)atmosphere);
                engineSim.thrust = GetThrust(Mathf.Lerp(minFuelFlow, maxFuelFlow, GetThrustPercent(thrustPercentage)) * flowModifier, engineSim.isp);
                engineSim.actualThrust = engineSim.isActive ? resultingThrust : 0.0;
                if (log != null)
                {
                    log.buf.AppendFormat("flowMod = {0:g6}\n", flowModifier);
                    log.buf.AppendFormat("isp     = {0:g6}\n", engineSim.isp);
                    log.buf.AppendFormat("thrust  = {0:g6}\n", engineSim.thrust);
                    log.buf.AppendFormat("actual  = {0:g6}\n", engineSim.actualThrust);
                }

                if (throttleLocked)
                {
                    if (log != null) log.buf.AppendLine("throttleLocked is true, using thrust for flowRate");
                    flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
                }
                else
                {
                    if (currentThrottle > 0.0f && engineSim.partSim.isLanded == false)
                    {
                        if (log != null) log.buf.AppendLine("throttled up and not landed, using actualThrust for flowRate");
                        flowRate = GetFlowRate(engineSim.actualThrust, engineSim.isp);
                    }
                    else
                    {
                        if (log != null) log.buf.AppendLine("throttled down or landed, using thrust for flowRate");
                        flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
                    }
                }
            }
            else
            {
                if (log != null) log.buf.AppendLine("hasVessel is false");
                float flowModifier = GetFlowModifier(atmChangeFlow, atmCurve, CelestialBodies.SelectedBody.GetDensity(BuildAdvanced.Altitude), velCurve, machNumber, ref engineSim.maxMach);
                engineSim.isp = atmosphereCurve.Evaluate((float)atmosphere);
                engineSim.thrust = GetThrust(Mathf.Lerp(minFuelFlow, maxFuelFlow, GetThrustPercent(thrustPercentage)) * flowModifier, engineSim.isp);
                engineSim.actualThrust = 0d;
                if (log != null)
                {
                    log.buf.AppendFormat("flowMod = {0:g6}\n", flowModifier);
                    log.buf.AppendFormat("isp     = {0:g6}\n", engineSim.isp);
                    log.buf.AppendFormat("thrust  = {0:g6}\n", engineSim.thrust);
                    log.buf.AppendFormat("actual  = {0:g6}\n", engineSim.actualThrust);
                }

                if (log != null) log.buf.AppendLine("no vessel, using thrust for flowRate");
                flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
            }

            if (log != null) log.buf.AppendFormat("flowRate = {0:g6}\n", flowRate);

            float flowMass = 0f;
            for (int i = 0; i < propellants.Count; ++i)
            {
                Propellant propellant = propellants[i];
                if (!propellant.ignoreForIsp)
                    flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id);
            }

            if (log != null) log.buf.AppendFormat("flowMass = {0:g6}\n", flowMass);

            for (int i = 0; i < propellants.Count; ++i)
            {
                Propellant propellant = propellants[i];

                if (propellant.name == "ElectricCharge" || propellant.name == "IntakeAir")
                {
                    continue;
                }

                double consumptionRate = propellant.ratio * flowRate / flowMass;
                if (log != null) log.buf.AppendFormat(
                        "Add consumption({0}, {1}:{2:d}) = {3:g6}\n",
                        ResourceContainer.GetResourceName(propellant.id),
                        theEngine.name,
                        theEngine.partId,
                        consumptionRate);
                engineSim.resourceConsumptions.Add(propellant.id, consumptionRate);
                engineSim.resourceFlowModes.Add(propellant.id, (double)propellant.GetFlowMode());
            }

            double thrustPerThrustTransform = engineSim.thrust / thrustTransforms.Count;
            for (int i = 0; i < thrustTransforms.Count; i++)
            {
                Transform thrustTransform = thrustTransforms[i];
                Vector3d direction = thrustTransform.forward.normalized;
                Vector3d position = thrustTransform.position;

                AppliedForce appliedForce = AppliedForce.New(direction * thrustPerThrustTransform, position);
                engineSim.appliedForces.Add(appliedForce);
            }

            return engineSim;
        }
Beispiel #42
0
        public long icar_SendTxtMsg(CmdParam.ParamType ParamType, string SimNum, string CarPw, CmdParam.CommMode CommMode, TxtMsg msgContent, int iMsgId, string sMsgType)
        {
            long num = (long)0;

            this.logMsg.FunctionName = "icar_SendTxtMsg";
            this.logMsg.Msg          = string.Concat("发送:类型-", ParamType.ToString(), ",车辆-", SimNum);
            string str    = string.Concat("消息类型-", msgContent.MsgType.ToString(), string.Format(",{0}-", sMsgType), msgContent.strMsg);
            LogMsg logMsg = this.logMsg;

            logMsg.Msg = string.Concat(logMsg.Msg, ",", str);
            this.log.WriteLog(this.logMsg);
            if (!this.isStartCommon())
            {
                num = (long)-1;
            }
            else
            {
                try
                {
                    if (msgContent.MsgType != CmdParam.MsgType.掉线短信通知)
                    {
                        int num1 = 1;
                        int num2 = iMsgId;
                        num = DownData.CarCmdSend.icar_SendTxtMsg(num1, num2, SimNum, msgContent.MsgType, msgContent.strMsg);
                        if (num == (long)0)
                        {
                            ReadDataFromDB.execSaveGpsLogTable(num1, num2, msgContent.CarId, (int)msgContent.MsgType, msgContent.strMsg);
                        }
                    }
                    else
                    {
                        object[] objArray   = new object[] { msgContent.MsgType.ToString(), msgContent.SimNum, msgContent.strMsg };
                        object   obj        = objArray;
                        int      num3       = 4;
                        int      newOrderId = DownData.CarCmdSend.GetNewOrderId();
                        num = DownData.CarCmdSend.icar_SetCommonCmd(num3, newOrderId, SimNum, (CmdParam.CmdCode) 768, ref obj, CmdParam.CommMode.未知方式);
                        if (num == (long)0)
                        {
                            ReadDataFromDB.execSaveGpsLogTable(num3, newOrderId, msgContent.CarId, (int)msgContent.MsgType, msgContent.strMsg);
                        }
                    }
                    if (num != (long)0)
                    {
                        AlarmMsg alarmMsg = new AlarmMsg()
                        {
                            ClassName    = "GpsPicDownData",
                            FunctionName = "icar_SendTxtMsg"
                        };
                        object[] workId = new object[] { "workid-", this.WorkId, ",simNum-", SimNum, ",strMsg-", msgContent.strMsg };
                        alarmMsg.AlarmText = string.Concat(workId);
                        alarmMsg.Code      = num.ToString();
                        this.log.WriteAlarm(alarmMsg);
                    }
                }
                catch (Exception exception1)
                {
                    Exception exception = exception1;
                    ErrorMsg  errorMsg  = new ErrorMsg()
                    {
                        ClassName = "GpsPicDownData",
                        ErrorText = "下发消息指令时发生错误!"
                    };
                    this.log.WriteError(errorMsg, exception);
                    num = (long)-1;
                }
            }
            return(num);
        }
Beispiel #43
0
        // This function prepares the simulation by creating all the necessary data structures it will 
        // need during the simulation.  All required data is copied from the core game data structures 
        // so that the simulation itself can be run in a background thread without having issues with 
        // the core game changing the data while the simulation is running.
        public bool PrepareSimulation(List<Part> parts, double theGravity, double theAtmosphere = 0, double theMach = 0, bool dumpTree = false, bool vectoredThrust = false, bool fullThrust = false)
        {
            LogMsg log = null;
            if (SimManager.logOutput)
            {
                log = new LogMsg();
                log.buf.AppendLine("PrepareSimulation started");
                dumpTree = true;
            }
            this._timer.Reset();
            this._timer.Start();

            // Store the parameters in members for ease of access in other functions
            this.partList = parts;
            this.gravity = theGravity;
            this.atmosphere = theAtmosphere;
            this.mach = theMach;
            this.lastStage = Staging.lastStage;
            this.maxMach = 1.0f;
            //MonoBehaviour.print("lastStage = " + lastStage);

            // Clear the lists for our simulation parts
            allParts.Clear();
            allFuelLines.Clear();
            drainingParts.Clear();
            allEngines.Clear();
            activeEngines.Clear();
            drainingResources.Clear();

            // A dictionary for fast lookup of Part->PartSim during the preparation phase
            partSimLookup.Clear();

            if (this.partList.Count > 0 && this.partList[0].vessel != null)
            {
                this.vesselName = this.partList[0].vessel.vesselName;
                this.vesselType = this.partList[0].vessel.vesselType;
            }
            //MonoBehaviour.print("PrepareSimulation pool size = " + PartSim.pool.Count());
            // First we create a PartSim for each Part (giving each a unique id)
            int partId = 1;
            for (int i = 0; i < partList.Count; ++i)
            {
                Part part = partList[i];

                // If the part is already in the lookup dictionary then log it and skip to the next part
                if (partSimLookup.ContainsKey(part))
                {
                    if (log != null)
                    {
                        log.buf.AppendLine("Part " + part.name + " appears in vessel list more than once");
                    }
                    continue;
                }

                // Create the PartSim
                PartSim partSim = PartSim.New(part, partId, this.atmosphere, log);

                // Add it to the Part lookup dictionary and the necessary lists
                partSimLookup.Add(part, partSim);
                this.allParts.Add(partSim);
                if (partSim.isFuelLine)
                {
                    this.allFuelLines.Add(partSim);
                }
                if (partSim.isEngine)
                {
                    partSim.CreateEngineSims(this.allEngines, this.atmosphere, this.mach, vectoredThrust, fullThrust, log);
                }

                partId++;
            }

            for (int i = 0; i < allEngines.Count; ++i)
            {
                maxMach = Mathf.Max(maxMach, allEngines[i].maxMach);
            }

            this.UpdateActiveEngines();

            // Now that all the PartSims have been created we can do any set up that needs access to other parts
            // First we set up all the parent links
            for (int i = 0; i < this.allParts.Count; i++)
            {
                PartSim partSim = this.allParts[i];
                partSim.SetupParent(partSimLookup, log);
            }

            // Then, in the VAB/SPH, we add the parent of each fuel line to the fuelTargets list of their targets
            if (HighLogic.LoadedSceneIsEditor)
            {
                for (int i = 0; i < allFuelLines.Count; ++i)
                {
                    PartSim partSim = allFuelLines[i];

                    CModuleFuelLine fuelLine = partSim.part.GetModule<CModuleFuelLine>();
                    if (fuelLine.target != null)
                    {
                        PartSim targetSim;
                        if (partSimLookup.TryGetValue(fuelLine.target, out targetSim))
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine("Fuel line target is " + targetSim.name + ":" + targetSim.partId);
                            }

                            targetSim.fuelTargets.Add(partSim.parent);
                        }
                        else
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine("No PartSim for fuel line target (" + partSim.part.partInfo.name + ")");
                            }
                        }
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine("Fuel line target is null");
                        }
                    }
                }
            }

            //MonoBehaviour.print("SetupAttachNodes and count stages");
            for (int i = 0; i < allParts.Count; ++i)
            {
                PartSim partSim = allParts[i];

                partSim.SetupAttachNodes(partSimLookup, log);
                if (partSim.decoupledInStage >= this.lastStage)
                {
                    this.lastStage = partSim.decoupledInStage + 1;
                }
            }

            // And finally release the Part references from all the PartSims
            //MonoBehaviour.print("ReleaseParts");
            for (int i = 0; i < allParts.Count; ++i)
            { 
                allParts[i].ReleasePart();
            }

            // And dereference the core's part list
            this.partList = null;

            this._timer.Stop();
            if (log != null)
            {
                log.buf.AppendLine("PrepareSimulation: " + this._timer.ElapsedMilliseconds + "ms");
                log.Flush();
            }

            if (dumpTree)
            {
                this.Dump();
            }

            return true;
        }
Beispiel #44
0
        public long icar_SetCaptureEx(CmdParam.ParamType ParamType, string SimNum, string CarPw, CmdParam.CommMode CommMode, CaptureEx captureEx, string PicTime, string CarID)
        {
            long num = (long)0;

            this.logMsg.FunctionName = "icar_SetCaptureEx";
            this.logMsg.Msg          = string.Concat("发送:类型-", ParamType.ToString(), ",车辆-", SimNum);
            object[] picTime = new object[] { "抓拍时间-", PicTime, ",是否多帧-", captureEx.IsMulitFramebool, ",监控次数-", captureEx.Times, ",间隔时间-", (double)captureEx.Interval * 0.1, ",图像质量-", captureEx.Quality, ",图像亮度-", captureEx.Brightness, ",图像对比度-", captureEx.Contrast, ",图像饱和度-", captureEx.Saturation, ",图像色度", captureEx.Chroma, ",停车是否拍照-", captureEx.IsCapWhenStop };
            string   str     = string.Concat(picTime);
            LogMsg   logMsg  = this.logMsg;

            logMsg.Msg = string.Concat(logMsg.Msg, ",", str);
            this.log.WriteLog(this.logMsg);
            if (!this.isStartCommon())
            {
                num = (long)-1;
            }
            else
            {
                try
                {
                    if (captureEx.ProtocolName == "JTBGPS")
                    {
                        int    newOrderId = DownData.CarCmdSend.GetNewOrderId();
                        string str1       = "";
                        captureEx.TransformCode = CmdParam.TrafficProtocolCodeExchange2((int)captureEx.OrderCode);
                        if (captureEx.Quality == 0)
                        {
                            captureEx.Quality = 1;
                        }
                        if (captureEx.CaptureCache == 1)
                        {
                            captureEx.CaptureCache = -1;
                        }
                        string xmlString = captureEx.ToXmlString(this.CalOrderId(this.WorkId, newOrderId), SimNum, captureEx.ProtocolName, (int)CommMode, "SetCapture", ref str1);
                        num = DownData.CarCmdSend.icar_SendCmdXML(this.WorkId, newOrderId, SimNum, captureEx.ProtocolName, captureEx.TransformCode, (int)CommMode, xmlString);
                    }
                    else
                    {
                        int newOrderId = DownData.CarCmdSend.GetNewOrderId();
                        num = DownData.CarCmdSend.icar_SetCaptureEx(this.WorkId, newOrderId, SimNum, captureEx.IsMultiFrame, captureEx.CamerasID, captureEx.CaptureFlag, captureEx.CaptureCache, captureEx.Times, captureEx.Interval, captureEx.Quality, captureEx.Brightness, captureEx.Contrast, captureEx.Saturation, captureEx.Chroma, captureEx.CapWhenStop);
                    }
                    if (num == (long)0)
                    {
                        ReadDataFromDB.execSaveGpsLogTable(this.WorkId, DownData.CarCmdSend.OrderId, CarID, 18, "定时拍照");
                    }
                    else
                    {
                        AlarmMsg alarmMsg = new AlarmMsg()
                        {
                            ClassName    = "GpsPicDownData",
                            FunctionName = "icar_SetCaptureEx"
                        };
                        object[] workId = new object[] { "workid-", this.WorkId, ",simNum-", SimNum, ",OrderCode-", captureEx.OrderCode };
                        alarmMsg.AlarmText = string.Concat(workId);
                        alarmMsg.Code      = num.ToString();
                        this.log.WriteAlarm(alarmMsg);
                    }
                }
                catch (Exception exception1)
                {
                    Exception exception = exception1;
                    ErrorMsg  errorMsg  = new ErrorMsg()
                    {
                        ClassName = "GpsPicDownData",
                        ErrorText = "下发消息指令时发生错误!"
                    };
                    this.log.WriteError(errorMsg, exception);
                    num = (long)-1;
                }
            }
            return(num);
        }
Beispiel #45
0
        private void BuildDontStageLists(LogMsg log)
        {
            if (log != null)
            {
                log.buf.AppendLine("Creating list with capacity of " + (this.currentStage + 1));
            }

            dontStagePartsLists.Clear();
            for (int i = 0; i <= this.currentStage; i++)
            {
                if (i < dontStagePartsLists.Count)
                {
                    dontStagePartsLists[i].Clear();
                }
                else
                {
                    dontStagePartsLists.Add(new List<PartSim>());
                }
            }

            for (int i = 0; i < allParts.Count; ++i)
            {
                PartSim partSim = allParts[i];

                if (partSim.isEngine || !partSim.Resources.Empty)
                {
                    if (log != null)
                    {
                        log.buf.AppendLine(
                            partSim.name + ":" + partSim.partId + " is engine or tank, decoupled = " + partSim.decoupledInStage);
                    }

                    if (partSim.decoupledInStage < -1 || partSim.decoupledInStage > this.currentStage - 1)
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine("decoupledInStage out of range");
                        }
                    }
                    else
                    {
                        dontStagePartsLists[partSim.decoupledInStage + 1].Add(partSim);
                    }
                }
            }

            for (int i = 1; i <= this.lastStage; i++)
            {
                if (dontStagePartsLists[i].Count == 0)
                {
                    dontStagePartsLists[i] = dontStagePartsLists[i - 1];
                }
            }
        }
Beispiel #46
0
        public long icar_SendCmdXML(CmdParam.ParamType ParamType, string SimNum, string CarId, string CarPw, string ProtocolName, CmdParam.CommMode CommMode, TxtMsg MsgContext, string sMsgType)
        {
            long num = (long)0;

            this.logMsg.FunctionName = "icar_SendTxtMsg";
            this.logMsg.Msg          = string.Concat("发送:类型-", ParamType.ToString(), ",车辆-", SimNum);
            string str    = string.Concat("消息类型-", MsgContext.MsgType.ToString(), string.Format(",{0}-", sMsgType), MsgContext.strMsg);
            LogMsg logMsg = this.logMsg;

            logMsg.Msg = string.Concat(logMsg.Msg, ",", str);
            this.log.WriteLog(this.logMsg);
            if (!this.isStartCommon())
            {
                num = (long)-1;
            }
            else
            {
                try
                {
                    int newOrderId = DownData.CarCmdSend.GetNewOrderId();
                    if (ProtocolName != "JTBGPS")
                    {
                        num = DownData.CarCmdSend.icar_SendTxtMsg(this.WorkId, newOrderId, SimNum, MsgContext.MsgType, MsgContext.strMsg);
                    }
                    else
                    {
                        MsgContext.TransformCode = CmdParam.TrafficProtocolCodeExchange((int)MsgContext.MsgType);
                        string str1      = "";
                        string xmlString = MsgContext.ToXmlString(this.CalOrderId(this.WorkId, newOrderId), SimNum, ProtocolName, (int)CommMode, "SimpleCmd", ref str1);
                        num = DownData.CarCmdSend.icar_SendCmdXML(this.WorkId, newOrderId, SimNum, ProtocolName, (int)MsgContext.MsgType, (int)CommMode, xmlString);
                    }
                    if (num == (long)0)
                    {
                        ReadDataFromDB.execSaveGpsLogTable(this.WorkId, newOrderId, CarId, (int)MsgContext.MsgType, MsgContext.strMsg);
                    }
                    if (num != (long)0)
                    {
                        AlarmMsg alarmMsg = new AlarmMsg()
                        {
                            ClassName    = "GpsPicDownData",
                            FunctionName = "icar_SendTxtMsg"
                        };
                        object[] workId = new object[] { "workid-", this.WorkId, ",simNum-", SimNum, ",strMsg-", MsgContext.strMsg };
                        alarmMsg.AlarmText = string.Concat(workId);
                        alarmMsg.Code      = num.ToString();
                        this.log.WriteAlarm(alarmMsg);
                    }
                }
                catch (Exception exception1)
                {
                    Exception exception = exception1;
                    ErrorMsg  errorMsg  = new ErrorMsg()
                    {
                        ClassName = "GpsPicDownData",
                        ErrorText = "下发消息指令时发生错误!"
                    };
                    this.log.WriteError(errorMsg, exception);
                    num = (long)-1;
                }
            }
            return(num);
        }
Beispiel #47
0
        public void DrainResources(double time, LogMsg log)
        {
            //if (log != null) log.Append("DrainResources(", name, ":", partId)
            //                    .AppendLine(", ", time, ")");
            for (int i = 0; i < resourceDrains.Types.Count; ++i)
            {
                int type = resourceDrains.Types[i];

                //if (log != null) log.AppendLine("draining ", (time * resourceDrains[type]), " ", ResourceContainer.GetResourceName(type));
                resources.Add(type, -time * resourceDrains[type]);
                //if (log != null) log.AppendLine(ResourceContainer.GetResourceName(type), " left = ", resources[type]);
            }
        }
 private void PostToStackify(LogMsg msg)
 {
     Logger.QueueLogObject(msg);
 }
Beispiel #49
0
        public void DumpPartToLog(LogMsg log, String prefix, List<PartSim> allParts = null)
        {
            if (log == null)
                return;

            log.Append(prefix);
            log.Append(name);
            log.Append(":[id = ", partId, ", decouple = ", decoupledInStage);
            log.Append(", invstage = ", inverseStage);

            //log.Append(", vesselName = '", vesselName, "'");
            //log.Append(", vesselType = ", SimManager.GetVesselTypeString(vesselType));
            //log.Append(", initialVesselName = '", initialVesselName, "'");

            log.Append(", isNoPhys = ", isNoPhysics);
            log.buf.AppendFormat(", baseMass = {0}", baseMass);
            log.buf.AppendFormat(", baseMassForCoM = {0}", baseMassForCoM);

            log.Append(", fuelCF = {0}", fuelCrossFeed);
            log.Append(", noCFNKey = '{0}'", noCrossFeedNodeKey);

            log.Append(", isSep = {0}", isSepratron);

            for (int i = 0; i < resources.Types.Count; i++)
            {
                int type = resources.Types[i];
                log.buf.AppendFormat(", {0} = {1:g6}", ResourceContainer.GetResourceName(type), resources[type]);
            }

            if (attachNodes.Count > 0)
            {
                log.Append(", attached = <");
                attachNodes[0].DumpToLog(log);
                for (int i = 1; i < attachNodes.Count; i++)
                {
                    log.Append(", ");
                    attachNodes[i].DumpToLog(log);
                }
                log.Append(">");
            }

            if (surfaceMountFuelTargets.Count > 0)
            {
                log.Append(", surface = <");
                log.Append(surfaceMountFuelTargets[0].name, ":", surfaceMountFuelTargets[0].partId);
                for (int i = 1; i < surfaceMountFuelTargets.Count; i++)
                {
                    log.Append(", ", surfaceMountFuelTargets[i].name, ":", surfaceMountFuelTargets[i].partId);
                }
                log.Append(">");
            }

            // Add more info here

            log.AppendLine("]");

            if (allParts != null)
            {
                String newPrefix = prefix + " ";
                for (int i = 0; i < allParts.Count; i++)
                {
                    PartSim partSim = allParts[i];
                    if (partSim.parent == this)
                        partSim.DumpPartToLog(log, newPrefix, allParts);
                }
            }
        }
Beispiel #50
0
        // This function runs the simulation and returns a newly created array of Stage objects
        public Stage[] RunSimulation()
        {
            if (SimManager.logOutput)
            {
                MonoBehaviour.print("RunSimulation started");
            }
            _timer.Start();
            // Start with the last stage to simulate
            // (this is in a member variable so it can be accessed by AllowedToStage and ActivateStage)
            currentStage = lastStage;

            LogMsg log = null;

            if (SimManager.logOutput)
            {
                log = new LogMsg();
            }

            // Work out which engines would be active if just doing the staging and if this is different to the
            // currently active engines then generate an extra stage
            // Loop through all the engines
            foreach (EngineSim engine in allEngines)
            {
                if (log != null)
                {
                    log.buf.AppendLine("Testing engine mod of " + engine.partSim.name + ":" + engine.partSim.partId);
                }
                bool bActive = engine.isActive;
                bool bStage  = (engine.partSim.inverseStage >= currentStage);
                if (log != null)
                {
                    log.buf.AppendLine("bActive = " + bActive + "   bStage = " + bStage);
                }
                if (HighLogic.LoadedSceneIsFlight)
                {
                    if (bActive != bStage)
                    {
                        // If the active state is different to the state due to staging
                        if (log != null)
                        {
                            log.buf.AppendLine("Need to do current active engines first");
                        }

                        doingCurrent = true;
                        currentStage++;
                        break;
                    }
                }
                else
                {
                    if (bStage)
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine("Marking as active");
                        }

                        engine.isActive = true;
                    }
                }
            }

            if (log != null)
            {
                log.Flush();
            }

            // Create the array of stages that will be returned
            Stage[] stages = new Stage[currentStage + 1];

            // Loop through the stages
            while (currentStage >= 0)
            {
                if (log != null)
                {
                    log.buf.AppendLine("Simulating stage " + currentStage);
                    log.buf.AppendLine("ShipMass = " + ShipMass);
                    log.Flush();
                    _timer.Reset();
                    _timer.Start();
                }

                // Update active engines and resource drains
                UpdateResourceDrains();

                // Create the Stage object for this stage
                Stage stage = new Stage();

                stageTime      = 0d;
                vecStageDeltaV = Vector3.zero;
                stageStartMass = ShipMass;
                stepStartMass  = stageStartMass;
                stepEndMass    = 0;

                CalculateThrustAndISP();

                // Store various things in the Stage object
                stage.thrust = totalStageThrust;
                //MonoBehaviour.print("stage.thrust = " + stage.thrust);
                stage.thrustToWeight    = totalStageThrust / (stageStartMass * gravity);
                stage.maxThrustToWeight = stage.thrustToWeight;
                //MonoBehaviour.print("StageMass = " + stageStartMass);
                //MonoBehaviour.print("Initial maxTWR = " + stage.maxThrustToWeight);
                stage.actualThrust         = totalStageActualThrust;
                stage.actualThrustToWeight = totalStageActualThrust / (stageStartMass * gravity);

                // Calculate the cost and mass of this stage
                foreach (PartSim partSim in allParts)
                {
                    if (partSim.decoupledInStage == currentStage - 1)
                    {
                        stage.cost += partSim.cost;
                        stage.mass += partSim.GetStartMass();
                    }
                }

                if (log != null)
                {
                    MonoBehaviour.print("Stage setup took " + _timer.ElapsedMilliseconds + "ms");
                }

                // Now we will loop until we are allowed to stage
                int loopCounter = 0;
                while (!AllowedToStage())
                {
                    loopCounter++;
                    //MonoBehaviour.print("loop = " + loopCounter);

                    // Calculate how long each draining tank will take to drain and run for the minimum time
                    double  resourceDrainTime = double.MaxValue;
                    PartSim partMinDrain      = null;
                    foreach (PartSim partSim in drainingParts)
                    {
                        double time = partSim.TimeToDrainResource();
                        if (time < resourceDrainTime)
                        {
                            resourceDrainTime = time;
                            partMinDrain      = partSim;
                        }
                    }

                    if (log != null)
                    {
                        MonoBehaviour.print("Drain time = " + resourceDrainTime + " (" + partMinDrain.name + ":" + partMinDrain.partId + ")");
                    }

                    foreach (PartSim partSim in drainingParts)
                    {
                        partSim.DrainResources(resourceDrainTime);
                    }

                    // Get the mass after draining
                    stepEndMass = ShipMass;
                    stageTime  += resourceDrainTime;

                    double stepEndTWR = totalStageThrust / (stepEndMass * gravity);
                    //MonoBehaviour.print("After drain mass = " + stepEndMass);
                    //MonoBehaviour.print("currentThrust = " + totalStageThrust);
                    //MonoBehaviour.print("currentTWR = " + stepEndTWR);
                    if (stepEndTWR > stage.maxThrustToWeight)
                    {
                        stage.maxThrustToWeight = stepEndTWR;
                    }

                    //MonoBehaviour.print("newMaxTWR = " + stage.maxThrustToWeight);

                    // If we have drained anything and the masses make sense then add this step's deltaV to the stage total
                    if (resourceDrainTime > 0d && stepStartMass > stepEndMass && stepStartMass > 0d && stepEndMass > 0d)
                    {
                        vecStageDeltaV += vecThrust * (float)((currentisp * STD_GRAVITY * Math.Log(stepStartMass / stepEndMass)) / simpleTotalThrust);
                    }

                    // Update the active engines and resource drains for the next step
                    UpdateResourceDrains();

                    // Recalculate the current thrust and isp for the next step
                    CalculateThrustAndISP();

                    // Check if we actually changed anything
                    if (stepStartMass == stepEndMass)
                    {
                        //MonoBehaviour.print("No change in mass");
                        break;
                    }

                    // Check to stop rampant looping
                    if (loopCounter == 1000)
                    {
                        MonoBehaviour.print("exceeded loop count");
                        MonoBehaviour.print("stageStartMass = " + stageStartMass);
                        MonoBehaviour.print("stepStartMass = " + stepStartMass);
                        MonoBehaviour.print("StepEndMass   = " + stepEndMass);
                        break;
                    }

                    // The next step starts at the mass this one ended at
                    stepStartMass = stepEndMass;
                }

                // Store more values in the Stage object and stick it in the array

                // Store the magnitude of the deltaV vector
                stage.deltaV = vecStageDeltaV.magnitude;

                // Recalculate effective stage isp from the stage deltaV (flip the standard deltaV calculation around)
                // Note: If the mass doesn't change then this is a divide by zero
                if (stageStartMass != stepStartMass)
                {
                    stage.isp = stage.deltaV / (STD_GRAVITY * Math.Log(stageStartMass / stepStartMass));
                }
                else
                {
                    stage.isp = 0;
                }

                // Zero stage time if more than a day (this should be moved into the window code)
                stage.time           = (stageTime < SECONDS_PER_DAY) ? stageTime : 0d;
                stage.number         = doingCurrent ? -1 : currentStage;        // Set the stage number to -1 if doing current engines
                stages[currentStage] = stage;

                // Now activate the next stage
                currentStage--;
                doingCurrent = false;

                if (log != null)
                {
                    // Log how long the stage took
                    _timer.Stop();
                    MonoBehaviour.print("Simulating stage took " + _timer.ElapsedMilliseconds + "ms");
                    stage.Dump();
                    _timer.Reset();
                    _timer.Start();
                }

                // Activate the next stage
                ActivateStage();

                if (log != null)
                {
                    // Log how long it took to activate
                    _timer.Stop();
                    MonoBehaviour.print("ActivateStage took " + _timer.ElapsedMilliseconds + "ms");
                }
            }

            // Now we add up the various total fields in the stages
            for (int i = 0; i < stages.Length; i++)
            {
                // For each stage we total up the cost, mass, deltaV and time for this stage and all the stages above
                for (int j = i; j >= 0; j--)
                {
                    stages[i].totalCost   += stages[j].cost;
                    stages[i].totalMass   += stages[j].mass;
                    stages[i].totalDeltaV += stages[j].deltaV;
                    stages[i].totalTime   += stages[j].time;
                }
                // We also total up the deltaV for stage and all stages below
                for (int j = i; j < stages.Length; j++)
                {
                    stages[i].inverseTotalDeltaV += stages[j].deltaV;
                }

                // Zero the total time if the value will be huge (24 hours?) to avoid the display going weird
                // (this should be moved into the window code)
                if (stages[i].totalTime > SECONDS_PER_DAY)
                {
                    stages[i].totalTime = 0d;
                }
            }

            if (log != null)
            {
                _timer.Stop();
                MonoBehaviour.print("RunSimulation: " + _timer.ElapsedMilliseconds + "ms");
            }

            return(stages);
        }
Beispiel #51
0
        public void GetSourceSet_Internal(int type, bool includeSurfaceMountedParts, List<PartSim> allParts, HashSet<PartSim> visited, HashSet<PartSim> allSources, ref int priMax, LogMsg log, String indent)
        {
            if (log != null)
            {
                log.Append(indent, "GetSourceSet_Internal(", ResourceContainer.GetResourceName(type), ") for ")
                    .AppendLine(name, ":", partId);
                indent += "  ";
            }

            // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns as is.
            if (visited.Contains(this))
            {
                if (log != null) log.Append(indent, "Nothing added, already visited (", name, ":")
                                    .AppendLine(partId + ")");
                return;
            }

            if (log != null) log.AppendLine(indent, "Adding this to visited");

            visited.Add(this);

            // Rule 2: Part performs scan on start of every fuel pipe ending in it. This scan is done in order in which pipes were installed.
            // Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result.
            //MonoBehaviour.print("for each fuel line");

            int lastCount = allSources.Count;

            for (int i = 0; i < this.fuelTargets.Count; i++)
            {
                PartSim partSim = this.fuelTargets[i];
                if (partSim != null)
                {
                    if (visited.Contains(partSim))
                    {
                        if (log != null) log.Append(indent, "Fuel target already visited, skipping (", partSim.name, ":")
                                            .AppendLine(partSim.partId, ")");
                    }
                    else
                    {
                        if (log != null) log.Append(indent, "Adding fuel target as source (", partSim.name, ":")
                                            .AppendLine(partSim.partId, ")");

                        partSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, ref priMax, log, indent);
                    }
                }
            }

            if (fuelCrossFeed)
            {
                if (includeSurfaceMountedParts)
                {
                    // check surface mounted fuel targets
                    for (int i = 0; i < surfaceMountFuelTargets.Count; i++)
                    {
                        PartSim partSim = this.surfaceMountFuelTargets[i];
                        if (partSim != null)
                        {
                            if (visited.Contains(partSim))
                            {
                                if (log != null) log.Append(indent, "Surface part already visited, skipping (", partSim.name, ":")
                                                    .AppendLine(partSim.partId, ")");
                            }
                            else
                            {
                                if (log != null) log.Append(indent, "Adding surface part as source (", partSim.name, ":")
                                                    .AppendLine(partSim.partId, ")");

                                partSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, ref priMax, log, indent);
                            }
                        }
                    }
                }

                lastCount = allSources.Count;
                //MonoBehaviour.print("for each attach node");
                for (int i = 0; i < this.attachNodes.Count; i++)
                {
                    AttachNodeSim attachSim = this.attachNodes[i];
                    if (attachSim.attachedPartSim != null)
                    {
                        if (attachSim.nodeType == AttachNode.NodeType.Stack)
                        {
                            if ((string.IsNullOrEmpty(noCrossFeedNodeKey) == false && attachSim.id.Contains(noCrossFeedNodeKey)) == false)
                            {
                                if (visited.Contains(attachSim.attachedPartSim))
                                {
                                    if (log != null) log.Append(indent, "Attached part already visited, skipping (", attachSim.attachedPartSim.name, ":")
                                                        .AppendLine(attachSim.attachedPartSim.partId, ")");
                                }
                                else
                                {
                                    if (log != null) log.Append(indent, "Adding attached part as source  (", attachSim.attachedPartSim.name, ":")
                                                        .AppendLine(attachSim.attachedPartSim.partId, ")");

                                    attachSim.attachedPartSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, ref priMax, log, indent);
                                }
                            }
                        }
                    }
                }
            }

            // If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel
            // type was not disabled) and it contains fuel, it adds itself.
            if (resources.HasType(type) && resourceFlowStates[type] > 0.0)
            {
                if (resources[type] > resRequestRemainingThreshold)
                {
                    // Get the priority of this tank
                    int pri = GetResourcePriority();
                    if (pri > priMax)
                    {
                        // This tank is higher priority than the previously added ones so we clear the sources
                        // and set the priMax to this priority
                        allSources.Clear();
                        priMax = pri;
                    }
                    // If this is the correct priority then add this to the sources
                    if (pri == priMax)
                    {
                        if (log != null) log.Append(indent, "Adding enabled tank as source (", name, ":")
                                            .AppendLine(partId, ")");

                        allSources.Add(this);
                    }
                }
            }
            else
            {
                if (log != null) log.Append(indent, "Not fuel tank or disabled. HasType = ", resources.HasType(type))
                                    .AppendLine("  FlowState = " + resourceFlowStates[type]);
            }
        }
Beispiel #52
0
        // This function prepares the simulation by creating all the necessary data structures it will
        // need during the simulation.  All required data is copied from the core game data structures
        // so that the simulation itself can be run in a background thread without having issues with
        // the core game changing the data while the simulation is running.
        public bool PrepareSimulation(List <Part> parts, double theGravity, double theAtmosphere = 0, double theVelocity = 0, bool dumpTree = false, bool vectoredThrust = false)
        {
            LogMsg log = null;

            if (SimManager.logOutput)
            {
                log = new LogMsg();
                log.buf.AppendLine("PrepareSimulation started");
                dumpTree = true;
            }
            _timer.Start();

            // Store the parameters in members for ease of access in other functions
            partList   = parts;
            gravity    = theGravity;
            atmosphere = theAtmosphere;
            velocity   = theVelocity;
            lastStage  = Staging.lastStage;
            //MonoBehaviour.print("lastStage = " + lastStage);

            // Create the lists for our simulation parts
            allParts          = new List <PartSim>();
            allFuelLines      = new List <PartSim>();
            drainingParts     = new HashSet <PartSim>();
            allEngines        = new List <EngineSim>();
            activeEngines     = new List <EngineSim>();
            drainingResources = new HashSet <int>();

            // A dictionary for fast lookup of Part->PartSim during the preparation phase
            Dictionary <Part, PartSim> partSimLookup = new Dictionary <Part, PartSim>();

            if (partList.Count > 0 && partList[0].vessel != null)
            {
                vesselName = partList[0].vessel.vesselName;
                vesselType = partList[0].vessel.vesselType;
            }

            // First we create a PartSim for each Part (giving each a unique id)
            int partId = 1;

            foreach (Part part in partList)
            {
                // If the part is already in the lookup dictionary then log it and skip to the next part
                if (partSimLookup.ContainsKey(part))
                {
                    if (log != null)
                    {
                        log.buf.AppendLine("Part " + part.name + " appears in vessel list more than once");
                    }
                    continue;
                }

                // Create the PartSim
                PartSim partSim = new PartSim(part, partId, atmosphere, log);

                // Add it to the Part lookup dictionary and the necessary lists
                partSimLookup.Add(part, partSim);
                allParts.Add(partSim);
                if (partSim.isFuelLine)
                {
                    allFuelLines.Add(partSim);
                }
                if (partSim.isEngine)
                {
                    partSim.CreateEngineSims(allEngines, atmosphere, velocity, vectoredThrust, log);
                }

                partId++;
            }

            UpdateActiveEngines();

            // Now that all the PartSims have been created we can do any set up that needs access to other parts
            // First we set up all the parent links
            foreach (PartSim partSim in allParts)
            {
                partSim.SetupParent(partSimLookup, log);
            }

            // Then, in the VAB/SPH, we add the parent of each fuel line to the fuelTargets list of their targets
            if (HighLogic.LoadedSceneIsEditor)
            {
                foreach (PartSim partSim in allFuelLines)
                {
                    if ((partSim.part as FuelLine).target != null)
                    {
                        PartSim targetSim;
                        if (partSimLookup.TryGetValue((partSim.part as FuelLine).target, out targetSim))
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine("Fuel line target is " + targetSim.name + ":" + targetSim.partId);
                            }

                            targetSim.fuelTargets.Add(partSim.parent);
                        }
                        else
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine("No PartSim for fuel line target (" + partSim.part.partInfo.name + ")");
                            }
                        }
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine("Fuel line target is null");
                        }
                    }
                }
            }

            //MonoBehaviour.print("SetupAttachNodes and count stages");
            foreach (PartSim partSim in allParts)
            {
                partSim.SetupAttachNodes(partSimLookup, log);
                if (partSim.decoupledInStage >= lastStage)
                {
                    lastStage = partSim.decoupledInStage + 1;
                }
            }

            // And finally release the Part references from all the PartSims
            //MonoBehaviour.print("ReleaseParts");
            foreach (PartSim partSim in allParts)
            {
                partSim.ReleasePart();
            }

            // And dereference the core's part list
            partList = null;

            _timer.Stop();
            if (log != null)
            {
                log.buf.AppendLine("PrepareSimulation: " + _timer.ElapsedMilliseconds + "ms");
                log.Flush();
            }

            if (dumpTree)
            {
                Dump();
            }

            return(true);
        }
Beispiel #53
0
        void Enqueue(LogMsg message)
        {
            _messageBuffer[_messageBufferPointer] = message;
            _messageBufferPointer++;

            if (_messageBufferPointer > FLUSH_SIZE) {
                Flush();
            }
        }
Beispiel #54
0
        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="pContext"></param>
        private void WriteLog(string pContext)
        {
            LogMsg msg = new LogMsg("业务服务", pContext, "");

            new LogHelper().WriteLog(msg);
        }
Beispiel #55
0
        public void CreateEngineSims(List<EngineSim> allEngines, double atmosphere, double mach, bool vectoredThrust, bool fullThrust, LogMsg log)
        {
            if (log != null)
            {
                log.buf.AppendLine("CreateEngineSims for " + this.name);
                for (int i = 0; i < this.part.Modules.Count; i++)
                {
                    PartModule partMod = this.part.Modules[i];
                    log.buf.AppendLine("Module: " + partMod.moduleName);
                }
            }

            if (hasMultiModeEngine)
            {
                // A multi-mode engine has multiple ModuleEngines but only one is active at any point
                // The mode of the engine is the engineID of the ModuleEngines that is active
                string mode = part.GetModule<MultiModeEngine>().mode;

                List<ModuleEngines> engines = part.GetModules<ModuleEngines>();
                for (int i = 0; i < engines.Count; ++i)
                {
                    ModuleEngines engine = engines[i];
                    if (engine.engineID == mode)
                    {
                        if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);

                        EngineSim engineSim = EngineSim.New(
                            this,
                            engine,
                            atmosphere,
                            (float)mach,
                            vectoredThrust,
                            fullThrust,
                            log);
                        allEngines.Add(engineSim);
                    }
                }
            }
            else if (hasModuleEngines)
            {
                List<ModuleEngines> engines = part.GetModules<ModuleEngines>();
                for (int i = 0; i < engines.Count; ++i)
                {
                    ModuleEngines engine = engines[i];
                    if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);

                    EngineSim engineSim = EngineSim.New(
                        this,
                        engine,
                        atmosphere,
                        (float)mach,
                        vectoredThrust,
                        fullThrust,
                        log);
                    allEngines.Add(engineSim);
                }
            }

            if (log != null)
            {
                log.Flush();
            }
        }
Beispiel #56
0
        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="funtionName"></param>
        /// <param name="pContext"></param>
        private void WriteLog(string funtionName, string pContext)
        {
            LogMsg msg = new LogMsg("业务服务", funtionName, pContext);

            new LogHelper().WriteLog(msg);
        }
Beispiel #57
0
        public void SetupAttachNodes(Dictionary<Part, PartSim> partSimLookup, LogMsg log)
        {
            if (log != null) log.buf.AppendLine("SetupAttachNodes for " + name + ":" + partId + "");

            attachNodes.Clear();

            for (int i = 0; i < part.attachNodes.Count; ++i)
            {
                AttachNode attachNode = part.attachNodes[i];

                if (log != null) log.buf.AppendLine("AttachNode " + attachNode.id + " = " + (attachNode.attachedPart != null ? attachNode.attachedPart.partInfo.name : "null"));

                if (attachNode.attachedPart != null && attachNode.id != "Strut")
                {
                    PartSim attachedSim;
                    if (partSimLookup.TryGetValue(attachNode.attachedPart, out attachedSim))
                    {
                        if (log != null) log.buf.AppendLine("Adding attached node " + attachedSim.name + ":" + attachedSim.partId + "");

                        attachNodes.Add(AttachNodeSim.New(attachedSim, attachNode.id, attachNode.nodeType));
                    }
                    else
                    {
                        if (log != null) log.buf.AppendLine("No PartSim for attached part (" + attachNode.attachedPart.partInfo.name + ")");
                    }
                }
            }

            for (int i = 0; i < part.fuelLookupTargets.Count; ++i)
            {
                Part p = part.fuelLookupTargets[i];

                if (p != null)
                {
                    PartSim targetSim;
                    if (partSimLookup.TryGetValue(p, out targetSim))
                    {
                        if (log != null) log.buf.AppendLine("Fuel target: " + targetSim.name + ":" + targetSim.partId);

                        fuelTargets.Add(targetSim);
                    }
                    else
                    {
                        if (log != null) log.buf.AppendLine("No PartSim for fuel target (" + p.name + ")");
                    }
                }
            }
        }
Beispiel #58
0
        // This function prepares the simulation by creating all the necessary data structures it will
        // need during the simulation.  All required data is copied from the core game data structures
        // so that the simulation itself can be run in a background thread without having issues with
        // the core game changing the data while the simulation is running.
        public bool PrepareSimulation(List <Part> parts, double theGravity, double theAtmosphere = 0, double theMach = 0, bool dumpTree = false, bool vectoredThrust = false, bool fullThrust = false)
        {
            LogMsg log = null;

            if (SimManager.logOutput)
            {
                log = new LogMsg();
                log.buf.AppendLine("PrepareSimulation started");
                dumpTree = true;
            }
            this._timer.Reset();
            this._timer.Start();

            // Store the parameters in members for ease of access in other functions
            this.partList   = parts;
            this.gravity    = theGravity;
            this.atmosphere = theAtmosphere;
            this.mach       = theMach;
            this.lastStage  = Staging.lastStage;
            this.maxMach    = 1.0f;
            //MonoBehaviour.print("lastStage = " + lastStage);

            // Clear the lists for our simulation parts
            allParts.Clear();
            allFuelLines.Clear();
            drainingParts.Clear();
            allEngines.Clear();
            activeEngines.Clear();
            drainingResources.Clear();

            // A dictionary for fast lookup of Part->PartSim during the preparation phase
            partSimLookup.Clear();

            if (this.partList.Count > 0 && this.partList[0].vessel != null)
            {
                this.vesselName = this.partList[0].vessel.vesselName;
                this.vesselType = this.partList[0].vessel.vesselType;
            }
            //MonoBehaviour.print("PrepareSimulation pool size = " + PartSim.pool.Count());
            // First we create a PartSim for each Part (giving each a unique id)
            int partId = 1;

            for (int i = 0; i < partList.Count; ++i)
            {
                Part part = partList[i];

                // If the part is already in the lookup dictionary then log it and skip to the next part
                if (partSimLookup.ContainsKey(part))
                {
                    if (log != null)
                    {
                        log.buf.AppendLine("Part " + part.name + " appears in vessel list more than once");
                    }
                    continue;
                }

                // Create the PartSim
                PartSim partSim = PartSim.New(part, partId, this.atmosphere, log);

                // Add it to the Part lookup dictionary and the necessary lists
                partSimLookup.Add(part, partSim);
                this.allParts.Add(partSim);
                if (partSim.isFuelLine)
                {
                    this.allFuelLines.Add(partSim);
                }
                if (partSim.isEngine)
                {
                    partSim.CreateEngineSims(this.allEngines, this.atmosphere, this.mach, vectoredThrust, fullThrust, log);
                }

                partId++;
            }

            for (int i = 0; i < allEngines.Count; ++i)
            {
                maxMach = Mathf.Max(maxMach, allEngines[i].maxMach);
            }

            this.UpdateActiveEngines();

            // Now that all the PartSims have been created we can do any set up that needs access to other parts
            // First we set up all the parent links
            for (int i = 0; i < this.allParts.Count; i++)
            {
                PartSim partSim = this.allParts[i];
                partSim.SetupParent(partSimLookup, log);
            }

            // Then, in the VAB/SPH, we add the parent of each fuel line to the fuelTargets list of their targets
            if (HighLogic.LoadedSceneIsEditor)
            {
                for (int i = 0; i < allFuelLines.Count; ++i)
                {
                    PartSim partSim = allFuelLines[i];

                    CModuleFuelLine fuelLine = partSim.part.GetModule <CModuleFuelLine>();
                    if (fuelLine.target != null)
                    {
                        PartSim targetSim;
                        if (partSimLookup.TryGetValue(fuelLine.target, out targetSim))
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine("Fuel line target is " + targetSim.name + ":" + targetSim.partId);
                            }

                            targetSim.fuelTargets.Add(partSim.parent);
                        }
                        else
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine("No PartSim for fuel line target (" + partSim.part.partInfo.name + ")");
                            }
                        }
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.buf.AppendLine("Fuel line target is null");
                        }
                    }
                }
            }

            //MonoBehaviour.print("SetupAttachNodes and count stages");
            for (int i = 0; i < allParts.Count; ++i)
            {
                PartSim partSim = allParts[i];

                partSim.SetupAttachNodes(partSimLookup, log);
                if (partSim.decoupledInStage >= this.lastStage)
                {
                    this.lastStage = partSim.decoupledInStage + 1;
                }
            }

            // And finally release the Part references from all the PartSims
            //MonoBehaviour.print("ReleaseParts");
            for (int i = 0; i < allParts.Count; ++i)
            {
                allParts[i].ReleasePart();
            }

            // And dereference the core's part list
            this.partList = null;

            this._timer.Stop();
            if (log != null)
            {
                log.buf.AppendLine("PrepareSimulation: " + this._timer.ElapsedMilliseconds + "ms");
                log.Flush();
            }

            if (dumpTree)
            {
                this.Dump();
            }

            return(true);
        }
Beispiel #59
0
        private Vector3 CalculateThrustVector(List<Transform> thrustTransforms, LogMsg log)
        {
            if (thrustTransforms == null)
            {
                return Vector3.forward;
            }

            Vector3 thrustvec = Vector3.zero;
            for (int i = 0; i < thrustTransforms.Count; ++i)
            {
                Transform trans = thrustTransforms[i];

                if (log != null) log.buf.AppendFormat("Transform = ({0:g6}, {1:g6}, {2:g6})   length = {3:g6}\n", trans.forward.x, trans.forward.y, trans.forward.z, trans.forward.magnitude);

                thrustvec -= trans.forward;
            }

            if (log != null) log.buf.AppendFormat("ThrustVec  = ({0:g6}, {1:g6}, {2:g6})   length = {3:g6}\n", thrustvec.x, thrustvec.y, thrustvec.z, thrustvec.magnitude);

            thrustvec.Normalize();

            if (log != null) log.buf.AppendFormat("ThrustVecN = ({0:g6}, {1:g6}, {2:g6})   length = {3:g6}\n", thrustvec.x, thrustvec.y, thrustvec.z, thrustvec.magnitude);

            return thrustvec;
        }
Beispiel #60
0
 private void InsertAlarmInfo(DataRow dr, CmdParam.CarAlarmState carAlarmState, int AddMsgType)
 {
     try
     {
         int    num   = 0;
         string empty = string.Empty;
         int    num1  = Convert.ToInt32(dr["carstatu"]);
         long   num2  = (long)0;
         num2 = (dr["carstatuex"] == DBNull.Value || dr["carstatuex"].ToString().Equals("") ? 2251799813685248L : 2251799813685248L | Convert.ToInt64(dr["carstatuex"]));
         int    num3 = 1154;
         int    num4 = 65;
         string str  = string.Empty;
         string str1 = dr["AddMsgTxt"].ToString();
         string str2 = null;
         bool   flag = false;
         string str3 = null;
         int    num5 = 0;
         try
         {
             SqlParameter[] sqlParameter = new SqlParameter[] { new SqlParameter("@wrkid", (object)num), new SqlParameter("@orderid", dr["OrderId"]), new SqlParameter("@userid", empty), new SqlParameter("@telephone", dr["telephone"]), new SqlParameter("@msgType", (object)num4), new SqlParameter("@recetime", dr["ReceTime"]), new SqlParameter("@gpstime", dr["GpsTime"]), new SqlParameter("@starCondition", dr["StarCondition"]), new SqlParameter("@starNum", dr["StarNum"]), new SqlParameter("@carStatu", (object)num1), new SqlParameter("@carStatuEx", (object)num2), new SqlParameter("@carCondition", dr["CarCondition"]), new SqlParameter("@Longitude", dr["Longitude"]), new SqlParameter("@Latitude", dr["Latitude"]), new SqlParameter("@direct", dr["Direct"]), new SqlParameter("@speed", dr["Speed"]), new SqlParameter("@Reserved", (object)num3), new SqlParameter("@TransportStatus", dr["TransportStatus"]), new SqlParameter("@Accelerration", dr["Accelerration"]), new SqlParameter("@Altitude", dr["Altitude"]), new SqlParameter("@DistanceDiff", dr["DistanceDiff"]), new SqlParameter("@commflag", dr["CommFlag"]), new SqlParameter("@addType", (object)AddMsgType), new SqlParameter("@addTxt", str1), new SqlParameter("@DutyStr", str2), new SqlParameter("@isPic", (object)flag), new SqlParameter("@pic", str3), new SqlParameter("@alarmInfo", str), new SqlParameter("@cameraID", (object)num5) };
             string         str4         = "GpsPicServer_Alarm_Insert";
             string         str5         = "GpsPicServer_RealTime_Insert";
             if (AddMsgType != -99997)
             {
                 int num6 = SqlDataAccess.insertBySp(str4, sqlParameter);
                 if (num6 > 0)
                 {
                     LogMsg   logMsg    = new LogMsg("PlatformAlarmPathAlarm", "InsertAlarmInfo", "");
                     string[] strArrays = new string[] { "车载电话为:", dr["telephone"].ToString(), "的平台检测", carAlarmState.ToString(), "报警报文已插入gpsrecebuffer" };
                     logMsg.Msg = string.Concat(strArrays);
                     this.logHelper.WriteLog(logMsg);
                 }
                 else
                 {
                     ErrorMsg errorMsg = new ErrorMsg("PlatformAlarmPathAlarm", "InsertAlarmInfo", string.Concat("将平台检测", carAlarmState.ToString(), "报警报文插入gpsrecbuffer表错误,返回值!", num6.ToString()));
                     this.logHelper.WriteError(errorMsg);
                 }
             }
             int num7 = SqlDataAccess.insertBySp(str5, sqlParameter);
             if (num7 > 0)
             {
                 string[] strArrays1 = new string[] { "车载电话为:", dr["telephone"].ToString(), "的平台检测", carAlarmState.ToString(), "报警报文已插入gpsrecerealtime" };
                 LogMsg   logMsg1    = new LogMsg("PlatformAlarmPathAlarm", "InsertAlarmInfo", string.Concat(strArrays1));
                 string[] strArrays2 = new string[] { "车载电话为:", dr["telephone"].ToString(), "的平台检测", carAlarmState.ToString(), "报警报文已插入gpsrecerealtime" };
                 logMsg1.Msg = string.Concat(strArrays2);
                 this.logHelper.WriteLog(logMsg1);
             }
             else
             {
                 ErrorMsg errorMsg1 = new ErrorMsg("PlatformAlarmPathAlarm", "InsertAlarmInfo", string.Concat("将平台检测", carAlarmState.ToString(), "报警报文插入gpsrecerealtime_buffer表发生错误,返回值!", num7.ToString()));
                 this.logHelper.WriteError(errorMsg1);
             }
         }
         catch (Exception exception1)
         {
             Exception exception  = exception1;
             string[]  strArrays3 = new string[] { "车载电话为:", dr["telephone"].ToString(), "的平台检测", carAlarmState.ToString(), "报警报文插入数据库发生错误! 信息:", exception.Message };
             ErrorMsg  errorMsg2  = new ErrorMsg("PlatformAlarmPathAlarm", "InsertAlarmInfo", string.Concat(strArrays3));
             this.logHelper.WriteError(errorMsg2);
         }
     }
     catch (Exception exception3)
     {
         Exception exception2 = exception3;
         LogHelper logHelper  = new LogHelper();
         ErrorMsg  errorMsg3  = new ErrorMsg("PlatformAlarmPathAlarm", "InsertAlarmInfo", string.Concat("将平台检测", carAlarmState.ToString(), "报警报文插入gpsrecbuffer表 、gpsrecerealtime_buffer表发生错误!", exception2.Message));
         logHelper.WriteError(errorMsg3);
     }
 }