Showing posts with label matlab. Show all posts
Showing posts with label matlab. Show all posts

Tuesday, July 30, 2019

Matlab: Dynamic cell array with string elements

In Matlab, to dynamically update cell array with string elements, use the following:

myCellArray = {}; %initializing cell array
for i=...
    myCellArray = [myCellArray; someString]; %dyn. update cell array
end

Note that when initializing the cell array you use curly brackets "{ }", while resizing the cell array you use square brackets "[ ]".

Saturday, May 11, 2019

Matlab: Save workspace to text file

In Matlab you can easily save workspace to a mat file. If you want to write workspace variables to a text file:

Friday, April 19, 2019

Accessing workspace from C-Mex s-function

In Matlab Simulink you can access workspace variables from a C-Mex (C++/C) s-function as follows:



To write to workspace from C-Mex, you can use
#include "matrix.h"
...
mxArray* pa = mxCreateDoubleScalar(12.34);
mexPutVariable("base", "myVarName", pa);

Note that you cannot use myVarName in a simulink block unless you call it before or during InitFcn.

Thursday, April 18, 2019

Matlab Simulink s-function handling of matrix (2D) type parameters

To demonstrate Matlab Simulink s-function handling of matrix (2D) type parameters, I prepared the following demo. The input is a constant block with "Interpret vector parameters as 1-D" unchecked and value [11, 12; 21, 22; 31, 32]:


Friday, November 30, 2018

PWM of a signal

Pulse Width Modulation can be used to convert an analog signal to digital or mimic an analog signal with digital (e.g. Arduino's analogWrite()). PWM basically converts the signal sample values into pulse width values (amplitude of pulses is constant). Below is a Matlab script that demonstrates PWM of a sine wave.


Saturday, March 18, 2017

Dealing with legacy Matlab code

A friend of mine has a project that works in Matlab Simulink 2007. He recently opened that simulink model in Matlab 2010 and could run it from Simulink without problems. But when he tried to transfer that model to xpc target for real time integration, the simulation hung and became unresponsive.

He and his team tried to find the problem by disabling Simulink blocks one at a time and in the end found the block that was causing problems. When they compared the 2007 version with the 2010 version, they could not find any differences which means that there is probably a backward compatibility issue that affects real time deployment. They had to manually recreate the whole model (more than hundred blocks) manually in Matlab 2010. Doing manual editing in code always carries the risk of breaking something. You might not know it unless you do tests with high coverage.

My first advice was to create a unit test framework so that you are sure that the new version yields the same outputs for the same inputs. A good strategy is to write scripts that vary inputs using unform distribution, run simulation on xpc target for every input, record outputs (or timeout when simulation hangs) and then compare outputs with previous results and create a report that highlights differences.

My second advice was to automate the update-to-newer-Matlab process by writing a program that automatically creates a new Simulink mdl file from the old one, beause it is easy to parse the mdl file which has an xml-look. Steps:
  1. Takes as input the depth of parsing. 1 = Copy the whole model. 2=Go one step deep and create separate mdl files for blocks in that depth 3=Go 2 steps deep etc.
  2. Parses the old Simulink mdl file and extracts the blocks
  3. Creates an mdl file in the new version format.
  4. Inserts the blocks into new mdl file(s)
  5. Runs unit tests on xpc target to see if the two versions have the same outputs (i.e. they are within 1e-15) neighborhood.
With this program, my friend can first check if for input depth =1, the model passes tests. If not, he can increase the depth until he can isolate the problem. Increasing depth on error could be automated too.

Monday, November 21, 2016

Geoid

Recently I was testing Matlab2012a geoid functions of which there are two: geoidheight (in Aerospace Toolbox) and egm96geoid (In Mapping Toolbox). I wrote the following script to check if there is a difference between these two function results for the same inputs (takes about half an hour to run):
clc; clear all;
[NVec,refvec] = egm96geoid(1, [-89.75  89.75],[-180 180]);
i = 0;
for lat_deg = -89:89
    fprintf(1, 'lat_deg = %1.1d\n', lat_deg);
    for lon_deg = 0:360
        i = i+1;
        N1_m(i) = geoidheight(lat_deg, lon_deg); %#ok<*SAGROW>

        N2Linear_m(i) = ltln2val(NVec,refvec,lat_deg,lon_deg,'bilinear');
        N2BiCubic_m(i) = ltln2val(NVec,refvec,lat_deg,lon_deg,'bicubic'); %to check if interpolation method makes any difference
    end
end
diff1 = N1_m-N2Linear_m;
diff2 = N2BiCubic_m-N2Linear_m;
subplot(2,1,1)
plot(diff1)
ylabel('diff1')
grid on
subplot(2,1,2)
plot(diff2)
ylabel('diff2')
grid on

As you can see from the plot, the difference between the two functions (diff1) can be as high as 7m! I checked the results with the zip files from NASA EGM96 and found that geoidheight is within 0.01m. This means that there is something wrong with egm96geoid or ltln2val.

Conclusion: Use geoidheight to get geoid offsets. Do not assume that Matlab's functions are correct and ABT (Always be testing). This error seems to be fixed in Matlab 2014 and later versions.