6
$\begingroup$

I'm learning to make a 3D simulation in MATLAB based on a model designed from SOLIDWORKS. There is an example: SIMULINK+SOLIDWORKS

The way used here is:

  1. Create a 3D model in SOLIDWORKS

  2. Create a xml file applicable to import to MATLAB via SimMechanics Link

  3. Import the model to MATLAB/SIMULINK. A simulink system is created.

After these steps, controlling the system will be implemented in SIMULINK. But I feel simulink is kind of strict to control. I want to be more flexible, apply any algorithm to the model. And using matlab *.m file to control is more efficient way.

So my question is this: Is there any way to do 3D simulation (MATLAB+SOLIDWORKS) by using only *.m file to control, no SIMULINK anymore?

All model information will be contained in the *m.file. Maybe the step 1 and 2 are inherited, but step 3 is different.

$\endgroup$
  • $\begingroup$ Basically you need a Simulink file because of the SimMechanics. But if is possible to "control" simulink files from a *.m file. Make sure the optimization "Inline Parameters" is disabled to be able to set all parameters of the simulink easily. Just start your simulation with the sim() command. If you can be more precise what you try to achieve I can give a better answer. $\endgroup$ – TobiasK Jul 22 '15 at 8:26
  • $\begingroup$ Thanks for your comment. I made a controller for a quadruped in MATLAB, and animated in 2D. I see the simulation in this video is very interesting. So i want to realize a 3D simulation for my work. $\endgroup$ – Phan Jul 22 '15 at 8:36
  • $\begingroup$ I usually create a simulation m-file which enables me to control any input to the system (creating offsets, provide measured data....) and set the parameters per non-inlining. So you can do easily DoE simulations and so on. $\endgroup$ – TobiasK Jul 22 '15 at 8:41
  • $\begingroup$ Can you explain it more clearly. I still don't get your point. What is DoE simulation? $\endgroup$ – Phan Jul 22 '15 at 8:44
  • $\begingroup$ I created a chat room to avoid discussion in comments: chat.stackexchange.com/rooms/26108/… $\endgroup$ – TobiasK Jul 22 '15 at 8:47
3
$\begingroup$

I use CAD software to generate 3D models, convert those 3D models to an STL format, then load those STL files to Matlab with the following script:

function [points,success] = LoadSTL(path)
% LoadSTL loads an ASCII STL file with units in [mm]. 
% The output is a structure array where each element in the array is 
% a vertex. 
%
% [points , success] = LoadSTL(path)
%
% path = String containing the path and extension of the file to be loaded.
% points = Matrix of locations where each column is a vertex, rows are x/y/z/1:
%    points(1,:) = x
%    points(2,:) = y
%    points(3,:) = z
%    points(4,:) = 1
%           NOTE - every three columns is a new face/facet. 
% success = Bit indicating if the file was successfully opened or not. 

success = 0;
fileID = fopen(path);
if fileID <0
    fprintf('File not found at path %s\n',path);
    return;
end
fprintf('Loading Path %s...\n',path);
fileData = fread(fileID,'*char');
eol = sprintf('\n');
stlFile = strsplit(fileData',eol);
fclose(fileID);
fprintf('Done.\n')
pause(0.25);
clc
assignin('base' , 'stlFile' , stlFile)
pointsTracker = 1;
for i=2:size(stlFile,2)
    if mod(pointsTracker,100)==0
        clc
        fprintf('Parsing file at %s...\n',path);
        fprintf('Currently logged %d points\n',pointsTracker);
    end

    testLine = stlFile{i};
    rawStrip = strsplit(testLine , ' ' , 'CollapseDelimiters' , true);
    if numel(rawStrip) == 5
        points(1,pointsTracker) = str2double(rawStrip{1,3})/1000;
        points(2,pointsTracker) = str2double(rawStrip{1,4})/1000;
        points(3,pointsTracker) = str2double(rawStrip{1,5})/1000;
        points(4,pointsTracker) = 1;
        pointsTracker = pointsTracker + 1;
    end
end
disp('Done.')
pause(0.25);
clc;

if mod(size(points,2),3) > 0
    disp('File format in an unexpected type.')
    disp('Check the file specified is an STL format file with ASCII formatting.')
    disp('(Error - number of vertices not a multiple of 3)')
    disp(numel(points.x))
    return;
end

success = 1;
return;

Once this is done I save the resulting output (points) as a .mat file and load exclusively from that .mat instead of the STL file because the .mat file loads significantly faster than parsing the STL file every time.

Once you've loaded the file, you can quickly plot the STL file in Matlab with the following command:

myPlotColor = [0.5 0.5 0.5];
nFaces = size(points,2)/3;
patch(...
    reshape(points(1,:),3,nFaces) , ...
    reshape(points(2,:),3,nFaces) , ...
    reshape(points(3,:),3,nFaces) , ...
    myPlotColor);

At this point, standard Matlab plot commands work; e.g., axis equal, hold on, etc.

Now, given how to load and display STL files in Matlab plots from an m-file, you can go about doing whatever form of control you want. Transform the CAD file with any 4x4 transform matrix composed of a rotation matrix $R$ and translation vector $s$:

$$ \mbox{transformedPoints} = \begin{bmatrix} & R& & s \\ 0 &0 &0& 1 \\ \end{bmatrix} \mbox{points} $$

Plot the transformed points with the patch command shown above. As long as you've generated your CAD model such that the origin of your 3D model corresponds with the origin of your mathematical model then any movement/rotation of the mathematical model about its origin can be correctly applied to the CAD model, which can then be displayed.

I'd just like to reiterate that this file loads STL files that are in ASCII format with units in millimeters, and the resulting plot is with units in meters, but of course you can change that with the /1000 scaling during the loading of the file.

$\endgroup$
  • $\begingroup$ It sounds great! Thank you for your answer. Can you share me an example of doing that or suggest me somewhere to look for more information about this method? $\endgroup$ – Phan Jul 23 '15 at 4:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.