All Projects → JuliaControl → SymbolicControlSystems.jl

JuliaControl / SymbolicControlSystems.jl

Licence: MIT License
An interface between ControlSystems.jl and SymPy.jl

Programming Languages

julia
2034 projects

Projects that are alternatives of or similar to SymbolicControlSystems.jl

SLICOT-Reference
SLICOT - A Fortran subroutines library for systems and control
Stars: ✭ 19 (-5%)
Mutual labels:  control-systems, filtering
filtered
Filters ActiveRecord queries in a nice way
Stars: ✭ 28 (+40%)
Mutual labels:  filtering
Google-Summer-of-Code-with-SymPy
This repository showcases my proposal, final report, and the work done during Google Summer of Code 2020 with the SymPy project.
Stars: ✭ 12 (-40%)
Mutual labels:  control-systems
php-json-schema-model-generator
Creates (immutable) PHP model classes from JSON-Schema files including all validation rules as PHP code
Stars: ✭ 36 (+80%)
Mutual labels:  code-generation
atbuild
Use JavaScript to generate JavaScript
Stars: ✭ 26 (+30%)
Mutual labels:  code-generation
hidev
Automation tool mixed with code generator for easier continuous development
Stars: ✭ 27 (+35%)
Mutual labels:  code-generation
ag-grid
The best JavaScript Data Table for building Enterprise Applications. Supports React / Angular / Vue / Plain JavaScript.
Stars: ✭ 8,743 (+43615%)
Mutual labels:  filtering
metalang
Meta-language used to generate code stubs in a variety of real-world programming languages.
Stars: ✭ 19 (-5%)
Mutual labels:  code-generation
gmail-gitlab-filtering
Google Apps Script for Gmail to filter and sort email from GitLab
Stars: ✭ 84 (+320%)
Mutual labels:  filtering
GraphQL.Tools
GraphQL.Tools is a GraphQL to C# compiler (code-generator) which turns your GraphQL schema into a set of C# classes, interfaces, and enums.
Stars: ✭ 49 (+145%)
Mutual labels:  code-generation
unbound-dns-firewall
DNS-Firewall Python script for UNBOUND
Stars: ✭ 23 (+15%)
Mutual labels:  filtering
Bracmat
Programming language for symbolic computation with unusual combination of pattern matching features: Tree patterns, associative patterns and expressions embedded in patterns.
Stars: ✭ 42 (+110%)
Mutual labels:  symbolic-computation
JqueryDataTablesServerSideDemo
Jquery DataTables with Asp.Net Core server side multi column sorting and searching Demo Project.
Stars: ✭ 43 (+115%)
Mutual labels:  filtering
overture
The Overture Tool
Stars: ✭ 45 (+125%)
Mutual labels:  code-generation
llvm-hs-typed
Type Safe LLVM IR ( Experimental )
Stars: ✭ 47 (+135%)
Mutual labels:  code-generation
control
Control in C++
Stars: ✭ 17 (-15%)
Mutual labels:  control-systems
Coalesce
Helping you quickly build amazing sites
Stars: ✭ 42 (+110%)
Mutual labels:  code-generation
copygen
Go generator to copy values from type to type and fields from struct to struct (copier without reflection). Generate any code based on types.
Stars: ✭ 121 (+505%)
Mutual labels:  code-generation
openmessaging.github.io
OpenMessaging homepage
Stars: ✭ 12 (-40%)
Mutual labels:  filtering
LTVModels.jl
Tools to estimate Linear Time-Varying models in Julia
Stars: ✭ 14 (-30%)
Mutual labels:  control-systems

SymbolicControlSystems

Utilities for

  • Working with ControlSystems.jl types with SymPy.jl symbols as coefficients.
  • Generation of C-code for filtering with LTI systems.

This package exports the names s,z for the Laplace and Z-transform variables. These can be used to build symbolic transfer functions.

Usage examples

julia> using ControlSystems, SymbolicControlSystems

julia> @vars w T d # Define (SymPy) symbolic variables
(w, T, d)

julia> h = 0.01;

