SimulationManager.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. package ui.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import classes.AbstractCpsObject;
  5. import classes.CpsEdge;
  6. import classes.CpsUpperNode;
  7. import classes.HolonElement;
  8. import classes.HolonObject;
  9. import classes.HolonSwitch;
  10. import classes.SubNet;
  11. import ui.model.Model;
  12. import ui.view.FlexiblePane;
  13. import ui.view.MyCanvas;
  14. /**
  15. * Controller for Simulation.
  16. *
  17. * @author Gruppe14
  18. */
  19. public class SimulationManager {
  20. private Model model;
  21. private ArrayList<AbstractCpsObject> objectsToHandle;
  22. private ArrayList<CpsEdge> allConnections;
  23. private ArrayList<SubNet> subNets;
  24. private ArrayList<CpsEdge> brokenEdges;
  25. private MyCanvas canvas;
  26. private int timeStep;
  27. private HashMap<Integer, Float> tagTable = new HashMap<Integer, Float>();
  28. private FlexiblePane flexPane;
  29. /**
  30. * Constructor.
  31. *
  32. * @param m
  33. * Model
  34. */
  35. public SimulationManager(Model m) {
  36. canvas = null;
  37. model = m;
  38. subNets = new ArrayList<SubNet>();
  39. brokenEdges = new ArrayList<CpsEdge>();
  40. }
  41. /**
  42. * calculates the flow of the edges and the supply for objects.
  43. *
  44. * @param x
  45. * current Iteration
  46. */
  47. public void calculateStateForTimeStep(int x) {
  48. reset();
  49. timeStep = x;
  50. searchForSubNets();
  51. for (SubNet singleSubNet : subNets) {
  52. resetConnections(singleSubNet.getObjects().get(0), new ArrayList<Integer>(), new ArrayList<CpsEdge>());
  53. }
  54. for (SubNet singleSubNet : subNets) {
  55. float production = calculateEnergy("prod", singleSubNet, timeStep);
  56. float consumption = calculateEnergy("cons", singleSubNet, timeStep);
  57. float minConsumption = calculateMinimumEnergy(singleSubNet, timeStep);
  58. setFlowSimulation(singleSubNet);
  59. for (HolonObject hl : singleSubNet.getObjects()) {
  60. if (!(hl.getState() == 0) && !(hl.getState() == 3)) {
  61. for (int i = 0; i < hl.getConnections().size(); i++) {
  62. CpsEdge edge = hl.getConnectedTo().get(i);
  63. if (edge.getState() && edge.getFlow() > 0 || edge.getCapacity() == -1) {
  64. // 0 = no energy, 1 = not supplied, 2 = supplied, 3
  65. // = producer, 4 = partially supplied
  66. if ((production + consumption) >= 0) {
  67. hl.setState(2);
  68. }
  69. if ((production + consumption) < 0) {
  70. if ((production + minConsumption) >= 0) {
  71. hl.setState(4);
  72. } else if (hl.checkIfPartiallySupplied(timeStep)) {
  73. hl.setState(4);
  74. } else {
  75. hl.setState(1);
  76. }
  77. }
  78. break;
  79. }
  80. hl.setState(1);
  81. }
  82. if (hl.checkIfPartiallySupplied(timeStep) && !(hl.getState() == 2)) {
  83. hl.setState(4);
  84. }
  85. }
  86. }
  87. }
  88. canvas.repaint();
  89. //printNet();
  90. flexPane.recalculate();
  91. }
  92. /**
  93. * Set Flow Simulation.
  94. *
  95. * @param sN
  96. * Subnet
  97. */
  98. public void setFlowSimulation(SubNet sN) {
  99. ArrayList<AbstractCpsObject> producers = new ArrayList<AbstractCpsObject>();
  100. AbstractCpsObject tmp = null;
  101. tagTable = new HashMap<Integer, Float>();
  102. for (HolonObject hl : sN.getObjects()) {
  103. float energy = hl.getCurrentEnergyAtTimeStep(timeStep);
  104. if (energy > 0) {
  105. tagTable.put(hl.getId(), energy);
  106. hl.addTag(hl.getId());
  107. for (CpsEdge edge : hl.getConnections()) {
  108. if (edge.getState()) {
  109. if (edge.getA().getId() == hl.getId()) {
  110. edge.getB().addTag(hl.getId());
  111. tmp = edge.getB();
  112. }
  113. if (edge.getB().getId() == hl.getId()) {
  114. edge.getA().addTag(hl.getId());
  115. tmp = edge.getA();
  116. }
  117. edge.setFlow(edge.getFlow() + energy);
  118. edge.calculateState();
  119. edge.addTag(hl.getId());
  120. if (edge.getState() && !producers.contains(tmp)) {
  121. if(tmp instanceof HolonSwitch){
  122. if(((HolonSwitch)tmp).getState(timeStep)){
  123. producers.add(tmp);
  124. }
  125. }else if(!(tmp instanceof CpsUpperNode)){
  126. producers.add(tmp);
  127. }
  128. }
  129. }
  130. }
  131. }
  132. }
  133. setFlowSimRec(producers, 0);
  134. }
  135. /**
  136. * Set Flow Rimulation Rec.
  137. *
  138. * @param nodes
  139. * the nodes
  140. * @param iter
  141. * the Iteration
  142. */
  143. public void setFlowSimRec(ArrayList<AbstractCpsObject> nodes, int iter) {
  144. ArrayList<AbstractCpsObject> newNodes = new ArrayList<AbstractCpsObject>();
  145. ArrayList<CpsEdge> changedEdges = new ArrayList<CpsEdge>();
  146. AbstractCpsObject tmp;
  147. if(nodes.size() != 0){
  148. for(AbstractCpsObject cps: nodes){
  149. if(legitState(cps)){
  150. for(CpsEdge edge: cps.getConnections()){
  151. if(edge.getState() && (!(edge.containsTags(edge.getTags(), cps.getTag())))){
  152. if(edge.getA().getId() == cps.getId()){
  153. tmp = edge.getB();
  154. }else{
  155. tmp = edge.getA();
  156. }
  157. for(Integer tag: cps.getTag()){
  158. if(!(edge.getTags().contains(tag)) && !(edge.getPseudoTags().contains(tag))){
  159. edge.setFlow(edge.getFlow() + tagTable.get(tag));
  160. edge.addTag(tag);
  161. }
  162. }
  163. // uppernodes do not spread energy
  164. if(!(tmp instanceof CpsUpperNode)){
  165. for(Integer tag: tmp.getTag()){
  166. if(!(edge.getTags().contains(tag)) && tagTable.get(tag) != null && !(edge.getPseudoTags().contains(tag))){
  167. edge.setFlow(edge.getFlow() + tagTable.get(tag));
  168. edge.addPseudoTag(tag);
  169. changedEdges.add(edge);
  170. }
  171. }
  172. }
  173. edge.calculateState();
  174. if(edge.getState() && !(tmp instanceof CpsUpperNode)){
  175. tmp.addAllPseudoTags(cps.getTag());
  176. if(!newNodes.contains(tmp)){
  177. newNodes.add(tmp);
  178. }
  179. }
  180. }
  181. }
  182. }
  183. }
  184. setPseudoTags(newNodes, changedEdges);
  185. setFlowSimRec(newNodes, iter+1);
  186. }
  187. }
  188. /**
  189. * Set the Pseudo Tags.
  190. *
  191. * @param nodes
  192. * Array of AbstractCpsObjects
  193. */
  194. public void setPseudoTags(ArrayList<AbstractCpsObject> nodes, ArrayList<CpsEdge> edges) {
  195. for (AbstractCpsObject node : nodes) {
  196. node.recalculateTags();
  197. node.setPseudoTags(new ArrayList<Integer>());
  198. }
  199. for(CpsEdge edge : edges){
  200. edge.recalculateTags();
  201. edge.setPseudoTag(new ArrayList<Integer>());
  202. }
  203. }
  204. /**
  205. * Print the nodes.
  206. *
  207. * @param nodes
  208. * Array of AbstractCpsObject
  209. */
  210. public void printNodes(ArrayList<AbstractCpsObject> nodes) {
  211. System.out.println("new Nodes:");
  212. for (AbstractCpsObject node : nodes) {
  213. System.out.println(node.getId());
  214. }
  215. }
  216. /**
  217. * Get String.
  218. *
  219. * @param tags
  220. * the tags
  221. * @return the String
  222. */
  223. public String getString(ArrayList<Integer> tags) {
  224. String result = "";
  225. for (Integer i : tags) {
  226. result = result + ", " + i;
  227. }
  228. return result;
  229. }
  230. /**
  231. * Merge the Lists.
  232. *
  233. * @param a
  234. * first liust
  235. * @param b
  236. * second list
  237. * @return the Result
  238. */
  239. public ArrayList<Integer> mergeLists(ArrayList<Integer> a, ArrayList<Integer> b) {
  240. ArrayList<Integer> result = new ArrayList<Integer>();
  241. for (Integer i : a) {
  242. if (!(result.contains(i))) {
  243. result.add(i);
  244. }
  245. }
  246. for (Integer j : b) {
  247. if (!(result.contains(j))) {
  248. result.add(j);
  249. }
  250. }
  251. return result;
  252. }
  253. /**
  254. * Reset the Connection.
  255. *
  256. * @param cps
  257. * CpsObject
  258. * @param visitedObj
  259. * the visited Objects
  260. * @param visitedEdges
  261. * the visited Edges
  262. */
  263. public void resetConnections(AbstractCpsObject cps, ArrayList<Integer> visitedObj,
  264. ArrayList<CpsEdge> visitedEdges) {
  265. visitedObj.add(cps.getId());
  266. cps.resetTags();
  267. for (CpsEdge e : cps.getConnections()) {
  268. if (!(visitedEdges.contains(e))) {
  269. e.setFlow(0);
  270. e.calculateState();
  271. e.setTags(new ArrayList<Integer>());
  272. visitedEdges.add(e);
  273. if (!(visitedObj.contains(e.getA().getId()))) {
  274. resetConnections(e.getA(), visitedObj, visitedEdges);
  275. e.getA().resetTags();
  276. }
  277. if (!(visitedObj.contains(e.getB().getId()))) {
  278. resetConnections(e.getB(), visitedObj, visitedEdges);
  279. e.getB().resetTags();
  280. }
  281. }
  282. }
  283. }
  284. /**
  285. * calculates the energy of either all producers or consumers.
  286. *
  287. * @param type
  288. * Type
  289. * @param sN
  290. * Subnet
  291. * @param x
  292. * Integer
  293. *
  294. * @return The Energy
  295. */
  296. public float calculateEnergy(String type, SubNet sN, int x) {
  297. float energy = 0;
  298. for (HolonObject hl : sN.getObjects()) {
  299. if (type.equals("prod")) {
  300. if (hl.getCurrentEnergyAtTimeStep(x) > 0) {
  301. energy = energy + hl.getCurrentEnergyAtTimeStep(x);
  302. hl.setState(3);
  303. }
  304. }
  305. if (type.equals("cons")) {
  306. if (hl.getCurrentEnergyAtTimeStep(x) < 0) {
  307. energy = energy + hl.getCurrentEnergyAtTimeStep(x);
  308. hl.setState(1);
  309. }
  310. }
  311. if (hl.getCurrentEnergyAtTimeStep(x) == 0) {
  312. hl.setState(0);
  313. }
  314. }
  315. return energy;
  316. }
  317. /**
  318. * Calculate the Minimum Energy.
  319. *
  320. * @param sN
  321. * Subnet
  322. * @param x
  323. * Integer
  324. * @return the Calculated minimum Energy
  325. */
  326. public float calculateMinimumEnergy(SubNet sN, int x) {
  327. float min = 0;
  328. float minElement = 0;
  329. for (HolonObject hl : sN.getObjects()) {
  330. if (hl.getElements().size() > 0 && hl.getElements().get(0).getTotalEnergyAtTimeStep(x) < 0) {
  331. minElement = hl.getElements().get(0).getTotalEnergyAtTimeStep(x);
  332. }
  333. for (HolonElement he : hl.getElements()) {
  334. if (minElement < he.getTotalEnergyAtTimeStep(x) && he.getTotalEnergyAtTimeStep(x) < 0) {
  335. minElement = he.getTotalEnergyAtTimeStep(x);
  336. }
  337. }
  338. min = min + minElement;
  339. }
  340. return min;
  341. }
  342. /**
  343. * generates all subNets from all objectsToHandle.
  344. */
  345. public void searchForSubNets() {
  346. subNets = new ArrayList<SubNet>();
  347. brokenEdges.clear();
  348. boolean end = false;
  349. int i = 0;
  350. AbstractCpsObject cps;
  351. if (objectsToHandle.size() > 0) {
  352. while (!end) {
  353. cps = objectsToHandle.get(i);
  354. SubNet singleSubNet = new SubNet(new ArrayList<HolonObject>(), new ArrayList<CpsEdge>(),
  355. new ArrayList<HolonSwitch>());
  356. singleSubNet = buildSubNet(cps, new ArrayList<Integer>(), singleSubNet);
  357. if (singleSubNet.getObjects().size() != 0) {
  358. subNets.add(singleSubNet);
  359. }
  360. if (0 == objectsToHandle.size()) {
  361. end = true;
  362. }
  363. }
  364. }
  365. }
  366. /**
  367. * recursivly generates a subnet of all objects, that one specific object is
  368. * connected to.
  369. *
  370. * @param cps
  371. * AbstractCpsObject
  372. * @param visited
  373. * visited Array of Integer
  374. * @param sN
  375. * Subnets
  376. * @return Subnet
  377. */
  378. public SubNet buildSubNet(AbstractCpsObject cps, ArrayList<Integer> visited, SubNet sN) {
  379. visited.add(cps.getId());
  380. if (cps instanceof HolonObject) {
  381. sN.getObjects().add((HolonObject) cps);
  382. }
  383. if (cps instanceof HolonSwitch) {
  384. sN.getSwitches().add((HolonSwitch) cps);
  385. }
  386. removeFromToHandle(cps.getId());
  387. AbstractCpsObject a;
  388. AbstractCpsObject b;
  389. for (CpsEdge edge : cps.getConnections()) {
  390. if(edge.getState()){
  391. a = edge.getA();
  392. b = edge.getB();
  393. if (!(cps instanceof HolonSwitch)) {
  394. if (!(sN.getEdges().contains(edge))) {
  395. sN.getEdges().add(edge);
  396. }
  397. }
  398. if(cps instanceof HolonSwitch && ((HolonSwitch)cps).getState(timeStep)){
  399. if (!(sN.getEdges().contains(edge))) {
  400. sN.getEdges().add(edge);
  401. }
  402. }
  403. if (!visited.contains(a.getId()) && legitState(cps) && !(a instanceof CpsUpperNode)) {
  404. sN = buildSubNet(a, visited, sN);
  405. }
  406. if (!visited.contains(b.getId()) && legitState(cps) && !(b instanceof CpsUpperNode)) {
  407. sN = buildSubNet(b, visited, sN);
  408. }
  409. if(a instanceof CpsUpperNode && a.getId() != cps.getId()){
  410. edge.setConnected(2);
  411. checkForConnectedStates(b, (CpsUpperNode)a, edge);
  412. }
  413. if(b instanceof CpsUpperNode && b.getId() != cps.getId()){
  414. edge.setConnected(2);
  415. checkForConnectedStates(a, (CpsUpperNode)b, edge);
  416. }
  417. }else{
  418. brokenEdges.add(edge);
  419. }
  420. }
  421. return sN;
  422. }
  423. /**
  424. * is the Switch in a legitimate State.
  425. *
  426. * @param neighbor AbstractCpsObject
  427. * @param current AbstractCpsObject
  428. * @return boolean
  429. */
  430. public boolean legitState(AbstractCpsObject current) {
  431. if (current instanceof HolonSwitch) {
  432. if (((HolonSwitch) current).getState(timeStep)) {
  433. return true;
  434. }else{
  435. return false;
  436. }
  437. }
  438. return true;
  439. }
  440. /**
  441. * removes an Object that already has been handled with.
  442. *
  443. * @param id the Object ID
  444. */
  445. public void removeFromToHandle(int id) {
  446. for (int i = 0; i < objectsToHandle.size(); i++) {
  447. if (objectsToHandle.get(i).getId() == id) {
  448. objectsToHandle.remove(i);
  449. }
  450. }
  451. }
  452. /**
  453. * ensures that objectsToHandle only contains HolonObjects.
  454. */
  455. public void cleanObjectsToHandle() {
  456. for (int i = 0; i < objectsToHandle.size(); i++) {
  457. if (!(objectsToHandle.get(i) instanceof HolonObject)) {
  458. objectsToHandle.remove(i);
  459. }
  460. }
  461. }
  462. /**
  463. * copies the data of an array of Objects.
  464. *
  465. * @param toCopy the ArrayList of CpsObjects co Copy
  466. */
  467. public void copyObjects(ArrayList<AbstractCpsObject> toCopy) {
  468. for (AbstractCpsObject cps : toCopy) {
  469. if(cps instanceof CpsUpperNode){
  470. copyObjects(((CpsUpperNode)cps).getNodes());
  471. }else{
  472. objectsToHandle.add(cps);
  473. }
  474. }
  475. }
  476. /**
  477. * Prints the Components auf all subnets.
  478. */
  479. public void printNet() {
  480. for (int i = 0; i < subNets.size(); i++) {
  481. System.out.println("SUBNET NR:" + i);
  482. System.out.println(" Objects:");
  483. for (int j = 0; j < subNets.get(i).getObjects().size(); j++) {
  484. HolonObject hl = subNets.get(i).getObjects().get(j);
  485. System.out.println(" " + hl.getName() + " " + hl.getId());
  486. }
  487. System.out.println(" Edges:");
  488. for (int j = 0; j < subNets.get(i).getEdges().size(); j++) {
  489. CpsEdge edge = subNets.get(i).getEdges().get(j);
  490. System.out.println(" " + edge.getA().getName() + " connected To " + edge.getB().getName());
  491. }
  492. System.out.println(" Switches:");
  493. for (int j = 0; j < subNets.get(i).getSwitches().size(); j++) {
  494. HolonSwitch sw = subNets.get(i).getSwitches().get(j);
  495. System.out.println(" " + sw.getName() + " " + sw.getId() + " State:" + sw.getActiveAt()[timeStep]);
  496. }
  497. }
  498. }
  499. /**
  500. * Set the Canvas.
  501. *
  502. * @param can
  503. * the Canvas
  504. */
  505. public void setCanvas(MyCanvas can) {
  506. canvas = can;
  507. }
  508. /**
  509. * Reset all Data to the current state of the Model.
  510. */
  511. public void reset() {
  512. objectsToHandle = new ArrayList<AbstractCpsObject>();
  513. copyObjects(model.getObjectsOnCanvas());
  514. }
  515. /**
  516. * Resets the State of all Edges
  517. */
  518. public void resetEdges(){
  519. for(CpsEdge e: brokenEdges){
  520. e.setState(true);
  521. }
  522. }
  523. /**
  524. * Resets the State for the whole Simulation Model
  525. */
  526. public void resetSimulation(){
  527. reset();
  528. resetEdges();
  529. }
  530. /**
  531. * Get all Subnets.
  532. *
  533. * @return all Subnets
  534. */
  535. public ArrayList<SubNet> getSubNets() {
  536. return subNets;
  537. }
  538. /**
  539. * Get broken Edges
  540. */
  541. public ArrayList<CpsEdge> getBrokenEdges(){
  542. return brokenEdges;
  543. }
  544. /**
  545. * checks wether a given object is connected to an object inside the upperNode.
  546. * if yes, the state for the edge is changed in "connected" or "not connected"
  547. * @param cps
  548. * @param cUNode
  549. */
  550. public void checkForConnectedStates(AbstractCpsObject cps, CpsUpperNode cUNode, CpsEdge theEdge){
  551. AbstractCpsObject tmp;
  552. for(CpsEdge edge: cps.getConnections()){
  553. if(edge.getA().getId() == cps.getId()){
  554. tmp = edge.getB();
  555. } else{
  556. tmp = edge.getA();
  557. }
  558. if(cUNode.getNodes().contains(tmp)){
  559. if(tmp instanceof CpsUpperNode){
  560. checkForConnectedStates(cps, (CpsUpperNode)tmp, theEdge);
  561. }else{
  562. theEdge.setConnected(1);
  563. break;
  564. }
  565. }
  566. }
  567. }
  568. public void setFlexiblePane(FlexiblePane fp) {
  569. flexPane = fp;
  570. }
  571. public FlexiblePane getFlexiblePane(){
  572. return flexPane;
  573. }
  574. }