import java.awt.*; import java.util.Date; import java.util.Iterator; import java.util.Vector; public class TreeAlgDraw implements ISimUICallback, ISwarmDraw { long m_nDrawEveryMilli; double m_lfStoreEveryMilliReal; double m_lfStoreEverySim; double m_lfLastSimStored; Date m_lastDateDrawn; Date m_dateZeroReference; double m_lfSecRealPerSecSim; double m_lfSecSimPerSecReal; IEnvironment m_env; IEnvDraw m_envDraw; IProjection m_xformToScreen; SwarmState m_stateToDraw; SynchronousStateQueue m_stateQueue; int m_nFrameCacheSize; CommGraph m_commGraph; boolean m_bDrawAllLinks; TreeAlgDraw() { m_xformToScreen = null; m_nDrawEveryMilli = 100; m_lfSecRealPerSecSim = 1.0; m_lfSecSimPerSecReal = 1.0/m_lfSecRealPerSecSim; m_dateZeroReference = new Date(); m_lastDateDrawn = m_dateZeroReference; m_stateToDraw = null; m_stateQueue = new SynchronousStateQueue(); m_lfStoreEveryMilliReal = 100.0; m_lfStoreEverySim = m_lfSecSimPerSecReal*0.001* m_lfStoreEveryMilliReal; m_lfLastSimStored = -m_lfStoreEverySim-1.0; m_nFrameCacheSize=60; m_commGraph = null; m_bDrawAllLinks = true; } public Date simTimeToRealTime(double lfSimTime) { return new Date(m_dateZeroReference.getTime() + (long)(m_lfSecRealPerSecSim*lfSimTime*1000)); } public double realTimeToSimTime(Date dateRealTime) { return (double)(dateRealTime.getTime()- m_dateZeroReference.getTime())* 0.001*m_lfSecSimPerSecReal; } public void setDrawAllLinks(boolean bDrawAllLinks) { m_bDrawAllLinks = bDrawAllLinks; } /** * does nothing in this implementation */ public void setStaticEnvironment(IEnvironment env) { m_env = env.makeCopy(); } /** * does nothing in this implementation */ public synchronized void setDynamicEnvironment(IEnvironment env) { m_env = env.makeCopy(); } public void setEnvDraw(IEnvDraw envDraw) { m_envDraw = envDraw; } Vector m_vecAgents; {m_vecAgents = new Vector(); } public void addDrawAgent(IDrawAgent agent) { m_vecAgents.add(agent); } /** * Pass in a projection class to handle mapping points to * screen coords. */ public void setProjection(IProjection proj) { m_xformToScreen = proj; } public void scaleProjection(int nNewX, int nNewY) {} public void xlateProjection(int nXOff, int nYOff) {} public void reDraw(java.awt.Graphics g) { Date currTime = new Date(); if(currTime.getTime() - m_lastDateDrawn.getTime() > m_nDrawEveryMilli) { m_lastDateDrawn = currTime; m_stateQueue.removeBefore(realTimeToSimTime(currTime)); } m_stateToDraw = m_stateQueue.getLeastRecent(m_stateToDraw); if(m_stateToDraw == null) { return; } double [] arrLfPoints = m_stateToDraw.accessPositions(); StateBundle [] arrAgentStates = m_stateToDraw.accessStates(); CommGraph currGraph = m_stateToDraw.getGraph(); if(m_xformToScreen == null) { g.setColor( globalsUI.getColorMap().getColor(0)); g.fillRect(0,0,20000,20000); if(m_envDraw != null) { m_envDraw.draw(m_env, m_xformToScreen, g); } for(int nDrwAgnt = 0; nDrwAgnt < m_vecAgents.size(); ++nDrwAgnt) { IDrawAgent drawAgent = m_vecAgents.elementAt(nDrwAgnt); drawAgent.draw(g, m_xformToScreen,arrLfPoints,arrAgentStates, currGraph); } g.setColor( globalsUI.getColorMap().getColor(1) ); g.setColor(globalsUI.getColorMap().getColor(2)); g.drawOval(50,50,10,10); if(arrLfPoints != null) { for(int i = 0; i < arrLfPoints.length; i += 2) { g.setColor(globalsUI.getColorMap().getColor(3)); g.drawOval((int)arrLfPoints[i], (int)arrLfPoints[i+1], 10, 10); } } } else { g.setColor( globalsUI.getColorMap().getColor(0)); g.fillRect(m_xformToScreen.left(), m_xformToScreen.top(), m_xformToScreen.left() + m_xformToScreen.width(), m_xformToScreen.top() + m_xformToScreen.height()); if(m_envDraw != null) { m_envDraw.draw(m_env, m_xformToScreen, g); } for(int nDrwAgnt = 0; nDrwAgnt < m_vecAgents.size(); ++nDrwAgnt) { IDrawAgent drawAgent = m_vecAgents.elementAt(nDrwAgnt); drawAgent.draw(g, m_xformToScreen,arrLfPoints,arrAgentStates, currGraph); } g.setColor( globalsUI.getColorMap().getColor(1) ); if(arrLfPoints != null) { int nRad = 10; try { nRad = m_xformToScreen.scaleRadius(0.01); } catch(Exception e) { double [] lfTmp = new double [2]; lfTmp[0] = 7.07; lfTmp[1] = 7.07; int [] nTmp = m_xformToScreen.scaleVector(lfTmp, 0); nRad = (int)Math.sqrt(nTmp[0]*nTmp[0]+nTmp[1]*nTmp[1]); } if(nRad < 1) { nRad = 10; } IProjection p = m_xformToScreen; double [] pts = arrLfPoints; int nPts = pts.length/2; // so lines don't run over 80 characters if(currGraph != null) { g.setColor(globalsUI.getColorMap().getColor(2)); for(int i = 0; i < nPts; ++i) { g.drawOval(p.getScreenComp(0, pts, 2*i)-nRad*2, p.getScreenComp(1, pts, 2*i)-nRad*2, nRad*4, nRad*4); if(m_bDrawAllLinks) { Iterator iterTo = currGraph.getEdgesTo(i); while(iterTo.hasNext()) { CommLink l = (CommLink)iterTo.next(); g.drawLine(p.getScreenComp(0,pts, 2*l.to()), p.getScreenComp(1,pts, 2*l.to()), p.getScreenComp(0,pts, 2*l.from()), p.getScreenComp(1,pts, 2*l.from())); } } } } g.setColor(globalsUI.getColorMap().getColor(1)); for(int i = 0; i < arrLfPoints.length; i += 2) { g.drawOval(m_xformToScreen.getScreenComp(0,arrLfPoints,i) -nRad, m_xformToScreen.getScreenComp(1,arrLfPoints,i) -nRad, 2*nRad, 2*nRad); } g.setColor(globalsUI.getColorMap().getColor(3)); for(int i = 0; i < nPts; ++i) { TreeAgentState treeState; try { treeState = (TreeAgentState)arrAgentStates[i].getVars(); int nParentIdx = treeState.getParentId(); if(treeState.getAlgVars().getBoolVar(new Integer(0)) == null || treeState.getAlgVars().getBoolVar(new Integer(0)).booleanValue() == false) { g.setColor(globalsUI.getColorMap().getColor(3)); } else { if(treeState.getAlgVars().getBoolVar(new Integer(1)) == null || treeState.getAlgVars().getBoolVar(new Integer(1)).booleanValue() == false) { g.setColor(globalsUI.getColorMap().getColor(1)); } else { if(treeState.getAlgVars().getBoolVar(new Integer(2)) == null || treeState.getAlgVars().getBoolVar(new Integer(2)).booleanValue() == false) { g.setColor(globalsUI.getColorMap().getColor(2)); } else { g.setColor(globalsUI.getColorMap().getColor(4)); } } } if(nParentIdx >= 0) { g.drawLine(p.getScreenComp(0, pts, 2*i), p.getScreenComp(1, pts, 2*i), p.getScreenComp(0,pts,2*nParentIdx), p.getScreenComp(1,pts,2*nParentIdx)); double [] arrLfCircPos = new double[2]; arrLfCircPos[0] = pts[2*i] + 0.75*(pts[2*nParentIdx]-pts[2*i]); arrLfCircPos[1] = pts[2*i+1] + 0.75*(pts[2*nParentIdx+1]-pts[2*i+1]); g.drawOval(p.getScreenComp(0, arrLfCircPos, 0) -nRad, p.getScreenComp(1, arrLfCircPos, 0) -nRad, 2*nRad,2*nRad); } } catch(java.lang.ClassCastException e) { // do nothing in catch block g.setColor(globalsUI.getColorMap().getColor(3)); } drawBorder(g); drawLabel(g); } if(false) { // for debugging only try { for(int i = 0; i < nPts; ++i ) { ControlFuncMoveTowards func = (ControlFuncMoveTowards) arrAgentStates[i].getControlFunc(); if(arrAgentStates[i].getVars().getBoolVar(new Integer(1)). booleanValue() ) { g.setColor(globalsUI.getColorMap().getColor(4)); } else { g.setColor(globalsUI.getColorMap().getColor(5)); } g.drawLine(p.getScreenComp(0, pts, 2*i), p.getScreenComp(1, pts, 2*i), p.getScreenComp(0, func.getTowards(),0), p.getScreenComp(1, func.getTowards(),0)); } } catch(java.lang.ClassCastException e) { } } } } } String m_strLabel; public void setLabel(String strLabel) { m_strLabel = new String(strLabel); } void drawLabel(java.awt.Graphics g) { g.setColor(globalsUI.getColorMap().getColor(5)); // String str = new String("Paths"); // g.setFont if(m_strLabel == null) { m_strLabel = new String("Constraint Tree"); } globalsUI.getInstance().doText(g, m_strLabel, m_xformToScreen.left() + 2*globalsUI.getInstance().getLineThickness(), m_xformToScreen.top()+m_xformToScreen.height()- 2*globalsUI.getInstance().getLineThickness(), -1); } void drawBorder(java.awt.Graphics g) { g.setColor(globalsUI.getColorMap().getColor(7)); g.drawLine(m_xformToScreen.left(), m_xformToScreen.top(), m_xformToScreen.left() + m_xformToScreen.width()-1, m_xformToScreen.top()); g.drawLine(m_xformToScreen.left(), m_xformToScreen.top()+ m_xformToScreen.height()-1, m_xformToScreen.left() + m_xformToScreen.width()-1, m_xformToScreen.top()+ m_xformToScreen.height()-1); g.drawLine(m_xformToScreen.left() + m_xformToScreen.width()-1, m_xformToScreen.top(), m_xformToScreen.left() + m_xformToScreen.width()-1, m_xformToScreen.top()+ m_xformToScreen.height()-1); g.drawLine(m_xformToScreen.left(), m_xformToScreen.top(), m_xformToScreen.left(), m_xformToScreen.top()+ m_xformToScreen.height()-1); } public void paint(java.awt.Graphics g) { reDraw(g); } /** * Callback function * @param arrLfState state vector (initially initial state, * overwritten with final state) * @param agent agent mapping (currently only support for homogenous swarms * ) * @param arrStates discrete state and control function * of each agent (assumed * not to change over integration) * @param arrSensors array of sensor interfaces. * @param env environment * @return true if something unusual has happened */ public boolean doCallback(double [] arrLfState, IAgent agent, StateBundle [] arrStates, ISensor [] arrSensors, IEnvironment env, CommGraph graph, double lfSimTime) { /* long m_nDrawEveryMilli; double m_lfStoreEveryMilliReal; double m_lfStoreEverySim; Date m_lastDateDrawn; Date m_dateZeroReference; double m_lfSecRealPerSecSim; double m_lfSecSimPerSecReal; double m_lfLastSimStored; IProjection m_xformToScreen; SwarmState m_stateToDraw; SynchronousStateQueue m_stateQueue; */ if(graph != null) { m_commGraph = new CommGraph(graph); } if(lfSimTime - m_lfLastSimStored > m_lfStoreEverySim) { m_lfLastSimStored = lfSimTime; double lfTimeAheadBy = m_stateQueue.addState(arrLfState, arrStates, agent, lfSimTime, m_commGraph); if(lfTimeAheadBy > m_nFrameCacheSize*m_nDrawEveryMilli*0.001) { try { Thread.sleep(m_nDrawEveryMilli); } catch(InterruptedException e) { } } } return false; } /** * In case we need more info then true/false from doCallback * @return null */ public Object getLastObject() { return null; } }