diff --git a/src/cc/ws/CtrlTiles.java b/src/cc/ws/CtrlTiles.java index a8770678..c0c30cde 100644 --- a/src/cc/ws/CtrlTiles.java +++ b/src/cc/ws/CtrlTiles.java @@ -449,7 +449,8 @@ private void addControl(HttpServletRequest oReq, HttpServletResponse oRes) { try { - long lNow = System.currentTimeMillis() - 10; + TimeSource timeSrc = (TimeSource) this.getServletContext().getAttribute(TimeSource.class.getName()); + long lNow = timeSrc.currentTimeMillis(); int nType = Integer.parseInt(oReq.getParameter("type")); String[] sVtypes = oReq.getParameterValues("vtypes[]"); ArrayList nVtypes = new ArrayList(sVtypes.length); @@ -518,7 +519,7 @@ private void addControl(HttpServletRequest oReq, HttpServletResponse oRes) dCenter = Arrays.add(dCenter, dW); } CtrlLineArcs oCla = new CtrlLineArcs(-1, -1, -1, -1, XodrUtil.getLaneType("driving"), dCenter, 0.1); - TrafCtrl oCtrl = new TrafCtrl(TrafCtrlEnums.CTRLS[nType][0], nControlValue, nVtypes, 0L, 0L, oCla.m_dLineArcs, sLabel, bReg, ProcCtrl.CC); + TrafCtrl oCtrl = new TrafCtrl(TrafCtrlEnums.CTRLS[nType][0], nControlValue, nVtypes, lNow, lNow, oCla.m_dLineArcs, sLabel, bReg, ProcCtrl.CC); oCtrl.write(ProcCtrl.g_sTrafCtrlDir, ProcCtrl.g_dExplodeStep, ProcCtrl.g_nDefaultZoom, ProcCtrl.CC); ArrayList oCtrls = new ArrayList(); oCtrls.add(oCtrl); @@ -561,7 +562,8 @@ private void saveEdit(HttpServletRequest oReq, HttpServletResponse oRes) { try { - long lNow = System.currentTimeMillis(); + TimeSource timeSrc = (TimeSource) this.getServletContext().getAttribute(TimeSource.class.getName()); + long lNow = timeSrc.currentTimeMillis(); int nType = Integer.parseInt(oReq.getParameter("type")); String[] sVtypes = oReq.getParameterValues("vtypes[]"); ArrayList nVtypes = new ArrayList(sVtypes.length); @@ -624,7 +626,7 @@ private void saveEdit(HttpServletRequest oReq, HttpServletResponse oRes) } else { - TrafCtrl oNewCtrl = new TrafCtrl(sType, nControlValue, nVtypes, 0L, 0L, oOriginalCtrl, sLabel, bReg, ProcCtrl.CC); + TrafCtrl oNewCtrl = new TrafCtrl(sType, nControlValue, nVtypes, lNow, lNow, oOriginalCtrl, sLabel, bReg, ProcCtrl.CC); oCtrlToWrite = oNewCtrl; oNewCtrl.write(ProcCtrl.g_sTrafCtrlDir, ProcCtrl.g_dExplodeStep, ProcCtrl.g_nDefaultZoom, ProcCtrl.CC); ArrayList oCtrls = new ArrayList(1); diff --git a/src/cc/ws/SimFederate.java b/src/cc/ws/SimFederate.java index e3a4baca..7424b612 100644 --- a/src/cc/ws/SimFederate.java +++ b/src/cc/ws/SimFederate.java @@ -3,14 +3,15 @@ import java.io.BufferedInputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; + import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.json.JSONObject; @@ -22,9 +23,13 @@ public class SimFederate extends HttpServlet implements Runnable protected static final Logger LOGGER = LogManager.getRootLogger(); private long m_lRetryInterval = 60000L; // registration retry 60 seconds + private static final Integer M_TIMEOUT = 10000; private String m_sAmbassadorAddress; + private Integer m_sAmbassadorPort; private String m_sCarmaCloudUrl = ""; private TimeSource m_oTs; + private boolean m_simulationMode = false; + private String m_carmaCloudId = ""; public SimFederate() @@ -41,28 +46,17 @@ public void init() if (sRetry != null) m_lRetryInterval = Integer.parseInt(sRetry) * 1000L; - String sAddress = oConf.getInitParameter("ambassador"); - if (sAddress != null) + m_sAmbassadorAddress = oConf.getInitParameter("ambassador"); + m_sAmbassadorPort = Integer.parseInt(oConf.getInitParameter("ambassadorPort")); + m_simulationMode = Boolean.parseBoolean(oConf.getInitParameter("simulationMode")); + m_sCarmaCloudUrl = oConf.getInitParameter("url"); + m_carmaCloudId = oConf.getInitParameter("carmaCloudId"); + m_oTs = new TimeSource(m_simulationMode); + if (m_simulationMode) { - try - { - InetAddress.getByName(sAddress); // validate network address - m_sAmbassadorAddress = sAddress; - m_oTs = new TimeSource(true); - - String sUrl = oConf.getInitParameter("url"); - if (sUrl != null) - m_sCarmaCloudUrl = sUrl; - - new Thread(this).start(); // begin registration cycle - } - catch (Exception oEx) - { - } + LOGGER.debug("Run in simulation mode."); + new Thread(this).start(); // begin registration cycle } - - if (m_oTs == null) // simulation time source not created - m_oTs = new TimeSource(false); } @@ -70,24 +64,27 @@ public void init() public void doPost(HttpServletRequest oReq, HttpServletResponse oRes) throws ServletException, IOException { - JSONObject oJson; + JSONObject simTimeJson; try (BufferedInputStream oIn = new BufferedInputStream(oReq.getInputStream())) { - oJson = new JSONObject(new JSONTokener(oIn)); + simTimeJson = new JSONObject(new JSONTokener(oIn)); } long lSeq = -1L; long lStep = -1L; - if (oJson.has("seq") && oJson.has("timestep")) + if (simTimeJson.has("seq") && simTimeJson.has("timestep")) { - lSeq = oJson.getLong("seq"); - lStep = oJson.getLong("timestep"); + lSeq = simTimeJson.getLong("seq"); + lStep = simTimeJson.getLong("timestep"); m_oTs.m_lSimTime = lStep; } - LOGGER.debug(String.format("seq: %d timestep: %d timesource: %d", lSeq, lStep, m_oTs.currentTimeMillis())); + this.getServletContext().setAttribute(TimeSource.class.getName(), m_oTs); + LOGGER.debug("seq: {} timestep: {} timesource: {}", lSeq, lStep, m_oTs.currentTimeMillis()); } - + /*** + * @brief A new thread to send registration request to simulation ambassador + */ @Override public void run() { @@ -96,9 +93,13 @@ public void run() { try (Socket oSock = new Socket()) { - oSock.connect(new InetSocketAddress(m_sAmbassadorAddress, 1617), 10000); + oSock.connect(new InetSocketAddress(m_sAmbassadorAddress, m_sAmbassadorPort), M_TIMEOUT); DataOutputStream oOut = new DataOutputStream(oSock.getOutputStream()); - oOut.writeUTF(String.format("{\"id\":\"carma-cloud\", \"url\":\"%s\"}", m_sCarmaCloudUrl)); + JSONObject json = new JSONObject(); + json.put("id", m_carmaCloudId); + json.put("url", m_sCarmaCloudUrl); + LOGGER.debug("Ambassador registration request: {}", json); + oOut.writeUTF(json.toString()); bRegistered = true; } catch (Exception oEx) @@ -112,8 +113,10 @@ public void run() { Thread.sleep(m_lRetryInterval); } - catch (Exception oEx) + catch (InterruptedException oEx) { + LOGGER.error("Ambassador registration task is interrupted."); + Thread.currentThread().interrupt(); } } } diff --git a/src/cc/ws/TcmReqServlet.java b/src/cc/ws/TcmReqServlet.java index 4390aabc..074cc59e 100644 --- a/src/cc/ws/TcmReqServlet.java +++ b/src/cc/ws/TcmReqServlet.java @@ -40,6 +40,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.json.JSONObject; /** @@ -108,7 +109,8 @@ public void run() { try { - long lNow = System.currentTimeMillis(); + TimeSource timeSrc = (TimeSource) this.getServletContext().getAttribute(TimeSource.class.getName()); + long lNow = timeSrc.currentTimeMillis(); String sReq = Thread.currentThread().getName(); int nPos = sReq.indexOf('<'); String sHost = sReq.substring(0, nPos); diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml index cefc0c24..75ce09c0 100644 --- a/web/WEB-INF/web.xml +++ b/web/WEB-INF/web.xml @@ -315,12 +315,30 @@ ambassador ambassador-address + + + OPTIONAL: Network port for simulation ambassador. Leave undefined for normal time operation. + ambassadorPort + 1617 + REQUIRED: Only needed if ambassador address is defined. URL where ambassador sends time sync messages. url simulation-url + + + REQUIRED: Indicator to signify whether carma-cloud is running in simulation mode. + simulationMode + true + + + + REQUIRED: Indicator to uniquely identifer car cloud entity. + carmaCloudId + carma-cloud + 3