📄 wxshower.clp
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; wxShower.clp
;;
;; Implements the Fuzzy Shower example using wxFuzzyCLIPS
;; for the user interface to the shower
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Global definitions used in the simulation
;;
(defglobal
?*coldValvePos* = 0.0
?*hotValvePos* = 0.0
?*coldTemp* = 5.0
?*hotTemp* = 55.0
?*coldPress* = 55.0
?*hotPress* = 55.0
?*optimalTempMin* = 34.0
?*optimalTempMax* = 38.0
?*optimalFlowMin* = 11.0
?*optimalFlowMax* = 13.0
?*atmosphericPress* = 30.0
?*iterationFactor* = 1.0
?*outFlow* = 0.0
?*outTemp* = 0.0
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; globals used by the interface
;;
(defglobal ?*main-frame* = 0)
(defglobal ?*panel* = 0)
(defglobal ?*canvas* = 0)
(defglobal ?*text-win* = 0)
(defglobal ?*hot-valve-slider* = 0)
(defglobal ?*cold-valve-slider* = 0)
(defglobal ?*hot-temp-slider* = 0)
(defglobal ?*cold-temp-slider* = 0)
(defglobal ?*hot-press-slider* = 0)
(defglobal ?*cold-press-slider* = 0)
(defglobal ?*outflow-slider* = 0)
(defglobal ?*outtemp-slider* = 0)
(defglobal ?*manual-auto-check-box* = 0)
(defglobal ?*manual-auto* = "manual")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Deftemplates below define the fuzzy variables being used
;;
;;
;; Outputs of the shower
;;
;; outTemp -- output temperature
;;
;; outFlow -- flow out of the shower
(deftemplate outTemp
5 65 Celcius
((none (5 1) (5.1 0))
(cold (z 10 35))
(OK (pi 2 36))
(hot (s 37 60)) )
())
(deftemplate outFlow
0 100 liters/minute
((none (0 1) (0.05 0))
(low (z 3 11.5))
(OK (pi 1 12))
(strong (s 12.5 25)) )
() )
;; controls for hot and cold valve positions
;;
(deftemplate change_vc
-1 1
((NB (-0.5 1) (-.25 0))
(NM (-.35 0) (-.3 1) (-.15 0))
(NS (-.25 0) (-.15 1) (0 0))
(Z (-.05 0) (0 1) (.05 0))
(PS (0 0) (.15 1) (.25 0))
(PM (.15 0) (.3 1) (.35 0))
(PB (.25 0)(0.5 1)) )
( ; modifier definitions
; (very sqr)
; (less sqrt)
)
)
(deftemplate change_vh
-1 1
((NB (-0.5 1) (-.25 0))
(NM (-.35 0) (-.3 1) (-.15 0))
(NS (-.25 0) (-.15 1) (0 0))
(Z (-.05 0) (0 1) (.05 0))
(PS (0 0) (.15 1) (.25 0))
(PM (.15 0) (.3 1) (.35 0))
(PB (.25 0)(0.5 1)) )
( ; modifier definitions
; (very sqr)
; (less sqrt)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Some supporting functions that do simulation of the Shower
;;
;;
;; initShower - initializes certain global values and requests some
;; initial values from the user and calls simulate to
;; calc the out flow and temp and assert these as
;; fuzzy facts to start the fuzzy rules going
;;
;; Simulate - calculates the new outFlow and outTemp when changes
;; to valve positions are made -- also asserts the
;; fuzzified facts representing these new values --
;; also checks for finished state (temp and flow in range
;; or for certain error conditions
;;
;; calc-outFlow-and-outTemp - calculate the value of the output flow
;; and temperature when something changes
;;
;; shutdown-and-set-to-manual - shut off the system and set the control to
;; manual mode so that the operator can try to fix the problem
;;
(deffunction calc-outFlow-and-outTemp ()
(bind ?hotFlow (* ?*hotValvePos* (- ?*hotPress* ?*atmosphericPress*)))
(bind ?coldFlow (* ?*coldValvePos* (- ?*coldPress* ?*atmosphericPress*)))
(bind ?*outFlow* (+ ?hotFlow ?coldFlow))
(if (= ?*outFlow* 0.0)
then
(bind ?*outTemp* 5.0)
else
(bind ?*outTemp* (/ (+ (* ?coldFlow ?*coldTemp*)
(* ?hotFlow ?*hotTemp*))
?*outFlow*)
)
)
(slider-set-value ?*outtemp-slider* (integer (+ 0.5 ?*outTemp*)))
(slider-set-value ?*outflow-slider* (integer (+ 0.5 ?*outFlow*)))
)
(deffunction shutdown-and-set-to-manual ()
(bind ?*coldValvePos* 0.0)
(bind ?*hotValvePos* 0.0)
(slider-set-value ?*cold-valve-slider* 0)
(slider-set-value ?*hot-valve-slider* 0)
(bind ?*manual-auto* "manual")
(check-box-set-value ?*manual-auto-check-box* 0)
(calc-outFlow-and-outTemp)
)
(deffunction Simulate (?coldValveChange ?hotValveChange)
;; Check for some rather bad situations where control is lost
;;
(if (and (= ?*coldValvePos* 1.0) (> ?coldValveChange 0.0) (< (abs ?hotValveChange) 0.0001))
then
(frame-set-status-text ?*main-frame*
"*** Cold Water Problem: Shutting Down - Cold valve full open and trying to open more ***")
(bind ?*iterationFactor* 1.0) ;; reset iteration Factor
;; (halt)
(shutdown-and-set-to-manual)
(return)
)
(if (and (= ?*hotValvePos* 1.0) (> ?hotValveChange 0.0) (< (abs ?coldValveChange) 0.0001))
then
(frame-set-status-text ?*main-frame*
"*** Hot Water Problem: Shutting Down - Hot valve full open and trying to open more ***")
(bind ?*iterationFactor* 1.0) ;; reset iteration Factor
;; (halt)
(shutdown-and-set-to-manual)
(return)
)
(if (and (= ?*coldValvePos* 0.0) (< ?coldValveChange 0.0) (< (abs ?hotValveChange) 0.0001))
then
(frame-set-status-text ?*main-frame*
"*** HOT TEMPERATURE PROBLEM: Shutting down - cannot get temperature high enough")
(bind ?*iterationFactor* 1.0) ;; reset iteration Factor
;; (halt)
(shutdown-and-set-to-manual)
(return)
)
(if (and (= ?*hotValvePos* 0.0) (< ?hotValveChange 0.0) (< (abs ?coldValveChange) 0.0001))
then
(frame-set-status-text ?*main-frame*
"*** HOT TEMPERATURE PROBLEM: Shutting down - cannot get temperature low enough")
(bind ?*iterationFactor* 1.0) ;; reset iteration Factor
;; (halt)
(shutdown-and-set-to-manual)
(return)
)
;; calc new hot and cold valve positions based on the recommendations
;; for change provided
;; NOTE: we perform a scaling factor on the recommendations making the assumption
;; that at high valve settings a change will produce less effect than
;; if we are operating at a low valve setting; this is due to the effect
;; of pressures -- low pressures will tend to put us at higher valve
;; positions; of course in a REAL situation the actual operating conditions
;; of the system would likely be known and we couuld adjust accordingly;
;; One problem that can occur is that the adjustments cause the system
;; to be too course in its adjustment and it makes a change to go up and then
;; a symmetric change to go down -- it will then endlessly flip flop between
;; a too high and a too low condition -- this is solved by reducing the scale
;; factor after each iteration so the adjustments get smaller and smaller.
;; Also note that we could also tune the fuzzy sets to reduce the range
;; of changes recommended.
;; REMEMBER the conditions of the problem -- we do not know the temps or
;; pressures of hot and cold supplies
(if (or (<> ?coldValveChange 0.0) (<> ?hotValveChange 0.0))
then
(bind ?*coldValvePos*
(max 0.0
(min 1.0
(+ ?*coldValvePos*
(* (* (max 0.1 ?*coldValvePos*) ?*iterationFactor*)
?coldValveChange
)
)
)
)
)
(bind ?*hotValvePos*
(max 0.0
(min 1.0
(+ ?*hotValvePos*
(* (* (max 0.1 ?*hotValvePos*) ?*iterationFactor*)
?hotValveChange
)
)
)
)
)
(slider-set-value ?*cold-valve-slider*
(integer (+ 0.5 (* ?*coldValvePos* 100.0))))
(slider-set-value ?*hot-valve-slider*
(integer (+ 0.5 (* ?*hotValvePos* 100.0))))
)
;; calculate the new outputs - flow and temp
(calc-outFlow-and-outTemp)
;; if both output flow and temp are within correct range control is
;; completed -- halt
;;
(if (and (and (> ?*outFlow* ?*optimalFlowMin*) (< ?*outFlow* ?*optimalFlowMax*))
(and (> ?*outTemp* ?*optimalTempMin*) (< ?*outTemp* ?*optimalTempMax*))
)
then
(frame-set-status-text ?*main-frame*
"Shower is under control!")
(bind ?*iterationFactor* 1.0) ;; reset iteration Factor
;; (halt)
(return)
)
(frame-set-status-text ?*main-frame*
"Fuzzy Control in effect - watch valve changes.")
;; iterationFactor reduces each cycle through
(if (> ?*iterationFactor* 0.1)
then
(bind ?*iterationFactor* (* ?*iterationFactor* .96))
)
;; now assert the fuzzified values of the Flow and Temp of Output
(if (<= ?*outFlow* 0.0)
then
(assert (outFlow (0.0 1.0) (0.5 0.0)))
else
(if (>= ?*outFlow* 100.0)
then
(assert (outFlow (99.5 0.0) (100.0 1.0)))
else
(assert (outFlow ((max 0.0 (- ?*outFlow* 0.5)) 0.0) (?*outFlow* 1.0)
((min 100.0 (+ ?*outFlow* 0.5)) 0.0) ))
)
)
(if (<= ?*outTemp* 5.0)
then
(assert (outTemp (5.0 1.0) (5.1 0.0)))
else
(if (>= ?*outTemp* 65.0)
then
(assert (outTemp (64.9 0.0) (65.0 1.0)))
else
(assert (outTemp ((max 5.0 (- ?*outTemp* 0.1)) 0.0) (?*outTemp* 1.0)
((min 65.0 (+ ?*outTemp* 0.1)) 0.0) ))
)
)
)
(deffunction initShower ()
(slider-set-value ?*cold-valve-slider*
(integer (+ 0.5 (* ?*coldValvePos* 100.0))))
(slider-set-value ?*hot-valve-slider*
(integer (+ 0.5 (* ?*hotValvePos* 100.0))))
(slider-set-value ?*cold-temp-slider* ?*coldTemp*)
(slider-set-value ?*hot-temp-slider* ?*hotTemp*)
(slider-set-value ?*cold-press-slider* ?*coldPress*)
(slider-set-value ?*hot-press-slider* ?*hotPress*)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Rules that control the shower with fuzzy inferencing
;;
(defrule none_none "will jump start an off system"
(outTemp none)
(outFlow none)
=>
(assert (change_vh PS))
(assert (change_vc PM))
)
(defrule cold_low
(outTemp cold)
(outFlow low)
=>
(assert (change_vh PB))
(assert (change_vc Z))
)
(defrule cold_OK
(outTemp cold)
(outFlow OK)
=>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -