package classes.holonControlUnit; import java.util.ArrayList; import java.util.HashMap; import classes.Holon; import classes.HolonElement; import classes.holonControlUnit.messages.Message; import classes.holonControlUnit.messages.StateMsg; import classes.holonControlUnit.messages.StateRequestMsg; /** * aggregates all states from sub holons and forwards the resulting own state to the state assembler * @author Jonas * */ public class StateEstimator { /* indicates the current state of the holon */ public enum StateIndicator { /* everything runs as expected, all parameters are inside their tresholds */ DESIRED, /* everything is still as expected except for minor deviations, parts may be endangered/dysfunctional */ ENDANGERED, /* stability/functionality of holon is not guaranteed */ DYSFUNCTIONAL } private final float POWER_TRESHOLD = 0.95f; private HolonControlUnit hcu; private StateIndicator stateInd; private float powerUsage; private HashMap childStates; public StateEstimator(HolonControlUnit hcu) { this.hcu = hcu; this.stateInd = StateIndicator.DESIRED; } public StateIndicator getStateIndicator() { return stateInd; } /** * Depth-first computation * aggregates childrens state first, then computes own state */ public void computeState(int timeStep) { //request childrens state this.childStates = new HashMap(); ArrayList children = this.hcu.getHierarchyController().getSubHolons(); for(String child : children) { //send request to child this.hcu.getCommunicator().sendMsg(child, Message.Type.STATE_REQUEST, this.hcu.getCommunicator().getGson().toJson(new StateRequestMsg(timeStep))); } //wait for sub holons to compute state and send it if(this.childStates.size() < children.size()) { System.err.println("Something went wrong while computing state of "+this.hcu.getHolon().getUniqueID()); System.err.println("\tchildStates "+childStates); System.err.println("\tchildren "+children); return; } //aggregate cub holons state this.powerUsage = 0; for(String s : this.childStates.keySet()) { this.powerUsage += this.childStates.get(s).getPowerUsage(); } //add state from holon elements Holon holon = this.hcu.getHolon(); if(holon.isPhysical) { this.powerUsage += holon.getHolonObject().getEnergyAtTimeStep(timeStep); } if(this.powerUsage < this.POWER_TRESHOLD * this.hcu.getStateAssembler().getDesiredPowerUsage()) { this.stateInd = StateIndicator.DESIRED; } else { this.stateInd = StateIndicator.ENDANGERED; } } public void receiveState(String sender, StateMsg stateMsg) { if(this.childStates == null) return; this.childStates.put(sender, stateMsg); } public void receiveStateRequest(String sender, StateRequestMsg req) { computeState(req.getTimeStep()); //send current state to sender/super holon StateMsg stateMsg = new StateMsg(this.powerUsage); String body = this.hcu.getCommunicator().getGson().toJson(stateMsg); this.hcu.getCommunicator().sendMsg(sender, Message.Type.STATE, body); } public float getPowerUsage() { return this.powerUsage; } }