1 package org.opentrafficsim.imb.transceiver.urbanstrategy; 2 3 import org.opentrafficsim.core.dsol.OTSDEVSRealTimeClock; 4 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface; 5 import org.opentrafficsim.imb.IMBException; 6 import org.opentrafficsim.imb.connector.Connector; 7 import org.opentrafficsim.imb.transceiver.AbstractTransceiver; 8 import org.opentrafficsim.imb.transceiver.IMBMessageHandler; 9 import org.opentrafficsim.imb.transceiver.OTSToIMBTransformer; 10 11 import nl.tno.imb.TByteBuffer; 12 import nl.tudelft.simulation.dsol.SimRuntimeException; 13 import nl.tudelft.simulation.dsol.simulators.DEVSRealTimeClock; 14 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface; 15 import nl.tudelft.simulation.event.EventInterface; 16 17 /** 18 * The SimulatorTranseiver sends and listens to start, stop and change speed messages. The SimulatorTransceiver publishes the 19 * following information on the IMB bus: 20 * <ol> 21 * <li>SimulatorInterface.START_EVENT when the simulator starts executing.</li> 22 * <li>SimulatorInterface.STOP_EVENT when the simulator stops executing.</li> 23 * <li>DEVSRealTimeClock.CHANGE_SPEED_FACTOR_EVENT when the simulator speed changes. Note that the simulation speed values are 24 * limited to the following: {0.1, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0, 25 * Double.MAX_DOUBLE}</li> 26 * </ol> 27 * <p> 28 * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br> 29 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>. 30 * </p> 31 * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $, 32 * initial version Sep 11, 2016 <br> 33 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 34 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 35 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a> 36 */ 37 public class SimulatorTransceiver extends AbstractTransceiver 38 { 39 /** */ 40 private static final long serialVersionUID = 20160911L; 41 42 /** the Empty transformer for IMB. */ 43 private final EmptyTransformer emptyTransformer = new EmptyTransformer(); 44 45 /** the simulation speed transformer for IMB. */ 46 private final SpeedTransformer speedTransformer = new SpeedTransformer(); 47 48 /** 49 * Construct a new SimulatorTransceiver. 50 * @param connector Connector; the IMB connector through which this transceiver communicates 51 * @param simulator OTSDEVSSimulatorInterface; the simulator to schedule the incoming notifications on 52 * @throws IMBException when the registration of one of the channels fails 53 * @throws NullPointerException in case one of the arguments is null. 54 */ 55 public SimulatorTransceiver(final Connector connector, final OTSDEVSSimulatorInterface simulator) throws IMBException 56 { 57 super("Simulator Control", connector, simulator); 58 59 // register the OTS to IMB updates for the simulator 60 final OTSDEVSRealTimeClock animator = (OTSDEVSRealTimeClock) simulator; 61 addOTSToIMBChannel(animator, SimulatorInterface.START_EVENT, "Sim_Start", new Object[] {}, this.emptyTransformer); 62 addOTSToIMBChannel(animator, SimulatorInterface.STOP_EVENT, "Sim_Stop", new Object[] {}, this.emptyTransformer); 63 addOTSToIMBChannel(animator, DEVSRealTimeClock.CHANGE_SPEED_FACTOR_EVENT, "Sim_Speed", new Object[] { new Double(1.0) }, 64 this.speedTransformer); 65 66 // register the IMB to OTS updates for the simulator 67 final IMBMessageHandler startHandler = new IMBMessageHandler() 68 { 69 @Override 70 public void handle(TByteBuffer imbPayload) throws IMBException 71 { 72 try 73 { 74 if (!animator.isRunning()) // to break message cycle between OTS and IMB 75 { 76 animator.start(true); 77 } 78 } 79 catch (SimRuntimeException exception) 80 { 81 throw new IMBException(exception); 82 } 83 } 84 85 @Override 86 public String getIMBEventName() 87 { 88 return "Sim_Start"; 89 } 90 }; 91 addIMBtoOTSChannel("Sim_Start", startHandler); 92 93 final IMBMessageHandler stopHandler = new IMBMessageHandler() 94 { 95 @Override 96 public void handle(TByteBuffer imbPayload) throws IMBException 97 { 98 if (animator.isRunning()) // to break message cycle between OTS and IMB 99 { 100 animator.stop(true); 101 } 102 } 103 104 @Override 105 public String getIMBEventName() 106 { 107 return "Sim_Stop"; 108 } 109 }; 110 addIMBtoOTSChannel("Sim_Stop", stopHandler); 111 112 final IMBMessageHandler speedHandler = new IMBMessageHandler() 113 { 114 @Override 115 public void handle(TByteBuffer imbPayload) throws IMBException 116 { 117 System.out.println("About to read the new speed value"); 118 double speed = imbPayload.readDouble(); 119 System.out.println( 120 "Sim_Stop event handler: new speed is " + speed + " current speed is " + animator.getSpeedFactor()); 121 if (speed != animator.getSpeedFactor()) // to break message cycle between OTS and IMB 122 { 123 animator.setSpeedFactor(speed, true); // TODO callback for speed not 100% ok yet... 124 } 125 } 126 127 @Override 128 public String getIMBEventName() 129 { 130 return "Sim_Speed"; 131 } 132 }; 133 addIMBtoOTSChannel("Sim_Speed", speedHandler); 134 } 135 136 /** 137 * Transform the an event without content to a corresponding IMB message. 138 * <p> 139 * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. 140 * <br> 141 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>. 142 * </p> 143 * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $, 144 * initial version Sep 11, 2016 <br> 145 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 146 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 147 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a> 148 */ 149 static class EmptyTransformer implements OTSToIMBTransformer 150 { 151 /** {@inheritDoc} */ 152 @Override 153 public Object[] transform(final EventInterface event) 154 { 155 return new Object[] {}; 156 } 157 } 158 159 /** 160 * Transform the a simulation speed change event to a corresponding IMB message.<br> 161 * Event is sent from OTS to IMB to indicate that the OTS simulation has changed the intended execution speed (there is, 162 * however, no guarantee that the simulator is able to reach that particular speed). The speed is coded as a 64-bits double, 163 * where 1.0 indicates exactly real-time; values less than 1.0 slower than real time, and larger than 1.0 indicates faster 164 * than real-time. The simulation speed values are limited to the following: {0.1, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 165 * 50.0, 100.0, 200.0, 500.0, 1000.0, Double.MAX_DOUBLE}. 166 * <p> 167 * <style>table,th,td {border:1px solid grey; border-style:solid; text-align:left; border-collapse: collapse;}</style> 168 * <H2>NEW</H2> Empty message, no payload 169 * </p> 170 * <p> 171 * <h2>CHANGE</h2> 172 * <table summary="" style="width:800px;"> 173 * <thead> 174 * <tr> 175 * <th style="width:25%;">Variable</th> 176 * <th style="width:15%;">Type</th> 177 * <th style="width:60%;">Comments</th> 178 * </tr> 179 * </thead><tbody> 180 * <tr> 181 * <td>newSimulationSpeed</td> 182 * <td>double</td> 183 * <td>Limit to {1,2,5} E {-1, 0, 1, 2}, 1000, MAX_DOUBLE</td> 184 * </tr> 185 * </tbody> 186 * </table> 187 * </p> 188 * <p> 189 * <h2>DELETE</h2> Not sent 190 * </p> 191 * <p> 192 * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. 193 * <br> 194 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>. 195 * </p> 196 * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $, 197 * initial version Sep 11, 2016 <br> 198 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 199 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 200 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a> 201 */ 202 static class SpeedTransformer implements OTSToIMBTransformer 203 { 204 /** {@inheritDoc} */ 205 @Override 206 public Object[] transform(final EventInterface event) 207 { 208 Double speed = ((Double) event.getContent()); 209 System.out.println("Transmitting speed " + speed + " to IMB"); 210 return new Object[] { speed }; 211 } 212 } 213 }