Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.06 KB | None | 0 0
  1. %% LQR-RRT* - Simple Pendulum
  2. function pend_rrt( time_interval, N )
  3.  
  4. % LQR-RRT* is a fast motion planning algorithm which guarantees to find an
  5. % optimal solution asymptotically. Here the approach is used to diverge
  6. % optimal motion policies for a simple pendulum in its phase plot.
  7. %
  8. % Author: Mahan Fathi
  9. %
  10. % Tree data is mainly stored in two matrices, one representing node
  11. % properites and one edges. You don't need graph libraries on matlab to run
  12. % this code.
  13. %
  14. % Notes:
  15. % 1. Feel free to apply LQR-RRT* by using this as a template.
  16. % 2. Refinements such as Tree Prunning (Branch-and-Bound) or goal directed
  17. % propogation algorithms are yet to be implemented here and I'm looking
  18. % forward for you to commit them.
  19. %
  20. % Inputs:
  21. % 1. time_interval: Determines how big you want your steps to be in time.
  22. % 2. N : Number of iterations the main loop counts.
  23. %
  24. % Output:
  25. % Phase plot updates peridically in figure 25.
  26. %
  27.  
  28. global GNodes GEdges model nun; % nun --> Current Number of Nodes
  29. GNodes = inf * ones( N , 2+1 ); % Each Row Contains States and Costz
  30. GEdges = inf * ones( N+1 , 2+1 ); % Each Row Contains EndNodes and Action
  31.  
  32. GNodes( 1, : ) = zeros( 1, 3 );
  33. nun = 1;
  34.  
  35. model.h = time_interval;
  36. model.N = N; % Number of Nodes
  37.  
  38. model.phy.m = 1;
  39. model.phy.l = 1;
  40. model.phy.b = 0.1;
  41. model.phy.g = 9.81;
  42.  
  43. model.cost.Q = 1*eye(2);
  44. model.cost.R = 50*eye(1);
  45.  
  46. model.bound.x1 = [ -pi pi ];
  47. model.bound.x2 = [ -2.5*pi 2.5*pi ];
  48. model.bound.u = [ -5 5 ];
  49.  
  50.  
  51. for i = 1 : model.N
  52.  
  53. SteerAction = inf;
  54. while abs(SteerAction) > 5
  55. x_rand = [ model.bound.x1(1)+(model.bound.x1(2)-model.bound.x1(1))*rand, ...
  56. model.bound.x2(1)+(model.bound.x2(2)-model.bound.x2(1))*rand ];
  57. % Setting Up Local LQR Cost and Policy on x_rand
  58. [ A_rand, B_rand ] = linmats( x_rand, 0 );
  59. [ K_rand, S_rand ] = lqr( A_rand, B_rand, model.cost.Q, model.cost.R );
  60. % Find Nearest Point in Phase Space
  61. [ id_nearest, x_nearest ] = LQRNearest( x_rand, S_rand );
  62. % Construct SteerAction and Check If It's in Limits
  63. SteerAction = -K_rand*( x_nearest - x_rand )';
  64. end
  65. % Steer from Nearest to New
  66. x_new = LQRSteer( x_nearest, x_rand, K_rand );
  67. % Setting Up Local LQR Cost and Policy on x_new
  68. [ A_new, B_new ] = linmats( x_new, 0 );
  69. [ K_new, S_new ] = lqr( A_new, B_new, model.cost.Q, model.cost.R );
  70. % Find the new neighborhood
  71. X_near_ids = LQRNear( x_new, S_new, id_nearest );
  72. % Choose Parent Candidate
  73. [ id_parent, x_parent, minCost ] = ChooseParent( X_near_ids, x_new, S_new );
  74. % If it's collision free add node x_new and the edge between parent
  75. % canddidate and the new node in this case -- simple pendulum -- all new
  76. % edges are collision free.
  77. % New Node
  78. to_parentCost = GNodes( id_parent, 3 );
  79. to_newCost = to_parentCost + (x_parent-x_new)*S_new*(x_parent-x_new)';
  80. nun = nun + 1;
  81. GNodes( nun, : ) = [ x_new to_newCost ];
  82. % New Edge
  83. action = -K_new*( x_parent - x_new )';
  84. GEdges( nun-1, : )= [ id_parent nun action' ];
  85. % Rewire
  86. Rewire( X_near_ids, x_new, i+1 );
  87. % Draw the Graph
  88.  
  89. % Display Info
  90. if mod(i,50) == 1
  91. fprintf('Iteration EdgeCount NodeCount\n')
  92. draw_graph( GNodes, GEdges )
  93. end
  94. fprintf( ' %i %i %i\n',i,nun-1,nun )
  95.  
  96. % Prune Costly Nodes
  97. % if mod(i,40) == 1
  98. % fprintf('\n PRUNE\n\n')
  99. % Prune();
  100. % end
  101.  
  102. % Check If Nodes Exists in Goal Neighborhood
  103. % Check( G );
  104.  
  105. end
  106.  
  107. end
  108.  
  109.  
  110.  
  111. %===================================
  112. % Linearization
  113. %===================================
  114. function [ A, B ] = linmats( x0, u0 )
  115.  
  116. global model;
  117. m = model.phy.m;
  118. l = model.phy.l;
  119. b = model.phy.b;
  120. g = model.phy.g;
  121.  
  122. A = [ 0, 1; -g*cos(x0(1))/l, -b/m/l^2 ];
  123. B = [ 0; 1/m/l^2 ];
  124.  
  125. end
  126.  
  127. %===================================
  128. % LQR Nearest
  129. %===================================
  130. function [ id_nearest, x_nearest ] = LQRNearest( x_rand, S_rand )
  131.  
  132. global GNodes nun;
  133.  
  134. nearest_cost = inf;
  135.  
  136. for i = 1 : nun
  137. x = GNodes( i, 1:2 );
  138. cost = (x-x_rand)*S_rand*(x-x_rand)';
  139. if cost < nearest_cost
  140. nearest_cost = cost;
  141. x_nearest = x;
  142. id_nearest = i;
  143. end
  144. end
  145.  
  146. end
  147.  
  148. %===================================
  149. % LQR Steer
  150. %===================================
  151. function x_new = LQRSteer( x_nearest, x_rand, K_rand )
  152. % This function contains system's explicit dynamics
  153. global model;
  154. m = model.phy.m;
  155. l = model.phy.l;
  156. b = model.phy.b;
  157. g = model.phy.g;
  158. h = model.h;
  159.  
  160. u = -K_rand*( x_nearest - x_rand )';
  161. x_dot = [ x_nearest(2), ( u - b*x_nearest(2) - m*g*l*sin(x_nearest(1)) ) ];
  162.  
  163. x_new = x_nearest + x_dot*h;
  164.  
  165. end
  166.  
  167. %===================================
  168. % LQR Near
  169. %===================================
  170. function X_near_ids = LQRNear( x_new, S_new, id_nearest )
  171.  
  172. global GNodes nun;
  173.  
  174. % Define Neighborhood Radius
  175. gamma = 1; d = 2;
  176. ner = gamma*( log(nun+1)/nun )^(1/d);
  177. % Allocate and Assign to Output
  178. X_near_ids = id_nearest;
  179.  
  180. for i = 1 : nun
  181. x = GNodes( i, 1:2 );
  182. cost = (x-x_new)*S_new*(x-x_new)';
  183. if cost < ner
  184. X_near_ids(end+1) = i;
  185. end
  186. end
  187.  
  188. X_near_ids = unique(X_near_ids);
  189.  
  190. end
  191.  
  192. %===================================
  193. % Choose Parent
  194. %===================================
  195. function [ id_parent, x_parent, minCost ] = ChooseParent( X_near_ids, x_new, S_new )
  196.  
  197. global GNodes;
  198.  
  199. minCost = inf;
  200.  
  201. for id_candidate = X_near_ids
  202. x_candidate = GNodes( id_candidate, 1:2 );
  203. to_canCost = GNodes( id_candidate, 3 );
  204. from_canCost = (x_candidate-x_new)*S_new*(x_candidate-x_new)';
  205. if to_canCost+from_canCost < minCost
  206. minCost = to_canCost + from_canCost;
  207. id_parent = id_candidate;
  208. x_parent = x_candidate;
  209. end
  210. end
  211.  
  212. end
  213.  
  214. %===================================
  215. % Rewire
  216. %===================================
  217. function Rewire( X_near_ids, x_new, id_newnode )
  218.  
  219. global model GNodes GEdges; % nun-1 --> Number of Edges
  220.  
  221. % Cost-to-go for x_new
  222. to_newCost = GNodes( id_newnode, 3 );
  223.  
  224. for id_candidate = X_near_ids
  225. x_candidate = GNodes( id_candidate, 1:2 );
  226. to_canCost = GNodes( id_candidate, 3 );
  227. % Find Local System at x_near
  228. [ A_near, B_near ] = linmats( x_candidate, 0 );
  229. [ K_near, S_near ] = lqr( A_near, B_near, model.cost.Q, model.cost.R );
  230. ntocCost = ( x_new-x_candidate )*S_near*( x_new-x_candidate )';
  231. if to_newCost + ntocCost < to_canCost
  232. % New Cost to Candidate Nodes Should be Modified in GNodes
  233. rnewcost = to_newCost + ntocCost;
  234. GNodes( id_candidate, 3 ) = rnewcost;
  235. action = -K_near*( x_new - x_candidate )';
  236. edge_index = GEdges(:,2) == id_candidate ;
  237. GEdges( edge_index, : ) = [ id_newnode id_candidate action ];
  238. end
  239. end
  240.  
  241. end
  242.  
  243. %===================================
  244. % Branch-and-Bound
  245. %===================================
  246. function Prune()
  247.  
  248. global G;
  249.  
  250. j = 1;
  251. while j <= numnodes(G)
  252. if G.Nodes.Costz(j) > 5000
  253. G = rmnode( G, j );
  254. j = j - 1;
  255. end
  256. j = j + 1;
  257. end
  258.  
  259.  
  260. end
  261.  
  262. %===================================
  263. % Check Completeness
  264. %===================================
  265. function Check( G )
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272. end
  273.  
  274.  
  275. %===================================
  276. % Draw Graph
  277. %===================================
  278. function draw_graph( GNodes, GEdges )
  279.  
  280. global nun
  281.  
  282. persistent gFig
  283. if (isempty(gFig))
  284. gFig = figure(25);
  285. end
  286.  
  287. figure(gFig); cla; hold on;
  288.  
  289. for ids = GEdges( 1:nun-1, 1:2 )'
  290.  
  291. plot( [GNodes(ids(1),1) GNodes(ids(2),1)], ...
  292. [GNodes(ids(1),2) GNodes(ids(2),2)] )
  293.  
  294. end
  295.  
  296. axis([ -pi pi -2.5*pi 2.5*pi ]);
  297. grid on;
  298. drawnow
  299.  
  300. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement