--- tags: Lecture Note, 運動控制 --- 運動控制系統導論 === <style> .blue {color: blue;} .ph { display : block; margin-left : auto ; margin-right: auto;} .ph_8 { display : block; margin-left : auto ; margin-right: auto; width : 80%} .ph_6 { display : block; margin-left : auto ; margin-right: auto; width : 60%} .ph_4 { display : block; margin-left : auto ; margin-right: auto; width : 40%} .ph_2 { display : block; margin-left : auto ; margin-right: auto; width : 20%} </style> ## Motion Planning ### Scurve - Discription - S-curve motion planning is often adopted in a point-topoint (PTP) motion. The position trajectory described by an S-curve is a 3rd order polynomial of time t. The corresponding acceleration curve is continuous, and the magnitude of jerk is finite. - S-curve motion planning can reduce the chance of causing abrupt ACC/DEC. As a result, the chance of endangering the machine safety can be substantially reduced. - Requestment To specify an S-curve users must provide the following information: A. total moving distance B. maximum speed C. maximum acceleration D. average of acceleration #### Main ```Matlab= %% ==== Parameter ==== acc_lim = 4; % acceleration limitation (m/sec^2) acc_avg = 0.7; % average accleration = acc_lim * acc_avg (m/sec^2) vec_lim = 4; % velocity limitation (m/sec) samp_t = 0.01; % sampling time(s) %% ==== Main ==== end_point = 20; % distance boundary = [0,0;0,end_point]; par = struct('acc',acc_lim,'vec',vec_lim,'avg',acc_avg*acc_lim,'samp_t',samp_t,'boundary',boundary); %% ==== Scurve ==== [res,T_total,tc,tb] = Scurve_single_axis(end_point,par); % Accleration, Velocity, position a = res(1,:); v = res(2,:); x = res(3,:); ``` - Scurve Motion planning <img src = https://i.imgur.com/W9q79Ch.png class="ph_8"> <img src = https://i.imgur.com/5DdzI8w.png class="ph_8"> <img src = https://i.imgur.com/cRpeeHt.png class="ph_4"> #### Scurve_single_axis ```Matlab= function [res,T_total,tc,tb] = Scurve_single_axis(end_point,par) %% ==== 解參數 ==== a_max = par.acc; v_max = par.vec; a_avg = par.avg; samp_t = par.samp_t; boundary = par.boundary; %% ==== 計算時間 ==== ta = v_max / a_avg; ts = (end_point - v_max*ta)/v_max; T_total = 2 * ta + ts; tb = 2*v_max/a_max - ta; tc = (ta-tb)/2; n = floor(T_total/samp_t) + 1; a = zeros(1,n); i = 2; %% ==== 給定各時間的加速度 ==== for t = samp_t:samp_t:T_total/2 if t<= tc a(i) = a_max*t/tc; a(end-i+1) = -a(i); elseif t<= tc+tb a(i) = a_max; a(end-i+1) = -a(i); elseif t<= ta a(i) = a_max*(2*tc+tb-t)/tc; a(end-i+1) = -a(i); else a(i) = 0; end i = i+1; end %% ==== 積分出各點的速度及位置 ==== res = Integral(a,2,samp_t,boundary); end ``` #### Integral ```Matlab= function res = Integral(a,order,samp_t,boundary) n = length(a); x = zeros(1+order,n); x(1,:) = a(:); for j = 1:order for i = 2 : n-1 x(1+j,i) = x(1+j,i-1) + (x(j,i)+x(j,i-1))*samp_t/2; end x(1+j,1) = boundary(j,1); x(1+j,n) = boundary(j,2); end res = x; end ``` --- ### BSpline <img src = https://i.imgur.com/Mdr3iCa.png class = "ph_4"> where $P_i$ are the control points, $k$ is the order, and $N_{i,k}(u)$ is the blending function <img src = https://i.imgur.com/2w78ojv.png class = "ph_6"> Notice: 1. k(階數) = p(級數) + 1 2. number of knot vector = number of control point(n+1) + k 3. example of bending function [ 0, 0 , 0 , 1/4 , 1/2 , 3/4 , 1 , 1 , 1 ]; <img src = https://i.imgur.com/cuX9SfT.png class = "ph_6"> #### Main ```Matlab= %% ==== Parameter ==== clc,clear,close all; % Control Point Ctrl_P = [ 0.0 , 1.5; 1.0 , 4.0; 4.0 , 4.5; 2.5 , 0.0; 7.0 , 0.0; 5.0 , 3.0]; % Knot vector (p = 2) knot = [ 0, 0 , 0 ,... 1/4 , 1/2 , 3/4 ,... 1 , 1 , 1 ]; p = 2; % Power k = p+1; % Order n = size(Ctrl_P,1); % number of control point knot = Knot_gen(knot,k,n); % Knot_generator samp = 0.01; % Sampling n = length(knot)-1; Auto = 1; %% ==== Bending Function ==== N = zeros(n, k, max(knot)/samp+1); % N initialization for j = 1:k % N(,j) for i = 1:n % N(i,) if j == 1 if i <= k start = 1; end_ = k + 1; elseif i > length(knot)-k start = length(knot)-k+1; end_ = length(knot); else start = i; end_ = i+1; end for u = 0:samp:max(knot) if j == 1 && i >= length(knot)-(k) && u == knot(end) N(i,j, round(u/samp + 1)) = 1; elseif knot(start) <= u && u < knot(end_) N(i,j, round(u/samp + 1)) = 1; end end else if i + j > n+1 break; end for u = 0:samp:max(knot) if knot(i+j-1)-knot(i) == 0 par1 = 0; else par1 = (u - knot(i))/(knot(i+j-1)-knot(i)); end if knot(i+j)-knot(i+1) == 0 par2 = 0; else par2 = (knot(i+j) - u)/(knot(i+j)-knot(i+1)); end N(i,j, round(u/samp + 1)) = ... par1*N(i,j-1,round(u/samp + 1))+... par2*N(i+1,j-1,round(u/samp + 1)); end end end end %% ==== Curve ==== for u = 0 : samp : max(knot) sum = 0; for i = 1 : size(Ctrl_P,1) sum = sum + N(i,k, round(u/samp + 1)) * Ctrl_P(i,:); end C(round(u/samp + 1),:) = sum; end ``` #### knot_gen ```Matlab= function knot = Knot_gen(knot_1, k , n ) % B-spline knot vector generator. % % Input arguments: % knot_1: % knot vector in setting. % k: % B-spline order (2 for linear, 3 for quadratic, etc.) % n: % number of Control point -1 % % Output arguments: % knot: % B-spline knot vector % % Copyright Hank Yu 2020/10/02 % Compute number of knot vector len = n + k; % Distinguish different conditions if len == length(knot_1) knot = knot_1; else knot = zeros(1,len); knot(1:k) = 0; knot(end-k+1:end) = 1; if mod ( length(knot) , 2 ) == 1 knot (round(length(knot)/2)) = 0.5; end for i = k+1:length(knot)-k if i < round(length(knot)/2) if (round(length(knot)/2)-i)*0.1 < 0.5 knot(i) = (round(length(knot)/2)-i)*0.1; else knot(i) = 0.5; end else if ( i )*0.1 < 1 knot(i) = ( i )*0.1 ; else knot(i) = 1; end end end end end ``` --- ### NURBS_Circle <img src = https://i.imgur.com/jeTvfIi.png class = "ph_6"> where - u : parameter - order = k - degree = k-1 = p - number of control points = n+1 - number of knots = n+k+1=r+1 - $P_i$: control point - $W_i$: weights Notice: <img src = https://i.imgur.com/B0GSMTB.png class = "ph_4"> ```Matlab= %% Parameter clc,clear,close all; % Control Point Ctrl_P = [ 0.0 , 0.0; 0.0 , 25.0; 50.0 , 25.0; 50.0 , 0.0; 50.0 ,-25.0; 0.0 ,-25.0; 0.0 , 0.0]; % Knot vector (p = 2) knot = [ 0, 0 , 0 ,... 1/4 , 1/2 , 1/2 , 3/4 ,... 1 , 1 , 1 ]; % Weight weight = [1, 0.5, 0.5, 1, 0.5, 0.5, 1]; p = 2; % Power k = p+1; % Order rp = Repeat(knot); % Knot_generator samp = 0.01; % Sampling n = length(knot)-1; Auto = 1; %% Bending Function N = zeros(n, k, max(knot)/samp+1); % N initialization for j = 1:k % N(,j) for i = 1:n % N(i,) if j == 1 if i <= rp(1) start = 1; end_ = rp(1) + 1; elseif i > length(knot)-rp(2) start = length(knot)-rp(2); end_ = length(knot); else start = i; end_ = i+1; end for u = 0:samp:max(knot) if j == 1 && i >= length(knot)-(rp(2)) && u == knot(end) N(i,j, round(u/samp + 1)) = 1; elseif knot(start) <= u && u < knot(end_) N(i,j, round(u/samp + 1)) = 1; end end else if i + j > n+1 break; end for u = 0:samp:max(knot) if knot(i+j-1)-knot(i) == 0 par1 = 0; else par1 = (u - knot(i))/(knot(i+j-1)-knot(i)); end if knot(i+j)-knot(i+1) == 0 par2 = 0; else par2 = (knot(i+j) - u)/(knot(i+j)-knot(i+1)); end N(i,j, round(u/samp + 1)) = ... par1*N(i,j-1,round(u/samp + 1))+... par2*N(i+1,j-1,round(u/samp + 1)); end end end end %% Curve for u = 0 : samp : max(knot) sum = 0; N_sum = 0; for i = 1 : size(Ctrl_P,1) N_sum = N_sum + N(i,k, round(u/samp + 1)) * weight(i); end for i = 1 : size(Ctrl_P,1) sum = sum + N(i,k, round(u/samp + 1)) * Ctrl_P(i,:) * weight(i) / N_sum ; end C(round(u/samp + 1),:) = sum; end ``` --- ## Velocity