{"id":13720164,"url":"https://github.com/swedishembedded/control","last_synced_at":"2026-03-09T00:21:13.406Z","repository":{"id":64028833,"uuid":"525080260","full_name":"swedishembedded/control","owner":"swedishembedded","description":"Embedded Firmware Control Systems Toolbox (Pure C and GNU Octave)","archived":false,"fork":false,"pushed_at":"2023-10-08T21:51:12.000Z","size":24551,"stargazers_count":117,"open_issues_count":0,"forks_count":24,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-11-14T09:39:07.628Z","etag":null,"topics":["c","control-systems","embedded-c","embedded-systems","firmware","system-identification","system-identification-toolbox","zephyr","zephyr-rtos"],"latest_commit_sha":null,"homepage":"https://swedishembedded.com/sdk","language":"MATLAB","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swedishembedded.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-08-15T17:37:10.000Z","updated_at":"2024-11-06T19:21:08.000Z","dependencies_parsed_at":"2024-01-10T07:01:55.863Z","dependency_job_id":"f8b257b9-96f4-4ba6-86f7-b8cd5a570639","html_url":"https://github.com/swedishembedded/control","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swedishembedded%2Fcontrol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swedishembedded%2Fcontrol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swedishembedded%2Fcontrol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swedishembedded%2Fcontrol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swedishembedded","download_url":"https://codeload.github.com/swedishembedded/control/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252876320,"owners_count":21818163,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","control-systems","embedded-c","embedded-systems","firmware","system-identification","system-identification-toolbox","zephyr","zephyr-rtos"],"created_at":"2024-08-03T01:01:00.467Z","updated_at":"2026-03-09T00:21:13.372Z","avatar_url":"https://github.com/swedishembedded.png","language":"MATLAB","funding_links":[],"categories":["Libraries"],"sub_categories":["Application frameworks"],"readme":"# Swedish Embedded Control Systems Toolbox\n\n![cover](pictures/cover.png)\n\nThis is a control systems design library written in pure C that provides you\nwith advanced algorithms for control, state estimation and model identification\nspecifically designed for use on embedded systems. It has been adopted for use\nwith embedded systems and [Swedish Embedded Platform\nSDK](https://github.com/swedishembedded/sdk)\n\n- Community: https://swedishembedded.com/community\n- Consulting: https://swedishembedded.com/consulting\n- Training: https://swedishembedded.com/tag/training\n\nIt library is fully compatible with Zephyr RTOS so you can simply add it as a\nmodule to your west.yml file and start using it.\n\nIt is focused on practical numerical methods that work best in realtime\nembedded environment without any complex dependencies.\n\nIt uses no dynamic memory allocation. All operations are done on C\narrays. The functions provided by this library are generic implementations that\ncan be used to implement controllers that use specific array sizes.\n\nOriginal library is based on excellent work by Daniel Mårtensson who has\ndeveloped the original algorithms in C and GNU Octave.\n\nThis library provides following functionality:\n\n- Artificial Intelligence\n  - Astar algorithm for quick path finding\n  - Point-in-polygon algorithm for checking if a point is inside the area\n- Control Engineering\n  - Kalman filter update\n  - Linear Quadratic Integral regulator\n  - Model predictive Control\n  - Model Reference Adaptive Control\n  - Transfer function to state space\n  - Stability check\n  - Continuous to discrete\n\n- Filtering\n  - Monte Carlo Simulation\n  - Comming soon: Particle filter\n  - Filtfilt \n  - Square Root Unscented Kalman Filter\n  \n- Linear Algebra\n  - Balance matrix\n  - Cholesky decomposition\n  - Cholesky update\n  - QR decomposition\n  - LUP decomposition\n  - Determinant\n  - Discrete Lyapunov solver\n  - Eigenvalues symmetric + Eigenvectors\n  - Random real eigenvalues and random imaginary eigenvalues\n  - Hankel matrix\n  - Inverse\n  - Pseudo inverse\n  - Linear solver\n  - Nonlinear solver\n  - Multiplication\n  - Singular Value Decomposition Golup Reinsch\n  - Singular Value Decomposition Jacobi One Sided\n  - Transpose\n  - Matrix sum\n  - Norm\n  - Matrix exponential\n\n- Miscellaneous\n  - Concatenate\n  - Cut matrix\n  - Insert sub matrix into matrix\n  - Print matrix or vector\n  - Saturation\n  - Sign\n  - Randn\n  - Mean\n  - Standard deviation\n  - Value min\n  - Value max\n  \n- Optimization\n  - Linear programming maximization\n  - Linear programming minimization\n\n- System Identification\n  - Observer Kalman Filter identification\n  - Eigensystem Realization Algorithm\n  - Recursive Least Square with forgetting factor and kalman filter identification\n  - Square Root Unscented Kalman Filter for parameter estimation\n\n# Building locally\n\nThe library core library should build just fine using the standard cmake\napproach:\n\n```\nmkdir build\ncmake ..\nmake \u0026\u0026 make test\n```\n\n# Building and running examples\n\nThe tests inside this repository are created to be buildable on top of Swedish\nEmbedded Platform SDK. If you are using 'swedishembedded/build:latest' docker\nimage then you should be able to simply run:\n\n```\nwest init -l .\nwest update\n./scripts/test\n```\n\nIf you want to build locally, you should be able to do so by installing west,\nrunning west init and then installing the SDK dependencies locally:\n\n```\npip3 install -g west\nmkdir workspace \u0026\u0026 cd workspace\n# it is important that you clone into a workspace!\ngit clone git@github.com:swedishembedded/control.git\nwest init -l .\nwest update\n../sdk/scripts/install-sdk\n```\n\nThis will install several different cross compilation toolchains and all the\nother tools you need in order to build firmware for a wide variety of\narchitectures.\n\nTo build and run individual tests on specific boards you can do like this:\n\n```\nwest boards # list boards\nwest build -p -b \u003cboard\u003e tests/ai -t run # build and run\nwest build -t run # do a subsequent run after building for the first time\n```\n\n# Building documentation\n\n``` shell\n  apt update \u0026\u0026  \n    apt install -qy \n    libglib2.0-dev\n    libglib2.0-dev-bin\n    libgtest-dev\n    ruby2.7-dev\n    libcairo2-dev\n    libpango1.0-dev\n    libgdk-pixbuf2.0-dev\n    libxml2-dev\n  pip install asciidoxy\n  gem install asciidoctor-mathematical\n  mkdir build \u0026\u0026\n    cd build \u0026\u0026\n    cmake .. \u0026\u0026\n    make docs\n```\n\n# How to help to build on this control toolbox\n\nIf you are interested in contributing to this library, feel free to raise a pull\nrequest.\n\n# GNU Octave Functions\nInstalling GNU Octave's Control-Toolbox or MATLAB's Control-Toolbox/System\nIdentification Toolbox WILL cause problems with this toolbox because they are\nusing the same function names. This toolbox implements better versions of the\noriginal functions so you should either use this toolbox inside you .m file or\nopt for using the default gnuoctave implementations - but not both.\n\n# System Identification Toolbox\n- OKID for multivariable hydraulic systems or temperature systems\n- ERA-DC for mechanical damped systems in the time plane\n- SINDY for multivariable abritary nonlinear systems\n- RLS for all kind of arbitary single input and single output systems (Use this\n  first!)\n- OCID for linear feedback systems (I haven't found any real world practice for\n  this method yet)\n- FILTFILT2 for low pass filtering without phase delay\n- SPA for spectral analysis\n- IDBODE for mechanical damped systems in the frequency plane\n- RPCA for filtering data and images\n- ICA for separating signals so they are independent from each other\n- SR-UKF-Parameter-Estimation for finding parameters from an very complex system\n  of equation if data is available\n- SR-UKF-State-Estimation for filtering noise and estimate the state of a system\n- SVM for classification of data\n- N4SID for MIMO, SIMO, MISO or SISO state space systems\n- MOESP for MIMO, SIMO, MISO or SISO state space systems\n- PIMOESP for MIMO, SIMO, MISO, or SISO state space systems\n\n## State space model identification methods\n\n|Function|Description|Status|Model\n|--------|-----------|------|-----\n|eradc|Eigensystem Realization Algorithm Data Correlation|Done|MIMO\n|okid|Observer Kalman Filter Identification|Done|MIMO\n|ocid|Observer Controller Identification|Done|MIMO\n|rls|Recursive Least Square|Done|SISO\n\n## Nonlinear system identification methods\n\n|Function|Description|Status|Model\n|--------|-----------|------|-----\n|sindy|Sparse Identification of Nonlinear Dynamics|Done|MIMO\n|sr_ukf_parameter_estimation|Estimate parameters for a nonlinear system. Notice that this is parameter estimation. Not system identification.|Done|MIMO\n|sr_ukf_state_estimation|Estimate states for a nonlinear system. This is system identification|Done|MIMO\n\n## Subspace identification algorithms\n\n|Function|Description|Status|Model\n|--------|-----------|------|-----\n|moesp|Multivariable Output-Error State Space|Done|MIMO\n|pimoesp|Past-Input Multivariable Output-Error State Space|Done|MIMO\n|n4sid|Numerical algorithms for Subspace State Space System IDentification|Done|MIMO\n\n## Analysis and filtering\n\n|Function|Description|Status\n|--------|-----------|------\n|spa|Plot bode spectral analysis plot using Fast Fourier Transform|Done\n|filtfilt2|Zero phase filtering with low pass filter|Done\n|idbode|Plot bode diagram from frequency data|Done\n|rpca|Filter data using Robust Principal Component Analysis|Done\n|ica|Separate signals from each other so they are independent|Done\n\n## Classification\n\n|Function|Description|Status\n|--------|-----------|------\n|Svm|Support Vector Machine with C code generation|Done\n|--------|-----------|------\n\n# Control systems design toolbox\n\nThese functions are used for control system design.\n\n## Model creation\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|tf|Crate transfer function model|Done|No|N/N|Y\n|zpk|Create zero-pole-gain model|Done|No|N/N|Y\n|ss|Create state space model|Done|Yes|N/N|Y\n\n## Model transformation\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|minreal|Minimal realization|Done|Yes|Y/Y|Y\n|balreal|Balanced realization|Done|Yes|N/Y|Y\n|modred|Model reduction|Done|Yes|N/Y|Y\n|append|Append systems|Done|Yes|Y/Y|Y\n|feedback|Feedback model|Done|Yes|Y/Y|Y\n|series|Serial model|Done|Yes|Y/Y|Y\n|parallel|Parallel model|Done|Yes|Y/Y|Y\n|pade|Internal time delay to model|Done|Yes|Y/N|Y\n|referencegain|Create gain for better tracking|Done|Yes|N/Y|Y\n\n## Model data access\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|dcgain|Get the low frequency gain|Done|Yes|Y/Y|Y\n|pzmap|Plot poles and zeros|Done|Yes|Y/Y|Y\n|damp|Get the damping|Done|Yes|Y/Y|Y\n|pole|Get poles|Done|Yes|Y/Y|Y\n|zero|zeros for SISO |Done|No|Y/Y|Y\n|tzero|zeros for MIMO |Done|Yes|N/Y|Y\n\n## Model conversions\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|c2d|Convert continuous to discrete|Done|Yes|Y/Y|N\n|c2dt|Convert continuous to discrete with delay|Done|Yes|Y/Y|N\n|d2c|Convert discrete to continuous|Done|Yes|Y/Y|Y\n|d2d|Rediscrete the model|Done|Yes|Y/Y|Y\n|tf2ss|Transfer function to state space|Done|No|Y/N|Y\n|ss2tf|State space to transfer function|Done|Yes|N/Y|Y\n\n## Frequency domain analysis\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|evalfr|Get one frequency|Done|Yes|Y/Y|Y\n|freqresp|Get multiple frequencies|Done|Yes|Y/Y|Y\n|bode|Bode diagram|Done|Yes|Y/Y|Y\n|bodemag|Bode diagram without phase|Done|Yes|Y/Y|Y\n|nyquist|Nyquist diagram|Done|Yes|Y/Y|Y\n|sigma|Singular value diagram|Done|Yes|Y/Y|Y\n|margin|Stability margins|Done|Yes|Y/Y|Y\n|allmargin|Show all margin|Done|Yes|Y/Y|Y\n|sensitivity|Show sensitivity margins|Done|Yes|Y/Y|Y\n|db2mag|Convert dB to magnintude|Done|Yes|Y/Y|Y\n|mag2db|Conver magnintude to dB|Done|Yes|Y/Y|Y\n|rlocus|Root locus plot|Done|Yes|Y/Y|Y\n|rlocfind|Find the P-gain of a pole|Done|Yes|Y/Y|Y\n|sgrid|Create ring and lines for damping|Done|Yes|Y/Y|Y\n|findmaxgain|Compute the max gain limit|Done|Yes|Y/Y|Y\n|dBdrop|Find the frequency at 3 dB drop|Done|Yes|Y/Y|Y\n\n## Time domain analysis\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|gensig|Generate signals|Done|No|N/N|Y\n|impulse|Impulse response|Done|Yes|Y/Y|Y\n|step|Step response|Done|Yes|Y/Y|Y\n|ramp|Ramp response|Done|Yes|Y/Y|Y\n|initial|Response with initial conditions|Done|Yes|N/Y|Y\n|lsim|Linear simulation response|Done|Yes|Y/Y|Y\n|satlsim|Saturation linear simulation|Done|Yes|Y/Y|Y\n|nlsim|Nonlinear simulation|Done|Yes|Y/Y|Y\n\n## Single variable control\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|pid|Parallel PID controller|Done|No|N/N|Y\n|pipd|Serial PID controller|Done|No|N/N|Y\n|loop|Loopshaping controller|Done|No|Y/N|Y\n|acker|Acker formula|Done|No|N/Y|Y\n\n## Multivariable control\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|lqr|Linear quadratic regulator|Done|Yes|N/Y|Y\n|lqe|Linear quadratic estimator|Done|Yes|N/Y|Y\n|lqi|Linear quadratic integral|Done|Yes|N/Y|Y\n|reg|Generates the LQ-model|Done|Yes|N/Y|Y\n|lqgreg|Generates the Gaussian LQG-model|Done|Yes|N/Y|Y\n|lmpc|Simulate a linear Model Predictive Control|Done|Yes|N/Y|Y\n\n## Systems of equations\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|lyap|Solve Lyapunov equation|Done|Y|N/N|Y\n|are|Solve algibraic riccati equation|Done|Y|N/Y|Y\n|obsv|Observbility matrix|Done|Y|N/Y|Y\n|ctrb|Controllbility matrix|Done|Y|N/Y|Y\n|gram|Gramian|Done|Y|N/Y|Y\n|hsvd|Hankel singular values|Done|Y|N/Y|Y\n|covar|Covaraiance matrix|Done|Y|N/Y|Y\n\n## Compensators\n\n|Function name|Description|Status|MIMO|TF/SS|Discrete\n|-------------|-----------|------|----|-----|--------\n|smithpredict|Otto Smith delay compensator|Done|No|Y/N|Y\n|imc|Disturbance compensator|Done|No|Y/N|Y\n\n\n# Tests\n\nThis is a major TODO for this source code: there is a basic test framework in\nplace, but we need actual automated tests that verify results. Currently the\ntests have form of examples which compile and run, but do not verify the\nresults. We need to add Unity macros for checking test results. Unity is\nalready supported, only the test assertions themselves need to be added.\n\n# Papers:\n\nThis library contains realization identification and polynomal algorithms. They\ncan be quite hard to understand, so I highly recommend to read papers in the\n\"reports\" folder about the realization identification algorithms if you want to\nunderstand how they work. \n\n### OKID - Observer Kalman Filter Identification\nOKID is an algoritm that creates the impulse makrov parameter response from\ndata for identify a state space model and also a kalman filter gain matrix. Use\nthis if you got regular data from a dynamical system. This algorithm can handle\nboth SISO and MISO. OKID have it's orgin from Hubble Telescope at NASA. This\nalgorithm was invented 1991. The drawback with OKID algorithm is that it's very\nextremely sensitive to noise. So I have modify OKID by including SINDy\nalgorithm and Euler simulation plus Algebraic Riccati Equations for finding the\ndiscrete kalman gain matrix K. So now it's very robust against noise.\n\n```matlab\n[sysd, K] = okid(u, y, t, sampleTime);\n```\n\n### Example OKID\n\nHere I programmed a Beijer PLC that controls the multivariable cylinder system.\nIt's a nonlinear system, but OKID can handle it because it's not so nonlinear as\na hydraulic motor. Cylinder 0 and Cylinder 1 affecting each other when the\npropotional control valves opens.\n\n![a](pictures/PLC%20system.jpg)\n\n![a](pictures/OKID_System.jpg)\n\n\n```matlab\n% Load the data\nX = csvread('MultivariableCylinders.csv');\nt = X(:, 1);\nr0 = X(:, 2);\nr1 = X(:, 3);\ny0 = X(:, 4);\ny1 = X(:, 5);\nsampleTime = 0.1;\n\n% Transpose the CSV data\nu = [r0';r1'];\ny = [y0';y1'];\nt = t';\n\n% Create the model\n[sysd, K] = okid(u, y, t, sampleTime);\n\n% Do simulation\n[outputs, T, x] = lsim(sysd ,y, t);\nclose\nplot(T, outputs(1, :), t, y(1, :))\ntitle('Cylinder 0');\nxlabel('Time');\nylabel('Position');\ngrid on\nlegend('Identified', 'Measured');\nylim([0 12]);\nfigure\nplot(T, outputs(2, :), t, y(2, :))\ntitle('Cylinder 1');\nxlabel('Time');\nylabel('Position');\ngrid on\nlegend('Identified', 'Measured');\nylim([0 12]);\n```\n![a](pictures/OKID_Result.png)\n\n### RLS - Recursive Least Squares\nRLS is an algorithm that creates a transfer function model from regular data.\nHere you can select if you want to estimate an ARX model or an ARMAX model,\ndepending on the number of zeros in the polynomal \"nze\". Select number of\nerror-zeros-polynomal \"nze\" to 1, and you will get a ARX model or select \"nze\"\nequal to model poles \"np\", you will get an ARMAX model that also includes a\nkalman gain matrix K. I recommending that. This algorithm can handle data with\nhigh noise, but you will only get a SISO model from it. This algorithm was\ninvented 1821 by Gauss, but it was until 1950 when it got its attention in\nadaptive control.\n\nUse this algorithm if you have regular data from a open loop system and you want\nto apply that algorithm into embedded system that have low RAM and low flash\nmemory. RLS is very suitable for system that have a lack of memory.\n\n```matlab\n[sysd, K] = rls(u, y, np, nz, nze, sampleTime, forgetting);\n```\n\n### Example RLS\n\nThis is a hanging load of a hydraulic system. This system is a linear system due to the hydraulic cylinder that lift the load. Here I create two linear first order models. One for up lifting up and one for lowering down the weight. I'm also but a small orifice between the outlet and inlet of the hydraulic cylinder. That's create a more smooth behavior. Notice that this RLS algorithm also computes a Kalman gain matrix.\n\n![a](pictures/RLS_System.jpg)\n\n```matlab\n% Load data\nX = csvread('HangingLoad.csv');\nt = X(:, 1); % Time\nr = X(:, 2); % Reference \ny = X(:, 3); % Output position\nu = X(:, 4); % Input signal from P-controller with gain 3\nsampleTime = 0.02;\n \n% Do identification of the first data set\nl = length(r) + 2000; % This is half data\n\n% Do identification on up and down\nsysd_up = rls(r(1:l/2), y(1:l/2), 1, 1, 1, sampleTime);\nsysd_down = rls(r(l/2+1:end), y(l/2+1:end), 1, 1, 1, sampleTime);\n\n% Simulate \n[~,~,x] = lsim(sysd_up, r'(1:l/2), t'(1:l/2));\nhold on\nlsim(sysd_down, r'(l/2+1:end), t'(l/2+1:end), x(:, end));\nhold on\nplot(t, y);\nlegend('Up model', 'Down model', 'Measured');\ntitle('Hanging load - Hydraulic system')\nxlabel('Time [s]')\nylabel('Position');\n````\n\nHere we can se that the first model follows the measured position perfect. The \"down-curve\" should be measured a little bit longer to get a perfect linear model.\n\n![a](pictures/RLS_Result.png)\n\n### ERA/DC - Eigensystem Realization Algorithm Data Correlations\nERA/DC was invented 1987 and is a successor from ERA, that was invented 1985 at NASA. The difference between ERA/DC and ERA is that ERA/DC can handle noise much better than ERA. But both algorihtm works as the same. ERA/DC want an impulse response. e.g called markov parameters. You will get a state space model from this algorithm. This algorithm can handle both SISO and MISO data.\n\nUse this algorithm if you got impulse data from e.g structural mechanics.\n\n```matlab\n[sysd] = eradc(g, sampleTime, systemorder);\n```\n### Example ERA/DC\n\n![a](pictures/ERADC_System.png)\n\n```matlab\n%% Parameters\nm1 = 2.3;\nm2 = 3.1;\nk1 = 8.5;\nk2 = 5.1;\nb1 = 3.3;\nb2 = 5.1;\n\nA=[0                 1   0                                              0\n  -(b1*b2)/(m1*m2)   0   ((b1/m1)*((b1/m1)+(b1/m2)+(b2/m2)))-(k1/m1)   -(b1/m1)\n   b2/m2             0  -((b1/m1)+(b1/m2)+(b2/m2))                      1\n   k2/m2             0  -((k1/m1)+(k1/m2)+(k2/m2))                      0];\nB=[0;                 \n   1/m1;              \n   0;                \n   (1/m1)+(1/m2)];\nC=[0 0 1 0];\nD=[0];\ndelay = 0;\n\n%% Model\nbuss = ss(delay,A,B,C,D);\n\n%% Simulation\n[g, t] = impulse(buss, 10);\n\n%% Add 15% noise\nload v\nfor i = 1:length(g)-1\n  noiseSigma = 0.15*g(i);\n  noise = noiseSigma*v(i); % v = noise, 1000 samples -1 to 1\n  g(i) = g(i) + noise;\nend\n\n%% Identification  \nsystemorder = 4;\n[sysd] = eradc(g, t(2) - t(1), systemorder);\n    \n%% Validation\ngt = impulse(sysd, 10);\nclose\n    \n%% Check\nplot(t, g, t, gt(:, 1:2:end))\nlegend(\"Data\", \"Identified\", 'location', 'northwest')\ngrid on\n```\n\n![a](pictures/ERADC_Result.png)\n\n\n### OCID - Observer Controller Identification\nThis is an extention from OKID. The idea is the same, but OCID creates a LQR contol law as well. This algorithm works only for closed loop data. It have its orgin from NASA around 1992 when NASA wanted to identify a observer, model and a LQR control law from closed loop data that comes from an actively controlled aircraft wing in a wind tunnel at NASA Langley Research Center. This algorithm works for both SISO and MIMO models.\n\nUse this algorithm if you want to extract a LQR control law, kalman observer and model from a running dynamical system. Or if your open loop system is unstable and it requries some kind of feedback to stabilize it. Then OCID is the perfect choice.\n\n```matlab\n[sysd, K, L] = ocid(r, uf, y, sampleTime, regularization, systemorder);\n```\n\n![a](pictures/OCID_System.png)\n\n### OCID Example\n\n```matlab\n%% Matrix A\nA = [0 1  0  0; \n    -7 -5 0  1; \n     0 0  0  1;\n     0 1 -8 -5];\n  \n%% Matrix B\nB = [0 0; \n     1 0; \n     0 0; \n     0 1];\n  \n%% Matrix C\nC = [1 0 0 0; \n     0 0 0 1];\n  \n%% Model and signals\ndelay = 0;\nsys = ss(delay, A, B, C);\nt = linspace(0, 20, 1000);\nr = [linspace(5, -11, 100) linspace(7, 3, 100) linspace(-6, 9, 100) linspace(-7, 1, 100) linspace(2, 0, 100) linspace(6, -9, 100) linspace(4, 1, 100) linspace(0, 0, 100) linspace(10, 17, 100) linspace(-30, 0, 100)];\nr = [r;2*r]; % MIMO\n  \n%% Feedback\nQ = sys.C'*sys.C;\nR = [1 4; 1 5];\nL = lqr(sys, Q, R);\n[feedbacksys] = reg(sys, L);\nyf = lsim(feedbacksys, r, t);\n\n%% Add 10% noise\nload v\nfor i = 1:length(yf)\n  noiseSigma = 0.10*yf(:, i);\n  noise = noiseSigma*v(i); % v = noise, 1000 samples -1 to 1\n  yf(:, i) = yf(:, i) + noise;\nend\n\n%% Identification  \nuf = yf(3:4, :); % Input feedback signals\ny = yf(1:2, :); % Output feedback signals\nregularization = 600;\nmodelorder = 4;\n[sysd, K, L] = ocid(r, uf, y, t(2) - t(1), regularization, modelorder);\n    \n%% Validation\nu = -uf + r; % Input signal %u = -Lx + r = -uf + r\nyt = lsim(sysd, u, t);\nclose\n    \n%% Check\nplot(t, yt(1:2, 1:2:end), t, yf(1:2, :))\nlegend(\"Identified 1\", \"Identified 2\", \"Data 1\", \"Data 2\", 'location', 'northwest')\ngrid on\n```\n\n![a](pictures/OCID_Result.png)\n\n\n### SINDy - Sparse Identification of Nonlinear Dynamics\nThis is a new identification technique made by ![Eurika Kaiser](https://github.com/eurika-kaiser) from University of Washington. It extends the identification methods of grey-box modeling to a much simplier way. This is a very easy to use method, but still powerful because it use least squares with sequentially thresholded least squares procedure. I have made it much simpler because now it also creates the formula for the system. In more practical words, this method identify a nonlinear ordinary differential equations from time domain data.\n\nThis is very usefull if you have heavy nonlinear systems such as a hydraulic orifice or a hanging load. \n\n### SINDy Example\n\nThis example is a real world example with noise and nonlinearities. Here I set up a hydraulic motor in a test bench and measure it's output and the current to the valve that gives the motor oil. The motor have two nonlinearities - Hysteresis and the input signal is not propotional to the output signal. By using two nonlinear models, we can avoid the hysteresis. \n\n![a](pictures/FestoBench.jpg)\n\n```matlab\n% Load CSV data\nX = csvread('MotorRotation.csv'); % Can be found in the folder \"data\"\nt = X(:, 1);\nu = X(:, 2);\ny = X(:, 3);\nsampleTime = 0.02;\n\n% Do filtering of y\ny = filtfilt2(y', t', 0.1)';\n\n% Sindy - Sparce identification Dynamics\nactivations = [1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; % Enable or disable the candidate functions such as sin(u), x^2, sqrt(y) etc...\nlambda = 0.05;\nl = length(u);\nh = floor(l/2);\ns = ceil(l/2);\nfx_up = sindy(u(1:h), y(1:h), activations, lambda, sampleTime); % We go up\nfx_down = sindy(u(s:end), y(s:end), activations, lambda, sampleTime); % We go down\n\n% Simulation up\nx0 = y(1:h)(1);\nu_up = u(1:h)(1:100:end)';\nstepTime = 1.2;\n[x_up, t] = nlsim(fx_up, u_up, x0, stepTime, 'ode15s');\n\n% Simulation down \nx0 = y(s:end)(1);\nu_down = u(s:end)(1:100:end)';\nstepTime = 1.2;\n[x_down, t] = nlsim(fx_down, u_down, x0, stepTime, 'ode15s');\n\n% Compare \nclose all\nplot([x_up x_down])\nhold on \nplot(y(1:100:end));\nlegend('Simulation', 'Measurement')\nylabel('Rotation')\nxlabel('Time')\ngrid on\n```\n\n![a](pictures/SINDY_Result.png)\n\nHere is a multivariable example with SINDy. It use the same data as the OKID scenario.\n\n```matlab\n% Data\nX = csvread('MultivariableCylinders.csv');\nt = X(:, 1);\nr0 = X(:, 2); % Reference 0\nr1 = X(:, 3); % Reference 1\ny0 = X(:, 4); % Output 0\ny1 = X(:, 5); % Output 1\nsampleTime = 0.1;\n\n% Identification\ninputs = [r0 r1];\noutputs = [y0 y1];\nactivations = [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];\nlambda = 0.2;\nmodel = sindy(inputs, outputs, activations, lambda, sampleTime);\n\n% Simulation\nu = inputs';\nx0 = outputs'(:, 1);\nstepTime = 1.0;\n[x, t] = nlsim(model, u, x0, stepTime, 'ode15s');\n\n% Compare\nclose all \nplot(x(1, :))\nhold on \nplot(y0)\nlegend('Simulation', 'Measurement')\nylabel('Position')\nxlabel('Time')\ntitle('Cylinder 0')\ngrid on\n\nfigure\nplot(x(2, :))\nhold on \nplot(y1)\nlegend('Simulation', 'Measurement')\nylabel('Position')\nxlabel('Time')\ntitle('Cylinder 1')\ngrid on\n```\n\n![a](pictures/SINDY_Result_multivariable.png)\n\n### IDBode - Identification Bode\nThis plots a bode diagram from measurement data. It can be very interesting to\nsee how the amplitudes between input and output behaves over frequencies. This\ncan be used to confirm if your estimated model is good or bad by using the\n`bode` command from this toolbox and compare it with idebode.\n\n```matlab\nidbode(u, y, w);\n```\n\n### IDBode Example\n\n![a](pictures/IDBODE_System.png)\n\n```matlab\n%% Model of a mass spring damper system\nM = 5; % Kg\nK = 100; % Nm/m\nb = 52; % Nm/s^2\nG = tf([1], [M b K]);\n\n%% Frequency response\nt = linspace(0.0, 50, 3000);\nw = linspace(0, 100, 3000);\nu = 10*sin(2*pi*w.*t);\n\n%% Simulation\ny = lsim(G, u, t);\nclose\n\n%% Identify bode diagram\nidbode(u, y, w);\n\n%% Check\nbode(G);\n```\n\n![a](pictures/IDBODE_Result.png)\n\n### SPA - Spectral Analysis\nThis plots all the amplitudes from noisy data over its frequencies. Very good to see what type of noise or signals you have. With this, you can determine what the real frequencies and amplitudes are and therefore you can create your filtered frequency response that are clean.\n\n```matlab\n[amp, wout] = spa(y, t);\n```\n\n### SPA Example\n\nAssume that we are using the previous example with different parameters.\n\n```matlab\n%% Model of a mass spring damper system\nM = 1; % Kg\nK = 500; % Nm/m\nb = 3; % Nm/s^2\nG = tf([1], [M b K]);\n\n%% Frequency response\nt = linspace(0.0, 100, 30000);\nu1 = 10*sin(2*pi*5.*t); % 5 Hz\nu2 = 10*sin(2*pi*10.*t); % 10 Hz\nu3 = 10*sin(2*pi*20.*t); % 20 Hz\nu4 = 10*sin(2*pi*8.*t); % 8 Hz\nu = u1 + u2 + u3 + u4;\n\n%% Simulation\ny = lsim(G, u, t);\nfigure\n\n%% Noise\ny = y + 0.001*randn(1, 30000); \n\n%% Identify what frequencies we had!\nspa(y, t);\n```\n\n![a](pictures/SPA_Result.png)\n\n### Filtfilt2 - Zero Phase Filter\nThis filter away noise with a good old low pass filter that are being runned twice. Filtfilt2 is equal to the famous function filtfilt, but this is a regular .m file and not a C/C++ subroutine. Easy to use and recommended. \n\n```matlab\n[y] = filtfilt2(y, t, K);\n```\n\n### Filtfilt2 Example\n\nWe are using the previous example here as well.\n\n```matlab\n%% Model of a mass spring damper system\nM = 1; % Kg\nK = 500; % Nm/m\nb = 3; % Nm/s^2\nG = tf([1], [M b K]);\n\n%% Input signal\nt = linspace(0.0, 100, 3000);\nu = 10*sin(t);\n\n%% Simulation\ny = lsim(G, u, t);\n\n%% Add 10% noise\nload v\nfor i = 1:length(y)\n  noiseSigma = 0.10*y(i);\n  noise = noiseSigma*v(i); % v = noise, 1000 samples -1 to 1\n  y(i) = y(i) + noise;\nend\n\n%% Filter away the noise\nlowpass = 0.2;\n[yf] = filtfilt2(y, t, lowpass);\n\n%% Check\nplot(t, yf, t, y);\nlegend(\"Filtered\", \"Noisy\");\n```\n![a](pictures/FILTFILT2_Result.png)\n\n### Robust Principal Component Analysis\nRobust principal component analysis(RPCA) is a great tool if you want to separate noise from data `X` into a matrix `S`. `RPCA` is a better tool than `PCA` because it using optimization and not only reconstructing the image using `SVD`, which `PCA` only does.\n\n```matlab\n[L, S] = rpca(X);\n```\n### Robust Principal Component Analysis example\n\n```matlab\nX = imread('bob.jpg'); % Load Mr Bob\nX = rgb2gray(X);       % Grayscale 8 bit\nX = double(X);         % Must be double 40 =\u003e 40.0\n[L, S] = rpca(X);      % Start RPCA. Our goal is to get L matrix\nfigure(1)\nimshow(uint8(X))       % Before RPCA\ntitle('Before RPCA - Bob')\nfigure(2)\nimshow(uint8(L))       % After RPCA\ntitle('After RPCA - Bob')\n```\n\n![a](pictures/RPCA_Bob.png)\n\n### Independent Component Analysis\nIndependent component analysis(ICA) is a tool if you want to separate independent signals from each other. This is not a filter algorithm, but instead of removing noise, it separate the disturbances from the signals. The disturbances are created from other signals. Assume that you have an engine and you are measuring vibration in X, Y and Z-axis. These axis will affect each other and therefore the signals will act like they are mixed. ICA separate the mixed signals into clean and independent signals.\n\n```matlab\n[S] = ica(X);\n```\n### Independent Component Analysis example\n\n```matlab\n% Clear all plots\nclear\nclose all\nclc\n\n% Tick clock\ntic\n\n%% Parameters\nN = 6;                            %The number of observed mixtures\nM = 1000;                         %Sample size, i.e.: number of observations\n\nK = 0.1;                          %Slope of zigzag function\nna = 8;                           %Number of zigzag oscillations within sample\nns = 5;                           %Number of alternating step function oscillations within sample\n\nfinalTime = 40*pi;                %Final sample time (s)\ninitialTime = 0;                  %Initial sample time (s)\n\n%% Generating Data for ICA\n% Create time vector data\ntimeVector  = initialTime:(finalTime-initialTime)/(M-1):finalTime;\n\n% Create random, cos, sin and fast cos signal\nsource1     = rand(1, M);                   \nsource2     = cos(0.25*timeVector);         \nsource3     = sin(0.1*timeVector);          \nsource4     = cos(0.7*timeVector);          \n\n% Ziggsack signal\nsource5 = zeros(1,M);   \nperiodSource5 = (finalTime-initialTime)/na; \nfor i = 1:M\n    source5(i) = K*timeVector(i)-floor(timeVector(i)/periodSource5)*K*periodSource5;\nend\nsource5 = source5 - mean(source5);\n\n% PWM signal\nsource6 = zeros(1,M);  \nperiodSource6 = (finalTime-initialTime)/ns/2;\nfor i = 1:M\n    if mod(floor(timeVector(i)/periodSource6),2) == 0\n        source6(i) = 1;\n    else\n        source6(i) = -1;\n    end    \nend\n\nsource6 = source6 - mean(source6);\n\n% Create our source matrix. This matrix is what want to find\nS = [source1;source2;source3;source4;source5;source6];\n\n% Create an matrix A that going to mix all signals in S, that we calling X\nAmix = rand(N,N);                    \nX = Amix*S;                                 \n\nfigure\nplot(timeVector,source1)                    \nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('source 1')\n\nfigure\nplot(timeVector,source2)                    \nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('source 2')\n\nfigure\nplot(timeVector,source3)                    \nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('source 3')\n\nfigure\nplot(timeVector,source4)                    \nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('source 4')\n\nfigure\nplot(timeVector,source5)                   \nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('source 5')\n\nfigure\nplot(timeVector,source6)                    \nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('source 6')\n\nfigure\nplot(timeVector,X);                      \nxlabel('time (s)') \nylabel('Signal Amplitude')\nlegend('Observed Mixture 1', 'Observed Mixture 2', 'Observed Mixture 3', 'Observed Mixture 4', 'Observed Mixture 5', 'Observed Mixture 6')\n\n% Use ICA to find S from X\nS = ica(X);\n\nfigure\nplot(timeVector, S(1,:))\nxlabel('time (s)') \nylabel('Signal Amplitude') \nlegend('Source Estimation 1')\n\nfigure\nplot(timeVector, S(2,:))\nxlabel('time (s)') \nylabel('Signal Amplitude') \nlegend('Source Estimation 2')\n\nfigure\nplot(timeVector, S(3,:))\nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('Source Estimation 3')\n\nfigure\nplot(timeVector, S(4,:))\nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('Source Estimation 4')\n\nfigure\nplot(timeVector, S(5,:))\nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('Source Estimation 5')\n\nfigure\nplot(timeVector, S(6,:))\nxlabel('time (s)')\nylabel('Signal Amplitude') \nlegend('Source Estimation 6')\n\n% End clock time and check the difference how long it took\ntoc\n```\n\nThese signals are what we want to find\n\n![a](pictures/ICA_Before.png)\n\nThis is how the signals look when we are measuring them\n\n![a](pictures/ICA_Mixed_Signals.png)\n\nThis is how the signals are reconstructed as they were independent\n\n![a](pictures/ICA_After.png)\n\n### Square Root Uncented Kalman Filter for parameter estimation\n\nThis is Uncented Kalman Filter that using cholesky update method (more stable),\ninstead of cholesky decomposition. This algorithm can estimate parameters to\nvery a complex function if data is available. This method is recursive and\nimplemented in this repository in C as well. Use this when you need to estimate\nparameters to a function if you have data that are generated from that function.\nIt can be for example an object that you have measured data and you know the\nmathematical formula for that object. Use the measured data with this algorithm\nand find the parameters for the formula.\n\n```matlab\n[Sw, what] = sr_ukf_parameter_estimation(d, what, Re, x, G, lambda_rls, Sw, alpha, beta, L);\n```\n\n### Square Root Uncented Kalman Filter for parameter estimation example\n```matlab\n% Initial parameters\nL = 3;                  % How many states we have\ne = 0.1;                % Tuning factor for noise\nalpha = 0.1;            % Alpha value - A small number like 0.01 -\u003e 1.0\nbeta = 2.0;             % Beta value - Normally 2 for gaussian noise\nRe = e*eye(L);          % Initial noise covariance matrix - Recommended to use identity matrix\nSw = eye(L);            % Initial covariance matrix - Recommended to use identity matrix\nwhat = zeros(L, 1);     % Estimated parameter vector\nd = zeros(L, 1);        % This is our measurement\nx = [4.4; 6.2; 1.0];    % State vector\nlambda_rls = 1.0;       % RLS forgetting parameter between 0.0 and 1.0, but very close to 1.0\n\n% Our transition function - This is the orifice equation Q = a*sqrt(P2 - P1) for hydraulics\nG = @(x, w) [w(1)*sqrt(x(2) - x(1));\n            % We only need to use w(1) so we assume that w(2) and w(3) will become close to 1.0 \n             w(2)*x(2);\n             w(3)*x(3)];\n             \n% Start clock time\ntic\n\n% Declare arrays \nsamples = 100;\nWHAT = zeros(samples, L);\nE = zeros(samples, L);\n\n% Do SR-UKF for parameter estimation\nfor i = 1:samples\n  % Assume that this is our measurement \n  d(1) = 5 + e*randn(1,1);\n  \n  % This is just to make sure w(2) and w(3) becomes close to 1.0\n  d(2) = x(2);\n  d(3) = x(3);\n  \n  % SR-UKF\n  [Sw, what] = sr_ukf_parameter_estimation(d, what, Re, x, G, lambda_rls, Sw, alpha, beta, L);\n  \n  % Save the estimated parameter \n  WHAT(i, :) = what';\n  \n  % Measure the error\n  E(i, :) = abs(d - G(x, what))';\nend\n\n% Stop the clock\ntoc \n\n% Print the data\n[M, N] = size(WHAT);\n\nfor k = 1:N                                 \n  subplot(3,1,k);\n  plot(1:M, WHAT(:,k), '-', 1:M, E(:, k), '--');\n  title(sprintf('Parameter estimation for parameter w%i', k));\n  ylabel(sprintf('w%i', k));\n  grid on\n  legend('Estimated parameters', 'Parameter error')\nend\n```\n\n![a](pictures/SR_UKF_parameter_estimation.png)\n\n### Square Root Uncented Kalman Filter for state estimation\n\nThis is Uncented Kalman Filter that using cholesky update method (more stable),\ninstead of cholesky decomposition. This algorithm can estimate states from a\nvery complex model. This method is reqursive and implemented in this repository\nin C as well. Use this when you need to estimate state to a model if you have\ndata that are generated from that function. It can be for example an object\nthat you have measured data and you know the mathematical formula for that\nobject. Use the measured data with this algorithm and find the states for the\nmodel.\n\n```matlab\n[S, xhat] = sr_ukf_state_estimation(y, xhat, Rn, Rv, u, F, S, alpha, beta, L);\n```\n\n### Square Root Uncented Kalman Filter for state estimation example\n```matlab\n% Initial parameters\nL = 3;                  % How many states we have\nr = 1.5;                % Tuning factor for noise\nq = 0.2;                % Tuning factor for disturbance\nalpha = 0.1;            % Alpha value - A small number like 0.01 -\u003e 1.0\nbeta = 2.0;             % Beta value - Normally 2 for gaussian noise\nRv = q*eye(L);          % Initial disturbance covariance matrix - Recommended to use identity matrix\nRn = r*eye(L);          % Initial noise covariance matrix - Recommended to use identity matrix\nS = eye(L);             % Initial covariance matrix - Recommended to use identity matrix\nxhat = [0; 0; 0];       % Estimated state vector\ny = [0; 0; 0];          % This is our measurement\nu = [0; 0; 0];          % u is not used in this example due to the transition function not using an input signal\nx = [0; 0; 0];          % State vector for the system (unknown in reality)\n\n% Our transition function\nF = @(x, u) [x(2);\n             x(3);\n             0.05*x(1)*(x(2) - x(3))];\n             \n% Start clock time\ntic\n\n% Declare arrays \nsamples = 200;\nX = zeros(samples, L);\nXHAT = zeros(samples, L);\nY = zeros(samples, L);\nphase = [90;180;140];\namplitude = [1.5;2.5;3.5];\n\n% Do SR-UKF for state estimation\nfor i = 1:samples\n  % Create measurement \n  y = x + r*randn(L, 1);\n  \n  % Save measurement \n  Y(i, :) = y';\n \n  % Save actual state\n  X(i, :) = x';\n  \n  % SR-UKF\n  [S, xhat] = sr_ukf_state_estimation(y, xhat, Rn, Rv, u, F, S, alpha, beta, L);\n\n  % Save the estimated parameter \n  XHAT(i, :) = xhat';\n  \n  % Update process\n  x = F(x, u) + q*amplitude.*sin(i-1 + phase);\nend\n\n% Stop the clock\ntoc \n\n% Print the data\n[M, N] = size(XHAT);\n\nfor k = 1:N                                 \n  subplot(3,1,k);\n  plot(1:M, Y(:,k), '-g', 1:M, XHAT(:, k), '-r', 1:M, X(:, k), '-b');\n  title(sprintf('State estimation for state x%i', k));\n  ylabel(sprintf('x%i', k));\n  grid on\n  legend('y', 'xhat', 'x')\nend\n```\n\n![a](pictures/SR_UKF_state_estimation.png)\n\n### Support Vector Machine with C code generation\n\nThis algorithm can do C code generation for nonlinear models. It's a very simple\nalgorithm because the user set out the support points by using the mouse\npointer. When all the supports are set ut, then the algorithm will generate C\ncode for you so you can apply the SVM model in pure C using supplied C\nimplementation in this repository.\n\nAll you need to have is two matrices, `X` and `Y`. Where the column length is the data and the row length is the amount of classes.\nThe `svm.m` file will plot your data and then when you have placed out your support points, then the `svm.m` will generate C code for you that contains all the support points.\n\nIf you have let's say more than two variables, e.g `Z` matrix or even more. Then you can create multiple models as well by just using diffrent data as arguments for the `svm` function below. The C code generation is very fast and it's very easy to build a model. \n\n```matlab\n[X_point, Y_point, amount_of_supports_for_class] = svm(X, Y)\n```\n\n### Support Vector Machine with C code generation example\n\n```matlab\n% How much data should we generate \nN = 50;\n\n% How many classes \nc = 5;\n\n% Create variance and average for X and Y data\nX_variance = [2, 4, 3, 4, 5];\nY_variance = [3, 5, 3, 4, 5];\nX_average = [50, 70, 10, 90, 20];\nY_average = [20, 70, 60, 10, 20];\n\n% Create scatter data\nX = zeros(c, N);\nY = zeros(c, N);\nfor i = 1:c\n  % Create data for X-axis \n  X(i, 1:N) = X_average(i) + X_variance(i)*randn(1, N);\n    \n  % Create data for Y-axis\n  Y(i, 1:N) = Y_average(i) + Y_variance(i)*randn(1, N);\nend\n  \n% Create SVM model - X_point and Y_point is coordinates for the SVM points.\n% amount_of_supports_for_class is how many points there are in each row\n[X_point, Y_point, amount_of_supports_for_class] = svm(X, Y);\n  \n% Do a quick re-sampling of random data again\nfor i = 1:c\n  % Create data for X-axis \n  X(i, 1:N) = X_average(i) + X_variance(i)*randn(1, N);\n    \n  % Create data for Y-axis\n  Y(i, 1:N) = Y_average(i) + Y_variance(i)*randn(1, N);\nend\n  \n% Check the SVM model\npoint_counter_list = zeros(1, c);\nfor i = 1:c\n  % Get the points \n  svm_points_X = X_point(i, 1:amount_of_supports_for_class(i));\n  svm_points_Y = Y_point(i, 1:amount_of_supports_for_class(i));\n    \n  % Count how many data points this got - Use inpolygon function that return 1 or 0 back\n  point_counter_list(i) = sum(inpolygon(X(i,:) , Y(i, :), svm_points_X, svm_points_Y));\nend\n  \n% Plot how many each class got - Maximum N points per each class\nfigure \nbar(point_counter_list);\nxlabel('Class index');\nylabel('Points');\n```\n\n![a](pictures/SVM_plot.png)\n\n![a](pictures/SVM_results.png)\n\n![a](pictures/SVM_c_source.png)\n\n![a](pictures/SVM_c_header.png)\n\n# Typical use\n\nTo use control library functions, you should allways start with to create a\ntransfer function or a state space model. Then you can use that mathematical\nmodel in almost all of the control system design functions. \n\nHere are some examples of using the control system design functions.\n\nMATLAB pictures are from Umeå University.\n\nCreating a transfer function in MATLAB®\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-00-55.png)\n\nCreating a transfer function in GNU Octave\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-01-11.png)\n\nCreate a bode diagram plot in MATLAB®\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-04-59.png)\n\nCreate a bode diagram plot in GNU Octave\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-04-32.png)\n\nCreate a state space model in MATLAB®\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-06-29.png)\n\nCreate a state space model in GNU Octave \n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-06-41.png)\n\nDo a step simulation in MATLAB®\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-08-23.png)\n\nDo a step simulation in GNU Octave\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-07-36.png)\n\nConvert a time continuous transfer function to a discrete transfer function in MATLAB®\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-09-19.png)\n\nConvert a time continuous transfer function to a discrete transfer function in GNU Octave\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-10-03.png)\n\nDo a nyquist diagram plot in MATLAB®\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-11-30.png)\n\nDo a nyquist diagram plot in GNU Octave\n\n![alt text](pictures/Sk%C3%A4rmbild%20fr%C3%A5n%202017-11-09%2000-12-02.png)\n\n# Model Predictive Control - Linear programming\n\nHere I use MPC with linear programming. I used to use MPC with a quadratic programming, but unfortunately quadprog is only available for MATLAB and you need to have a license for that. So I wrote my own linear programming MPC with regularization for smoother outputs and inputs. The linear programming algorithm is available in C code as well in my other projects for embedded MPC systems, and that's the main reason why I selected a simple optimization solver instead of a large and difficult one.\n\n![alt text](pictures/Markering_024.png)\n\n# Usage with Octave\n\nTo use these algorithms in GNU octave, just add the path to the octave source\ncode to your octave project:\n\nExample:\n```matlab\npath('/path/to/control/octave/systemid', path)\npath('/path/to/control/octave/control', path)\nsavepath\n```\n\n# Square Root Uncented Kalman Filter for state estimation and parameter estimation\n\nThis is the latest Uncented Kalman Filter. MATLAB is using the same algorithm. A\n`.m` file is available at the `SR-UKF` folder.\n\nFor state estimation\n\n![a](pictures/SR-UKF/sr-ukf-state-estimation.png)\n\nFor parameter estimation\n\n![a](pictures/SR-UKF/sr-ukf-parameter-estimation.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswedishembedded%2Fcontrol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswedishembedded%2Fcontrol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswedishembedded%2Fcontrol/lists"}