footPDR.m 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. function pos_result = footPDR(index, gyr, acc, press)
  2. global C;
  3. global vel_n;
  4. global pos_n;
  5. global P;
  6. global H;
  7. global R;
  8. global sigma_omega;
  9. global sigma_a;
  10. global sigma_v;
  11. global press_data;
  12. global gyr_norm;
  13. global ZUPT_STATUS;
  14. global stand_num;
  15. global last_position;
  16. global last_yaw;
  17. global last_zupt;
  18. global gyr_data;
  19. global g;
  20. global gyrBias;
  21. global can_output;
  22. global stay;
  23. global stay_status;
  24. global acc_buff;
  25. global acc_size;
  26. global acc_data;
  27. if(index == 1)
  28. sigma_v = 0.01;
  29. sigma_a = 0.01;
  30. sigma_omega = 0.01;
  31. g = 9.80665;
  32. pitch = asin(-acc(1)/g);
  33. roll = atan2(acc(2), acc(3));
  34. yaw = 0;
  35. C= [cos(yaw)*cos(pitch), -sin(yaw)*cos(roll)+cos(yaw)*sin(pitch)*sin(roll), sin(yaw)*sin(roll)+ cos(yaw)*sin(pitch)*cos(roll);
  36. sin(yaw)*cos(pitch), cos(yaw)*cos(roll)+sin(yaw)*sin(pitch)*sin(roll), -cos(yaw)*sin(roll)+sin(yaw)*sin(pitch)* cos(roll);
  37. -sin(pitch), cos(pitch)* sin(roll), cos(pitch)*cos(roll);];
  38. H = [zeros(3,3), zeros(3,3), eye(3);];
  39. R = diag([sigma_v*0.1 sigma_v*0.1 sigma_v*0.1]).^2;
  40. P = zeros(9,9);
  41. vel_n = [0;0;0];
  42. pos_n = [0;0;0];
  43. pos_result = [0;0;0;0;0];
  44. ZUPT_STATUS = 0;
  45. press_data = [press];
  46. gyr_norm = [norm(gyr)];
  47. stand_num = 0;
  48. last_position = [0;0;0;];
  49. last_yaw = 0;
  50. last_zupt = 0;
  51. gyr_data = [gyr];
  52. gyrBias = [0;0;0];
  53. acc_buff = [norm(acc)];
  54. acc_data = [acc];
  55. can_output = 0;
  56. stay_status = 0;
  57. acc_size = 1;
  58. else
  59. gyr_norm = [gyr_norm, norm([gyr(1);gyr(3)])];
  60. acc_buff = [acc_buff norm(acc)];
  61. press_data = [press_data, press];
  62. gyr_data = [gyr_data gyr];
  63. w = gyr;
  64. if(index>500)
  65. if(max(gyr_data(1,index-500:index)) - min(gyr_data(1,index-500:index)) < 0.04 && max(gyr_data(2,index-500:index)) - min(gyr_data(2,index-500:index)) < 0.04 && max(gyr_data(3,index-500:index)) - min(gyr_data(3,index-500:index)) < 0.04 )
  66. gyrBias = mean(gyr_data(:,index-500:index),2);
  67. acc_size = 9.80665/mean(acc_buff(:,index-500:index));
  68. end
  69. end
  70. w = w - gyrBias;
  71. acc = acc.*acc_size;
  72. dt = 1/100;
  73. %当前时刻陀螺仪生成的叉乘矩阵,姿态矩阵迭代需要
  74. temp = [0, -w(3), w(2);
  75. w(3), 0, -w(1);
  76. -w(2), w(1), 0;]* dt;
  77. C= C * (2*eye(3)+temp)/(2*eye(3) - temp);
  78. acc_n = C * acc;
  79. acc_data = [acc_data acc_n-[0;0;g ]];
  80. vel_n = vel_n + (acc_n - [0;0;g])*dt;
  81. pos_n = pos_n + vel_n* dt;
  82. S = [0, -acc_n(3), acc_n(2);
  83. acc_n(3), 0, -acc_n(1);
  84. -acc_n(2), acc_n(1), 0;];
  85. F = [eye(3), zeros(3,3), zeros(3,3);
  86. zeros(3,3), eye(3), dt*eye(3);
  87. -dt*S, zeros(3,3), eye(3)];
  88. Q = diag([sigma_omega sigma_omega sigma_omega sigma_omega sigma_omega sigma_omega sigma_a sigma_a sigma_a]*dt).^2;
  89. P = F*P*F' + Q;
  90. if(index > 10 )
  91. max_mum = max(gyr_norm(index-9:index));
  92. % min_mum = min(gyr_norm(index-9:index));
  93. end
  94. if(index> 6 && press_data(index) - min(press_data(index-6:index-1)) > 100000)
  95. ZUPT_STATUS = 1;
  96. elseif(index> 6 && press_data(index) - max(press_data(index-6:index-1)) < -100000 )
  97. ZUPT_STATUS = 2;
  98. end
  99. stand_zupt = 0;
  100. if(((gyr_norm(index)< 0.4) && (index > 15) && ((max_mum - gyr_norm(index)) < 0.35)))
  101. stand_zupt = 1;
  102. end
  103. run_zupt = 0;
  104. if((index> 10 && ZUPT_STATUS == 1 && norm([gyr(1);gyr(3)]) < 0.5))
  105. run_zupt = 1;
  106. end
  107. if( run_zupt== 1 || stand_zupt == 1)
  108. % if((((gyr_norm(index)< 0.4) && (index > 15) && ((max_mum - gyr_norm(index)) < 0.35))))
  109. if(var(gyr_norm(index-4:index),1) <0.001 && var(press_data(index-4:index)./10000,1)>1.0)
  110. disp("下蹲");
  111. end
  112. zupt = 0;
  113. K = P*H'/(H*P*H' + R);
  114. delta_x = K * [vel_n;];
  115. P = P - K*H*P;
  116. delta_x(3) = atan2(C(2,1),C(1,1));
  117. C_fix = [0, -delta_x(3), delta_x(2);
  118. delta_x(3), 0, -delta_x(1);
  119. -delta_x(2), delta_x(1), 0];
  120. C = ((2*eye(3)-C_fix)/(2*eye(3) + C_fix))* C;
  121. pos_n = pos_n - delta_x(4:6);
  122. vel_n = vel_n - delta_x(7:9);
  123. last_position = pos_n;
  124. last_yaw = atan2(C(2,1),C(1,1));
  125. last_zupt = 1;
  126. can_output = 1;
  127. stay_status = stay_status+ 1;
  128. else
  129. zupt = 1;
  130. stay_status = 0;
  131. % delta_yaw = atan2(C(2,1), C(1,1)) - last_yaw;
  132. %
  133. % pos_result(2) = norm(pos_n(1:2))*sin(delta_yaw);
  134. % pos_result(1) = norm(pos_n(1:2))*cos(delta_yaw) - norm(last_position(1:2));
  135. % pos_result = pos_n - last_position;
  136. end
  137. pos_result(1:3) = pos_n(:) - last_position(:);
  138. % pos_result(1:3) = ((2*eye(3)-C_fix)/(2*eye(3) + C_fix))*pos_n(:) - ((2*eye(3)-C_fix)/(2*eye(3) + C_fix))*last_position(:);
  139. % pos_result(1:3) = pos_n(:) - last_position(:);
  140. % pos_result(1) = distance'*pos_n(1:2)/norm(pos_n(1:2));
  141. % % pos_result(2) = (distance(1)*pos_n(2) - distance(2)*pos_n(1))/norm(pos_n(1:2));
  142. %
  143. theta = 0.12;
  144. temp = [cos(theta), sin(theta);-sin(theta), cos(theta)];
  145. pos_temp = temp*[pos_result(1);pos_result(2)];
  146. pos_result(1) =pos_temp(1);
  147. pos_result(2) =pos_temp(2);
  148. % if index > 5
  149. % pos_result = mean(acc_data(:,index - 5 :index),2);
  150. % end
  151. % pos_result(1) = 0;
  152. % pos_result = acc_n - [0;0;g];
  153. % pos_result(1) = atan2(C(2,1),C(1,1));
  154. %
  155. % pos_result(2) = asin(-C(3,1));
  156. % pos_result(3) = atan2(C(3,2),C(3,3));
  157. % pos_result(2) = 2 * pos_result(2);
  158. if(can_output == 1 && norm(pos_result(1:2)) >0.1)
  159. if(pos_result(2) < -0.2)
  160. disp("右跳");
  161. can_output = 0;
  162. elseif(pos_result(2) > 0.2)
  163. disp("左跳")
  164. can_output = 0;
  165. elseif(pos_result(3) > 0.2)
  166. disp("跳高")
  167. can_output = 0;
  168. end
  169. end
  170. % distance = pos_n(1:2) - last_position(1:2);
  171. % pos_result(1) = last_position(1:2)' * distance(1:2)/norm(last_position(1:2));
  172. % pos_result(2) = (last_position(1)*distance(2)-distance(1)*last_position(2))/norm(last_position(1:2));
  173. % pos_result(3) = pos_n(3) - last_position(3);
  174. % pos_result(1:3)= (pos_result(1:3)+ 6) * 1000000;
  175. pos_result(4) = norm([gyr(1);gyr(3)]);
  176. pos_result(5) = var(gyr_norm(index-4:index),1) ;
  177. % pos_result(3) = norm(gyr) * 1000000;
  178. P = (P+P')/2;
  179. end
  180. end