diff --git a/analyze_jacobian.m b/analyze_jacobian.m index 309f48e..a48b1bb 100644 --- a/analyze_jacobian.m +++ b/analyze_jacobian.m @@ -1,3 +1,6 @@ +%% Script Description +% + figure; plot(d_meas.Time, d.Data-d_meas.Data) diff --git a/identification_control.m b/identification_cart.m similarity index 65% rename from identification_control.m rename to identification_cart.m index a7b6f78..55ad03a 100644 --- a/identification_control.m +++ b/identification_cart.m @@ -11,17 +11,17 @@ initializeNanoHexapod(); %% initializeSample(struct('mass', 0)); -G_cart_0 = getPlantCart(); +G_cart_0 = identifyPlantCart(); %% initializeSample(struct('mass', 10)); -G_cart_10 = getPlantCart(); +G_cart_10 = identifyPlantCart(); %% initializeSample(struct('mass', 50)); -G_cart_50 = getPlantCart(); +G_cart_50 = identifyPlantCart(); %% freqs = logspace(1, 4, 1000); @@ -54,30 +54,3 @@ exportFig('hexapod_cart_coupling', 'normal-normal') %% Save identify transfer functions save('./mat/G_cart.mat', 'G_cart_0', 'G_cart_10', 'G_cart_50'); - -%% Centralized control (Cartesian coordinates) -% Input/Output definition -io(1) = linio([mdl, '/F_legs'],1,'input'); -io(2) = linio([mdl, '/Stewart_Platform'],2,'output'); - -% Run the linearization -G_legs_raw = linearize(mdl,io, 0); - -G_legs = preprocessIdTf(G_legs_raw, 10, 10000); - -% Input/Output names -G_legs.InputName = {'F1', 'F2', 'F3', 'M4', 'M5', 'M6'}; -G_legs.OutputName = {'D1', 'D2', 'D3', 'R4', 'R5', 'R6'}; - -% Bode Plot of the linearized function -freqs = logspace(2, 4, 1000); - -bodeFig({G_legs(1, 1)}, freqs, struct('phase', true)) -legend({'$F_i \rightarrow D_i$'}) -exportFig('hexapod_legs', 'normal-normal') - -bodeFig({G_legs(1, 1), G_legs(2, 1)}, freqs, struct('phase', true)) -legend({'$F_i \rightarrow D_i$', '$F_i \rightarrow D_j$'}) -exportFig('hexapod_legs_coupling', 'normal-normal') - -save('mat/G_legs.mat', 'G_legs'); diff --git a/identification_legs.m b/identification_legs.m new file mode 100644 index 0000000..ad8f14b --- /dev/null +++ b/identification_legs.m @@ -0,0 +1,45 @@ +%% Script Description +% Script used to identify the transfer functions of the +% Stewart platform (from actuator to displacement) + +%% +clear; close all; clc; + +%% +initializeNanoHexapod(); + +%% +initializeSample(struct('mass', 0)); + +G_legs_0 = identifyPlantLegs(); + +%% +initializeSample(struct('mass', 10)); + +G_legs_10 = identifyPlantLegs(); + +%% +initializeSample(struct('mass', 50)); + +G_legs_50 = identifyPlantLegs(); + +%% +freqs = logspace(1, 4, 1000); + +bodeFig({G_legs_0(1, 1), G_legs_10(1, 1), G_legs_50(1, 1)}, freqs, struct('phase', true)) +legend({'$F_i \rightarrow D_i$ - $M = 0Kg$', '$F_i \rightarrow D_i$ - $M = 10Kg$', '$F_i \rightarrow D_i$ - $M = 50Kg$'}) +legend('location', 'southwest') + +exportFig('hexapod_legs_mass', 'normal-tall') + +%% +freqs = logspace(1, 4, 1000); + +bodeFig({G_legs_0(1, 2), G_legs_10(1, 2), G_legs_50(1, 2)}, freqs, struct('phase', true)) +legend({'$F_i \rightarrow D_j$ - $M = 0Kg$', '$F_i \rightarrow D_j$ - $M = 10Kg$', '$F_i \rightarrow D_j$ - $M = 50Kg$'}) +legend('location', 'southwest') + +exportFig('hexapod_legs_coupling_mass', 'normal-tall') + +%% Save identify transfer functions +save('./mat/G_legs.mat', 'G_legs_0', 'G_legs_10', 'G_legs_50'); diff --git a/init_simulink.m b/init_simulink.m index 60c9efc..8f154eb 100644 --- a/init_simulink.m +++ b/init_simulink.m @@ -1,2 +1,6 @@ +%% Script Description +% + +%% Load the sample and the stewart platform load('./mat/sample.mat', 'sample') load('./mat/stewart.mat', 'stewart') diff --git a/params_micro_hexapod.m b/params_micro_hexapod.m deleted file mode 100644 index 83db096..0000000 --- a/params_micro_hexapod.m +++ /dev/null @@ -1,90 +0,0 @@ -%% Stewart Object -stewart = struct(); -stewart.h = 350; % Total height of the platform [mm] -stewart.jacobian = 435; % Point where the Jacobian is computed => Center of rotation [mm] - -%% Bottom Plate -BP = struct(); - -BP.rad.int = 110; % Internal Radius [mm] -BP.rad.ext = 207.5; % External Radius [mm] -BP.thickness = 26; % Thickness [mm] -BP.leg.rad = 175.5; % Radius where the legs articulations are positionned [mm] -BP.leg.ang = 9.5; % Angle Offset [deg] -BP.density = 8000; % Density of the material [kg/m^3] -BP.color = [0.6 0.6 0.6]; % Color [rgb] -BP.shape = [BP.rad.int BP.thickness; BP.rad.int 0; BP.rad.ext 0; BP.rad.ext BP.thickness]; - -%% Top Plate -TP = struct(); - -TP.rad.int = 82; % Internal Radius [mm] -TP.rad.ext = 150; % Internal Radius [mm] -TP.thickness = 26; % Thickness [mm] -TP.leg.rad = 118; % Radius where the legs articulations are positionned [mm] -TP.leg.ang = 12.1; % Angle Offset [deg] -TP.density = 8000; % Density of the material [kg/m^3] -TP.color = [0.6 0.6 0.6]; % Color [rgb] -TP.shape = [TP.rad.int TP.thickness; TP.rad.int 0; TP.rad.ext 0; TP.rad.ext TP.thickness]; - -%% Leg -Leg = struct(); - -Leg.stroke = 10e-3; % Maximum Stroke of each leg [m] -Leg.k.ax = 5e7; % Stiffness of each leg [N/m] -Leg.ksi.ax = 3; % Maximum amplification at resonance [] -Leg.rad.bottom = 25; % Radius of the cylinder of the bottom part [mm] -Leg.rad.top = 17; % Radius of the cylinder of the top part [mm] -Leg.density = 8000; % Density of the material [kg/m^3] -Leg.color.bottom = [0.5 0.5 0.5]; % Color [rgb] -Leg.color.top = [0.5 0.5 0.5]; % Color [rgb] - -Leg.sphere.bottom = Leg.rad.bottom; % Size of the sphere at the end of the leg [mm] -Leg.sphere.top = Leg.rad.top; % Size of the sphere at the end of the leg [mm] -Leg.m = TP.density*((pi*(TP.rad.ext/1000)^2)*(TP.thickness/1000)-(pi*(TP.rad.int/1000^2))*(TP.thickness/1000))/6; % TODO [kg] -Leg = updateDamping(Leg); - - -%% Sphere -SP = struct(); - -SP.height.bottom = 27; % [mm] -SP.height.top = 27; % [mm] -SP.density.bottom = 8000; % [kg/m^3] -SP.density.top = 8000; % [kg/m^3] -SP.color.bottom = [0.6 0.6 0.6]; % [rgb] -SP.color.top = [0.6 0.6 0.6]; % [rgb] -SP.k.ax = 0; % [N*m/deg] -SP.ksi.ax = 10; - -SP.thickness.bottom = SP.height.bottom-Leg.sphere.bottom; % [mm] -SP.thickness.top = SP.height.top-Leg.sphere.top; % [mm] -SP.rad.bottom = Leg.sphere.bottom; % [mm] -SP.rad.top = Leg.sphere.top; % [mm] -SP.m = SP.density.bottom*2*pi*((SP.rad.bottom*1e-3)^2)*(SP.height.bottom*1e-3); % TODO [kg] - -SP = updateDamping(SP); - -%% -Leg.support.bottom = [0 SP.thickness.bottom; 0 0; SP.rad.bottom 0; SP.rad.bottom SP.height.bottom]; -Leg.support.top = [0 SP.thickness.top; 0 0; SP.rad.top 0; SP.rad.top SP.height.top]; - -%% -stewart.BP = BP; -stewart.TP = TP; -stewart.Leg = Leg; -stewart.SP = SP; - -%% -stewart = initializeParameters(stewart); - -%% -clear BP TP Leg SP; - -%% -function element = updateDamping(element) - field = fieldnames(element.k); - for i = 1:length(field) - element.c.(field{i}) = 1/element.ksi.(field{i})*sqrt(element.k.(field{i})/element.m); - end -end diff --git a/params_nano_hexapod.m b/params_nano_hexapod.m deleted file mode 100644 index b6ac2c4..0000000 --- a/params_nano_hexapod.m +++ /dev/null @@ -1,90 +0,0 @@ -%% Stewart Object -stewart = struct(); -stewart.h = 90; % Total height of the platform [mm] -stewart.jacobian = 174.5; % Point where the Jacobian is computed => Center of rotation [mm] - -%% Bottom Plate -BP = struct(); - -BP.rad.int = 0; % Internal Radius [mm] -BP.rad.ext = 150; % External Radius [mm] -BP.thickness = 10; % Thickness [mm] -BP.leg.rad = 100; % Radius where the legs articulations are positionned [mm] -BP.leg.ang = 5; % Angle Offset [deg] -BP.density = 8000;% Density of the material [kg/m^3] -BP.color = [0.7 0.7 0.7]; % Color [rgb] -BP.shape = [BP.rad.int BP.thickness; BP.rad.int 0; BP.rad.ext 0; BP.rad.ext BP.thickness]; - -%% Top Plate -TP = struct(); - -TP.rad.int = 0; % Internal Radius [mm] -TP.rad.ext = 100; % Internal Radius [mm] -TP.thickness = 10; % Thickness [mm] -TP.leg.rad = 90; % Radius where the legs articulations are positionned [mm] -TP.leg.ang = 5; % Angle Offset [deg] -TP.density = 8000;% Density of the material [kg/m^3] -TP.color = [0.7 0.7 0.7]; % Color [rgb] -TP.shape = [TP.rad.int TP.thickness; TP.rad.int 0; TP.rad.ext 0; TP.rad.ext TP.thickness]; - -%% Leg -Leg = struct(); - -Leg.stroke = 80e-6; % Maximum Stroke of each leg [m] -Leg.k.ax = 5e7; % Stiffness of each leg [N/m] -Leg.ksi.ax = 10; % Maximum amplification at resonance [] -Leg.rad.bottom = 12; % Radius of the cylinder of the bottom part [mm] -Leg.rad.top = 10; % Radius of the cylinder of the top part [mm] -Leg.density = 8000; % Density of the material [kg/m^3] -Leg.color.bottom = [0.5 0.5 0.5]; % Color [rgb] -Leg.color.top = [0.5 0.5 0.5]; % Color [rgb] - -Leg.sphere.bottom = Leg.rad.bottom; % Size of the sphere at the end of the leg [mm] -Leg.sphere.top = Leg.rad.top; % Size of the sphere at the end of the leg [mm] -Leg.m = TP.density*((pi*(TP.rad.ext/1000)^2)*(TP.thickness/1000)-(pi*(TP.rad.int/1000^2))*(TP.thickness/1000))/6; % TODO [kg] -Leg = updateDamping(Leg); - - -%% Sphere -SP = struct(); - -SP.height.bottom = 15; % [mm] -SP.height.top = 15; % [mm] -SP.density.bottom = 8000; % [kg/m^3] -SP.density.top = 8000; % [kg/m^3] -SP.color.bottom = [0.7 0.7 0.7]; % [rgb] -SP.color.top = [0.7 0.7 0.7]; % [rgb] -SP.k.ax = 0; % [N*m/deg] -SP.ksi.ax = 3; - -SP.thickness.bottom = SP.height.bottom-Leg.sphere.bottom; % [mm] -SP.thickness.top = SP.height.top-Leg.sphere.top; % [mm] -SP.rad.bottom = Leg.sphere.bottom; % [mm] -SP.rad.top = Leg.sphere.top; % [mm] -SP.m = SP.density.bottom*2*pi*((SP.rad.bottom*1e-3)^2)*(SP.height.bottom*1e-3); % TODO [kg] - -SP = updateDamping(SP); - -%% -Leg.support.bottom = [0 SP.thickness.bottom; 0 0; SP.rad.bottom 0; SP.rad.bottom SP.height.bottom]; -Leg.support.top = [0 SP.thickness.top; 0 0; SP.rad.top 0; SP.rad.top SP.height.top]; - -%% -stewart.BP = BP; -stewart.TP = TP; -stewart.Leg = Leg; -stewart.SP = SP; - -%% -stewart = initializeParameters(stewart); - -%% -clear BP TP Leg SP; - -%% -function element = updateDamping(element) - field = fieldnames(element.k); - for i = 1:length(field) - element.c.(field{i}) = 1/element.ksi.(field{i})*sqrt(element.k.(field{i})/element.m); - end -end diff --git a/params_sample.m b/params_sample.m deleted file mode 100644 index e69de29..0000000 diff --git a/plot_max_positions.m b/plot_max_positions.m index 0393901..fd4236b 100644 --- a/plot_max_positions.m +++ b/plot_max_positions.m @@ -1,10 +1,16 @@ -%% -run stewart_parameters.m -run stewart_init.m +%% Script Description +% %% -[X, Y, Z] = getMaxPositions(Leg, J); +clear; close all; clc; +%% +init_simulink; + +%% +[X, Y, Z] = getMaxPositions(stewart); + +%% figure; hold on; mesh(X, Y, Z); diff --git a/readme.org b/readme.org index 4bc910b..5b85997 100644 --- a/readme.org +++ b/readme.org @@ -1,2 +1,5 @@ * Stewart Platform using Simscape +* TODO Add functions to identify transmissibility and sensitivity +* TODO Rewrite the script to study the effect of various parameters on the stiffness/stroke/... +* TODO Rewrite the function to study the jacobian, or delete it. diff --git a/src/getMaxPositions.m b/src/getMaxPositions.m index ab93ed3..f162db1 100644 --- a/src/getMaxPositions.m +++ b/src/getMaxPositions.m @@ -1,4 +1,6 @@ -function [X, Y, Z] = getMaxPositions(Leg, J) +function [X, Y, Z] = getMaxPositions(stewart) + Leg = stewart.Leg; + J = stewart.J; theta = linspace(0, 2*pi, 100); phi = linspace(-pi/2 , pi/2, 100); dmax = zeros(length(theta), length(phi)); diff --git a/src/getPlantCart.m b/src/identifyPlantCart.m similarity index 94% rename from src/getPlantCart.m rename to src/identifyPlantCart.m index 9994def..e287405 100644 --- a/src/getPlantCart.m +++ b/src/identifyPlantCart.m @@ -1,4 +1,4 @@ -function [G_cart, G_cart_raw] = getPlantCart() +function [G_cart, G_cart_raw] = identifyPlantCart() %% Default values for opts opts = struct('f_low', 1,... 'f_high', 10000 ... diff --git a/src/identifyPlantLegs.m b/src/identifyPlantLegs.m new file mode 100644 index 0000000..39b064c --- /dev/null +++ b/src/identifyPlantLegs.m @@ -0,0 +1,35 @@ +function [G_legs, G_legs_raw] = identifyPlantLegs() + %% Default values for opts + opts = struct('f_low', 1, ... + 'f_high', 10000 ... + ); + + %% Populate opts with input parameters + if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end + end + + %% Options for Linearized + options = linearizeOptions; + options.SampleTime = 0; + + %% Name of the Simulink File + mdl = 'stewart_simscape'; + + %% Centralized control (Cartesian coordinates) + % Input/Output definition + io(1) = linio([mdl, '/F_legs'], 1,'input'); + io(2) = linio([mdl, '/Stewart_Platform'],2,'output'); + + % Run the linearization + G_legs_raw = linearize(mdl,io, 0); + + G_legs = preprocessIdTf(G_legs_raw, opts.f_low, opts.f_high); + + % Input/Output names + G_legs.InputName = {'F1', 'F2', 'F3', 'M4', 'M5', 'M6'}; + G_legs.OutputName = {'D1', 'D2', 'D3', 'R4', 'R5', 'R6'}; +end + diff --git a/stewart_simscape.slx b/stewart_simscape.slx index 85f43d1..f097f85 100644 Binary files a/stewart_simscape.slx and b/stewart_simscape.slx differ diff --git a/study_architecture.m b/study_architecture.m index f91427d..3769553 100644 --- a/study_architecture.m +++ b/study_architecture.m @@ -1,4 +1,8 @@ -%% TODO - rewrite this script +%% Script Description +% + +%% +clear; close all; clc; %% run stewart_parameters.m