package ui.controller; import java.util.ArrayList; import java.util.HashMap; import classes.CpsEdge; import classes.CpsNode; import classes.CpsObject; import classes.HolonElement; import classes.HolonObject; import classes.HolonSwitch; import classes.subNet; import ui.model.Model; import ui.view.MyCanvas; public class SimulationManager { private Model model; private ArrayList objectsToHandle; private ArrayList allConnections; private ArrayList subNets; private MyCanvas canvas; private int timeStep; private boolean simMode; private HashMap tagTable = new HashMap(); public SimulationManager(Model m){ canvas = null; model = m; subNets = new ArrayList(); simMode = model.getIsSimulation(); } /** * calculates the flow of the edges and the supply for objects * @param x */ public void calculateStateForTimeStep(int x){ simMode = model.getIsSimulation(); timeStep = x; searchForSubNets(); for(subNet singleSubNet: subNets){ ResetConnections(singleSubNet.getObjects().get(0), new ArrayList(), new ArrayList()); } for(subNet singleSubNet: subNets){ float production = calculateEnergy("prod", singleSubNet, timeStep); float consumption = calculateEnergy("cons", singleSubNet, timeStep); float minConsumption = calculateMinimumEnergy( singleSubNet, timeStep); setFlow(singleSubNet, simMode); for(HolonObject hl: singleSubNet.getObjects()){ if(!(hl.getState() == 0) && !(hl.getState() == 3)){ for(int i = 0; i < hl.getConnections().size(); i++){ CpsEdge edge = hl.getConnectedTo().get(i); if(edge.getState() && edge.getFlow() > 0 || edge.getCapacity() == -1){ // 0 = no energy, 1 = not supplied, 2 = supplied, 3 = producer, 4 = partially supplied if((production + consumption) >= 0){ hl.setState(2); } if((production + consumption) < 0 ){ if((production + minConsumption) >= 0){ hl.setState(4); }else if(hl.checkIfPartiallySupplied(timeStep)){ hl.setState(4); }else { hl.setState(1); } } break; } hl.setState(1); } if(hl.checkIfPartiallySupplied(timeStep) && !(hl.getState() == 2)){ hl.setState(4); } } } } canvas.repaint(); } public void setFlow(subNet sN, boolean simulation){ if(simulation){ setFlowSimulation(sN); } else { setFlowModelation(sN); } } public void setFlowModelation(subNet sN){ for(HolonObject hl: sN.getObjects()){ float energy = hl.getCurrentEnergyAtTimeStep(timeStep); if(energy > 0){ for(CpsEdge e : sN.getEdges()){ e.setFlow(e.getFlow() + energy); e.calculateState(simMode); } } } } public void setFlowSimulation(subNet sN){ ArrayList producers = new ArrayList(); CpsObject tmp = null; tagTable = new HashMap(); for(HolonObject hl: sN.getObjects()){ float energy = hl.getCurrentEnergyAtTimeStep(timeStep); if(energy > 0){ tagTable.put(hl.getID(), energy); for(CpsEdge edge: hl.getConnections()){ if(edge.getState()){ if(edge.getA().getID() == hl.getID()){ edge.getB().addTag(hl.getID()); tmp = edge.getB(); } if(edge.getB().getID() == hl.getID()){ edge.getA().addTag(hl.getID()); tmp = edge.getA(); } edge.setFlow(edge.getFlow() + energy); edge.calculateState(true); edge.addTag(hl.getID()); if(edge.getState() && !producers.contains(tmp)){ producers.add(tmp); } } } } } setFlowSimRec(producers); } public void setFlowSimRec(ArrayList nodes){ ArrayList newNodes = new ArrayList(); CpsObject tmp = null; if(nodes.size() != 0){ for(CpsObject cps: nodes){ for(CpsEdge edge: cps.getConnections()){ for(Integer tag: cps.getTag()){ if(edge.getState() && !(edge.getTags().contains(tag))){ edge.setFlow(edge.getFlow() + tagTable.get(tag)); System.out.println(cps.getID() + " has tags:" + getString(cps)); edge.addTag(tag); if(edge.getA().getID() == cps.getID()){ tmp = edge.getB(); tmp.setTags(mergeLists(tmp.getTag(), cps.getTag())); } if(edge.getB().getID() == cps.getID()){ tmp = edge.getA(); tmp.setTags(mergeLists(tmp.getTag(), cps.getTag())); } if(edge.getState() && !(newNodes.contains(tmp))){ newNodes.add(tmp); } } } edge.calculateState(true); } } setFlowSimRec(newNodes); } } public String getString(CpsObject cps){ String result = ""; for(Integer i:cps.getTag()){ result = result + ", " + i; } return result; } public ArrayList mergeLists(ArrayList A, ArrayList B){ ArrayList result = new ArrayList(); for(Integer i: A){ if(!(B.contains(i))){ result.add(i); } } result.addAll(B); return result; } public void ResetConnections(CpsObject cps, ArrayList visitedObj, ArrayList visitedEdges){ visitedObj.add(cps.getID()); cps.resetTags(); for(CpsEdge e: cps.getConnections()){ if(!(visitedEdges.contains(e))){ e.setFlow(0); e.calculateState(simMode); e.setTags(new ArrayList()); visitedEdges.add(e); if(!(visitedObj.contains(e.getA().getID()))){ ResetConnections(e.getA(), visitedObj, visitedEdges); e.getA().resetTags(); } if(!(visitedObj.contains(e.getB().getID()))){ ResetConnections(e.getB(), visitedObj, visitedEdges); e.getB().resetTags(); } } } } /** * calculates the energy of either all producers or consumers * @param type * @param sN * @return */ public float calculateEnergy(String type, subNet sN, int x){ float energy = 0; for(HolonObject hl: sN.getObjects()){ if(type.equals("prod")){ if(hl.getCurrentEnergyAtTimeStep(x) > 0){ energy = energy + hl.getCurrentEnergyAtTimeStep(x); hl.setState(3); } } if(type.equals("cons")){ if(hl.getCurrentEnergyAtTimeStep(x) < 0){ energy = energy + hl.getCurrentEnergyAtTimeStep(x); hl.setState(1); } } if(hl.getCurrentEnergyAtTimeStep(x) == 0){ hl.setState(0); } } return energy; } public float calculateMinimumEnergy(subNet sN, int x){ float min = 0; float minElement = 0; for(HolonObject hl: sN.getObjects()){ if(hl.getElements().size() > 0 && hl.getElements().get(0).getTotalEnergyAtTimeStep(x) < 0 ){ minElement = hl.getElements().get(0).getTotalEnergyAtTimeStep(x); } for(HolonElement he: hl.getElements()){ if(minElement < he.getTotalEnergyAtTimeStep(x) && he.getTotalEnergyAtTimeStep(x) < 0){ minElement = he.getTotalEnergyAtTimeStep(x); } } min = min + minElement; } return min; } /** * generates all subNets from all objectsToHandle */ public void searchForSubNets(){ subNets = new ArrayList(); boolean end = false; int i = 0; CpsObject cps; if(objectsToHandle.size() > 0){ while(!end){ cps = objectsToHandle.get(i); subNet singleSubNet = new subNet(new ArrayList(), new ArrayList(), new ArrayList()); singleSubNet = buildSubNet(cps, new ArrayList(), singleSubNet); if(singleSubNet.getObjects().size() != 0){ subNets.add(singleSubNet); } if(0 == objectsToHandle.size()){ end = true; } } } } /** * recursivly generates a subnet of all objects, that one specific object is connected to * @param cps * @param visited * @param sN * @return */ public subNet buildSubNet(CpsObject cps, ArrayList visited, subNet sN){ visited.add(cps.getID()); if(cps instanceof HolonObject){ sN.getObjects().add((HolonObject) cps); } if(cps instanceof HolonSwitch){ sN.getSwitches().add((HolonSwitch) cps); } removeFromToHandle(cps.getID()); CpsObject A; CpsObject B; for(CpsEdge edge: cps.getConnections()){ A = edge.getA(); B = edge.getB(); if(!(cps instanceof HolonSwitch)){ if(!(sN.getEdges().contains(edge))){ sN.getEdges().add(edge); } } if(!visited.contains(A.getID()) && legitState(A, cps)){ sN = buildSubNet(A, visited, sN); } if(!visited.contains(B.getID()) && legitState(B, cps)){ sN = buildSubNet(B, visited, sN); } } return sN; } public boolean legitState(CpsObject neighbor, CpsObject current){ if(current instanceof HolonSwitch){ if(((HolonSwitch) current).getActiveAt()[timeStep]){ if(neighbor instanceof HolonSwitch){ if(((HolonSwitch) neighbor).getActiveAt()[timeStep]){ return true; }else{ return false; } } }else{ return false; } } return true; } /** * removes an Object that already has been handled with * @param id */ public void removeFromToHandle(int id){ for(int i = 0; i < objectsToHandle.size(); i++){ if(objectsToHandle.get(i).getID() == id){ objectsToHandle.remove(i); } } } /** * ensures that objectsToHandle only contains HolonObjects */ public void cleanObjectsToHandle(){ for(int i = 0; i < objectsToHandle.size(); i++){ if(!(objectsToHandle.get(i) instanceof HolonObject)){ objectsToHandle.remove(i); } } } /** * copies the data of an array of Objects * @param toCopy */ public void copyObjects(ArrayList toCopy){ objectsToHandle = new ArrayList(); for(CpsObject cps: toCopy){ objectsToHandle.add(cps); } } /** * Prints the Components auf all subnets */ public void printNet(){ for(int i = 0; i < subNets.size(); i++){ System.out.println("SUBNET NR:" + i); System.out.println(" Objects:"); for(int j = 0; j < subNets.get(i).getObjects().size(); j++){ HolonObject hl = subNets.get(i).getObjects().get(j); System.out.println(" " + hl.getName() + " " + hl.getID()); } System.out.println(" Edges:"); for(int j = 0; j < subNets.get(i).getEdges().size(); j++){ CpsEdge edge = subNets.get(i).getEdges().get(j); System.out.println(" " + edge.getA().getName() + " connected To " + edge.getB().getName()); } System.out.println(" Switches:"); for(int j = 0; j < subNets.get(i).getSwitches().size(); j++){ HolonSwitch sw = subNets.get(i).getSwitches().get(j); System.out.println(" " + sw.getName() + " " + sw.getID() + " State:" + sw.getActiveAt()[timeStep]); } } } public void setCanvas(MyCanvas can){ canvas = can; } public void reset(){ copyObjects(model.getObjectsOnCanvas()); } }