#+TITLE: Kinematic Study of the Stewart Platform :DRAWER: #+HTML_LINK_HOME: ./index.html #+HTML_LINK_UP: ./index.html #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+PROPERTY: header-args:matlab :session *MATLAB* #+PROPERTY: header-args:matlab+ :tangle matlab/kinematic_study.m #+PROPERTY: header-args:matlab+ :comments org #+PROPERTY: header-args:matlab+ :exports both #+PROPERTY: header-args:matlab+ :results none #+PROPERTY: header-args:matlab+ :eval no-export #+PROPERTY: header-args:matlab+ :noweb yes #+PROPERTY: header-args:matlab+ :mkdirp yes #+PROPERTY: header-args:matlab+ :output-dir figs :END: #+begin_src matlab :results none :exports none :noweb yes <> addpath('src'); addpath('library'); #+end_src * Needed Actuator Stroke The goal is to determine the needed stroke of the actuators to obtain wanted translations and rotations. ** Stewart architecture definition We use a cubic architecture. #+begin_src matlab :results silent opts = struct(... 'H_tot', 90, ... % Total height of the Hexapod [mm] 'L', 200/sqrt(3), ... % Size of the Cube [mm] 'H', 60, ... % Height between base joints and platform joints [mm] 'H0', 200/2-60/2 ... % Height between the corner of the cube and the plane containing the base joints [mm] ); stewart = initializeCubicConfiguration(opts); opts = struct(... 'Jd_pos', [0, 0, 100], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] 'Jf_pos', [0, 0, -50] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] ); stewart = computeGeometricalProperties(stewart, opts); opts = struct(... 'stroke', 50e-6 ... % Maximum stroke of each actuator [m] ); stewart = initializeMechanicalElements(stewart, opts); save('./mat/stewart.mat', 'stewart'); #+end_src ** Wanted translations and rotations We define wanted translations and rotations #+begin_src matlab :results silent Tx_max = 15e-6; % Translation [m] Ty_max = 15e-6; % Translation [m] Tz_max = 15e-6; % Translation [m] Rx_max = 30e-6; % Rotation [rad] Ry_max = 30e-6; % Rotation [rad] #+end_src ** Needed stroke for "pure" rotations or translations First, we estimate the needed actuator stroke for "pure" rotations and translation. #+begin_src matlab :results silent LTx = stewart.Jd*[Tx_max 0 0 0 0 0]'; LTy = stewart.Jd*[0 Ty_max 0 0 0 0]'; LTz = stewart.Jd*[0 0 Tz_max 0 0 0]'; LRx = stewart.Jd*[0 0 0 Rx_max 0 0]'; LRy = stewart.Jd*[0 0 0 0 Ry_max 0]'; #+end_src #+begin_src matlab :results value :exports results ans = sprintf('From %.2g[m] to %.2g[m]: Total stroke = %.1f[um]', min(min([LTx,LTy,LTz,LRx,LRy])), max(max([LTx,LTy,LTz,LRx,LRy])), 1e6*(max(max([LTx,LTy,LTz,LRx,LRy]))-min(min([LTx,LTy,LTz,LRx,LRy])))) #+end_src #+RESULTS: : From -1.2e-05[m] to 1.1e-05[m]: Total stroke = 22.9[um] ** Needed stroke for combined translations and rotations Now, we combine translations and rotations, and we try to find the worst case (that we suppose to happen at the border). #+begin_src matlab :results none Lmax = 0; Lmin = 0; pos = [0, 0, 0, 0, 0]; for Tx = [-Tx_max,Tx_max] for Ty = [-Ty_max,Ty_max] for Tz = [-Tz_max,Tz_max] for Rx = [-Rx_max,Rx_max] for Ry = [-Ry_max,Ry_max] lmax = max(stewart.Jd*[Tx Ty Tz Rx Ry 0]'); lmin = min(stewart.Jd*[Tx Ty Tz Rx Ry 0]'); if lmax > Lmax Lmax = lmax; pos = [Tx Ty Tz Rx Ry]; end if lmin < Lmin Lmin = lmin; end end end end end end #+end_src We obtain a needed stroke shown below (almost two times the needed stroke for "pure" rotations and translations). #+begin_src matlab :results value :exports results ans = sprintf('From %.2g[m] to %.2g[m]: Total stroke = %.1f[um]', Lmin, Lmax, 1e6*(Lmax-Lmin)) #+end_src #+RESULTS: : From -3.1e-05[m] to 3.1e-05[m]: Total stroke = 61.5[um] * Maximum Stroke From a specified actuator stroke, we try to estimate the available maneuverability of the Stewart platform. #+begin_src matlab :results silent [X, Y, Z] = getMaxPositions(stewart); #+end_src #+begin_src matlab :results silent figure; plot3(X, Y, Z, 'k-') #+end_src * Functions :PROPERTIES: :HEADER-ARGS:matlab+: :exports code :HEADER-ARGS:matlab+: :comments no :HEADER-ARGS:matlab+: :mkdir yes :HEADER-ARGS:matlab+: :eval no :END: ** getMaxPositions :PROPERTIES: :HEADER-ARGS:matlab+: :tangle src/getMaxPositions.m :END: #+begin_src matlab function [X, Y, Z] = getMaxPositions(stewart) Leg = stewart.Leg; J = stewart.Jd; theta = linspace(0, 2*pi, 100); phi = linspace(-pi/2 , pi/2, 100); dmax = zeros(length(theta), length(phi)); for i = 1:length(theta) for j = 1:length(phi) L = J*[cos(phi(j))*cos(theta(i)) cos(phi(j))*sin(theta(i)) sin(phi(j)) 0 0 0]'; dmax(i, j) = Leg.stroke/max(abs(L)); end end X = dmax.*cos(repmat(phi,length(theta),1)).*cos(repmat(theta,length(phi),1))'; Y = dmax.*cos(repmat(phi,length(theta),1)).*sin(repmat(theta,length(phi),1))'; Z = dmax.*sin(repmat(phi,length(theta),1)); end #+end_src ** getMaxPureDisplacement :PROPERTIES: :HEADER-ARGS:matlab+: :tangle src/getMaxPureDisplacement.m :END: #+begin_src matlab function [max_disp] = getMaxPureDisplacement(Leg, J) max_disp = zeros(6, 1); max_disp(1) = Leg.stroke/max(abs(J*[1 0 0 0 0 0]')); max_disp(2) = Leg.stroke/max(abs(J*[0 1 0 0 0 0]')); max_disp(3) = Leg.stroke/max(abs(J*[0 0 1 0 0 0]')); max_disp(4) = Leg.stroke/max(abs(J*[0 0 0 1 0 0]')); max_disp(5) = Leg.stroke/max(abs(J*[0 0 0 0 1 0]')); max_disp(6) = Leg.stroke/max(abs(J*[0 0 0 0 0 1]')); end #+end_src