<HSM name="Pelican Crossing">
<authors>Jonathan Kaye</authors>
<local varName="pc"/>
<description>This is the state engine to implement Miro Samek's Intersection Crossing Example (from C/C++ User's Journal,
June 2003</description>
<hState name="State Net">
<hState name="operational" defaultStart="true">
<transition targetName="off" trigger="OFF">
</transition>
<hState name="vehiclesEnabled" defaultStart="true">
<local id="50" />
<onEnter>
<code>
<![CDATA[
signalPedestrians("DONT_WALK");
]]>
</code>
</onEnter>
<state name="vehiclesGreen" defaultStart="true">
<onEnter>
<code>
<![CDATA[
signalVehicles("GREEN");
setTimer(1000 * greenMinTime.val, 1);
pedWait = false;
]]>
</code>
</onEnter>
<intAct trigger="PEDESTRIAN_WAITING">
<comment>When Pedestrian crossing is pressed</comment>
<code>
<![CDATA[
pedWait = true;
]]>
</code>
</intAct>
<onLeave>
<code>
<![CDATA[
killTimer();
]]></code>
</onLeave>
<transition trigger="onTimeoutPedWait" targetName="vehiclesYellow">
</transition>
<transition trigger="onTimeoutNoPedWait" targetName="vehiclesGreenInt">
</transition>
</state>
<state name="vehiclesGreenInt">
<transition trigger="PEDESTRIAN_WAITING" targetName="vehiclesYellow">
</transition>
</state>
<state name="vehiclesYellow">
<onEnter>
<code>
<![CDATA[
signalVehicles("YELLOW");
setTimer(1000 * yellowTime.val, 1);
]]>
</code>
</onEnter>
<onLeave>
<code>
<![CDATA[
killTimer();
]]>
</code>
</onLeave>
<transition targetName="pedestriansEnabled" trigger="TIMEOUT">
<local levels2LCA="1" path2Target="51" />
</transition>
</state>
</hState>
<hState name="pedestriansEnabled">
<local id="51" />
<onEnter>
<code>
<![CDATA[
signalVehicles("RED");
]]>
</code>
</onEnter>
<state name="pedestriansWalk" defaultStart="true">
<onEnter>
<code>
<![CDATA[
setTimer(1000 * pedWalkTime.val);
signalPedestrians("WALK");
]]>
</code>
</onEnter>
<onLeave>
<code>
<![CDATA[
killTimer();
]]>
</code>
</onLeave>
<transition targetName="pedestriansFlash" trigger="TIMEOUT">
</transition>
</state>
<state name="pedestriansFlash">
<onEnter>
<code>
<![CDATA[
if (pedNumFlashes.val > 0) {
setTimer(1000 * pedFlashTime.val / (2*pedNumFlashes.val + 1), (2*pedNumFlashes.val + 1));
} else {
setTimer(100, 1);
}
signalPedestrians("WALK");
lastWalkOn = true;
]]>
</code>
</onEnter>
<onLeave>
<code>
<![CDATA[
killTimer();
]]>
</code>
</onLeave>
<intAct trigger="TIMEOUT">
<code>
<![CDATA[
FlashPedLight();
]]>
</code>
</intAct>
<transition trigger="onNFlashes" targetName="vehiclesEnabled">
<local levels2LCA="1" path2Target="50" />
</transition>
</state>
</hState>
</hState>
<state name="off">
<onEnter>
<comment>shutdown</comment>
</onEnter>
</state>
</hState>
</HSM>
<events>
<simpleEvent name="PEDESTRIAN_WAITING">
<local condition="{evID} == "onPress"" />
</simpleEvent>
<simpleEvent name="OFF">
<local condition="{evID} == "SystemOff"" />
</simpleEvent>
<simpleEvent name="TIMEOUT">
<local condition="{evID} == "onTimeout"" />
</simpleEvent>
<compoundEvent name="onNFlashes">
<local condition="{evID} == "onTimeout" && {evVal} == 0" />
</compoundEvent>
<simpleEvent name="onTimeoutPedWait">
<local condition="{evID} == "onTimeout" && pedWait" />
</simpleEvent>
<simpleEvent name="onTimeoutNoPedWait">
<local condition="{evID} == "onTimeout" && !pedWait" />
</simpleEvent>
</events>