-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcartpole_src.m
More file actions
87 lines (64 loc) · 2.13 KB
/
cartpole_src.m
File metadata and controls
87 lines (64 loc) · 2.13 KB
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
77
78
79
80
81
82
83
84
85
86
87
% Copyright 2019 Jonas Koenemann, Moritz Diehl, University of Freiburg
% Redistribution is permitted under the 3-Clause BSD License terms. Please
% ensure the above copyright notice is visible in any derived work.
%
function [sol,times,solver] = cartpole
solver = ocl.Solver([], 'vars', @varsfun, 'dae', @daefun, 'pointcosts', @pointcosts, 'N', 40, 'd', 3);
p0 = 0; v0 = 0;
theta0 = 180*pi/180; omega0 = 0;
solver.setInitialBounds('p', p0);
solver.setInitialBounds('v', v0);
solver.setInitialBounds('theta', theta0);
solver.setInitialBounds('omega', omega0);
solver.setInitialBounds('time', 0);
solver.setEndBounds('p', 0);
solver.setEndBounds('v', 0);
solver.setEndBounds('theta', 0);
solver.setEndBounds('omega', 0);
% Run solver to obtain solution
[sol,times] = solver.solve(solver.ig());
% visualize solution
figure; hold on; grid on;
oclStairs(times.controls, sol.controls.F/10.)
xlabel('time [s]');
oclPlot(times.states, sol.states.p)
xlabel('time [s]');
oclPlot(times.states, sol.states.v)
xlabel('time [s]');
oclPlot(times.states, sol.states.theta)
legend({'force [10*N]','position [m]','velocity [m/s]','theta [rad]'})
xlabel('time [s]');
animate(sol,times);
end
function varsfun(sh)
sh.addState('p', 'lb', -5, 'ub', 5);
sh.addState('theta', 'lb', -2*pi, 'ub', 2*pi);
sh.addState('v');
sh.addState('omega');
sh.addState('time', 'lb', 0, 'ub', 10);
sh.addControl('F', 'lb', -12, 'ub', 12);
end
function daefun(sh,x,~,u,~)
g = 9.8;
cm = 1.0;
pm = 0.1;
phl = 0.5; % pole half length
m = cm+pm;
pml = pm*phl; % pole mass length
ctheta = cos(x.theta);
stheta = sin(x.theta);
domega = (g*stheta + ...
ctheta * (-u.F-pml*x.omega^2*stheta) / m) / ...
(phl * (4.0 / 3.0 - pm * ctheta^2 / m));
a = (u.F + pml*(x.omega^2*stheta-domega*ctheta)) / m;
sh.setODE('p',x.v);
sh.setODE('theta',x.omega);
sh.setODE('v',a);
sh.setODE('omega',domega);
sh.setODE('time', 1);
end
function pointcosts(self,k,K,x,~)
if k == K
self.add( x.time );
end
end