View Javadoc
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 }