content: -- |PID related functions for 'Topic's.
  module Ros.Topic.PID where
  import Control.Applicative
  import Ros.Topic
  import Ros.Topic.Util
  import qualified Ros.Util.PID as P
  
  -- |@pidUniform2 kp ki kd setpoint t@ runs a PID controller that
  -- transforms 'Topic' @t@ of process outputs into a 'Topic' of control
  -- signals designed to steer the output to the setpoints produced by
  -- 'Topic' @setpoint@ using the PID gains @kp@, @ki@, and @kd@. The
  -- interval between samples produced by the 'Topic' is assumed to be
  -- 1.
  pidUniform2 :: Fractional a => a -> a -> a -> Topic IO a -> Topic IO a -> 
                 Topic IO a
  pidUniform2 kp ki kd setpoint t = 
    Topic $ do controller <- uncurry <$> P.pidUniformIO kp ki kd
               runTopic . join $ controller <$> everyNew setpoint t
  
  -- |@pidUniform kp ki kd setpoint t@ runs a PID controller that
  -- transforms 'Topic' @t@ of process outputs into a 'Topic' of control
  -- signals designed to steer the output to the given setpoint using
  -- the PID gains @kp@, @ki@, and @kd@. The interval between samples
  -- produced by the 'Topic' is assumed to be 1.
  pidUniform :: Fractional a => a -> a -> a -> a -> Topic IO a -> Topic IO a
  pidUniform kp ki kd setpoint t = 
    Topic $ do controller <- ($ setpoint) <$> P.pidUniformIO kp ki kd
               runTopic . join $ controller <$> t
  
  -- |@pidFixed2 kp ki kd setpoint dt t@ runs a PID controller that
  -- transforms 'Topic' @t@ of process outputs into a 'Topic' of control
  -- signals designed to steer the output to the setpoints produced by
  -- 'Topic' @setpoint@ using the PID gains @kp@, @ki@, and @kd@, along
  -- with an assumed fixed time interval, @dt@, between samples.
  pidFixed2 :: Fractional a => a -> a -> a -> a -> Topic IO a -> Topic IO a -> 
               Topic IO a
  pidFixed2 kp ki kd dt setpoint t = 
    Topic $ do controller <- uncurry <$> P.pidFixedIO kp ki kd dt
               runTopic . join $ controller <$> everyNew setpoint t
  
  
  -- |@pidFixed kp ki kd setpoint dt t@ runs a PID controller that
  -- transforms 'Topic' @t@ of process outputs into a 'Topic' of control
  -- signals designed to steer the output to the given setpoint using
  -- the PID gains @kp@, @ki@, and @kd@, along with an assumed fixed
  -- time interval, @dt@, between samples.
  pidFixed :: Fractional a => a -> a -> a -> a -> a -> Topic IO a -> Topic IO a
  pidFixed kp ki kd setpoint dt t = 
    Topic $ do controller <- ($ setpoint) <$> P.pidFixedIO kp ki kd dt
               runTopic . join $ controller <$> t
  
  -- |@pidTimed2 kp ki kd setpoint t@ runs a PID controller that
  -- transforms 'Topic' @t@ of process outputs into a 'Topic' of control
  -- signals designed to steer the output to the setpoints produced by
  -- 'Topic' @setpoint@ using the PID gains @kp@, @ki@, and @kd@. The
  -- system clock is checked for each value produced by the input
  -- 'Topic' to determine the actual sampling rate.
  pidTimed2 :: Fractional a => a -> a -> a -> Topic IO a -> Topic IO a -> 
               Topic IO a
  pidTimed2 kp ki kd setpoint t = 
    Topic $ do controller <- uncurry <$> P.pidTimedIO kp ki kd
               runTopic . join $ controller <$> everyNew setpoint t
  
  -- |@pidTimed kp ki kd setpoint t@ runs a PID controller that
  -- transforms 'Topic' @t@ of process outputs into a 'Topic' of control
  -- signals designed to steer the output to the given setpoint using
  -- the PID gains @kp@, @ki@, and @kd@. The system clock is checked for
  -- each value produced by the input 'Topic' to determine the actual
  -- sampling rate.
  pidTimed :: Fractional a => a -> a -> a -> a -> Topic IO a -> Topic IO a
  pidTimed kp ki kd setpoint t = 
    Topic $ do controller <- ($ setpoint) <$> P.pidTimedIO kp ki kd
               runTopic . join $ controller <$> t
  
  
  -- |@pidStamped2 kp ki kd setpoint t@ runs a PID controller that
  -- transforms 'Topic' @t@ of process outputs into a 'Topic' of control
  -- signals designed to steer the output to the given setpoint using
  -- the PID gains @kp@, @ki@, and @kd@. Values produced by the 'Topic'
  -- @t@ must be paired with a timestamp and thus have the form
  -- (timeStamp, sample).
  pidStamped2 :: Fractional a => a -> a -> a -> Topic IO a -> Topic IO (a,a) -> 
                 Topic IO a
  pidStamped2 kp ki kd setpoint t =
    Topic $ do controller <- uncurry <$> P.pidWithTimeIO kp ki kd
               runTopic . join $ controller <$> everyNew setpoint t
  
  -- |@pidStamped kp ki kd setpoint t@ runs a PID controller that
  -- transforms 'Topic' @t@ of process outputs into a 'Topic' of control
  -- signals designed to steer the output to the given setpoint using
  -- the PID gains @kp@, @ki@, and @kd@. Values produced by the 'Topic'
  -- @t@ must be paired with a timestamp and thuse have the form
  -- (timeStamp, sample).
  pidStamped :: Fractional a => a -> a -> a -> a -> Topic IO (a,a) -> Topic IO a
  pidStamped kp ki kd setpoint t =
    Topic $ do controller <- ($ setpoint) <$> P.pidWithTimeIO kp ki kd
               runTopic . join $ controller <$> t
  