forked from ebertolazzi/G1fitting
-
Notifications
You must be signed in to change notification settings - Fork 0
/
G1spline.m
76 lines (76 loc) · 3.69 KB
/
G1spline.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
%=============================================================================%
% intXY: Compute G1 interpolating curve %
% %
% USAGE: [X,Y] = G1spline( PNTS, varargin ) ; %
% %
% compute clotoids segments which passes for points PNTS and joins %
% with G1 continuity. A minimization process is performed in order %
% to minimize the jump of curvature %
% %
% On input: %
% %
% PNTS = interpolation points %
% %
% On output: %
% %
%=============================================================================%
% %
% Autors: Enrico Bertolazzi and Marco Frego %
% Department of Industrial Engineering %
% University of Trento %
% enrico.bertolazzi@unitn.it %
% m.fregox@gmail.com %
% %
%=============================================================================%
function [theta,k,dk,L,nevalG1,nevalF,iter,Fvalue,Fgradnorm] = G1spline( PNTS, varargin )
global G1SPLINE_PNTS G1SPLINE_NBUILD_CLOTHOID G1SPLINE_NBUILD_CLOTHOID ;
G1SPLINE_PNTS = PNTS ;
G1SPLINE_NBUILD_CLOTHOID = 0 ;
%
% Compute guess angles
%
theta = zeros(size(PNTS,1),1) ;
theta(1) = atan2( PNTS(2,2)-PNTS(1,2), PNTS(2,1)-PNTS(1,1) ) ;
theta(2:end-1) = atan2( PNTS(3:end,2)-PNTS(1:end-2,2), PNTS(3:end,1)-PNTS(1:end-2,1) ) ;
theta(end) = atan2( PNTS(end,2)-PNTS(end-1,2), PNTS(end,1)-PNTS(end-1,1) ) ;
%
% Compute solution using lsqnonlin
%
options = optimset(varargin{:});
[theta,resnorm,residual,exitflag,output,lambda,jacobian] = lsqnonlin(@target, theta, [], [], options ) ;
%
% Compute spline parameters
%
N = length(theta) ;
k = zeros(N-1,1) ;
dk = zeros(N-1,1) ;
L = zeros(N-1,1) ;
for j=1:N-1
xL = PNTS(j,1) ; yL = PNTS(j,2) ; tL = theta(j) ;
xR = PNTS(j+1,1) ; yR = PNTS(j+1,2) ; tR = theta(j+1) ;
[ k(j), dk(j), L(j) ] = buildClothoid( xL, yL, tL, xR, yR, tR ) ;
end
nevalG1 = G1SPLINE_NBUILD_CLOTHOID ;
nevalF = output.funcCount ;
iter = output.iterations ;
Fvalue = sqrt(resnorm/N) ;
Fgradnorm = output.firstorderopt ;
end
%
%
%
function RES = target( THETA )
global G1SPLINE_PNTS G1SPLINE_NBUILD_CLOTHOID G1SPLINE_NBUILD_CLOTHOID ;
N = length(THETA) ;
k = zeros(N-1,1) ;
dk = zeros(N-1,1) ;
L = zeros(N-1,1) ;
for j=1:N-1
xL = G1SPLINE_PNTS(j,1) ; yL = G1SPLINE_PNTS(j,2) ; tL = THETA(j) ;
xR = G1SPLINE_PNTS(j+1,1) ; yR = G1SPLINE_PNTS(j+1,2) ; tR = THETA(j+1) ;
[ k(j), dk(j), L(j), iter ] = buildClothoid( xL, yL, tL, xR, yR, tR ) ;
end
G1SPLINE_NBUILD_CLOTHOID = G1SPLINE_NBUILD_CLOTHOID + N-1 ;
kL = k+dk.*L ;
RES = [ dk(1) ; k(2:end)-kL(1:end-1) ; dk(end) ] ;
end