Advertisement
Guest User

Untitled

a guest
Aug 29th, 2015
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.77 KB | None | 0 0
  1. Matlab code with Euler approximation:
  2. %%%%%%%%%%%%%%%%%%%%
  3. % Perform a simulation, from t = 0 through t = 10.
  4. % As an argument, take a controller function. This function must accept
  5. % a struct containing the physical parameters of the system and the current
  6. % gyro readings. The controller may use the strust to store persistent state, and
  7. % return this state as a second output value. If no controller is given,
  8. % a simulation is run with some pre-determined inputs.
  9. % The output of this function is a data struct with the following fields, recorded
  10. % at each time-step during the simulation:
  11. %
  12. % data =
  13. %
  14. % x: [3xN double]
  15. % theta: [3xN double]
  16. % vel: [3xN double]
  17. % angvel: [3xN double]
  18. % t: [1xN double]
  19. % input: [4xN double]
  20. % dt: 0.0050
  21. function result = simulate(controller, tstart, tend, dt)
  22. % Physical constants.
  23. g = 9.81;
  24. m = 0.95;
  25.  
  26. d = 0.35;
  27. h = 0.08;
  28.  
  29. I_body = diag([5e-3, 5e-3, 10e-3]);
  30. I_react=1e-3;
  31. I_gyro=1e-3;
  32.  
  33. I = struct('I_body', I_body, 'I_react', I_react, 'I_gyro', I_gyro);
  34.  
  35. kd = 0.25;
  36.  
  37. kt = 0.00001*9.8;
  38. kf = 0.0015*9.8;
  39.  
  40. % Simulation times, in seconds.
  41. if nargin < 4
  42. tstart = 0;
  43. tend = 1;
  44. dt = 0.05;
  45. end
  46. ts = tstart:dt:tend;
  47.  
  48. % Number of points in the simulation.
  49. N = numel(ts);
  50.  
  51. % Output values, recorded as the simulation runs.
  52. xout = zeros(3, N);
  53. xdotout = zeros(3, N);
  54. thetaout = zeros(3, N);
  55. thetadotout = zeros(3, N);
  56.  
  57. inputout_beta = zeros(2, N);
  58. inputout_motor_w = zeros(2, N);
  59.  
  60. inputout_beta_speed = zeros(2, N);
  61. inputout_beta_acc = zeros(2, N);
  62.  
  63. inputout = struct('inputout_beta', inputout_beta, 'inputout_beta_speed', inputout_beta_speed ,...
  64. 'inputout_beta_acc', inputout_beta_acc,'inputout_motor_w', inputout_motor_w);
  65.  
  66. % Struct given to the controller. Controller may store its persistent state in it.
  67. controller_params = struct('dt', dt, 'I', I, 'kf', kf, 'd', d, 'h', h, 'm', m, 'g', g);
  68.  
  69. % Initial system state.
  70. x = [0; 0; 10];
  71. xdot = zeros(3, 1);
  72. theta = zeros(3, 1);
  73.  
  74. % If we are running without a controller, do not disturb the system.
  75. if nargin == 0
  76. thetadot = zeros(3, 1);
  77. else
  78. % With a control, give a random deviation in the angular velocity.
  79. % Deviation is in degrees/sec.
  80. deviation = 300;
  81. thetadot = deg2rad(2 * deviation * rand(3, 1) - deviation);
  82. end
  83.  
  84. ind = 0;
  85. for t = ts
  86. ind = ind + 1;
  87.  
  88. % Get input from built-in input or controller.
  89. if nargin == 0
  90. i = input(t); %built-in generator
  91. else
  92. [i, controller_params] = controller(controller_params, thetadot);
  93. end
  94.  
  95. % Store simulation state for output.
  96. % don't go through the ground
  97. if (x(3) < 0)
  98. x(3) = 0;
  99. theta(1) = 0; % avoid integration windup
  100. theta(2) = 0;
  101. end
  102.  
  103. %%%%% Compute forces, torques, and accelerations.
  104. omega = thetadot2omega(thetadot, theta);
  105. a = acceleration(i, theta, m, g, kf, kt, kd, xdot);
  106. omegadot = angular_acceleration(i, omega, I, d, h, kf, kt);
  107.  
  108. %%%% Advance system state. Euler method.
  109. omega = omega + dt * omegadot;
  110. thetadot = omega2thetadot(omega, theta);
  111.  
  112. theta = theta + dt * thetadot;
  113. xdot = xdot + dt * a;
  114. x = x + dt * xdot;
  115.  
  116. xout(:, ind) = x;
  117. xdotout(:, ind) = xdot;
  118. thetaout(:, ind) = theta;
  119. thetadotout(:, ind) = thetadot;
  120. inputout(:, ind) = i;
  121. end
  122.  
  123. %% Put all simulation variables into an output struct.
  124.  
  125. result = struct('x', xout, 'theta', thetaout, 'vel', xdotout, ...
  126. 'angvel', thetadotout, 't', ts, 'dt', dt, 'input', inputout);
  127. end
  128.  
  129. %% Arbitrary test input.
  130. function in = input(t)
  131. inputout_beta= zeros(2, 1);
  132. inputout_motor_w= zeros(2, 1);
  133.  
  134. inputout_beta(1) = 0.09;%-0.1*cos(t);
  135. inputout_beta(2) = 0;%0.1*cos(t);
  136. inputout_motor_w(1)= 3000*pi/30;%100*pi/30*cos(t) %rpm to radian per second
  137. inputout_motor_w(2)= 3000*pi/30;%101*pi/30*cos(t) %rpm to radian per second
  138.  
  139. inputout_beta_speed(1)=0;
  140. inputout_beta_speed(2)=inputout_beta_speed(1);
  141. inputout_beta_acc = zeros(2, 1);
  142.  
  143. in = struct('inputout_beta', inputout_beta, 'inputout_beta_speed', inputout_beta_speed ,...
  144. 'inputout_beta_acc', inputout_beta_acc,'inputout_motor_w', inputout_motor_w);
  145.  
  146. end
  147.  
  148. % Compute thrust given current inputs and thrust coefficient.
  149. function F = force(w_motor, beta_motor, kf)
  150. w_l=w_motor(1);
  151. w_r=w_motor(2);
  152. beta_l=beta_motor(1);
  153. beta_r=beta_motor(2);
  154.  
  155. %Right power plant force
  156. f_r=kf*w_r;
  157. %Left power plant force
  158. f_l=kf*w_l;
  159. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  160. %Left motor force rot mat
  161. R_Pl_Bm=[cos(beta_l), 0, sin(beta_l);
  162. 0, 1, 0;
  163. -sin(beta_l),0, cos(beta_l)];
  164. %Right motor force rot mat
  165. R_Pr_Bm=[cos(beta_r), 0, sin(beta_r);
  166. 0, 1, 0;
  167. -sin(beta_r),0, cos(beta_r)] ;
  168. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  169. F_l=[0; 0; f_l];
  170. F_r=[0; 0; f_r];
  171. F=R_Pl_Bm*F_l+R_Pr_Bm*F_r;
  172. end
  173.  
  174. % Compute torques, given current inputs, length, drag coefficient, and thrust coefficient.
  175. function T_Bm = torque(input, d, h, k_f, k_d, I)
  176. w_l=input.inputout_motor_w(1);
  177. w_r=input.inputout_motor_w(2);
  178.  
  179. beta_l=input.inputout_beta(1);
  180. beta_r=input.inputout_beta(2);
  181.  
  182. beta_l_speed=input.inputout_beta_speed(1);
  183. beta_r_speed=input.inputout_beta_speed(2);
  184.  
  185. beta_l_acc=input.inputout_beta_acc(1);
  186. beta_r_acc=input.inputout_beta_acc(2);
  187.  
  188. %Right power plant torque
  189. tau_drag_r=k_d*w_r;
  190. %Left power plant torque
  191. tau_drag_l=k_d*w_l;
  192.  
  193. %Right power plant force
  194. f_r=k_f*w_r;
  195. %Left power plant force
  196. f_l=k_f*w_l;
  197.  
  198. F_l=[0; 0; f_l];
  199. F_r=[0; 0; f_r];
  200.  
  201. OlOb=[0;d;h];
  202. OrOb=[0;-d;h];
  203.  
  204. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  205. %Left motor force rot mat
  206. R_Pl_Bm=[cos(beta_l), 0, sin(beta_l);
  207. 0, 1, 0;
  208. -sin(beta_l),0, cos(beta_l)];
  209. %Right motor force rot mat
  210. R_Pr_Bm=[cos(beta_r), 0, sin(beta_r);
  211. 0, 1, 0;
  212. -sin(beta_r),0, cos(beta_r)] ;
  213. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  214.  
  215. I_gyro = I.I_gyro;
  216. I_react = I.I_react;
  217.  
  218. % TORQUES
  219. %Gyroscopic moments, longitudinal tilting
  220. Mgyro_Pl_beta_l=[0;-I_gyro*w_l*beta_l_speed;0];
  221. Mgyro_Pr_beta_r=[0;I_gyro*w_r*beta_r_speed;0];
  222. %Gyroscopic momentin body frame
  223. Mgyro_Bm=R_Pl_Bm*Mgyro_Pl_beta_l+R_Pr_Bm*Mgyro_Pr_beta_r;
  224.  
  225. %Fan torques due aerodynamic drag of the propeller
  226. Mdrugr_Pr=[0;0;-tau_drag_r];
  227. Mdrugl_Pl=[0;0;tau_drag_l];
  228. %Drag torques in body frame
  229. Mdrug_Bm=R_Pl_Bm*Mdrugl_Pl+R_Pr_Bm*Mdrugr_Pr;
  230.  
  231. %Moment from trust vectoring in body frame
  232. M_thrv_Bm=cross((R_Pl_Bm*F_l),OlOb)+cross((R_Pr_Bm*F_r),OrOb);
  233.  
  234. %Adverse Inertial Reaction moment
  235. M_react_Pr=[0;-I_react*beta_r_acc;0];
  236. M_react_Pl=[0;-I_react*beta_l_acc;0];
  237. %Adverse Inertial Reaction moment, body frame
  238. M_react_Bm=R_Pr_Bm*M_react_Pr+R_Pl_Bm*M_react_Pl;
  239. %FULL TORQUE
  240. %Body frame
  241. T_Bm=Mgyro_Bm+Mdrug_Bm+M_thrv_Bm+M_react_Bm;
  242. end
  243.  
  244. % Compute acceleration in inertial reference frame
  245. % Parameters:
  246. % g: gravity acceleration
  247. % m: mass of quadcopter
  248. % kf: thrust coefficient
  249. % kt: global drag coefficient
  250. function A = acceleration(inputs, angles, m, g, kf, kt, kd, linear_velocity)
  251. F_g = [0; 0; -g];
  252. R_Bm_Wi = rotation(angles);
  253. F_Bm = force(inputs.inputout_motor_w, inputs.inputout_beta, kf);
  254. %Friction as a force proportional to the linear velocity in each direction.
  255. F_a = -kd * linear_velocity;
  256. %mV=R*F
  257. A = R_Bm_Wi * F_Bm * 1/m + F_g + F_a;
  258. end
  259.  
  260. % Compute angular acceleration in body frame
  261. % Parameters:
  262. % I: inertia matrix
  263. function omegad = angular_acceleration(inputs, omega, I, d, h, kf, kt)
  264. T = torque(inputs, d, h, kf, kt, I);
  265. omegad = I.I_body(T - cross(omega, I.I_body * omega));
  266. end
  267.  
  268. % Convert derivatives of roll, pitch, yaw to omega.
  269. function omega = thetadot2omega(thetadot, angles)
  270. phi = angles(1);
  271. theta = angles(2);
  272. psi = angles(3);
  273. W = [1, 0, -sin(phi);
  274. 0 cos(phi), cos(phi)*sin(phi);
  275. 0 -sin(phi), cos(theta)/cos(phi)];
  276. omega = W * thetadot;
  277. end
  278.  
  279. % Convert omega to roll, pitch, yaw derivatives
  280. function thetadot = omega2thetadot(omega, angles)
  281. phi = angles(1);
  282. theta = angles(2);
  283. psi = angles(3);
  284. W = [1, sin(phi)*tan(theta),cos(phi)*tan(theta);
  285. 0 cos(phi), -sin(phi);
  286. 0 sin(phi)/cos(theta), cos(phi)/cos(phi)];
  287. thetadot = W * omega;
  288. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement