PasteRack.org
Paste # 49484
2025-01-23 22:54:43

Fork as a new paste.

Paste viewed 263 times.


Embed:

#lang racket

(require parsack)

(module+ test
  (require
    (for-syntax syntax/parse)
    rackunit)
  
  (define-syntax (check-parse stx)
    (syntax-parse stx
      [(_ (_ p inp) expected)
       (syntax/loc #'p
         (check-equal? (parse-result p inp) expected))]))
  )

(struct sm-name
  (group
   machine
   name)
  #:transparent)

(struct bind
  (binder
   name
   type
   expr)
  #:transparent)

(struct body
  (statements)
  #:transparent)

(struct controller
  (name
   body)
  #:transparent)

(struct state
  (name
   controller
   sequences)
  #:transparent)

(struct state-machine
  (name
   states)
  #:transparent)

(define prog "state_machine proxy_alarms.run:
    state active:
        controller:
            # Calc Health Alarms, designed to trip if calcs are stale
            let ftp_rotorthrust_calc_watchdog:bool = (|PRXY:NS:CALC.FTP_ROTORTHRUST_CALC_HEALTH|:int == past_value(|PRXY:NS:CALC.FTP_ROTORTHRUST_CALC_HEALTH|:int, 1.0))
            alarm(ftp_rotorthrust_calc_watchdog, 2.0, |ALARM.FTP_ROTORTHRUST_CALC_STALE|:bool, \"FTP Rotor thrust calcs are stale. Check runtime status.\", \"type:warning\")

            let otp_rotorthrust_calc_watchdog:bool = (|PRXY:NS:CALC.OTP_ROTORTHRUST_CALC_HEALTH|:int == past_value(|PRXY:NS:CALC.OTP_ROTORTHRUST_CALC_HEALTH|:int, 1.0))
            alarm(otp_rotorthrust_calc_watchdog, 2.0, |ALARM.OTP_ROTORTHRUST_CALC_STALE|:bool, \"OTP Rotor thrust calcs are stale. Check runtime status.\", \"type:warning\")
            
            let prxy_alarm_calc_watchdog:bool = (|PRXY:NS:CALC.PRXY_ALARMS_CALC_HEALTH|:int == past_value(|PRXY:NS:CALC.PRXY_ALARMS_CALC_HEALTH|:int, 1.0))
            alarm(prxy_alarm_calc_watchdog, 2.0, |ALARM.PRXY_ALARMS_CALC_STALE|:bool, \"PRXY ALARM calcs are stale. Check runtime status.\", \"type:warning\")

            if |PRXY:NS:AEONR.ALARM_PHASE|:int == enum_alarms_engine_powered_lv:

                # RATVAC temperature
                # Rationale: protect against damage to or inability to move RATVACs
                # LL: -20F, per Will Rumplik. This is based on test data, and it's well away from nominal operation points.
                const ratvac_temp_low:float = -20.0
                # UL: highest cavity temp observed on engine (during fire anomaly), where a throttle valve successfully operated afterwords.
                # # There is probably more room to go up here, this would be severly off nominal and worth flagging to ops
                const ratvac_temp_high:float = 200.0
                # persistence: set arbitrarily high to ensure alarm isn' tripped on a brief transient
                const ratvac_temp_persistence:float = 2.0
                alarm((|VEH:RC:AEONR.T-FMRA|:float < ratvac_temp_low) or (|VEH:RC:AEONR.T-FMRA|:float > ratvac_temp_high), ratvac_temp_persistence, |ALARM.AEONR.T-FMRA|:bool, \"FMR RATVAC temp out of bounds\", \"type:warning\")
                alarm((|VEH:RC:AEONR.T-FTVA|:float < ratvac_temp_low) or (|VEH:RC:AEONR.T-FTVA|:float > ratvac_temp_high), ratvac_temp_persistence, |ALARM.AEONR.T-FTVA|:bool, \"FTV RATVAC temp out of bounds\", \"type:warning\")
                alarm((|VEH:RC:AEONR.T-OTVA|:float < ratvac_temp_low) or (|VEH:RC:AEONR.T-OTVA|:float > ratvac_temp_high), ratvac_temp_persistence, |ALARM.AEONR.T-OTVA|:bool, \"OTV RATVAC temp out of bounds\", \"type:warning\")

            # Temps reported in deg F. Resistance of the harness in the calc is conservatively assumed to be 0 ohms since we haven't done resistence checks on the harness yet.
            if (|PRXY:NS:AEONR.ALARM_PHASE|:int == enum_alarms_engine_powered_lv or |PRXY:NS:AEONR.ALARM_PHASE|:int == enum_alarms_site_cleared_hv):
                # dekavalve coil temperature calc only active after solenoid is energized, so gate the alarm on coil temp on solenoid energized (curr > 1A) for 500 ms
                if min_past_value(|VEH:RC:AEONR.SV-H2I-CUR-FB|:float, 0.5) > 1.0:
                    alarm(|PRXY:NS:AEONR.SV-H2I_COIL_TEMP|:float > 300.0, 1.0, |ALARM.SV-H2I_COIL_TEMP_HIGH|:bool, \"SV-H2I solenoid coil temperature high\", \"type:warning\")
                if min_past_value(|VEH:RC:AEONR.SV-GOI-CUR-FB|:float, 0.5) > 1.0:
                    alarm(|PRXY:NS:AEONR.SV-GOI_COIL_TEMP|:float > 300.0, 1.0, |ALARM.SV-GOI_COIL_TEMP_HIGH|:bool, \"SV-GOI solenoid coil temperature high\", \"type:warning\")


            if |PRXY:NS:AEONR.ALARM_PHASE|:int == enum_alarms_site_cleared_hv:
                # IPS health alarms
                alarm(|VEH:RC:AEONR.P-HEIPS|:float < 75.0, 1.0, |PRXY:NS:ALARM.P-HEIPS_LOW|:bool, \"IPS Buffer Pressure low\", \"type:warning\")
                # no P-HEIPS high alarm because stand relief setpoint is lower than engine IPS limit
                alarm(|VEH:RC:AEONR.P-HEIPS|:float - |VEH:RC:AEONR.P-OIPSD|:float > 150.0, 1.0, |ALARM.OX_IPS_INNER_DP_HIGH|:bool, \"Ox IPS inner seal dP high (limit is 150 psid when spinning, 500 psid when stationary)\", \"type:warning\")
                alarm(|VEH:RC:AEONR.P-HEIPS|:float - |VEH:RC:AEONR.P-FIPSD|:float > 150.0, 1.0, |ALARM.FUEL_IPS_INNER_DP_HIGH|:bool, \"Fuel IPS inner seal dP high (limit is 150 psid when spinning, 500 psid when stationary)\", \"type:warning\")
                alarm(|VEH:RC:AEONR.P-HEIPS|:float - |VEH:RC:AEONR.P-OIPSD|:float < 20.0, 1.0, |ALARM.OX_IPS_INNER_DP_LOW|:bool, \"Ox IPS inner seal dP low\", \"type:warning\")
                alarm(|VEH:RC:AEONR.P-HEIPS|:float - |VEH:RC:AEONR.P-FIPSD|:float < 20.0, 1.0, |ALARM.FUEL_IPS_INNER_DP_LOW|:bool, \"Fuel IPS inner seal dP low\", \"type:warning\")
")


(define $p_number
  (λ (in)
    (define-values (r c pos) (port-next-location in))
    (define byte-pos (file-position in))
    (define n (read in))
    (cond
      [(number? n) (Consumed (Ok n))]
      [else (file-position in byte-pos) ; backtrack
            (set-port-next-location! in r c pos)
            (Empty (Error))])))

(define $p_arithmetic-operator
  (oneOf "+-/*")
  )

(define $p_binary-numeric
  (parser-seq
   $p_binary-numeric (~ $spaces)
   $p_arithmetic-operator (~ $spaces)
   $p_binary-numeric
   ))

(define $p_numeric
  (parser-compose
   (<or>
    (try $p_binary-numeric)
    $p_number))
  )

(module+ test
  (check-parse (parse $p_numeric "1")
               (list 1))
  )

(define $p_identifier
  (<?>
   (parser-compose
    (id <- (many1 (<or> $letter $digit (char #\_))))
    (return (list->string id))
    )
   "identifier")
  )

(define $p_name (many $letter))

(define $p_comment
  (parser-seq (char #\#)
              (<or>
               $alphaNum
               $space
               (oneOf "!@#$%^&*()[]/.,<>?;':\\|-_\"'")
               )))

(define $p_bool (<or> (>> (string "True") (return #t))
                      (>> (string "False") (return #f))))


(define $p_whitespace (many1 (<or> $space $eol $tab)))

(define $p_rexpr
  (<?> (parser-compose
        (<or>
         $p_numeric
         $p_bool
         #;(>> (many1
                (<or>
                 $alphaNum
                 $space
                 (oneOf "!@#$%^&*()[]/.,<>?;':\\|-_\"'")
                 ))
               (return 'other)
               )))
       "right side expression"
       ))

(define $p_type
  (<?> (<or>
        (>> (string "float") (return 'float))
        (>> (string "bool") (return 'bool))
        (>> (string "int") (return 'int))
        )
       "type"))

(define $p_bind
  (parser-compose
   (binder <- (<or> (try (string "let"))
                    (string "const")))
   $spaces
   (var <- $p_identifier)
   (char #\:)
   (type <- $p_type)
   $spaces
   (char #\=)
   $spaces
   (expr <- $p_rexpr)
   (return (bind (string->symbol (list->string binder)) var type expr))
   ))



(define $p_statement
  (parser-compose
   (<?> (<or>
         (>> (string "pass") (return 'pass))
         (>> $p_comment (return null))
         $p_bind
         ) "statement")
   ))

(define $p_body (many1 $p_statement))

(define $p_controller
  (parser-compose
   (string "controller")
   $p_whitespace
   (name <- $p_identifier) (char #\:)
   $p_whitespace
   (body <- $p_body)
   (return (controller name body))
   ))

(define $p_sequence
  (parser-compose
   (string "sequence:")
   $p_whitespace
   (statements <- $p_body)
   (return (body statements))
   ))

(define $p_state
  (parser-compose
   (string "state")
   $p_whitespace

   ;; parse name -- either "name" or "machine.group.name"
   (name <- (<or>
             (try (parser-compose
                   (m <- $p_identifier) (char #\.)
                   (g <- $p_identifier) (char #\.)
                   (n <- $p_identifier) (char #\:)
                   (return (sm-name m g n))))

             (parser-compose
              (n <- (parser-one (~> $p_identifier) (char #\:)))
              (return (sm-name #f #f (first n))))

             ))
   ;;$p_whitespace
   ;;(controller <- (try $p_controller))
   $p_whitespace
   (sequences <- (many1 $p_sequence))
   
   (return (state name '() sequences))
   ))

(define $p_state-machine
  (parser-compose
   (string "state_machine")
   $spaces
   (group <- $p_identifier)
   (char #\.)
   (machine <- $p_identifier)
   (char #\:)
   $spaces
   (states <- (many $p_state))
   (return (state-machine (sm-name group machine #f) states))
   ))
 
(module+ test

  
  (check-parse (parse $p_state-machine "state_machine proxy_alarms.run:
     state group.machine.state:
         sequence:
             pass")
               (state-machine (sm-name "proxy_alarms" "run" #f)
                              (list
                               (state (sm-name "group" "machine" "state")
                                      '()
                                      (list
                                       (body (list 'pass))
                                       ))
                               )))

  (check-parse (parse $p_state-machine "state_machine proxy_alarms.run:
    state state:
        sequence:
            pass")
               (state-machine (sm-name "proxy_alarms" "run" #f)
                              (list
                               (state
                                (sm-name #f #f "state")
                                '()
                                (list
                                 (body (list 'pass))
                                 )
                                ))))

  (check-parse (parse $p_bind "let ftp_rotorthrust_calc_watchdog:float = 12.0")
               (bind 'let "ftp_rotorthrust_calc_watchdog" 'float 12.0))

  (check-parse (parse $p_bind "let watchdog_tripped:bool = False")
               (bind 'let "watchdog_tripped" 'bool #f))

  (check-parse (parse $p_bind "let cycle_count:int = 2345")
               (bind 'let "cycle_count" 'int 2345))

  (check-parse (parse $p_bind "const a:int = 3456")
               (bind 'const "a" 'int 3456))

  (check-parse (parse $p_bind "const time_stamp:float = 8.0")
               (bind 'const "time_stamp" 'float 8.0))
  
  
  #;(check-parse (parse $p_bind "let ftp_rotorthrust_calc_watchdog:bool = (|PRXY:NS:CALC.FTP_ROTORTHRUST_CALC_HEALTH|:int == past_value(|PRXY:NS:CALC.FTP_ROTORTHRUST_CALC_HEALTH|:int, 1.0))")
                 (list 'let "ftp_rotorthrust_calc_watchdog" 'bool 'other))
               

  #;(check-parse (parse $p_body "let ftp_rotorthrust_calc_watchdog:bool = (|PRXY:NS:CALC.FTP_ROTORTHRUST_CALC_HEALTH|:int == past_value(|PRXY:NS:CALC.FTP_ROTORTHRUST_CALC_HEALTH|:int, 1.0))
            alarm(ftp_rotorthrust_calc_watchdog, 2.0, |ALARM.FTP_ROTORTHRUST_CALC_STALE|:bool, \"FTP Rotor thrust calcs are stale. Check runtime status.\", \"type:warning\")"
                        )
                 (body
                  (list 'let 'alarm)
                  )
                 )
  
  )

=>

standard-module-name-resolver: collection not found
  for module path: parsack
  collection: "parsack"
  in collection directories:
   /home/pasterack/.local/share/racket/8.8/collects
   /home/pasterack/racket88/collects/
   ... [179 additional linked and package directories]
  context...:
   /home/pasterack/racket88/collects/racket/require-transform.rkt:266:2: expand-import
   /home/pasterack/racket88/collects/racket/private/reqprov.rkt:648:16
   /home/pasterack/racket88/collects/racket/private/reqprov.rkt:646:2: filter-by-mode
   /home/pasterack/racket88/collects/racket/require-transform.rkt:266:2: expand-import
   /home/pasterack/racket88/collects/racket/private/reqprov.rkt:287:21: try-next
   /home/pasterack/racket88/collects/racket/private/reqprov.rkt:401:21: try-next
   /home/pasterack/racket88/collects/racket/private/reqprov.rkt:258:2
   /home/pasterack/racket88/collects/syntax/wrap-modbeg.rkt:46:4
   /home/pasterack/racket88/share/pkgs/scribble-lib/scribble/run.rkt:175:26: go
   .../private/map.rkt:40:19: loop
   .../racket/cmdline.rkt:191:51
   body of "/home/pasterack/racket88/share/pkgs/scribble-lib/scribble/run.rkt"