1 package org.opentrafficsim.imb.transceiver.urbanstrategy;
2
3 import java.rmi.RemoteException;
4
5 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
6 import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
7 import org.opentrafficsim.core.network.Network;
8 import org.opentrafficsim.core.network.Node;
9 import org.opentrafficsim.core.network.OTSNetwork;
10 import org.opentrafficsim.imb.IMBException;
11 import org.opentrafficsim.imb.connector.Connector;
12 import org.opentrafficsim.imb.connector.Connector.IMBEventType;
13 import org.opentrafficsim.imb.transceiver.AbstractTransceiver;
14
15 import nl.tudelft.simulation.event.EventInterface;
16 import nl.tudelft.simulation.event.EventType;
17 import nl.tudelft.simulation.event.TimedEvent;
18
19 /**
20 * OTS publishes events about the Nodes to IMB to be able to identify the nodes in the network.<br>
21 * At the start of the OTS simulation, or when a Node is added later, a NEW message is sent to IMB for each node to identify the
22 * node id. No CHANGE messages are posted. When a Node is removed from the network, a DELETE event is posted. The Node NEW
23 * messages are posted after the Network NEW message is posted.
24 * <p>
25 * <style>table,th,td {border:1px solid grey; border-style:solid; text-align:left; border-collapse: collapse;}</style>
26 * <H2>NEW</H2>
27 * <table summary="" style="width:800px;">
28 * <thead>
29 * <tr>
30 * <th style="width:25%;">Variable</th>
31 * <th style="width:15%;">Type</th>
32 * <th style="width:60%;">Comments</th>
33 * </tr>
34 * </thead><tbody>
35 * <tr>
36 * <td>timestamp</td>
37 * <td>double</td>
38 * <td>time of the event, in simulation time seconds</td>
39 * </tr>
40 * <tr>
41 * <td>networkId</td>
42 * <td>String</td>
43 * <td>Id of the Network where the Node resides</td>
44 * </tr>
45 * <tr>
46 * <td>nodeId</td>
47 * <td>String</td>
48 * <td>id of the Node; unique within the Network</td>
49 * </tr>
50 * <tr>
51 * <td>coordinate.x</td>
52 * <td>double</td>
53 * <td>x-coordinate of the Node</td>
54 * </tr>
55 * <tr>
56 * <td>coordinate.y</td>
57 * <td>double</td>
58 * <td>y-coordinate of the Node</td>
59 * </tr>
60 * <tr>
61 * <td>coordinate.z</td>
62 * <td>double</td>
63 * <td>z-coordinate of the Node</td>
64 * </tr>
65 * </tbody>
66 * </table>
67 * </p>
68 * <p>
69 * <h2>CHANGE</h2> Not sent
70 * </p>
71 * <p>
72 * <h2>DELETE</h2>
73 * <table summary="" style="width:800px;">
74 * <thead>
75 * <tr>
76 * <th style="width:25%;">Variable</th>
77 * <th style="width:15%;">Type</th>
78 * <th style="width:60%;">Comments</th>
79 * </tr>
80 * </thead><tbody>
81 * <tr>
82 * <td>timestamp</td>
83 * <td>double</td>
84 * <td>time of the event, in simulation time seconds</td>
85 * </tr>
86 * <tr>
87 * <td>networkId</td>
88 * <td>String</td>
89 * <td>Id of the Network where the Node resides</td>
90 * </tr>
91 * <tr>
92 * <td>nodeId</td>
93 * <td>String</td>
94 * <td>id of the Node that is removed from the Network</td>
95 * </tr>
96 * </tbody>
97 * </table>
98 * </p>
99 * <p>
100 * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
101 * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
102 * <p>
103 * @version $Revision$, $LastChangedDate$, by $Author$, initial version Sep 13, 2016 <br>
104 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
105 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
106 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
107 */
108 public class NodeTransceiver extends AbstractTransceiver
109 {
110 /** */
111 private static final long serialVersionUID = 20160918L;
112
113 /** the OTS network on which Nodes are registered. */
114 private final OTSNetwork network;
115
116 /**
117 * Construct a new NodeTransceiver.
118 * @param connector Connector; the IMB connector through which this transceiver communicates
119 * @param simulator OTSDEVSSimulatorInterface; the simulator to schedule the incoming notifications on
120 * @param network OTSNetwork; the OTS network on which Nodes are registered
121 * @throws IMBException when the registration of one of the channels fails
122 * @throws NullPointerException in case one of the arguments is null.
123 */
124 public NodeTransceiver(final Connector connector, final OTSDEVSSimulatorInterface simulator, final OTSNetwork network)
125 throws IMBException
126 {
127 super("Node", connector, simulator);
128 this.network = network;
129
130 // listen on network changes and register the listener to all the Links
131 addListeners();
132 }
133
134 /**
135 * Ensure that we get notified about newly created and destroyed Nodes, and instrument all currently existing Nodes.
136 * @throws IMBException in case notification of existing Nodes fails
137 */
138 private void addListeners() throws IMBException
139 {
140 // Subscribe to all future link creation and removal events.
141 this.network.addListener(this, Network.NODE_ADD_EVENT);
142 this.network.addListener(this, Network.NODE_REMOVE_EVENT);
143
144 // For already existing links, post ourselves a LINK_ADD_EVENT
145 for (Node node : this.network.getNodeMap().values())
146 {
147 try
148 {
149 this.notify(new TimedEvent<OTSSimTimeDouble>(Network.NODE_ADD_EVENT, this.network, node.getId(),
150 getSimulator().getSimulatorTime()));
151 }
152 catch (RemoteException exception)
153 {
154 throw new IMBException(exception);
155 }
156 }
157 }
158
159 /** {@inheritDoc} */
160 @Override
161 public void notify(final EventInterface event) throws RemoteException
162 {
163 EventType type = event.getType();
164 if (type.equals(Network.NODE_ADD_EVENT))
165 {
166 Node node = this.network.getNode((String) event.getContent());
167 try
168 {
169 getConnector().postIMBMessage("Node", IMBEventType.NEW,
170 new Object[] { getSimulator().getSimulatorTime().getTime().si, this.network.getId(), node.getId(),
171 node.getPoint().x, node.getPoint().y, node.getPoint().z });
172 }
173 catch (IMBException exception)
174 {
175 exception.printStackTrace();
176 }
177 }
178 else if (type.equals(Network.NODE_REMOVE_EVENT))
179 {
180 Node node = this.network.getNode((String) event.getContent());
181 try
182 {
183 getConnector().postIMBMessage("Node", IMBEventType.DELETE,
184 new Object[] { getSimulator().getSimulatorTime().getTime().si, this.network.getId(), node.getId() });
185 }
186 catch (IMBException exception)
187 {
188 exception.printStackTrace();
189 }
190 }
191 else
192 {
193 System.err.println("NodeTransceiver.notify: Unhandled event: " + event);
194 }
195 }
196 }