protected void InitStates() { fsm = new FiniteStateMachine(); fsm.AddAllStates(typeof(States)); fsm.AddStateTransition(States.Disconnected, States.Connecting, Transitions.StartConnect); fsm.AddStateTransition(States.Connecting, States.Connected, Transitions.ConnectionSuccess); fsm.AddStateTransition(States.Connecting, States.Disconnected, Transitions.ConnectionFailure); fsm.AddStateTransition(States.Connected, States.Disconnected, Transitions.Disconnect); fsm.SetCurrentState(States.Disconnected); }
/// <summary> /// Demo: sets up a simple light chase sequence. /// </summary> private void Setup() { _light1 = GridTerminalSystem.GetBlockWithName("Interior Light") as IMyInteriorLight; _light2 = GridTerminalSystem.GetBlockWithName("Interior Light 2") as IMyInteriorLight; _light3 = GridTerminalSystem.GetBlockWithName("Interior Light 3") as IMyInteriorLight; _fsm.AddState("CHASER1", () => SetLightColor(_light1, Color.Red), () => SetLightColor(_light1, Color.White)); _fsm.AddState("CHASER2", () => SetLightColor(_light2, Color.Red), () => SetLightColor(_light2, Color.White)); _fsm.AddState("CHASER3", () => SetLightColor(_light3, Color.Red), () => SetLightColor(_light3, Color.White)); _fsm.AddStateTransition("CHASER1", "CHASER2", () => true); _fsm.AddStateTransition("CHASER2", "CHASER3", () => true); _fsm.AddStateTransition("CHASER3", "CHASER1", () => true); _fsm.SetCurrentStateName("CHASER1"); }
private void InitStates() { fsm = new FiniteStateMachine(); fsm.AddAllStates(typeof(PacketReadState)); fsm.AddStateTransition(PacketReadState.WAIT_NEW_PACKET, PacketReadState.WAIT_DATA_SIZE, PacketReadTransition.HeaderReceived); fsm.AddStateTransition(PacketReadState.WAIT_DATA_SIZE, PacketReadState.WAIT_DATA, PacketReadTransition.SizeReceived); fsm.AddStateTransition(PacketReadState.WAIT_DATA_SIZE, PacketReadState.WAIT_DATA_SIZE_FRAGMENT, PacketReadTransition.IncompleteSize); fsm.AddStateTransition(PacketReadState.WAIT_DATA_SIZE_FRAGMENT, PacketReadState.WAIT_DATA, PacketReadTransition.WholeSizeReceived); fsm.AddStateTransition(PacketReadState.WAIT_DATA, PacketReadState.WAIT_NEW_PACKET, PacketReadTransition.PacketFinished); fsm.AddStateTransition(PacketReadState.WAIT_DATA, PacketReadState.INVALID_DATA, PacketReadTransition.InvalidData); fsm.AddStateTransition(PacketReadState.INVALID_DATA, PacketReadState.WAIT_NEW_PACKET, PacketReadTransition.InvalidDataFinished); fsm.SetCurrentState(PacketReadState.WAIT_NEW_PACKET); }
private void SetupFSM() { // main sequence states _fsm.AddState( "DRILLING", () => { DrillsEnable(_drills); PistonsExtend(_pistonsAxial); }, () => { DrillsDisable(_drills); } ); _fsm.AddState( "LOCKING FRONT", () => { GearsAutolock(_gearsFront); PistonsExtend(_pistonsFront); }, NoOp ); _fsm.AddState( "UNLOCKING REAR", () => { GearsUnlock(_gearsRear); PistonsRetract(_pistonsRear); }, NoOp ); _fsm.AddState( "CONTRACTING", () => { PistonsRetract(_pistonsAxial); }, NoOp ); _fsm.AddState( "LOCKING REAR", () => { GearsAutolock(_gearsRear); PistonsExtend(_pistonsRear); }, NoOp ); _fsm.AddState( "UNLOCKING FRONT", () => { GearsUnlock(_gearsFront); PistonsRetract(_pistonsFront); }, NoOp ); // main sequence transitions _fsm.AddStateTransition("DRILLING", "LOCKING FRONT", () => ArePistonsInHighestPosition(_pistonsAxial)); _fsm.AddStateTransition("LOCKING FRONT", "UNLOCKING REAR", () => AreAnyGearsLocked(_gearsFront)); _fsm.AddStateTransition("UNLOCKING REAR", "CONTRACTING", () => ArePistonsInLowestPosition(_pistonsRear)); _fsm.AddStateTransition("CONTRACTING", "LOCKING REAR", () => ArePistonsInLowestPosition(_pistonsAxial)); _fsm.AddStateTransition("LOCKING REAR", "UNLOCKING FRONT", () => AreAnyGearsLocked(_gearsRear)); _fsm.AddStateTransition("UNLOCKING FRONT", "DRILLING", () => ArePistonsInLowestPosition(_pistonsFront)); // states to exit in-game edge-cases, conditions to detect these states, and transitions in/out // // FIDDLING has to be done when LOCKING gears, but no gears happen to lock: most often because // the pistons can extend no further (the walls are too far away), or because the wall is too // curved. In either case, the fact that the gears won't be moving can be used to detect the // condition. _fsm.AddStateTransition("LOCKING FRONT", "FIDDLING FRONT", () => !AreAnyGearsMoving(_gearsFront)); _fsm.AddState( "FIDDLING FRONT", () => { ResetTicks(); PistonsReverse(_pistonsAxial); PistonsReverse(_pistonsFront); }, () => { ResetTicks(); } ); _fsm.AddStateTransition("FIDDLING FRONT", "LOCKING FRONT", () => FiddleTick(_gearsFront, _pistonsFront)); _fsm.AddStateTransition("LOCKING REAR", "FIDDLING REAR", () => !AreAnyGearsMoving(_gearsRear)); _fsm.AddState( "FIDDLING REAR", () => { ResetTicks(); PistonsReverse(_pistonsAxial); PistonsReverse(_pistonsRear); }, () => { ResetTicks(); } ); _fsm.AddStateTransition("FIDDLING REAR", "LOCKING REAR", () => FiddleTick(_gearsRear, _pistonsRear)); // PUMPING has to be done when pistons get "sticky", or gears clip walls and therefore get "stuck". // This can happen during any piston extension/contraction in the main sequence, but the case is // also inadvertently covered by the FIDDLING states, so there is no need to also describe it here. // The operation itself is as simple as reversing the pistons back and forth. The gears-moving check // on exit is only there to update the gear positions, the result of the check is discarded. _fsm.AddStateTransition("UNLOCKING FRONT", "PUMPING FRONT", () => !AreAnyGearsMoving(_gearsFront)); _fsm.AddState( "PUMPING FRONT", () => { PistonsReverse(_pistonsFront); }, () => { PistonsReverse(_pistonsFront); AreAnyGearsMoving(_gearsFront); } ); _fsm.AddStateTransition("PUMPING FRONT", "UNLOCKING FRONT", () => true); _fsm.AddStateTransition("UNLOCKING REAR", "PUMPING REAR", () => !AreAnyGearsMoving(_gearsRear)); _fsm.AddState( "PUMPING REAR", () => { PistonsReverse(_pistonsRear); }, () => { PistonsReverse(_pistonsRear); AreAnyGearsMoving(_gearsRear); } ); _fsm.AddStateTransition("PUMPING REAR", "UNLOCKING REAR", () => true); // TODO: determine which state to return to based on velocity (+/-), have 1 state, 2 exit conditions! _fsm.AddStateTransition("CONTRACTING", "PUMPING AXIAL C", () => !AreAnyGearsMoving(_gearsRear)); _fsm.AddState( "PUMPING AXIAL C", () => { PistonsReverse(_pistonsAxial); }, () => { PistonsReverse(_pistonsAxial); AreAnyGearsMoving(_gearsRear); } ); _fsm.AddStateTransition("PUMPING AXIAL C", "CONTRACTING", () => true); _fsm.AddStateTransition("DRILLING", "PUMPING AXIAL D", () => !AreAnyGearsMoving(_gearsFront)); _fsm.AddState( "PUMPING AXIAL D", () => { PistonsReverse(_pistonsAxial); }, () => { PistonsReverse(_pistonsAxial); AreAnyGearsMoving(_gearsFront); } ); _fsm.AddStateTransition("PUMPING AXIAL D", "DRILLING", () => true); // meta/helper states _fsm.AddState( "HALT", () => DrillsDisable(_drills), NoOp ); _fsm.AddState( "RESET", () => { DrillsDisable(_drills); GearsUnlock(_gearsFront); GearsUnlock(_gearsRear); PistonsRetract(_pistonsAxial); PistonsRetract(_pistonsFront); PistonsRetract(_pistonsRear); }, NoOp ); _fsm.AddState("INVALID", NoOp, NoOp); }