o09Axis.cs 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using UnityEngine;
  6. using MathNet.Numerics.LinearAlgebra;
  7. using UnityEngine.UI;
  8. using MathNet.Numerics;
  9. using System.Runtime.InteropServices;
  10. public class o0Vector3Filter
  11. {
  12. Vector3 state = default;
  13. float Variance = 1;
  14. public Vector3 Update(Vector3 v)
  15. {
  16. if (state == default)
  17. return state = v;
  18. Variance += 10;
  19. float mVariance = 1;
  20. state = Vector3.Lerp(state, v, mVariance/ (Variance + mVariance));
  21. Variance = Variance * mVariance / (Variance + mVariance);
  22. return state;
  23. }
  24. }
  25. public class o0MagneticCalibraterEllipsoidFitting//默认在无磁干扰环境下,有磁干扰则无法保证效果
  26. {
  27. [JsonIgnore]
  28. public Vector3 _Center = Vector3.zero;
  29. [JsonIgnore]
  30. Matrix<double> _CorrectMatrix = null;
  31. public float[] Center
  32. {
  33. get
  34. {
  35. return new float[]{_Center.x, _Center.y, _Center.z};
  36. }
  37. set
  38. {
  39. _Center = new Vector3(value[0], value[1], value[2]);
  40. }
  41. }
  42. public double[] CorrectMatrix
  43. {
  44. get
  45. {
  46. if (_CorrectMatrix == null)
  47. return default;
  48. var m = new double[9];
  49. for (var i = 0; i < 3; ++i)
  50. for (var j = 0; j < 3; ++j)
  51. m[j + i * 3] = _CorrectMatrix[i,j];
  52. return m;
  53. }
  54. set
  55. {
  56. if (value == default)
  57. {
  58. _CorrectMatrix = null;
  59. return;
  60. }
  61. _CorrectMatrix = CreateMatrix.Dense<double>(3,3);
  62. for (var i = 0; i < 3; ++i)
  63. for (var j = 0; j < 3; ++j)
  64. _CorrectMatrix[i, j] = value[j + i * 3];
  65. }
  66. }
  67. public o0MagneticCalibraterEllipsoidFitting()
  68. {
  69. //Calibration = true;
  70. }
  71. // public o0MagneticCalibraterEllipsoidFitting(o0Project.Vector3f Center, double[] CorrectMatrix)
  72. public o0MagneticCalibraterEllipsoidFitting(float[] Center, double[] CorrectMatrix)
  73. {
  74. this.Center = Center;
  75. this.CorrectMatrix = CorrectMatrix;
  76. }
  77. [JsonIgnore]
  78. List<Vector3> records = null;
  79. [JsonIgnore]
  80. public Vector3 _Radius = default;
  81. public float[] Radius
  82. {
  83. get
  84. {
  85. return new float[]{_Radius.x, _Radius.y, _Radius.z};
  86. }
  87. set
  88. {
  89. _Radius = new Vector3(value[0], value[1], value[2]);
  90. }
  91. }
  92. public List<Vector3> getRecords() {
  93. //Debug.LogWarning(records);
  94. return records;
  95. }
  96. [JsonIgnore]
  97. List<Vector3> BadRecords = null;
  98. [JsonIgnore]
  99. public bool Calibration
  100. {
  101. get
  102. {
  103. return records != null;
  104. }
  105. set
  106. {
  107. if (value == true)
  108. {
  109. records = new List<Vector3>();
  110. }
  111. else
  112. {
  113. try
  114. {
  115. int mag_data_counter = records.Count; //mag数据数量
  116. double mag_x, mag_y, mag_z;
  117. var mat_D = CreateMatrix.Dense<double>(mag_data_counter, 9);
  118. //读取mag
  119. for (int i = 0; i < mag_data_counter; i++)
  120. {
  121. //mag_x_y_z赋值
  122. mag_x = records[i].x;
  123. mag_y = records[i].y;
  124. mag_z = records[i].z;
  125. mat_D[i, 0] = mag_x * mag_x;
  126. mat_D[i, 1] = mag_y * mag_y;
  127. mat_D[i, 2] = mag_z * mag_z;
  128. mat_D[i, 3] = 2 * mag_x * mag_y;
  129. mat_D[i, 4] = 2 * mag_x * mag_z;
  130. mat_D[i, 5] = 2 * mag_y * mag_z;
  131. mat_D[i, 6] = 2 * mag_x;
  132. mat_D[i, 7] = 2 * mag_y;
  133. mat_D[i, 8] = 2 * mag_z;
  134. }
  135. var mat_DT = mat_D.Transpose();
  136. var mat_Ones = CreateMatrix.Dense<double>(mag_data_counter, 1, 1.0);
  137. var mat_Result = (mat_DT * mat_D).Inverse() * (mat_DT * mat_Ones);
  138. var mat_A_4x4 = CreateMatrix.Dense<double>(4, 4);
  139. mat_A_4x4[0, 0] = mat_Result[0, 0];
  140. mat_A_4x4[0, 1] = mat_Result[3, 0];
  141. mat_A_4x4[0, 2] = mat_Result[4, 0];
  142. mat_A_4x4[0, 3] = mat_Result[6, 0];
  143. mat_A_4x4[1, 0] = mat_Result[3, 0];
  144. mat_A_4x4[1, 1] = mat_Result[1, 0];
  145. mat_A_4x4[1, 2] = mat_Result[5, 0];
  146. mat_A_4x4[1, 3] = mat_Result[7, 0];
  147. mat_A_4x4[2, 0] = mat_Result[4, 0];
  148. mat_A_4x4[2, 1] = mat_Result[5, 0];
  149. mat_A_4x4[2, 2] = mat_Result[2, 0];
  150. mat_A_4x4[2, 3] = mat_Result[8, 0];
  151. mat_A_4x4[3, 0] = mat_Result[6, 0];
  152. mat_A_4x4[3, 1] = mat_Result[7, 0];
  153. mat_A_4x4[3, 2] = mat_Result[8, 0];
  154. mat_A_4x4[3, 3] = -1.0;
  155. var mat_Center = -((mat_A_4x4.SubMatrix(0, 3, 0, 3)).Inverse() * mat_Result.SubMatrix(6, 3, 0, 1));
  156. //椭球圆心 //分块,从0,0开始的3*3的矩阵
  157. var mat_T_4x4 = CreateMatrix.DenseIdentity<double>(4, 4);
  158. mat_T_4x4.SetSubMatrix(3, 1, 0, 3, mat_Center.Transpose());
  159. var mat_R = mat_T_4x4 * mat_A_4x4 * mat_T_4x4.Transpose();
  160. var evd = mat_R.SubMatrix(0, 3, 0, 3) / -mat_R[3, 3];
  161. var eig = evd.Evd();
  162. var mat_Eigval = CreateVector.Dense<double>(3);
  163. var mat_Evecs = eig.EigenVectors;
  164. mat_Eigval[0] = eig.EigenValues[0].Real; //特征值的实部
  165. mat_Eigval[1] = eig.EigenValues[1].Real;
  166. mat_Eigval[2] = eig.EigenValues[2].Real;
  167. var mat_Radii = mat_Eigval.Map(delegate (double x)
  168. {
  169. return 1.0 / Math.Sqrt(Math.Abs(x));
  170. }); //椭球半径,特征值倒数后开方
  171. var mat_Scale = CreateMatrix.DenseIdentity<double>(3, 3);
  172. mat_Scale[0, 0] = mat_Radii[0];
  173. mat_Scale[1, 1] = mat_Radii[1];
  174. mat_Scale[2, 2] = mat_Radii[2];
  175. //double min_Radii = mat_Radii.Minimum(); //返回最小的元素
  176. mat_Scale = mat_Scale.Inverse();// * min_Radii;
  177. var mat_Correct = mat_Evecs * mat_Scale * mat_Evecs.Transpose();
  178. //_Center = new Vector3((float)mat_Center[0], (float)mat_Center[1], (float)mat_Center[2]);
  179. Debug.Log("The Ellipsoid center is:" + mat_Center.ToString());
  180. Debug.Log("The Ellipsoid radii is:" + mat_Radii.ToString());
  181. Debug.Log("The scale matrix is:" + mat_Scale.ToString());
  182. Debug.Log("The correct matrix is:" + mat_Correct.ToString());
  183. _Center = new Vector3((float)mat_Center[0, 0], (float)mat_Center[1, 0], (float)mat_Center[2, 0]);
  184. _Radius = new Vector3((float)mat_Radii[0], (float)mat_Radii[1], (float)mat_Radii[2]);
  185. this._CorrectMatrix = mat_Correct;
  186. {
  187. BadRecords = new List<Vector3>();
  188. var AverageDistance = 0f;
  189. foreach (var i in records)
  190. {
  191. var v = i - new Vector3((float)mat_Center[0, 0], (float)mat_Center[1, 0], (float)mat_Center[2, 0]);
  192. var MathNetV = CreateVector.Dense<double>(3);
  193. MathNetV[0] = v.x;
  194. MathNetV[1] = v.y;
  195. MathNetV[2] = v.z;
  196. //MathNetV = (MathNetV * mat_Scale) * mat_Correct;
  197. MathNetV = (MathNetV) * mat_Correct;
  198. v = new Vector3((float)MathNetV[0], (float)MathNetV[1], (float)MathNetV[2]);
  199. AverageDistance += v.magnitude;
  200. }
  201. AverageDistance /= records.Count;
  202. foreach (var i in records)
  203. {
  204. var v = i - new Vector3((float)mat_Center[0, 0], (float)mat_Center[1, 0], (float)mat_Center[2, 0]);
  205. var MathNetV = CreateVector.Dense<double>(3);
  206. MathNetV[0] = v.x;
  207. MathNetV[1] = v.y;
  208. MathNetV[2] = v.z;
  209. //MathNetV = (MathNetV * mat_Scale) * mat_Correct;
  210. MathNetV = (MathNetV) * mat_Correct;
  211. v = new Vector3((float)MathNetV[0], (float)MathNetV[1], (float)MathNetV[2]);
  212. if (Math.Abs(v.magnitude - AverageDistance) > 0.1 * AverageDistance)
  213. {
  214. BadRecords.Add(i);
  215. }
  216. }
  217. Debug.Log("BadRecords: "+ BadRecords.Count);
  218. }
  219. }
  220. catch(NonConvergenceException)
  221. {
  222. Debug.Log("数据错误无法拟合");
  223. }
  224. records = null;
  225. }
  226. }
  227. }
  228. public Vector3 Update(Vector3 v)
  229. {
  230. if (v.magnitude > 30)
  231. Debug.Log(v);
  232. if (Calibration)
  233. {
  234. records.Add(v);
  235. return v;
  236. }
  237. if(_CorrectMatrix != null)
  238. {
  239. v -= _Center;
  240. var MathNetV = CreateVector.Dense<double>(3);
  241. MathNetV[0] = v.x;
  242. MathNetV[1] = v.y;
  243. MathNetV[2] = v.z;
  244. //MathNetV = (MathNetV * mat_Scale) * mat_Correct;
  245. MathNetV = (MathNetV) * _CorrectMatrix;
  246. v = new Vector3((float)MathNetV[0], (float)MathNetV[1], (float)MathNetV[2]);
  247. //Debug.Log(v.magnitude);
  248. return v;
  249. }
  250. return v;
  251. }
  252. public float CalibratCompletionPercentage()
  253. {
  254. return 0;
  255. }
  256. }
  257. public class o0MagneticCalibraterSimple//默认在无磁干扰环境下,有磁干扰则无法保证效果
  258. {
  259. [JsonIgnore]
  260. public Vector3 _Center = Vector3.zero;
  261. //Vector3 Center = new Vector3(0,0,0);
  262. [JsonIgnore]
  263. public Vector3 _Radius = new Vector3(2, 2, 2);
  264. public o0Project.Vector3f Center
  265. {
  266. get
  267. {
  268. return new o0Project.Vector3f(_Center.x, _Center.y, _Center.z);
  269. }
  270. set
  271. {
  272. _Center = new Vector3(value.x, value.y, value.z);
  273. }
  274. }
  275. public o0Project.Vector3f Radius
  276. {
  277. get
  278. {
  279. return new o0Project.Vector3f(_Radius.x, _Radius.y, _Radius.z);
  280. }
  281. set
  282. {
  283. _Radius = new Vector3(value.x, value.y, value.z);
  284. }
  285. }
  286. public o0MagneticCalibraterSimple()
  287. {
  288. //Calibration = true;
  289. }
  290. public o0MagneticCalibraterSimple(o0Project.Vector3f Center, o0Project.Vector3f Radius)
  291. {
  292. this.Center = Center;
  293. this.Radius = Radius;
  294. }
  295. [JsonIgnore]
  296. Vector3 Min = new Vector3(float.MinValue, float.MinValue, float.MinValue);
  297. [JsonIgnore]
  298. Vector3 Max = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
  299. [JsonIgnore]
  300. public bool Calibration
  301. {
  302. get
  303. {
  304. return !(Min == new Vector3(float.MinValue, float.MinValue, float.MinValue) && Max == new Vector3(float.MaxValue, float.MaxValue, float.MaxValue));
  305. }
  306. set
  307. {
  308. if (value == true)
  309. {
  310. Min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
  311. Max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
  312. }
  313. else
  314. {
  315. Min = new Vector3(float.MinValue, float.MinValue, float.MinValue);
  316. Max = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
  317. }
  318. }
  319. }
  320. public Vector3 Update(Vector3 v)
  321. {
  322. if (v.magnitude > 30)
  323. Debug.Log(v);
  324. if (Calibration)
  325. {
  326. if (Min.x > v.x)
  327. Min.x = v.x;
  328. if (Min.y > v.y)
  329. Min.y = v.y;
  330. if (Min.z > v.z)
  331. Min.z = v.z;
  332. if (Max.x < v.x)
  333. Max.x = v.x;
  334. if (Max.y < v.y)
  335. Max.y = v.y;
  336. if (Max.z < v.z)
  337. Max.z = v.z;
  338. _Center = (Max + Min) / 2;
  339. _Radius = (Max - Min) / 2;
  340. return v;
  341. }
  342. v -= _Center;
  343. v = new Vector3(v.x / _Radius.x, v.y / _Radius.y, v.z / _Radius.z);
  344. return v;
  345. }
  346. public float CalibratCompletionPercentage()
  347. {
  348. return 0;
  349. }
  350. }
  351. public class o0MagneticCalibrater//默认在无磁干扰环境下,有磁干扰则无法保证效果
  352. {
  353. [JsonIgnore]
  354. public Vector3 _Center = Vector3.zero;
  355. //Vector3 Center = new Vector3(0,0,0);
  356. [JsonIgnore]
  357. public Vector3 _Radius = new Vector3(2, 2, 2);
  358. public o0Project.Vector3f Center
  359. {
  360. get
  361. {
  362. return new o0Project.Vector3f(_Center.x, _Center.y, _Center.z);
  363. }
  364. set
  365. {
  366. _Center = new Vector3(value.x, value.y, value.z);
  367. }
  368. }
  369. public o0Project.Vector3f Radius
  370. {
  371. get
  372. {
  373. return new o0Project.Vector3f(_Radius.x, _Radius.y, _Radius.z);
  374. }
  375. set
  376. {
  377. _Radius = new Vector3(value.x, value.y, value.z);
  378. }
  379. }
  380. public o0MagneticCalibrater()
  381. {
  382. //Calibration = true;
  383. }
  384. public o0MagneticCalibrater(o0Project.Vector3f Center, o0Project.Vector3f Radius)
  385. {
  386. this.Center = Center;
  387. this.Radius = Radius;
  388. }
  389. [JsonIgnore]
  390. HashSet<Vector3> Point = default;
  391. [JsonIgnore]
  392. int PointMaxCount = 50;
  393. [JsonIgnore]
  394. Dictionary<(Vector3, Vector3), float> Distance = default;
  395. public void AddPoint(Vector3 v)
  396. {
  397. if (Point.Contains(v))
  398. return;
  399. foreach (var i in Point)
  400. Distance.Add((i, v), Vector3.Distance(v, i));
  401. Point.Add(v);
  402. }
  403. public void RemovePoint(Vector3 v)
  404. {
  405. Point.Remove(v);
  406. foreach (var i in Point)
  407. {
  408. Distance.Remove((v, i));
  409. Distance.Remove((i, v));
  410. }
  411. }
  412. public float TotalDistance(Vector3 v)
  413. {
  414. float t = 0;
  415. foreach (var i in Point)
  416. {
  417. if (Distance.ContainsKey((i, v)))
  418. {
  419. t += Distance[(i, v)];
  420. continue;
  421. }
  422. else if (Distance.ContainsKey((v, i)))
  423. {
  424. t += Distance[(v, i)];
  425. continue;
  426. }
  427. }
  428. return t;
  429. }
  430. public Vector3 MinDistancePoint()
  431. {
  432. Vector3 minV = default;
  433. float minD = float.MaxValue;
  434. foreach (var i in Point)
  435. {
  436. float d = TotalDistance(i);
  437. if (minV == default || minD > d)
  438. {
  439. minD = d;
  440. minV = i;
  441. }
  442. }
  443. return minV;
  444. }
  445. public Vector3 RadiusScale()
  446. {
  447. Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
  448. Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
  449. foreach (var i in Point)
  450. {
  451. if (min.x > i.x)
  452. min.x = i.x;
  453. if (min.y > i.y)
  454. min.y = i.y;
  455. if (min.z > i.z)
  456. min.z = i.z;
  457. if (max.x < i.x)
  458. max.x = i.x;
  459. if (max.y < i.y)
  460. max.y = i.y;
  461. if (max.z < i.z)
  462. max.z = i.z;
  463. }
  464. return (max - min) / 2;
  465. }
  466. [JsonIgnore]
  467. public bool Calibration
  468. {
  469. get
  470. {
  471. return Distance != null;
  472. }
  473. set
  474. {
  475. if (value == true)
  476. {
  477. Point = new HashSet<Vector3>();
  478. Distance = new Dictionary<(Vector3, Vector3), float>();
  479. }
  480. else
  481. {
  482. Distance = null;
  483. }
  484. }
  485. }
  486. [JsonIgnore]
  487. public System.Random r = new System.Random();
  488. public Vector3 Update(Vector3 v)
  489. {
  490. if (v.magnitude > 30)
  491. Debug.Log(v);
  492. if (Calibration)
  493. {
  494. AddPoint(v);
  495. if (Point.Count > PointMaxCount)
  496. {
  497. RemovePoint(MinDistancePoint());
  498. _Radius = RadiusScale();
  499. }
  500. Vector3 randomV = Point.ElementAt(r.Next(Point.Count));
  501. var scaledCenter = new Vector3(_Center.x / _Radius.x, _Center.y / _Radius.y, _Center.z / _Radius.z);
  502. var scaledV = new Vector3(randomV.x / _Radius.x, randomV.y / _Radius.y, randomV.z / _Radius.z);
  503. float diff = Vector3.Distance(scaledCenter, scaledV) - 1;
  504. scaledCenter += (scaledV - scaledCenter).normalized * diff * 0.1f;
  505. _Center = new Vector3(scaledCenter.x * _Radius.x, scaledCenter.y * _Radius.y, scaledCenter.z * _Radius.z);
  506. }
  507. /*
  508. if (diff > 0)
  509. {
  510. Center -= v * diff;
  511. }
  512. else
  513. {
  514. }/**/
  515. //Point.Add(v);
  516. //Debug.Log(v.magnitude);
  517. v -= _Center;
  518. v = new Vector3(v.x / _Radius.x, v.y / _Radius.y, v.z / _Radius.z);
  519. return v;
  520. }
  521. public float CalibratCompletionPercentage()
  522. {
  523. if (Point == null)
  524. return 0;
  525. List<float> ScaleDistance = new List<float>();
  526. foreach (var i in Point)
  527. {
  528. var v = i - _Center;
  529. ScaleDistance.Add(new Vector3(v.x / _Radius.x, v.y / _Radius.y, v.z / _Radius.z).magnitude);
  530. }
  531. while (ScaleDistance.Count < PointMaxCount)
  532. ScaleDistance.Add(0);
  533. float average = 0;
  534. foreach (var i in ScaleDistance)
  535. average += i;
  536. average /= ScaleDistance.Count;
  537. float variance = 0;
  538. foreach (var i in ScaleDistance)
  539. variance += Mathf.Pow(average - i, 2);
  540. variance /= ScaleDistance.Count;
  541. return Mathf.Pow((1 - variance / average), 10) * 100;
  542. //return variance;
  543. }
  544. }
  545. public class o0GyrCalibrater
  546. {
  547. [JsonIgnore]
  548. public Vector3 _Average = Vector3.zero;
  549. [JsonIgnore]
  550. public long Count = -1;
  551. [JsonIgnore]
  552. public bool Calibration
  553. {
  554. get
  555. {
  556. return Count != -1;
  557. }
  558. set
  559. {
  560. if (value)
  561. Count = 0;
  562. else
  563. Count = -1;
  564. }
  565. }
  566. public float[] Average
  567. {
  568. get
  569. {
  570. return new float[]{_Average.x, _Average.y, _Average.z};
  571. }
  572. set
  573. {
  574. _Average = new Vector3(value[0], value[1], value[2]);
  575. }
  576. }
  577. public o0GyrCalibrater()
  578. {
  579. }
  580. //[JsonConstructor, o0.BinarySerialization.Constructor]
  581. // public o0GyrCalibrater(o0Project.Vector3f Average)
  582. public o0GyrCalibrater(float[] Average)
  583. {
  584. this.Average = Average;
  585. }
  586. public Vector3 Update(Vector3 v)
  587. {
  588. if (Calibration)
  589. _Average += (v - _Average) / ++Count;
  590. v -= _Average;
  591. if (v.magnitude < 0.0003)
  592. return Vector3.zero;
  593. return v;
  594. }
  595. }
  596. // public class o09Axis
  597. // {
  598. // public List<o0UIRawImageTester> Tester = new List<o0UIRawImageTester>();
  599. // public List<Text> TextTester = new List<Text>();
  600. // public GameObject AccMesh;
  601. // public GameObject GryMesh;
  602. // public GameObject MagMesh;
  603. // public struct State
  604. // {
  605. // public Int32 TimeGap;
  606. // public Vector3 Acc;
  607. // public Vector3 AccSmooth;
  608. // public float AccVariance;
  609. // public Vector3 Gyr;
  610. // public Vector3 Mag;
  611. // public Vector3 MagSmooth;
  612. // public Quaternion Qua;
  613. // public Quaternion QuaSmooth;
  614. // public float Variance;
  615. // }
  616. // public void SetIdentityAndSave()
  617. // {
  618. // setIdentity();
  619. // TextTester[0].text = "AccIdentity:" + getAccIdentity();
  620. // AccMesh.transform.localRotation = default;
  621. // MagMesh.transform.localRotation = default;
  622. // GryMesh.transform.localRotation = default;
  623. // SaveIdentity();
  624. // }
  625. // public void LoadIdentity()
  626. // {
  627. // try {
  628. // string magIdentityStr = PlayerPrefs.GetString("MagIdentity", "");
  629. // if (magIdentityStr.Length > 0) {
  630. // float[] arr = JsonConvert.DeserializeObject<float[]>(magIdentityStr);
  631. // setMagIdentity(new Vector3(arr[0], arr[1], arr[2]));
  632. // }
  633. // string accIdentityStr = PlayerPrefs.GetString("AccIdentity", "");
  634. // if (accIdentityStr.Length > 0) {
  635. // float[] arr = JsonConvert.DeserializeObject<float[]>(accIdentityStr);
  636. // setAccIdentity(new Vector3(arr[0], arr[1], arr[2]));
  637. // }
  638. // }
  639. // catch (System.Exception e) { Debug.LogError(e.Message); }
  640. // }
  641. // private void SaveIdentity() {
  642. // Vector3 m = getMagIdentity();
  643. // Vector3 a = getAccIdentity();
  644. // PlayerPrefs.SetString("MagIdentity",JsonConvert.SerializeObject(new float[]{
  645. // m.x, m.y, m.z
  646. // }));
  647. // PlayerPrefs.SetString("AccIdentity", JsonConvert.SerializeObject(new float[]{
  648. // a.x, a.y, a.z
  649. // }));
  650. // }
  651. // int platformID = -1;
  652. // void SetPlatformID()
  653. // {
  654. // if (Application.platform == RuntimePlatform.WindowsEditor) platformID = 1;
  655. // else platformID = 2;
  656. // }
  657. // bool IsWindows()
  658. // {
  659. // if (platformID == -1) SetPlatformID();
  660. // return platformID == 1;
  661. // }
  662. // public Quaternion update(Vector3 AccOld, Vector3 GyrOld, Vector3 MagOld, long TimeGapOld) {
  663. // if (IsWindows()) return Update_f(AccOld, GyrOld, MagOld, TimeGapOld);
  664. // else return SO_Update_f(AccOld, GyrOld, MagOld, TimeGapOld);
  665. // }
  666. // private void setIdentity() {
  667. // if (IsWindows()) SetIdentity();
  668. // else SO_SetIdentity();
  669. // }
  670. // public Vector3 getGyrOld() {
  671. // if (IsWindows()) return GetGyrOld_f();
  672. // else return SO_GetGyrOld_f();
  673. // }
  674. // public State getLastState() {
  675. // if (IsWindows()) return GetLastState_f();
  676. // else return SO_GetLastState_f();
  677. // }
  678. // private Vector3 getAccIdentity() {
  679. // if (IsWindows()) return GetAccIdentity_f();
  680. // else return SO_GetAccIdentity_f();
  681. // }
  682. // private Vector3 getMagIdentity() {
  683. // if (IsWindows()) return GetMagIdentity_f();
  684. // else return SO_GetMagIdentity_f();
  685. // }
  686. // private void setAccIdentity(Vector3 value) {
  687. // if (IsWindows()) SetAccIdentity(value);
  688. // else SO_SetAccIdentity(value);
  689. // }
  690. // private void setMagIdentity(Vector3 value) {
  691. // if (IsWindows()) SetMagIdentity(value);
  692. // else SO_SetMagIdentity(value);
  693. // }
  694. // [DllImport("o09Axis")]
  695. // extern static Quaternion Update_f(Vector3 AccOld, Vector3 GyrOld, Vector3 MagOld, long TimeGapOld);
  696. // [DllImport("o09Axis")]
  697. // extern static void SetIdentity();
  698. // [DllImport("o09Axis")]
  699. // extern static Vector3 GetGyrOld_f();
  700. // [DllImport("o09Axis")]
  701. // extern static State GetLastState_f();
  702. // [DllImport("o09Axis")]
  703. // extern static Vector3 GetAccIdentity_f();
  704. // [DllImport("o09Axis")]
  705. // extern static Vector3 GetMagIdentity_f();
  706. // [DllImport("o09Axis")]
  707. // extern static void SetAccIdentity(Vector3 value);
  708. // [DllImport("o09Axis")]
  709. // extern static void SetMagIdentity(Vector3 value);
  710. // [DllImport("libSharedObjectAxis")]
  711. // extern static Quaternion SO_Update_f(Vector3 AccOld, Vector3 GyrOld, Vector3 MagOld, long TimeGapOld);
  712. // [DllImport("libSharedObjectAxis")]
  713. // extern static void SO_SetIdentity();
  714. // [DllImport("libSharedObjectAxis")]
  715. // extern static Vector3 SO_GetGyrOld_f();
  716. // [DllImport("libSharedObjectAxis")]
  717. // extern static State SO_GetLastState_f();
  718. // [DllImport("libSharedObjectAxis")]
  719. // extern static Vector3 SO_GetAccIdentity_f();
  720. // [DllImport("libSharedObjectAxis")]
  721. // extern static Vector3 SO_GetMagIdentity_f();
  722. // [DllImport("libSharedObjectAxis")]
  723. // extern static void SO_SetAccIdentity(Vector3 value);
  724. // [DllImport("libSharedObjectAxis")]
  725. // extern static void SO_SetMagIdentity(Vector3 value);
  726. // }
  727. public class o09Axis
  728. {
  729. // public static List<o0UIRawImageTester> Tester = new List<o0UIRawImageTester>();
  730. // public static List<Text> TextTester = new List<Text>();
  731. public List<o0UIRawImageTester> Tester = new List<o0UIRawImageTester>();
  732. public List<Text> TextTester = new List<Text>();
  733. public GameObject AccMesh;
  734. public GameObject GryMesh;
  735. public GameObject MagMesh;
  736. static public Vector3 AccIdentity = new Vector3(0, -1, 0);
  737. static public Vector3 MagIdentity = new Vector3(-1, 2, 0).normalized;
  738. public class State
  739. {
  740. public long TimeGap;
  741. public Vector3 Acc = AccIdentity;
  742. public Vector3 AccSmooth = AccIdentity;
  743. public double AccVariance = 1;
  744. public Vector3 Gyr;
  745. public Vector3 Mag = MagIdentity;
  746. public Vector3 MagSmooth = MagIdentity;
  747. public Quaternion Qua = Quaternion.identity;
  748. public Quaternion QuaSmooth = Quaternion.identity;
  749. public double Variance = 1;
  750. }
  751. o0Project.Variance HardwareVarianceGyr = new o0Project.Variance(1000);
  752. o0Project.Variance HardwareVarianceAcc = new o0Project.Variance(1000);
  753. o0Project.Variance HardwareVarianceMag = new o0Project.Variance(1000);
  754. public List<State> States = new List<State>();
  755. public Vector3 AccOld;
  756. public Vector3 GyrOld;
  757. public Vector3 MagOld;
  758. public float x;
  759. public float y;
  760. public float z;
  761. long TimeGapOld;
  762. //o0Aien.o0SigmoidIntegrationFilterVector3 AccFilter = new o0Aien.o0SigmoidIntegrationFilterVector3(0.2f, 1);
  763. //o0Aien.o0SigmoidIntegrationFilterVector3 MagFilter = new o0Aien.o0SigmoidIntegrationFilterVector3(0.2f,1);
  764. o0Aien.o0WeightedAverageFilterVector3 AccFilter = new o0Aien.o0WeightedAverageFilterVector3(5);
  765. o0Aien.o0WeightedAverageFilterVector3 MagFilter = new o0Aien.o0WeightedAverageFilterVector3(10);
  766. // o0Aien.o0SigmoidIntegrationFilterVector3 AccFilter = new o0Aien.o0SigmoidIntegrationFilterVector3(5.2f,5);
  767. // o0Aien.o0SigmoidIntegrationFilterVector3 MagFilter = new o0Aien.o0SigmoidIntegrationFilterVector3(5.2f,5);
  768. /////////////////////g degree/ms
  769. public Quaternion update(Vector3 AccOld, Vector3 GyrOld, Vector3 MagOld, long TimeGapOld)
  770. {
  771. o0UIRawImageTester.UpdateAllOffset();
  772. //Debug.Log(TimeGapOld);
  773. var Acc = this.AccOld;
  774. var Gyr = (this.GyrOld + GyrOld)/2;
  775. var Mag = this.MagOld;
  776. float TimeGap = this.TimeGapOld;
  777. this.AccOld = AccOld;
  778. this.GyrOld = GyrOld;
  779. this.MagOld = MagOld;
  780. this.TimeGapOld = TimeGapOld;
  781. var Last = States.LastOrDefault() ?? new State();
  782. if (this.TimeGapOld <= 0)
  783. return Last.Qua;
  784. States.Add(new State());
  785. if (States.Count > 200)
  786. States.RemoveAt(0);
  787. var state = States.Last();
  788. state.Acc = Acc;
  789. state.AccSmooth = AccFilter.Update(Acc);
  790. //state.AccSmooth = Vector3.Slerp(Last.AccSmooth, Acc, 0.2f);
  791. state.Gyr = Gyr;
  792. state.Mag = Mag;/**/
  793. state.MagSmooth = MagFilter.Update(Mag);
  794. if (States.Count <=1)
  795. return Quaternion.identity;
  796. /*
  797. state.Acc = Last.Acc;
  798. AccFilter.Update(ref state.Acc, Acc);
  799. state.Gyr = Gyr;
  800. state.Mag = Last.Mag;
  801. MagFilter.Update(ref state.Mag, Mag);/**/
  802. HardwareVarianceGyr.Update((Gyr).magnitude);//每毫秒方差2.331017E-09 度左右 0.00000002331017
  803. HardwareVarianceAcc.Update(Vector3.Angle(state.Acc, Last.Acc));//方差0.0012度左右
  804. HardwareVarianceMag.Update(Vector3.Angle(state.Mag, Last.Mag));//方差3.5度左右
  805. //Tester?[7].DrawLine(HardwareVarianceAcc.Value, new Color(0, 0, 0));//0.0012左右
  806. //Tester?[8].DrawLine(HardwareVarianceMag.Value, new Color(0, 0, 0));//3.5左右
  807. //Debug.Log(HardwareVarianceMag.Value);
  808. //var Accwit = GameObject.Find("Accwit");
  809. //var Gyrwit = GameObject.Find("Gyrwit");
  810. //var Magwit = GameObject.Find("Magwit");
  811. var LastQuaternion = Last.Qua;
  812. //var LastQuaternion = Gyrwit.transform.localRotation;
  813. var newQua = new Quaternion();
  814. newQua.eulerAngles = Gyr * TimeGap;
  815. var quaGyr = LastQuaternion * newQua;
  816. AccMesh.transform.localRotation = o0Project.o0.FormQuaternion(AccMesh.transform.localRotation, AccIdentity, Acc, 1);
  817. MagMesh.transform.localRotation = o0Project.o0.FormQuaternion(MagMesh.transform.localRotation, MagIdentity, Mag, 1);
  818. GryMesh.transform.localRotation = GryMesh.transform.localRotation * newQua;
  819. //Tester?[3].DrawLine(Vector3.Angle(Acc, Last.Acc) / 1, new Color(1, 0, 0));
  820. //Tester?[4].DrawLine(Quaternion.Angle(LastQuaternion, quaGyr) / 45, new Color(1, 0, 0));
  821. //Tester?[5].DrawLine(Vector3.Angle(Mag, Last.Mag) / 5, new Color(1, 0, 0));
  822. double AccLengthToAngle = 5;//1倍引力差相当于多少度方差
  823. double MagLengthToAngle = 5;//1倍磁力差相当于多少度方差
  824. /*
  825. float GyrVariance = Last.Variance + (Gyr * TimeGap).magnitude * 0.05f;
  826. float AccVariance = Mathf.Max(TimeGap / 1, Mathf.Sqrt(Mathf.Pow((Acc.magnitude - 9.8f) / 9.8f * AccLengthToAngle, 2) + Mathf.Pow(Vector3.Angle(Acc, Last.Acc) * 0.8f, 2)));
  827. //Debug.Log(AccVariance);
  828. float MagVariance = Mathf.Max(TimeGap / 0.2f, Mathf.Sqrt(Mathf.Pow((Mag.magnitude - 1) / 1 * MagLengthToAngle, 2) + Mathf.Pow(Vector3.Angle(Mag, Last.Mag) * 0.05f, 2)));
  829. state.Variance = state.Variance * AccVariance / (state.Variance + AccVariance);
  830. state.Variance = state.Variance * MagVariance / (state.Variance + MagVariance);/**/
  831. //测试效果不错但没迭代的版本
  832. /*
  833. *
  834. float GyrVariance = state.Variance + TimeGap/100 + (Gyr * TimeGap).magnitude * 0.05f;
  835. float AccVariance = TimeGap / 30 + Mathf.Sqrt(Mathf.Pow((Acc.magnitude - 9.8f) / 9.8f * AccLengthToAngle, 2)+ Mathf.Pow(Vector3.Angle(Acc,Last.Acc) * 0.5f, 2));
  836. //Debug.Log(AccVariance);
  837. float MagVariance = TimeGap / 1 + Mathf.Sqrt(Mathf.Pow((Mag.magnitude - 1) / 1 * MagLengthToAngle, 2) + Mathf.Pow(Vector3.Angle(Mag, Last.Mag) * 0.1f, 2));
  838. /**/
  839. //Tester?[1].DrawLine(TimeGap / 100f, new Color(0, 0, 1));
  840. //Tester?[2].DrawLine((int)(Last.Variance / 90), new Color(0, 0, 0));
  841. // double GyrVariance = Last.Variance + 0.00000002331017 * TimeGap + Math.Pow((Gyr * TimeGap).magnitude * 0.03, 2);// 指数4 = 方差2 * 欧拉角旋转误差2 移动导致累计误差
  842. // //Debug.Log(Math.Max(0.00000002331017 * TimeGap, Math.Pow((Gyr * TimeGap).magnitude * 0.001f, 2)));
  843. // //Tester?[6].DrawLine((Gyr * TimeGap).magnitude * 0.05f / 90, new Color(0, 0, 0));
  844. // double AccVariance = Math.Max(0.01, Math.Pow((Acc.magnitude - 9.8) / 9.8 * AccLengthToAngle, 4) + Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc) / TimeGap) * 20, 2));
  845. // //double AccVariance = Math.Max(0.01, Math.Pow((Acc.magnitude - 9.8) / 9.8 * AccLengthToAngle, 4) + Math.Pow(Vector3.Angle(Acc, Last.Acc) * 2, 2));
  846. // //Debug.Log(Vector3.Angle(Mag, Last.Mag));
  847. // double MagVariance = Math.Max(3.5, Math.Pow((Mag.magnitude - 1) / 1 * MagLengthToAngle, 4) + Math.Pow(Vector3.Angle(Mag, Last.Mag) * 0.07, 2));
  848. /*
  849. double GyrVariance = Last.Variance + 0.00000002331017 * TimeGap + Math.Pow((Gyr * TimeGap).magnitude, 2) * 0.04;// 指数4 = 方差2 * 欧拉角旋转误差2 移动导致累计误差
  850. double AccVariance = Math.Max(0.01, Math.Pow((Acc.magnitude - 9.8) / 9.8 * AccLengthToAngle, 4) + Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc) / TimeGap), 2) * 400);
  851. //double AccVariance = Math.Max(0.01, Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc) / TimeGap), 2) * 1000);
  852. double MagVariance = Math.Max(3.5, Math.Pow((Mag.magnitude - 1) / 1 * MagLengthToAngle, 4) + Math.Pow(Vector3.Angle(Mag, Last.Mag), 2) * 0.005);/**/
  853. /*
  854. double GyrVariance = Last.Variance + 0.00000002331017 * TimeGap + Math.Pow((Gyr * TimeGap).magnitude, 2) * 0.1;// 指数4 = 方差2 * 欧拉角旋转误差2 移动导致累计误差
  855. double AccVariance = Math.Max(0.01, Math.Pow((Acc.magnitude - 9.8) / 9.8 * AccLengthToAngle, 4) + Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc) / TimeGap), 2) * 20);
  856. //double AccVariance = Math.Max(0.01, Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc) / TimeGap), 2) * 1000);
  857. double MagVariance = Math.Max(3.5, Math.Pow((Mag.magnitude - 1) / 1 * MagLengthToAngle, 4) + Math.Pow(Vector3.Angle(Mag, Last.Mag), 2) * 0.005);/**/
  858. /*
  859. double GyrVariance = Last.Variance + Math.Pow((Gyr * TimeGap).magnitude, 2) * 0.1;// 指数4 = 方差2 * 欧拉角旋转误差2 移动导致累计误差
  860. double AccVariance = Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc) / TimeGap), 2) * 20;
  861. //double AccVariance = Math.Max(0.01, Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc) / TimeGap), 2) * 1000);
  862. double MagVariance = Math.Pow(Vector3.Angle(Mag, Last.Mag), 2) * 0.005;/**/
  863. double GyrVariance = Last.Variance + Math.Pow((Gyr * TimeGap).magnitude * 0.3,3);// 指数4 = 方差2 * 欧拉角旋转误差2 移动导致累计误差
  864. double AccVariance = Math.Max((Gyr * TimeGap).magnitude, Vector3.Angle(state.AccSmooth, Last.AccSmooth)) * 1 + Math.Pow(Math.Abs(state.AccSmooth.magnitude - 9.8) / 9.8 * AccLengthToAngle,4);
  865. //double AccVariance = Math.Max(0.01, Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc) / TimeGap), 2) * 1000);
  866. double MagVariance = Math.Max((Gyr * TimeGap).magnitude, Vector3.Angle(state.MagSmooth, Last.MagSmooth)) * 1 + Math.Pow(Math.Abs(state.MagSmooth.magnitude - 1) / 1 * MagLengthToAngle,4);/**/
  867. state.Variance = GyrVariance;
  868. state.Variance = state.Variance * (AccVariance+ MagVariance) / (state.Variance + (AccVariance + MagVariance));
  869. if (double.IsNaN(GyrVariance))
  870. GyrVariance = double.MinValue;
  871. if (double.IsNaN(AccVariance))
  872. AccVariance = double.MinValue;
  873. if (double.IsNaN(MagVariance))
  874. MagVariance = double.MinValue;
  875. if (double.IsNaN(state.Variance))
  876. state.Variance = double.MinValue;
  877. TextTester[1].text = "GyrVariance:" + GyrVariance;
  878. TextTester[2].text = "StaticGyrVariance:" + 0.00000002331017 * TimeGap;
  879. TextTester[3].text = "MothonGyrVariance:" + Math.Pow((Gyr * TimeGap).magnitude * 0.07, 2);
  880. TextTester[4].text = "GyrSpeed:" + Gyr.magnitude;
  881. TextTester[5].text = "AccVariance:" + AccVariance;
  882. TextTester[6].text = "AccLengthVariance:" + Math.Pow((Acc.magnitude - 9.8) / 9.8 * AccLengthToAngle, 4);
  883. TextTester[7].text = "AccRotate:" + Math.Pow(Math.Max(Gyr.magnitude, Vector3.Angle(Acc, Last.Acc)/TimeGap)* 20, 2);
  884. TextTester[9].text = "AccLength:" + Acc.magnitude;
  885. TextTester[10].text = "Gyr*1000,000:" + (Gyr * 1000000).ToString();
  886. TextTester[11].text = "AngleBetweenIdentity*1000:" + Quaternion.Angle(Last.Qua, Quaternion.identity) * 1000;
  887. // TextTester[12].text = "Qua.eulerAngles.x:" + Last.Qua.eulerAngles.x;
  888. // TextTester[13].text = "Qua.eulerAngles.y:" + Last.Qua.eulerAngles.y;
  889. // TextTester[14].text = "Qua.eulerAngles.z:" + Last.Qua.eulerAngles.z;
  890. /*if (Gyr != Vector3.zero)
  891. {
  892. Debug.Log(Gyr);
  893. }/**/
  894. var quaAccMag = o0Project.o0.FormQuaternion(AccIdentity, MagIdentity, state.AccSmooth, state.MagSmooth, (float)(AccVariance / (AccVariance + MagVariance)));
  895. var quaMinRate = GyrVariance / (GyrVariance + Math.Max(AccVariance, MagVariance));
  896. var quaMaxRate = GyrVariance / (GyrVariance + Math.Min(AccVariance, MagVariance));
  897. Quaternion quaFirst = Quaternion.Slerp(quaGyr, quaAccMag, (float)quaMinRate).normalized;
  898. if (float.IsNaN(quaFirst.w))
  899. quaFirst = Last.Qua;
  900. /*
  901. Debug.Log("start");
  902. Debug.Log(Last.Qua);
  903. Debug.Log(quaFirst);
  904. Debug.Log(quaGyr);
  905. Debug.Log(quaAccMag);
  906. Debug.Log("end");/**/
  907. var quaSecondRate = (quaMaxRate - quaMinRate) / (1 - quaMinRate);
  908. // Gyrwit.transform.localRotation = AccVariance < MagVariance ? o0Project.o0.FormQuaternion(quaFirst, AccIdentity, Acc, (float)quaSecondRate) : o0Project.o0.FormQuaternion(quaFirst, MagIdentity, Mag, (float)quaSecondRate);
  909. // state.Qua = Gyrwit.transform.localRotation;
  910. state.Qua = AccVariance < MagVariance ? o0Project.o0.FormQuaternion(quaFirst, AccIdentity, state.AccSmooth, (float)quaSecondRate) : o0Project.o0.FormQuaternion(quaFirst, MagIdentity, state.MagSmooth, (float)quaSecondRate);
  911. if (float.IsNaN(state.Qua.w))
  912. state.Qua = Last.Qua;/**/
  913. state.QuaSmooth = Quaternion.Slerp(Last.QuaSmooth, state.Qua, 0.3f);
  914. // state.Qua = Quaternion.Lerp(state.Qua, state.Qua,0.99);
  915. // state.Qua = Quaternion.Slerp(state.Qua, state.Qua,0.99);
  916. //Tester?[0].DrawLine(TimeGap / 200, new Color(1, 0, 0));
  917. //Image1.DrawLine();
  918. //Debug.Log((Gyr * TimeGap).magnitude);
  919. //Debug.Log(Quaternion.Angle(state.Qua, Last.Qua));
  920. //TextTester[8].text = "AngleRotated:" + Quaternion.Angle(state.Qua, Last.Qua);
  921. var frontV = Last.Qua * Vector3.forward;
  922.         var upV = Last.Qua * Vector3.up;
  923. x = (Mathf.Atan(upV.y / upV.z) / Mathf.PI * 180 + (upV.z < 0 ? 90:270));
  924.         y = (Mathf.Atan(frontV.z / frontV.x) / Mathf.PI * 180+(frontV.x < 0 ? 90:270));
  925.         z = (Mathf.Atan(upV.y / upV.x) / Mathf.PI * 180 + (upV.x < 0 ? 90:270));
  926. // TextTester[18].text = "x轴角度:" + (Mathf.Atan(upV.y / upV.z) / Mathf.PI * 180 + (upV.z < 0 ? 90:270));
  927. //         TextTester[19].text = "y轴角度:" + (Mathf.Atan(frontV.z / frontV.x) / Mathf.PI * 180+(frontV.x < 0 ? 90:270));
  928. //         TextTester[20].text = "z轴角度" + (Mathf.Atan(upV.y / upV.x) / Mathf.PI * 180 + (upV.x < 0 ? 90:270));
  929. // TextTester[12].text = "x轴角度:\n" + (Mathf.Atan(upV.y / upV.z) / Mathf.PI * 180 + (upV.z < 0 ? 90:270));
  930. //         TextTester[13].text = "y轴角度:\n" + (Mathf.Atan(frontV.z / frontV.x) / Mathf.PI * 180+(frontV.x < 0 ? 90:270));
  931. //         TextTester[14].text = "z轴角度:\n" + (Mathf.Atan(upV.y / upV.x) / Mathf.PI * 180 + (upV.x < 0 ? 90:270));
  932. //TextTester[12].text = "加速计:" + Acc;
  933.         //TextTester[13].text = "陀螺仪:" + Gyr;
  934.         //TextTester[14].text = "地磁计:" + Mag;
  935. TextTester[12].text = "x:" +x;
  936.         TextTester[13].text = "y:" +y;
  937.         TextTester[14].text = "z:" +z;
  938. /* Tester?[0].DrawLine(Vector3.Angle(Last.Acc, state.Acc) / 3f, new Color(0, 0, 1));
  939. Tester?[1].DrawLine(Vector3.Angle(Last.AccSmooth, state.AccSmooth) / 3f, new Color(0, 0, 1));
  940. Tester?[3].DrawLine(Vector3.Angle(Last.Mag, state.Mag) / 3f, new Color(0, 0, 1));
  941. Tester?[4].DrawLine(Vector3.Angle(Last.MagSmooth, state.MagSmooth) / 3f, new Color(0, 0, 1));
  942. Tester?[6].DrawLine(Quaternion.Angle(Last.Qua, state.Qua) / 3f, new Color(0, 0, 1));
  943. Tester?[7].DrawLine(Quaternion.Angle(Last.QuaSmooth, state.QuaSmooth) / 3f, new Color(0, 0, 1));*/
  944. return state.Qua;
  945. }
  946. public void SetIdentityAndSave()
  947. {
  948. Quaternion qua = default;
  949. AccIdentity = AccOld;
  950. MagIdentity = MagOld;
  951. qua = o0Project.o0.FormQuaternion(Quaternion.identity, Vector3.down,AccIdentity, 1);
  952. AccIdentity=qua*AccIdentity;
  953. MagIdentity = qua*MagIdentity;
  954. TextTester[0].text = "AccIdentity:"+AccIdentity;
  955. States.Last().Qua = Quaternion.identity;
  956. States.Last().Qua = qua*States.Last().Qua;//Quaternion.identity;
  957. States.Last().Variance = 0.0000001;
  958. AccMesh.transform.localRotation = default;
  959. MagMesh.transform.localRotation = default;
  960. GryMesh.transform.localRotation = default;
  961. SaveIdentity();
  962. }
  963. public void SetIdentityAccordingToRecords()
  964. {
  965. AccIdentity = Vector3.zero;
  966. foreach (var i in States)
  967. AccIdentity += i.Acc;
  968. AccIdentity /= States.Count;
  969. MagIdentity = Vector3.zero;
  970. foreach (var i in States)
  971. MagIdentity += i.Mag;
  972. MagIdentity /= States.Count;
  973. States.Last().Qua = Quaternion.identity;
  974. States.Last().Variance = 0.0000001;
  975. Vector3.Angle(Vector3.up, States.Last().Mag);
  976. }
  977. public void LoadIdentity()
  978. {
  979. try
  980. {
  981. string magIdentityStr = PlayerPrefs.GetString("MagIdentity", "");
  982. if (magIdentityStr.Length > 0) {
  983. float[] arr = JsonConvert.DeserializeObject<float[]>(magIdentityStr);
  984. MagIdentity = new Vector3(arr[0], arr[1], arr[2]);
  985. }
  986. string accIdentityStr = PlayerPrefs.GetString("AccIdentity", "");
  987. if (accIdentityStr.Length > 0) {
  988. float[] arr = JsonConvert.DeserializeObject<float[]>(accIdentityStr);
  989. AccIdentity = new Vector3(arr[0], arr[1], arr[2]);
  990. }
  991. }
  992. catch (System.Exception e) { Debug.LogError(e.Message); }
  993. }
  994. void SaveIdentity() {
  995. PlayerPrefs.SetString("MagIdentity",JsonConvert.SerializeObject(new float[]{
  996. MagIdentity.x, MagIdentity.y, MagIdentity.z
  997. }));
  998. PlayerPrefs.SetString("AccIdentity", JsonConvert.SerializeObject(new float[]{
  999. AccIdentity.x, AccIdentity.y, AccIdentity.z
  1000. }));
  1001. }
  1002. public State getLastState() {
  1003. return this.States.Last();
  1004. }
  1005. public Vector3 getGyrOld() {
  1006. return GyrOld;
  1007. }
  1008. }