예제 #1
0
        /// <summary>
        /// Applies a bounding function to the current capacity of the battery, to prohibit discharging below 0 joules,
        /// and the prevent charging above the maximum specified capabilities. If the battery exceeds the specification,
        /// a warning (for overcharge) or critical error (for discharged) will be logged to the solution.
        /// </summary>
        /// <param name="battery">The battery parameters to enforce.</param>
        /// <param name="pass">The last pass that was executed.</param>
        /// <returns>A value indicating whether the requested capacity could be accomplished successfully.</returns>
        private bool EnforceBatteryLimits(Battery battery, PassOrbit pass, IPassPhase phase)
        {
            var success = true;

            if (this.currentCapacityJoules < 0)
            {
                // Orbit parameters are impossible - we've run out of power.
                // Error is fatal - denote the problem and abort scheduling.
                this.solution.IsSolvable = false;
                this.solution.Problems.Add(new ScheduleSolution.SchedulerProblem(
                                               ScheduleSolution.SchedulerProblem.SeverityLevel.Fatal,
                                               $"Orbit parameters for {pass.Name} are impossible. No power remains while scheduling the {phase.PhaseName} for {pass.Name}."));

                this.currentCapacityJoules = 0;

                // Discharging completely is a fatal error that will prevent the pass from completing
                success = false;
            }
            else if (this.currentCapacityJoules > battery.EffectiveCapacityJ)
            {
                this.solution.Problems.Add(new ScheduleSolution.SchedulerProblem(
                                               ScheduleSolution.SchedulerProblem.SeverityLevel.Warning,
                                               $"The battery was a contraint during {pass.Name}. {this.currentCapacityJoules:n} J were available, but max charge capacity is {battery.EffectiveCapacityJ:n} J"));

                // Apply the cap.
                this.currentCapacityJoules = battery.EffectiveCapacityJ;

                // Overcharging doesn't prevent the mission from continuing, but indicates inefficiency
                success = true;
            }

            return(success);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="EditControlViewModel"/> class.
        /// </summary>
        /// <param name="pass">The pass to edit.</param>
        /// <param name="editComplete">The action to execute when the edit is completed.</param>
        public EditControlViewModel(PassOrbit pass, Action <PassOrbit> editComplete)
        {
            this.originalPass = pass;
            this.InitPhases();

            this.SaveCallback  = editComplete;
            this.SaveCommand   = new RelayCommand(this.SaveCommandHandler);
            this.CancelCommand = new RelayCommand(this.CancelCommandHandler);
        }
예제 #3
0
 private void ReportProfileNotAvailable(PassOrbit pass, string operation)
 {
     // No profile could be found that fits the available power and time
     // All previous schedules have already been done with the lowest-power option that fits
     // so if we're out of power, there is no solution possible.
     // If we're out of time, faster devices are needed, or the phase needs lengthened.
     this.solution.IsSolvable = false;
     this.solution.Problems.Add(new ScheduleSolution.SchedulerProblem(
                                    ScheduleSolution.SchedulerProblem.SeverityLevel.Fatal,
                                    $"Orbit parameters for {pass.Name} are impossible. No devices are capable of performing the {operation} in the required power and time window."));
 }
예제 #4
0
        private bool FindProfileForPhase(SortedDictionary <double, IByteStreamProcessor> optimizationMap, PassOrbit pass, IPassPhase phase, long bytes)
        {
            var allowedTime = phase.EndTime.Subtract(phase.StartTime);

            // For the encryption phase, we have an abs max of currentCapacityJoules
            // and the time allocated to encryptionPhase.

            // Start with the most ideal profile and keep testing until we find one that fits
            var foundViableProfile = false;

            foreach (var profile in optimizationMap.Values)
            {
                var timeRequired   = bytes / profile.BytesPerSecond;
                var energyRequired = bytes * profile.JoulesPerByte;

                if (timeRequired > allowedTime.TotalSeconds)
                {
                    // Out of time
                    foundViableProfile = false;
                }
                else if (energyRequired > this.currentCapacityJoules)
                {
                    // Out of power
                    foundViableProfile = false;
                }
                else
                {
                    // This solution works for this part
                    this.solution.ViableProfiles[pass][phase.PhaseName] = profile;
                    phase.TotalEnergyUsed       = energyRequired;
                    foundViableProfile          = true;
                    this.currentCapacityJoules -= energyRequired;
                    break;
                }
            }

            return(foundViableProfile);
        }