public void Disable() { balanceStatus = BalanceStatus.Deactivated; _tanks = null; Status = "Deactivated"; Events["Disable"].active = false; Events["BalanceFuel"].active = true; Events["Maintain"].active = true; // Clear the list of tanks. They will have to be rebuilt next time balancing is enabled }
public void Maintain() { // If we were previously Deactivated then we need to build a list of tanks and set up to start balancing if (balanceStatus == BalanceStatus.Deactivated || balanceStatus == BalanceStatus.Balance_not_possible) { BuildTanksList(); _iNextSourceTank = 0; _iNextDestinationTank = 0; ResetfNextAmountMoved(); _fMostMovedThisRound = 0; DeactivateOtherPWBModules(); } Events["Disable"].active = true; Events["BalanceFuel"].active = false; Events["Maintain"].active = false; balanceStatus = BalanceStatus.Maintaining; Status = "Maintaining"; }
public BalanceStatus Balance(string cardNumber) { var card = cardRepository.GetByNumber(cardNumber); if (card == null) { return(null); } TrackOperation(card, OperationTypes.BalanceCheck); Save(); var balance = new BalanceStatus { Date = DateTime.Now, Amount = card.Account.Balance, CardNumber = cardNumber }; return(balance); }
// Transfer fuel to move the center of mass from current position towards target. // Returns the new distance the CoM was moved towards its target public float MoveFuel() { float fCoMStartingError = CalculateCoMFromTargetCoM(vessel.CoM); float mass = vessel.GetTotalMass(); // Get total mass. Vector3 oldWorldCoM = vessel.CoM; float fOldCoMError = fCoMStartingError; bool moveMade = false; int iNumberofTanks = _tanks.Count; Log.Info("MoveFuel, mass: " + mass.ToString("F1") + ", iNumberOfTanks: " + iNumberofTanks); //Log.Info("Number of tanks " + iNumberofTanks); // Now go through the list of parts and resources and consider making transfers while (_iNextSourceTank < iNumberofTanks && false == moveMade) { //Log.Info("Considering moving fuel from tank" + this.iNextSourceTank); PartResource resource1 = ((PartAndResource)_tanks[_iNextSourceTank]).Resource; Part part1 = ((PartAndResource)_tanks[_iNextSourceTank]).Part; // Only process nonempty tanks, and tanks that are not locked. if (resource1.amount > 0 && resource1.flowState && resource1.resourceName != "Ore" && resource1.resourceName != "Ablator" && resource1.resourceName != "SolidFuel") { // Only move resources that have mass (don't move electricity!) if (resource1.info.density > 0) { // If the two tanks are the same move on. if (_iNextDestinationTank == _iNextSourceTank) { _iNextDestinationTank++; } while (_iNextDestinationTank < iNumberofTanks && false == moveMade) { Log.Info("Considering moving fuel from tank: " + _iNextSourceTank + " to tank: " + this._iNextDestinationTank); PartResource resource2 = ((PartAndResource)_tanks[_iNextDestinationTank]).Resource; Part part2 = ((PartAndResource)_tanks[_iNextDestinationTank]).Part; // Check that the resources are of the same type and the tank is not locked if (resource2.resourceName == resource1.resourceName && resource2.flowState) { // Clamp resource quantity by the amount available in the two tanks. //Log.Info("MoveFuel: _iNextSourceTank: " + _iNextSourceTank + ", _fNextAmountMoved: " + ((PartAndResource)_tanks[_iNextDestinationTank])._fNextAmountMoved + ", resource1.amount: " + resource1.amount); float moveAmount = (float)Math.Min(((PartAndResource)_tanks[_iNextDestinationTank]).fNextAmountMoved, resource1.amount); moveAmount = (float)Math.Max(moveAmount, -(resource1.maxAmount - resource1.amount)); moveAmount = (float)Math.Max(moveAmount, -resource2.amount); moveAmount = (float)Math.Min(moveAmount, resource2.maxAmount - resource2.amount); Log.Info("Considering moving " + moveAmount.ToString("F2")); if (moveAmount > 0) { // Calculate the new CoM to see if it helped: float fVesselMass = vessel.GetTotalMass(); //Log.Info("part1.transform.position : " + part1.transform.position.ToString()); //Log.Info("part2.transform.position : " + part2.transform.position.ToString()); Vector3 newCenterOfMass = ((oldWorldCoM * fVesselMass) - (part1.transform.position * (moveAmount * resource1.info.density)) + (part2.transform.position * (moveAmount * resource2.info.density))) * (1 / fVesselMass); // Recompute the distance between CoM and the TargetCoM float fNewError = CalculateCoMFromTargetCoM(newCenterOfMass); //Log.Info("Old world CoM: " + OldWorldCoM.ToString()); //Log.Info("New suggested CoM: " + NewCenterOfMass.ToString()); //Log.Info("new error is: " + fNewError.ToString() + " compared to " + fOldCoMError.ToString()); if (fNewError < fOldCoMError) { //Log.Info("CoM moved in correct direction"); // This is moving us in the right direction fOldCoMError = fNewError; // Actually move the fuel resource1.amount -= moveAmount; resource2.amount += moveAmount; // set the new CoM for the next iteration oldWorldCoM = newCenterOfMass; moveMade = true; if (moveAmount > _fMostMovedThisRound) { _fMostMovedThisRound = moveAmount; } // Finally, move on to another source tank, so that the flow out of each source tank appears a bit smoother. _iNextSourceTank++; } } } // Move on the the next destination tank _iNextDestinationTank++; if (_iNextDestinationTank == _iNextSourceTank) { _iNextDestinationTank++; } } // If we have reached the end of the list of destination tanks then we need to reset tank list for next time if (_iNextDestinationTank < iNumberofTanks) { continue; } _iNextDestinationTank = 0; _iNextSourceTank++; } else { //Log.Info("Tank" + this.iNextSourceTank + " contains a zero density resource, moving on to the next source tank"); _iNextSourceTank++; } } else { //Log.Info("Tank" + this.iNextSourceTank + " was empty, moving on to the next source tank"); _iNextSourceTank++; } } // If we have reached the end of the source tanks then we need to reset the list for next time if (_iNextSourceTank >= iNumberofTanks) { _iNextSourceTank = 0; // Since we are now starting a new round, the next thing to consider is whether we moved anything this round. If not then we need to consider moving smaller amounts if (_fMostMovedThisRound == 0) { ((PartAndResource)_tanks[_iNextDestinationTank]).fNextAmountMoved /= 2f; //Log.Info("changing the amount to move to be " + fNextAmountMoved); // Finally has the amount move become so small that we need to call it a day? if (((PartAndResource)_tanks[_iNextDestinationTank]).fNextAmountMoved < 0.0005) { // Since perfect balance is not possible, we need to move into an appropriate state.If we are trying to maintain blanace then we will keep trying trying again with larger amounts. If we were trying for a single balance then move to a state that shows it is not possible. if (balanceStatus == BalanceStatus.Maintaining) { ResetfNextAmountMoved(); Events["Disable"].active = true; } else { balanceStatus = BalanceStatus.Balance_not_possible; Status = "Balance not possible"; Events["Disable"].active = true; Events["BalanceFuel"].active = true; Events["Maintain"].active = true; // throw away the tanks list _tanks = null; } } } _fMostMovedThisRound = 0; } // Update the member variable that remembers what the error is to display it FComError = fOldCoMError; // Return the amount that the CoM has been corrected return(fCoMStartingError - fOldCoMError); }
/// <summary> /// Per-physx-frame update /// </summary> private void FixedUpdate() { Log.Info("FixedUpdate, ActualCoMMarker: " + (ActualCoMMarker != null) + ", ActualCoMMarkerVisible: " + ActualCoMMarkerVisible); if (ActualCoMMarker != null) { ActualCoMMarker.SetActive(!MapView.MapIsEnabled && ActualCoMMarkerVisible && !HideUI); } if (ActualCoLMarker != null) { ActualCoLMarker.SetActive(!MapView.MapIsEnabled && ActualCoLMarkerVisible && vessel.srf_velocity.magnitude > 0.1f && !HideUI); } if (!_started || !HighLogic.LoadedSceneIsFlight || balanceStatus < BalanceStatus.Maintaining) { return; } if (SavedCoMMarker != null) { SavedCoMMarker.SetActive(!MapView.MapIsEnabled && SavedCoMMarkerVisible && !HideUI); } // Update the ComError (hopefully this will not kill our performance) FComError = CalculateCoMFromTargetCoM(part.vessel.CoM); if (balanceStatus == BalanceStatus.Deactivated || balanceStatus == BalanceStatus.Balance_not_possible) { return; } if (FComError < 0.002) { // The error is so small we need not worry anymore if (balanceStatus == BalanceStatus.Balancing) { DeactivateModule(this); // Clear the list of tanks. They will have to be rebuilt next time balancing is enabled _tanks = null; } else if (balanceStatus == BalanceStatus.Maintaining) { // Move from a maintaining state to a standby one. If the error increases we con mvoe back to a maintining state balanceStatus = BalanceStatus.Standby; Status = "Standby"; _iNextSourceTank = 0; _iNextDestinationTank = 0; ResetfNextAmountMoved(); _fMostMovedThisRound = 0; } } else { // There is an error if (balanceStatus == BalanceStatus.Standby) { // is the error large enough to get us back into a maintaining mode? if (FComError > 0.002 * 2) { balanceStatus = BalanceStatus.Maintaining; Status = "Maintaining"; } } MoveFuel(); } }