julia> G = tf([w^2], [1, 2*d*w, w^2]) * tf(1, [T, 1])
TransferFunction{Continuous, SisoRational{Sym}}
                      w^2
-----------------------------------------------
T*s^3 + 2*T*d*w + 1*s^2 + T*w^2 + 2*d*w*s + w^2

Continuous-time transfer function model

julia> Gd = tustin(G, h); # Discretize

julia> Sym(G) # Convert a TransferFunction to symbolic expression
                        2                      
                       w                       
───────────────────────────────────────────────
   3    222
Ts  + s (2Tdw + 1) + s⎝Tw  + 2dw⎠ + w 

julia> ex = w^2 / (s^2 + 2*d*w*s + w^2) # Define symbolic expression
         2       
        w        
─────────────────
           2    2
2dsw + s  + w 

julia> tf(ex) # Convert symbolic expression to TransferFunction
TransferFunction{Continuous, SisoRational{Sym}}
         w^2
---------------------
1*s^2 + 2*d*w*s + w^2

Continuous-time transfer function model

julia> # Replace symbols with numbers
       T_, d_, w_ = 0.03, 0.2, 2.0 # Define system parameters
(0.03, 0.2, 2.0)

julia> Gd_  = sym2num(Gd, h, Pair.((T, d, w), (T_, d_, w_))...)
TransferFunction{Discrete{Float64}, SisoRational{Float64}}
1.4227382019434605e-5*z^3 + 4.2682146058303814e-5*z^2 + 4.2682146058303814e-5*z + 1.4227382019434605e-5
-------------------------------------------------------------------------------------------------------
              1.0*z^3 - 2.705920013658287*z^2 + 2.414628594192383*z - 0.7085947614779404

Sample Time: 0.01 (seconds)
Discrete-time transfer function model

Get a Latex-string

julia> latextf(G)
"\$\\dfrac{1.0w^2}{0.003s^3 + s^2(0.006dw + 1.0) + s(2.0dw + 0.003w^2) + 1.0w^2}\$"

Code generation

The function code = SymbolicControlSystems.ccode(G::LTISystem) returns a string with C-code for filtering of a signal through the linear system G. All symbolic variables present in G will be expected as inputs to the generated function. The transfer-function state is handled by the C concept of static variables, i.e., a variable that remembers it's value since the last function invocation. The signature of the generated function transfer_function expects all input arguments in alphabetical order, except for the input u which always comes first.

A usage example follows

using ControlSystems, SymbolicControlSystems

@vars w T d # Define symbolic variables
h        = 0.01
G        = tf([w^2], [1, 2*d*w, w^2]) * tf(1, [T, 1])
Gd       = tustin(G, h) # Discretize
code     = SymbolicControlSystems.ccode(Gd, cse=true)
path     = mktempdir()
filename = joinpath(path, "code.c")
outname  = joinpath(path, "test.so")
write(joinpath(path, filename), code)
run(`gcc $filename -lm -shared -o $outname`)

## Test that the C-code generates the same output as lsim in Julia

function c_lsim(u, T, d, w)
    Libc.Libdl.dlopen(outname) do lib
        fn = Libc.Libdl.dlsym(lib, :transfer_function)
        map(u) do u
            @ccall $(fn)(u::Float64, T::Float64, d::Float64, w::Float64)::Float64
        end
    end
end

u    = randn(100); # Random input signal 
T_, d_, w_ = 0.03, 0.2, 2.0 # Define system parameters
y    = c_lsim( u,  T_,  d_,  w_); # Filter u through the C-function filter
Gd_  = sym2num(Gd, h, Pair.((T, d, w), (T_, d_, w_))...) # Replace symbols with numeric constants
y_,_ = lsim(Gd_, u); # Filter using Julia
@test norm(y-y_)/norm(y_) < 1e-10
plot([u y y_], lab=["u" "y c-code" "y julia"]) |> display

NOTE: The usual caveats for transfer-function filtering applies. High-order transfer functions might cause numerical problems. Consider either filtering through many smaller transfer function in series, or convert the system into a well-balanced statespace system and generate code for this instead. See lecture notes slide 45 and onwards.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].