Skip to content
Snippets Groups Projects
Select Git revision
  • main
1 result

EGM_Example_IRB14000_RW608.rspag

Blame
  • ballandbeam.jl 3.12 KiB
    # Interface implementation Ball And Beam ====================================================
    
    # The ball and beam can be used in two modes, either just the Beam, in which case there is a
    # single output (measurement signal) or the BallAndBeam, in which case there are two.
    # There are a few union types defined for convenience, these are
    # AbstractBeam = Union{Beam, BeamSimulator}
    # AbstractBallAndBeam   = Union{BallAndBeam, BallAndBeamSimulator}
    # AbstractBeamOrBallAndBeam = All types
    # Although not Abstract per se, the names AbstractBeam etc. were chosen since this reflects
    # their usage in dispatch.
    
    export Beam, BeamSimulator, AbstractBeam, BallAndBeam, BallAndBeamSimulator, AbstractBeamOrBallAndBeam
    
    struct Beam <: PhysicalProcess
        h::Float64
        bias::Float64
    end
    Beam() = Beam(0.01, 0.0)
    
    struct BeamSimulator <: SimulatedProcess
        h::Float64
        state::Vector{Float64} # angle,ω
    end
    BeamSimulator() = BeamSimulator(0.01, zeros(2))
    
    struct BallAndBeam <: PhysicalProcess
        h::Float64
        bias::Float64
    end
    BallAndBeam() = BallAndBeam(0.01, 0.0)
    
    struct BallAndBeamSimulator <: SimulatedProcess
        h::Float64
        state::Vector{Float64} # pos,vel,angle,ω
    end
    BallAndBeamSimulator() = BallAndBeamSimulator(0.01, zeros(4))
    
    
    const AbstractBeam              = Union{Beam, BeamSimulator}
    const AbstractBallAndBeam       = Union{BallAndBeam, BallAndBeamSimulator}
    const AbstractBeamOrBallAndBeam = Union{AbstractBeam, AbstractBallAndBeam}
    
    
    num_outputs(p::AbstractBeam)             = 1
    num_outputs(p::AbstractBallAndBeam)      = 2
    num_inputs(p::AbstractBeamOrBallAndBeam) = 1
    outputrange(p::Beam)                     = [(-10,10)]
    outputrange(p::AbstractBallAndBeam)      = [(-10,10),(-1,1)] # Beam angle, Ball position
    inputrange(p::AbstractBeamOrBallAndBeam) = [(-10,10)]
    isstable(p::Beam)                        = true
    isstable(p::AbstractBallAndBeam)         = false
    isasstable(p::AbstractBeamOrBallAndBeam) = false
    sampletime(p::AbstractBeamOrBallAndBeam) = p.h
    bias(p::AbstractBeamOrBallAndBeam)       = p.bias
    bias(p::BallAndBeamSimulator)            = 0
    
    
    control(p::AbstractBeamOrBallAndBeam, u) = ccall((:comedi_write, comedipath),Int32,
                                            (Int32,Int32,Int32,Int32),0,1,1,num2io(u[1]+p.bias))
    measure(p::Beam) = io2num(ccall((:comedi_read,comedipath), Int32,
                                            (Int32,Int32,Int32), 0,0,0))
    measure(p::BallAndBeam) = [io2num(ccall((:comedi_read,comedipath), Int32,
    (Int32,Int32,Int32), 0,0,i)) for i = 0:1]
    
    control(p::BallAndBeamSimulator, u)  = error("Not yet implemented")
    measure(p::BallAndBeamSimulator)     = [p.state[1], p.state[3]]
    
    const comedipath = Pkg.dir("LabProcesses","c","comedi_bridge.so")
    const conversion = 65535/20
    io2num(x) = x/conversion -10            # Converts from io to float
    num2io(x) = round(Int32,x*100 + 2048)   # Converts from regular number to io
    
    initialize(p::AbstractBeamOrBallAndBeam) = ccall((:comedi_start, comedipath),Int32,(Int32,), 0)
    finalize(p::AbstractBeamOrBallAndBeam)   = (control(p,0);ccall((:comedi_stop, comedipath),Int32,(Int32,), 0))
    initialize(p::BallAndBeamSimulator)      = nothing
    finalize(p::BallAndBeamSimulator)        = nothing