Durum Makineleri (State Machines)
Durum makinesi, önceki durumlardan gelen değerlere veya sistem girdilerine bağlı olarak durumlara dinamik akış sağlayan bir programlama mimarisidir. Bu mimari, aşağıdakilerin bir kombinasyonu olarak tanımlanabilecek uygulamalar için uygundur:
- Durumlar (states)
- Belirli bir duruma ne zaman geçileceğini belirleyen karar verme mantığı
Bir durum, programın genel görevini yerine getirirken program içindeki durum olarak tanımlanabilir. Durum örnekleri başlatma, bekleme, bir hesaplama çalıştırma, durumu kontrol etme vb. olabilir.
Mantıksal ifadeler yeni bir duruma ne zaman geçileceğini ve hangi duruma geçileceğini belirlemeye yardımcı olur. Olaylar bir durumdan diğerine geçişi tetiklemek için kullanılabilir. Bunlar programatik olaylar olabileceği gibi bir butona basmak gibi kullanıcı tanımlı olaylar da olabilir.
Durum Makinesindeki her durum benzersiz bir şey yapar ve diğer durumları çağırır. Böylece işlemler belli bir sırayla yapılabilir. Örneğin, resimde gördüğünüz state şemasına göre kapı sadece kapalı durumdayken kilitlenebilir. Kapı kilitli durumdayken açılamaz. Kapıyı açmak için, önce kilidi açmak gerekir.
State makinesi örnekleri
- Bir otomatik vezne makinesi (ATM). Bu uygulamadaki state'ler, kullanıcı girdisini bekleme, istenen miktarı hesap bakiyesiyle karşılaştırma, parayı dağıtma, makbuzu yazdırma ve benzeri işlemleri içerebilir.
- Durum makinesi, yaygın olarak oyun programlamasında kullanılır. Örneğin, kullanıcının atladığı her seviye bir durumdur.
- Süreç testi, Durum Makinelerinin bir başka yaygın uygulamasıdır. Bu örnekte, sürecin her bir bölümü bir durum ile temsil edilmektedir. Her bir durumun testinin sonucuna bağlı olarak farklı bir durum çağrılabilir. Bir fabrikada ürünler için kullanılan sızdırmazlık vb. testleri yapan bir makine süreç testine örnek gösterilebilir.
- Vapur iskelesinde bulunan turnikeler. Ödeme işlemi yapıldıktan sonra kapı bir kez açılır. Ödeme işlemi kapıyı kapalı durumdan açık durumuna getirmektedir.
- İnsan davranışları da örnek gösterilebilir. Araç kullanırken yola bir yaya adım attığında, frene basmak. Saçımız uzayınca berbere gitmek gibi.
Palet etiketleme aplikatörü yazılım örneği
Aplikatör plc girişleri
- Palet ön etiketini bas ve palete uygula
- Palet yan etiketini bas ve palete uygula
Aplikatör plc çıkışları
- Hata durumu (yazıcıda veya sistemde oluşan hata)
- Meşgül sinyali (aplikatör etiketi yapıştırken bu sinyal 1 olur)
- Hazır
- Aplikatör kolu dışarıda veya home pozisyonunda
Fabrikaya özel geliştirilecek .Net yazılımı için state'ler
- Konveyörde taşınan paletin, etiket aplikatörünün yanına gelmesi. Optik bir sensör ile yazılım bunu algılamalıdır.
- Yazılım, palet geldi bilgisini aldığında paleti taşıyan konveyörü durdurmalıdır. (Yazılım, konveyör plc'si ile de haberleşmelidir)
- Yazılım, ERP sistemiyle haberleşerek etikete yazılacak bilgileri oluşturmalı, gerekirse ERP'den onay almalıdır.
- Yazılım, etikete basılacak bilgileri, aplikatör yazıcısına yollamalı.
- Yazıcıya işin gittiğinden emin olduktan sonra plc'ye etiketi bas ve palete uygula komutu verilmelidir. Yazıcıda iş yokken bu komut verilirse hata durumu oluşacaktır.
- Yazılım, plc'den gelen meşgül sinyalinin 1 den 0 a düşmesini beklemelidir. Bu sinyal, palet aplikatör kolunun etiketi yapıştırıp geri geldiğini belirtir.
- Üstteki state'e ulaşılması durumunda ayrı bir önlem olarak aplikatör kolunun yuvaya (home) döndüğünü gösteren sinyal de kontrol edilmelidir.
- Aplikatör home pozisyonunda ise ve meşgül sinyali yoksa paletin işi bitmiştir. Palet, serbest bırakılabilir. Yani konveyör dönsün komutu verilebilecektir. Aplikatör kolu dışarıdayken bu komut verilirse palet, aplikatöre çarparak zarar verecektir.
PureBasic ile basit bir state makinesi örneği
Enumeration
#GADGET_btnStart
#GADGET_btnReset
#GADGET_btnOpen
#GADGET_btnClose
#GADGET_btnLock
#GADGET_btnUnlock
#GADGET_txtState
#GADGET_lbTrace
EndEnumeration
Enumeration
#STATE_Start
#STATE_Opened
#STATE_Closed
#STATE_Locked
EndEnumeration
#WINDOW_Main = 0
#WINDOW_Main_Flags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
State = #STATE_Start
Macro Trace(MessageText)
AddGadgetItem(#GADGET_lbTrace, -1, MessageText)
SetGadgetState(#GADGET_lbTrace, CountGadgetItems(#GADGET_lbTrace) -1)
EndMacro
Procedure.s StateInfo(number.i)
st.s = ""
Select number
Case 0 : st = "START"
Case 1 : st = "OPENED"
Case 2 : st = "CLOSED"
Case 3 : st = "LOCKED"
EndSelect
SetGadgetText(#GADGET_txtState, "Current state : " + st)
ProcedureReturn st
EndProcedure
OpenWindow(#WINDOW_Main, 0, 0, 400, 360, "State Machine example...", #WINDOW_Main_Flags)
StickyWindow(#WINDOW_Main, 1) ; show test app always above the PB_IDE
ButtonGadget(#GADGET_btnStart, 8, 4, 192, 32, "Start")
ButtonGadget(#GADGET_btnReset, 200, 4, 192, 32, "Reset Machine")
ButtonGadget(#GADGET_btnOpen, 8, 40, 192, 32, "Open")
ButtonGadget(#GADGET_btnClose, 200, 40, 192, 32, "Close")
ButtonGadget(#GADGET_btnLock, 8, 76, 192, 32, "Lock")
ButtonGadget(#GADGET_btnUnlock, 200, 76, 192, 32, "Unlock")
TextGadget(#GADGET_txtState, 8, 115, 384, 20, "Current state : START")
SetGadgetColor(#GADGET_txtState, #PB_Gadget_BackColor, RGB(204,255,204))
ListViewGadget(#GADGET_lbTrace, 8, 145, 384, 208, $4000) ; #LBS_NOSEL == 0x4000
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case #GADGET_btnStart
Select State
Case #STATE_Start
State = #STATE_Opened
Trace("State is changed to : " + StateInfo(State))
Default
Trace("It is already STARTED")
EndSelect
Case #GADGET_btnReset
ClearGadgetItems(#GADGET_lbTrace)
State = #STATE_Start
Trace("State is changed to : " + StateInfo(State))
Case #GADGET_btnOpen
Select State
Case #STATE_Start
Trace("First you have to press the Start button")
Case #STATE_Opened
Trace("It is already OPENED")
Case #STATE_Closed
State = #STATE_Opened
Trace("State is changed to : " + StateInfo(State))
Case #STATE_Locked
Trace("You can NOT open! it is LOCKED")
EndSelect
Case #GADGET_btnClose
Select State
Case #STATE_Start
Trace("First you have to press the Start button")
Case #STATE_Opened
State = #STATE_Closed
Trace("State is changed to : " + StateInfo(State))
Case #STATE_Closed
Trace("It is already CLOSED")
Case #STATE_Locked
Trace("You can NOT close! it is already CLOSED and LOCKED!")
EndSelect
Case #GADGET_btnLock
Select State
Case #STATE_Start
Trace("First you have to press the Start button")
Case #STATE_Opened
Trace("You can NOT lock! fisrt you have to CLOSE to lock!")
Case #STATE_Closed
State = #STATE_Locked
Trace("State is changed to : " + StateInfo(State))
Case #STATE_Locked
Trace("It is already LOCKED")
EndSelect
Case #GADGET_btnUnlock
Select State
Case #STATE_Start
Trace("First you have to press the Start button")
Case #STATE_Opened
Trace("You can NOT unlock! state must be LOCKED to unlock!")
Case #STATE_Closed
Trace("You can NOT unlock! fist you have to LOCK to unlock!")
Case #STATE_Locked
State = #STATE_Closed
Trace("State is changed to : " + StateInfo(State))
EndSelect
EndSelect
EndSelect
ForEver
End
Youtube'da izle..
Yorumlar
Yorum Gönder