| |
libFAUDES
Sections
Types
|
Elevator Example - DetailsThis page gathers detailed models, specifications and supervisors related to the elevator example from the iodevice plug-in. Corresponding files are located in libfaudes/plugin/iodevice/tutorial/data. Signals and EventsThe LRT laboratory set-up uses a simple analog circuit to simulate the behaviour of the elevator plant. Relevant digital signals (over continuous time) are given in the below table. The bit address in the first column refers to the wiring of the laboratory set-up.
Relevant discrete events by definition correspond to edges on the above signals. An event that is triggered by the plant is called a sensor event. An event that must be triggered externally (e.g. by the supervisor) is called an actuator event. The below tables specify the correspondence between edges of signals and actuator- and sensor events. Cabin
Door
Operator
Device ConfigurationThe LRT laboratory set-up uses two Advantech PCI boards for digital IO, one of them providing 64 inputs, the other 64 outputs. Signals are accessed through the comedi framework, where we use the system device files /dev/comedi0 and /dev/comedi1. The below iodevice configuration introduces events to libFAUDES according to the above definition. Signals referenced by a bits address, where each board uses a range from 0 to 63. <DeviceContainer> "LrtElevatorIO" % overall device name 10 % ms/ftu (overwrites per device def) <Devices> <ComediDevice> "LrtElevatorInput" % device name 10 % ms/ftu 64 % max bitaddress 100 % background sample period in nsec "/dev/comedi0" % system device file <EventConfiguration> %%% Cabin sensor: arrive oat upper position "c_arup" <Sensor> <Triggers> 6 +PosEdge+ </Triggers> </Sensor> %%% Cabin sensor: leave upper position "c_lvup" <Sensor> <Triggers> 6 +NegEdge+ </Triggers> </Sensor> %%% Cabin sensor: arrive at lower position "c_arlw" <Sensor> <Triggers> 4 +PosEdge+ </Triggers> </Sensor> %%% Cabin sensor: leave lower position "c_lvlw" <Sensor> <Triggers> 4 +NegEdge+ </Triggers> </Sensor> %%% Door sensor: door reached closed position "d_closed" <Sensor> <Triggers> 8 +PosEdge+ </Triggers> </Sensor> %%% Door sensor: door leaving closed position "d_lvClosed" <Sensor> <Triggers> 8 +NegEdge+ </Triggers> </Sensor> %%% Door sensor: door reached open position "d_opened" <Sensor> <Triggers> 10 +PosEdge+ </Triggers> </Sensor> %%% Door sensor: door leaving open position "d_lvOpened" <Sensor> <Triggers> 10 +NegEdge+ </Triggers> </Sensor> %%% Door sensor: light break occupied "lb_occupied" <Sensor> <Triggers> 16 +PosEdge+ </Triggers> </Sensor> %%% Door sensor: light break released "lb_released" <Sensor> <Triggers> 16 +NegEdge+ </Triggers> </Sensor> %%% Opertor sensor: upper button pressed "upb_pressed" <Sensor> <Triggers> 12 +NegEdge+ </Triggers> </Sensor> %%% Opertor sensor: lower button pressed "lwb_pressed" <Sensor> <Triggers> 14 +NegEdge+ </Triggers> </Sensor> </EventConfiguration> </ComediDevice> <ComediDevice> "LrtElevatorOuput" % device name 10 % ms/ftu 64 % max bitaddress 100 % background sample period in nsec "/dev/comedi1" % system device file <EventConfiguration> %%% Cabin actuator: stop motor "c_stp" <Actuator> <Actions> 0 +Clr+ 2 +Clr+ </Actions> </Actuator> %%% Cabin actuator: start motor upwards "c_mvup" <Actuator> <Actions> 2 +Clr+ 0 +Set+ </Actions> </Actuator> %%% Cabin actuator: start motor downwards "c_mvdw" <Actuator> <Actions> 0 +Clr+ 2 +Set+ </Actions> </Actuator> %%% Door actuator: stop motor "d_stp" <Actuator> <Actions> 4 +Clr+ 6 +Clr+ </Actions> </Actuator> %%% Door actuator: start motor to open door "d_open" <Actuator> <Actions> 6 +Clr+ 4 +Set+ </Actions> </Actuator> %%% Door actuator: start motor to close door "d_close" <Actuator> <Actions> 4 +Clr+ 6 +Set+ </Actions> </Actuator> %%% Operator actuator: illuminate button upstairs "upLED_on" <Actuator> <Actions> 8 +Set+ </Actions> </Actuator> %%% Operator actuator: turn off light for button upstairs "upLED_off" <Actuator> <Actions> 8 +Clr+ </Actions> </Actuator> %%% Operator actuator: illuminate button downstairs "dwLED_on" <Actuator> <Actions> 10 +Set+ </Actions> </Actuator> %%% Operator actuator: turn off light for button downstairs "dwLED_off" <Actuator> <Actions> 10 +Clr+ </Actions> </Actuator> </EventConfiguration> </ComediDevice> </Devices> </DeviceContainer> Plant ModelOur plant model is organized in four components, namely Gcabin, Gdoor, and Glbracket, and G_operator, each referring to the respective alphabet.
Operator events are the push buttons incl. illumination. The operator model G_operator realises the corresponding full language. Specification
Eopcmds:
We sense the operator button to enable cabin activity.
The internal events a_* are introduced to simplify
synchronisation with further specification components.
Ecabmot:
Cabin movement must not be interupted until the
upper or lower position is reached. Note that this specification
also introduces that a_done can only occur after
the cabin did perform some shuttle operation.
Edrmot1:
Similar to the cabin motion as specified by Ecabmot,
the door motion specification requires the door to either open or close and
to stop once the goal is accomplished.
However, the we allow the closing operation to fail to accomodate for
the light bracket. The internal events a_close and
a_open to indicate the outcome of a door operation.
Escheds: The top level schedule enables cabin movement
once the door has been closed. After cabin movement,
the door is to be opened.
Edrsaf1:
The first safety requirement to the door is that it must not be open
when the cabin moves.
Edrsaf2:
The second safety requirement to the door is that
it must re-open when the light bracket becomes blocked during closing.
Controller SynthesisController synthesis for the entire elevator setup is performed by the luafaudes script elevator_synthesis.lua from the iodevice plug-in tutorial. ------------------------------------------------------------------------------- -- read files ------------------------------------------------------------------------------- -- report print("elevator: reading plant and specification data") -- load plant components from file plant_cabin = faudes.Generator("data/elevator_plant_cabin.gen") plant_door = faudes.Generator("data/elevator_plant_door.gen") plant_lbracket = faudes.Generator("data/elevator_plant_lbracket.gen") plant_buttons = faudes.Generator("data/elevator_plant_buttons.gen") plant_leds = faudes.Generator("data/elevator_plant_leds.gen") -- load specification components from file spec_opcmd = faudes.Generator("data/elevator_spec_opcmd.gen") spec_opcmds = faudes.Generator("data/elevator_spec_opcmds.gen") spec_opled = faudes.Generator("data/elevator_spec_opled.gen") spec_cabmot = faudes.Generator("data/elevator_spec_cabmot.gen") spec_cabmots = faudes.Generator("data/elevator_spec_cabmots.gen") spec_drmot1 = faudes.Generator("data/elevator_spec_drmot1.gen") spec_drsaf1 = faudes.Generator("data/elevator_spec_drsaf1.gen") spec_drsaf2 = faudes.Generator("data/elevator_spec_drsaf2.gen") spec_scheds = faudes.Generator("data/elevator_spec_scheds.gen") -- dont name states faudes.StateNamesOff(); ------------------------------------------------------------------------------- -- build plant model ------------------------------------------------------------------------------- -- report print("elevator: build pant model") -- prepare plant model plant_full = faudes.Generator() plant_full_min = faudes.Generator() -- build full model consisting of cabin, door and operator faudes.Parallel(plant_full,plant_cabin,plant_full) faudes.Parallel(plant_full,plant_door,plant_full) faudes.Parallel(plant_full,plant_lbracket,plant_full) faudes.Parallel(plant_full,plant_buttons,plant_full) faudes.Parallel(plant_full,plant_leds,plant_full) -- have a sensible name plant_full:Name("elevator full plant (cabin plus buttons)") -- get eventset of plant model plant_full_alphabet = faudes.EventSet(plant_full:Alphabet()) -- reduce state space faudes.StateMin(plant_full,plant_full_min) -- write to file plant_full_min:Write("tmp_elevator_plant_full.gen") ------------------------------------------------------------------------------- -- build specification ------------------------------------------------------------------------------- -- report print("elevator: build specification") -- prepare overall specification spec_full = faudes.Generator() spec_full_min = faudes.Generator() -- compose overall specification faudes.Parallel(spec_full,spec_opcmds,spec_full) faudes.Parallel(spec_full,spec_scheds,spec_full) faudes.Parallel(spec_full,spec_opled,spec_full) faudes.Parallel(spec_full,spec_cabmots,spec_full) faudes.Parallel(spec_full,spec_drmot1,spec_full) faudes.Parallel(spec_full,spec_drsaf1,spec_full) faudes.Parallel(spec_full,spec_drsaf2,spec_full) faudes.StateMin(spec_full,spec_full_min) -- write to file spec_full_min:Write("tmp_elevator_spec_full.gen") ------------------------------------------------------------------------------- -- build synthesis ------------------------------------------------------------------------------- -- report print("elevator: synthesis") -- match plant and spec alphabets alphabet_full = faudes.EventSet(); alphabet_plant_extra = faudes.EventSet(); faudes.AlphabetUnion(plant_full:Alphabet(),spec_full:Alphabet(),alphabet_full); faudes.AlphabetDifference(alphabet_full,plant_full:Alphabet(),alphabet_plant_extra); faudes.InvProject(spec_full_min,alphabet_full); faudes.InvProject(plant_full_min,alphabet_full); -- extra events in the specification are controllable plant_full_min:SetControllable(alphabet_plant_extra); -- compute supervisor for full elevator setup super_full = faudes.Generator(); super_full_min = faudes.Generator(); faudes.SupConNB(plant_full_min,spec_full_min,super_full) super_full:Name("elevator supervisor (full)") faudes.StateMin(super_full,super_full_min) -- write to file super_full_min:Write("tmp_elevator_super_full.gen") -- report print("elevator: full supervisor statistics") super_full_min:WriteStatistics()
SimulationA shell script elevator_simulation.sh and a configuration file elevator_supervisor.sim are prepared to run a simulation on the supervisor. The simulation also includes the plant components Gcabin and Gdoor to monitor the plant state. The below log shows the elevator moving from the the lower level to the upper level incl. door operations. $ cd ./libfaudes/plugins/iodevice/tutorial $ ./elevator_simulation.sh -v % simfaudes: ========================================== found generator #1: cabin % simfaudes: ========================================== found generator #2: door % simfaudes: ========================================== found generator #3: supervisor (full) ... % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "IdleOp" 1 </DiscreteState> % simfaudes: ========================================== enabled events: <EnabledEvents> "d_lbbl" "o_upb" "o_lwb" </EnabledEvents> % simfaudes: ========================================== proposed action: <ProposedTime> inf </ProposedTime> % simfaudes: ========================================== enter command: The simulator starts in its initisl state, where the first two components refer to the cabin and the door respectively. The third component is the supervisor state. All enabled events are sensor events and cofigured to have a negative priority. Hence, the simulation will not propose to execute either of them automatically. We decide to manually issue a o_upb event, i.e. the operator presses the upper button. The simulator proposes to execute the synchronisation event a_start and to turn on the button lights. We accept the proposal by hitting the return key. % simfaudes: ========================================== enter command: o_upb % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "IdleOp" 34 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "a_start" </ProposedEvent> % simfaudes: ========================================== enter command: a_start % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "IdleOp" 69 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "o_uplon" </ProposedEvent> % simfaudes: ========================================== enter command: o_uplon % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "IdleOp" 30 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "o_lwlon" </ProposedEvent> % simfaudes: ========================================== enter command: o_lwlon % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "IdleOp" 64 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "d_close" </ProposedEvent> % simfaudes: ========================================== enter command: In the remaining log, the simulator closes the door, drives the cabin upstairs and opens the door again. As above, sensor events must be chosen manually, actuator events are proposed by the simulator. The simulation ends with door opened and the cabin upstairs, while waiting for sensor events (e.g. an operator button). % simfaudes: ========================================== execute event: d_close % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "CloseOp" 16 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedTime> inf </ProposedTime> % simfaudes: ========================================== enter command: d_lvop % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "CloseMd" 55 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedTime> inf </ProposedTime> % simfaudes: ========================================== enter command: d_arcl % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "CloseCl" 26 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "d_stp" </ProposedEvent> % simfaudes: ========================================== enter command: d_stp % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "IdleCl" 27 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "a_close" </ProposedEvent> % simfaudes: ========================================== enter command: a_close % simfaudes: ========================================== current state: <DiscreteState> "IdleLw" "IdleCl" 2 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "c_up" </ProposedEvent> % simfaudes: ========================================== enter command: c_up % simfaudes: ========================================== current state: <DiscreteState> "UpLw" "IdleCl" 8 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedTime> inf </ProposedTime> % simfaudes: ========================================== enter command: c_lvlw % simfaudes: ========================================== current state: <DiscreteState> "UpMd" "IdleCl" 81 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedTime> inf </ProposedTime> % simfaudes: ========================================== enter command: c_arup % simfaudes: ========================================== current state: <DiscreteState> "UpUp" "IdleCl" 100 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "c_stp" </ProposedEvent> % simfaudes: ========================================== enter command: c_stp % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "IdleCl" 25 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "d_open" </ProposedEvent> % simfaudes: ========================================== enter command: d_open % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "OpenCl" 98 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedTime> inf </ProposedTime> % simfaudes: ========================================== enter command: d_lvcl % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "OpenMd" 57 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedTime> inf </ProposedTime> % simfaudes: ========================================== enter command: d_arop % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "OpenOp" 90 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "d_stp" </ProposedEvent> % simfaudes: ========================================== enter command: d_stp % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "IdleOp" 40 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "a_open" </ProposedEvent> % simfaudes: ========================================== enter command: a_open % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "IdleOp" 82 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "a_done" </ProposedEvent> % simfaudes: ========================================== enter command: a_done % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "IdleOp" 49 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "o_uploff" </ProposedEvent> % simfaudes: ========================================== enter command: o_uploff % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "IdleOp" 76 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedEvent> "o_lwloff" </ProposedEvent> % simfaudes: ========================================== enter command: o_lwloff % simfaudes: ========================================== current state: <DiscreteState> "IdleUp" "IdleOp" 3 </DiscreteState> % simfaudes: ========================================== proposed action: <ProposedTime> inf </ProposedTime> % simfaudes: ========================================== enter command: |
libFAUDES 2.14g --- 2009-12-3 --- plugins "example synthesis observer diagnosis hiosys multitasking timed simulator iodevice luabindings"