# Interface implementation Furuta Pendulum ==================================================== export Furuta, FurutaSimulator, AbstractFuruta # @with_kw allows specification of default values for fields. If none is given, this value must be supplied by the user. replaces many constructors that would otherwise only supply default values. # Call constructor like Furuta(bias=1.0) if you want a non-default value for bias # Furuta(;kwargs...) #Physical Furuta process #Arguments (fields) #- `h::Float64 = 0.01` #- `bias::Float64 = 0.0` #- `stream::LabStream = ComediStream()` #- `measure::AnalogInput10V = AnalogInput10V(0)` #- `control::AnalogOutput10V = AnalogOutput10V(1)` struct Furuta <: PhysicalProcess h::Float64 bias::Float64 stream::LabStream measure::AnalogInput10V control::AnalogOutput10V end function Furuta(; h::Float64 = 0.01, bias::Float64 = 0., stream::LabStream = ComediStream(), measure::AnalogInput10V = AnalogInput10V(4), control::AnalogOutput10V = AnalogOutput10V(0)) p = Furuta(Float64(h),Float64(bias),stream,measure,control) init_devices!(p.stream, p.measure, p.control) p end include("define_furuta_system.jl") const furuta_system = define_furuta_system() struct FurutaSimulator <: SimulatedProcess h::Float64 s::SysFilter FurutaSimulator(;h::Real = 0.01, bias=0) = new(Float64(h), SysFilter(furuta_system, h)) end #FurutaSimulator() = FurutaSimulator() const AbstractFuruta = Union{Furuta, FurutaSimulator} num_outputs(p::AbstractFuruta) = 1 num_inputs(p::AbstractFuruta) = 1 outputrange(p::AbstractFuruta) = [(-10,10)] inputrange(p::AbstractFuruta) = [(-10,10)] isstable(p::AbstractFuruta) = false isasstable(p::AbstractFuruta) = false sampletime(p::AbstractFuruta) = p.h bias(p::AbstractFuruta) = p.bias function control(p::AbstractFuruta, u::AbstractArray) length(u) == 1 || error("Process $(typeof(p)) only accepts one control signal, tried to send u=$u.") control(p,u[1]) end control(p::AbstractFuruta, u::Number) = send(p.control,u) control(p::FurutaSimulator, u::Number) = p.s(u) measure(p::Furuta) = read(p.measure) measure(p::FurutaSimulator) = p.s.sys.C*p.s.state initialize(p::Furuta) = nothing finalize(p::Furuta) = foreach(close, p.stream.devices) initialize(p::FurutaSimulator) = nothing finalize(p::FurutaSimulator) = nothing