forked from RnD/machineGroupControl
Added edge case for when 1 pump cant handle the scope
This commit is contained in:
@@ -333,42 +333,71 @@ class MachineGroup {
|
|||||||
|
|
||||||
calcBestCombination(combinations, Qd) {
|
calcBestCombination(combinations, Qd) {
|
||||||
let bestCombination = null;
|
let bestCombination = null;
|
||||||
|
|
||||||
//keep track of totals
|
|
||||||
let bestPower = Infinity;
|
let bestPower = Infinity;
|
||||||
let bestFlow = 0;
|
let bestFlow = 0;
|
||||||
let bestCog = 0;
|
let bestCog = 0;
|
||||||
|
|
||||||
combinations.forEach(combination => {
|
|
||||||
|
|
||||||
let flowDistribution = []; // Stores the flow distribution for the best combination
|
combinations.forEach(combination => {
|
||||||
|
let flowDistribution = [];
|
||||||
let totalCoG = 0;
|
let totalCoG = 0;
|
||||||
let totalPower = 0;
|
let totalPower = 0;
|
||||||
let totalFlow = 0;
|
|
||||||
|
|
||||||
// Calculate the total CoG for the current combination
|
// Sum normalized CoG for the combination
|
||||||
combination.forEach(machineId => { totalCoG += ( Math.round(this.machines[machineId].NCog * 100 ) /100 ) ; });
|
|
||||||
|
|
||||||
// Calculate the total power for the current combination
|
|
||||||
combination.forEach(machineId => {
|
combination.forEach(machineId => {
|
||||||
let flow = 0;
|
totalCoG += Math.round((this.machines[machineId].NCog || 0) * 100) / 100;
|
||||||
|
});
|
||||||
// Prevent division by zero
|
|
||||||
if (totalCoG === 0) {
|
// Initial CoG-based distribution
|
||||||
// Distribute flow equally among all pumps
|
combination.forEach(machineId => {
|
||||||
flow = Qd / combination.length;
|
let flow = 0;
|
||||||
|
|
||||||
} else {
|
if (totalCoG === 0) {
|
||||||
// Normal CoG-based distribution
|
flow = Qd / combination.length;
|
||||||
flow = (this.machines[machineId].NCog / totalCoG) * Qd ;
|
} else {
|
||||||
this.logger.debug(`Machine Normalized CoG-based distribution ${machineId} flow: ${flow}`);
|
flow = ((this.machines[machineId].NCog || 0) / totalCoG) * Qd;
|
||||||
}
|
this.logger.debug(`Machine Normalized CoG-based distribution ${machineId} flow: ${flow}`);
|
||||||
totalFlow += flow;
|
}
|
||||||
totalPower += this.machines[machineId].inputFlowCalcPower(flow);
|
|
||||||
flowDistribution.push({ machineId: machineId,flow: flow });
|
flowDistribution.push({ machineId, flow });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clamp to min/max and spill leftover once
|
||||||
|
const clamped = flowDistribution.map(entry => {
|
||||||
|
const machine = this.machines[entry.machineId];
|
||||||
|
const min = machine.predictFlow.currentFxyYMin;
|
||||||
|
const max = machine.predictFlow.currentFxyYMax;
|
||||||
|
const clampedFlow = Math.min(max, Math.max(min, entry.flow));
|
||||||
|
return { ...entry, flow: clampedFlow, min, max, desired: entry.flow };
|
||||||
|
});
|
||||||
|
|
||||||
|
let remainder = Qd - clamped.reduce((sum, entry) => sum + entry.flow, 0);
|
||||||
|
|
||||||
|
if (Math.abs(remainder) > 1e-6) {
|
||||||
|
const adjustable = clamped.filter(entry =>
|
||||||
|
remainder > 0 ? entry.flow < entry.max : entry.flow > entry.min
|
||||||
|
);
|
||||||
|
const weightSum = adjustable.reduce((sum, entry) => sum + entry.desired, 0) || adjustable.length;
|
||||||
|
|
||||||
|
adjustable.forEach(entry => {
|
||||||
|
const weight = entry.desired / weightSum || 1 / adjustable.length;
|
||||||
|
const delta = remainder * weight;
|
||||||
|
const next = remainder > 0
|
||||||
|
? Math.min(entry.max, entry.flow + delta)
|
||||||
|
: Math.max(entry.min, entry.flow + delta);
|
||||||
|
|
||||||
|
remainder -= (next - entry.flow);
|
||||||
|
entry.flow = next;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
flowDistribution = clamped;
|
||||||
|
|
||||||
|
let totalFlow = 0;
|
||||||
|
flowDistribution.forEach(({ machineId, flow }) => {
|
||||||
|
totalFlow += flow;
|
||||||
|
totalPower += this.machines[machineId].inputFlowCalcPower(flow);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update the best combination if the current one is better
|
|
||||||
if (totalPower < bestPower) {
|
if (totalPower < bestPower) {
|
||||||
this.logger.debug(`New best combination found: ${totalPower} < ${bestPower}`);
|
this.logger.debug(`New best combination found: ${totalPower} < ${bestPower}`);
|
||||||
this.logger.debug(`combination ${JSON.stringify(flowDistribution)}`);
|
this.logger.debug(`combination ${JSON.stringify(flowDistribution)}`);
|
||||||
@@ -382,6 +411,7 @@ class MachineGroup {
|
|||||||
return { bestCombination, bestPower, bestFlow, bestCog };
|
return { bestCombination, bestPower, bestFlow, bestCog };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------- Mode and Input Management -------- //
|
// -------- Mode and Input Management -------- //
|
||||||
isValidActionForMode(action, mode) {
|
isValidActionForMode(action, mode) {
|
||||||
const allowedActionsSet = this.config.mode.allowedActions[mode] || [];
|
const allowedActionsSet = this.config.mode.allowedActions[mode] || [];
|
||||||
|
|||||||
Reference in New Issue
Block a user