PageRenderTime 28ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/man/motion/bhwalk/Modules/Sensing/JointDynamicsProvider.cpp

https://github.com/emamanto/nbites
C++ | 540 lines | 451 code | 62 blank | 27 comment | 73 complexity | d81fa02c34c0b61fe8c3823054a40ff3 MD5 | raw file
  1. /**
  2. * @file JointDynamicsProvider.cpp
  3. *
  4. * Implementation of a module which estimates the dynamics of all joints.
  5. */
  6. #include "JointDynamicsProvider.h"
  7. #include "Representations/Sensing/RobotModel.h"
  8. #include "Representations/MotionControl/IndykickEngineOutput.h"
  9. #include "Eigen/Geometry"
  10. MAKE_MODULE(JointDynamicsProvider, Sensing)
  11. JointDynamicsProvider::JointDynamicsProvider()
  12. : covariancesNeedUpdate(true),
  13. xAxis(1.0f, 0.0f, 0.0f), yAxis(0.0f, 1.0f, 0.0f), zAxis(0.0f, 0.0f, 1.0f),
  14. cycleTime(theFrameInfoBH.cycleTime)
  15. {
  16. jointDynamicsInitialized = false;
  17. assembleTimeDependentMatrices();
  18. /* Calculate axes of the leg joints. */
  19. float sign = -1.0f; // Left leg.
  20. leftAxis[0] = Eigen::Quaternionf(Eigen::AngleAxisf(-pi_4 * sign, xAxis)) * zAxis * sign;
  21. leftAxis[1] = xAxis * sign;
  22. leftAxis[2] = yAxis;
  23. leftAxis[3] = yAxis;
  24. leftAxis[4] = yAxis;
  25. leftAxis[5] = xAxis * sign;
  26. sign = 1.0f; // Right leg.
  27. rightAxis[0] = Eigen::Quaternionf(Eigen::AngleAxisf(-pi_4 * sign, xAxis)) * zAxis * sign;
  28. rightAxis[1] = xAxis * sign;
  29. rightAxis[2] = yAxis;
  30. rightAxis[3] = yAxis;
  31. rightAxis[4] = yAxis;
  32. rightAxis[5] = xAxis * sign;
  33. /*
  34. * Eigen classes do not initialize their components by default.
  35. * Since they may contain random garbage, they're zeroed here.
  36. */
  37. for(int i = 0; i < numOfNonLegJoints; ++i)
  38. {
  39. model[i] = Eigen::Vector3f::Zero();
  40. stateNoLeg[i] = Eigen::Vector3f::Zero();
  41. }
  42. for(int i = 0; i < numOfLegJoints; ++i)
  43. {
  44. model[JointDataBH::LHipYawPitch + i] = Eigen::Vector3f::Zero();
  45. model[JointDataBH::RHipYawPitch + i] = Eigen::Vector3f::Zero();
  46. }
  47. stateLeftLeg = Eigen::Vector18f::Zero();
  48. stateRightLeg = Eigen::Vector18f::Zero();
  49. }
  50. void JointDynamicsProvider::assembleTimeDependentMatrices()
  51. {
  52. const float cycleTimeMs = cycleTime * 1000.0f;
  53. /* Row major form! Yeeha! */
  54. smallA(0, 0) = 1.0f; smallA(0, 1) = cycleTimeMs; smallA(0, 2) = sqrBH(cycleTimeMs) / 2.0f;
  55. smallA(1, 0) = 0.0f; smallA(1, 1) = 1.0f; smallA(1, 2) = cycleTimeMs;
  56. smallA(2, 0) = 0.0f; smallA(2, 1) = 0.0f; smallA(2, 2) = 1.0f;
  57. smallAtranspose = smallA.transpose();
  58. A = Eigen::Matrix18f::Zero();
  59. for(int i = 0; i < numOfLegJoints; ++i)
  60. {
  61. const int index = i * 3;
  62. A.block<3, 3>(index, index) = smallA;
  63. }
  64. Atranspose = A.transpose();
  65. C = Eigen::Matrix6x18f::Zero();
  66. for(int i = 0; i < numOfLegJoints; ++i)
  67. C(i, i * 3) = 1.0f;
  68. Ctranspose = C.transpose();
  69. }
  70. void JointDynamicsProvider::assembleCovariances()
  71. {
  72. smallCovarianceProcess = Eigen::Matrix3f::Zero();
  73. smallCovarianceProcess(0, 0) = sqrBH(positionStddev);
  74. smallCovarianceProcess(1, 1) = sqrBH(velocityStddev); //* 1e-1f;
  75. smallCovarianceProcess(2, 2) = sqrBH(accelerationStddev);
  76. covarianceProcess = Eigen::Matrix18f::Zero();
  77. for(int i = 0; i < numOfLegJoints; ++i)
  78. {
  79. const int index = 3 * i;
  80. covarianceProcess.block<3, 3>(index, index) = smallCovarianceProcess;
  81. }
  82. covarianceGyro = Eigen::Matrix2f::Zero();
  83. covarianceGyro(0, 0) = sqrBH(gyroStddev.x);
  84. covarianceGyro(1, 1) = sqrBH(gyroStddev.y);
  85. }
  86. void JointDynamicsProvider::update(JointDynamicsBH& jointDynamics)
  87. {
  88. DECLARE_PLOT("module:JointDynamicsProvider:leftHipPitchPosition");
  89. DECLARE_PLOT("module:JointDynamicsProvider:leftHipPitchVelocity");
  90. DECLARE_PLOT("module:JointDynamicsProvider:leftHipPitchAcceleration");
  91. DECLARE_PLOT("module:JointDynamicsProvider:leftHipPitchPositionModel");
  92. DECLARE_PLOT("module:JointDynamicsProvider:leftHipPitchVelocityModel");
  93. DECLARE_PLOT("module:JointDynamicsProvider:gyroXMeasure");
  94. DECLARE_PLOT("module:JointDynamicsProvider:gyroXModel");
  95. DECLARE_PLOT("module:JointDynamicsProvider:gyroYMeasure");
  96. DECLARE_PLOT("module:JointDynamicsProvider:gyroYModel");
  97. DECLARE_PLOT("module:JointDynamicsProvider:supportAnkleRollDifference");
  98. if(theFrameInfoBH.cycleTime != cycleTime)
  99. {
  100. cycleTime = theFrameInfoBH.cycleTime;
  101. assembleTimeDependentMatrices();
  102. }
  103. /* Try to set the support leg. */
  104. if(theMotionRequestBH.motion == MotionRequestBH::indykick)
  105. jointDynamics.supportLeg = theMotionRequestBH.indykickRequest.supportLeg;
  106. else if(theMotionInfoBH.motion == MotionRequestBH::indykick)
  107. jointDynamics.supportLeg = theIndykickEngineOutputBH.executedIndykickRequest.supportLeg;
  108. else
  109. jointDynamics.supportLeg = IndykickRequest::unspecified;
  110. if(covariancesNeedUpdate)
  111. {
  112. assembleCovariances();
  113. covariancesNeedUpdate = false;
  114. }
  115. jointRequestsBuffer.add(theJointRequestBH);
  116. if(theMotionInfoBH.motion == MotionRequestBH::indykick && theIndykickEngineOutputBH.useGyroCorrection)
  117. for(int i = 0; i < JointDataBH::LAnkleRoll - JointDataBH::LHipYawPitch + 1; ++i)
  118. {
  119. JointRequestBH& request = jointRequestsBuffer[0];
  120. request.angles[JointDataBH::LHipYawPitch + i] = theIndykickEngineOutputBH.notGyroCorrectedLeftLegAngles[i];
  121. request.angles[JointDataBH::RHipYawPitch + i] = theIndykickEngineOutputBH.notGyroCorrectedRightLegAngles[i];
  122. }
  123. if(jointRequestsBuffer.getNumberOfEntries() < maxFrameDelay)
  124. {
  125. jointDynamicsInitialized = false;
  126. }
  127. else if(!jointDynamicsInitialized)
  128. {
  129. for(int i = 0; i < numOfNonLegJoints; ++i)
  130. {
  131. Eigen::Vector3f& s = stateNoLeg[i];
  132. for(int j = 0; j < 3; ++j)
  133. s[j] = 0.0f;
  134. covarianceNoLeg[i] = smallCovarianceProcess * 2.0f;
  135. }
  136. for(int i = 0; i < numOfLegJoints; ++i)
  137. {
  138. const int index = i * 3;
  139. for(int j = 0; j < 3; ++j)
  140. {
  141. stateLeftLeg[index + j] = 0.0f;
  142. stateRightLeg[index + j] = 0.0f;
  143. }
  144. covarianceLeftLeg = covarianceProcess * 2.0f;
  145. covarianceRightLeg = covarianceProcess * 2.0f;
  146. }
  147. jointDynamicsInitialized = true;
  148. }
  149. else
  150. {
  151. ASSERT(jointRequestsBuffer.getNumberOfEntries() >= maxFrameDelay);
  152. const JointRequestBH& next = jointRequestsBuffer[frameDelay];
  153. STOP_TIME_ON_REQUEST("module:JointDynamicsProvider:applyGyroMeasurementModel", applyGyroMeasurementModel(jointDynamics););
  154. STOP_TIME_ON_REQUEST("module:JointDynamicsProvider:updateModel", updateModel(next, model, velocity););
  155. STOP_TIME_ON_REQUEST("module:JointDynamicsProvider:predictNoLeg", predictNoLeg(stateNoLeg, covarianceNoLeg););
  156. STOP_TIME_ON_REQUEST("module:JointDynamicsProvider:predictLeg", predictLeg(stateLeftLeg, covarianceLeftLeg, stateRightLeg, covarianceRightLeg););
  157. STOP_TIME_ON_REQUEST("module:JointDynamicsProvider:correctNoLeg", correctNoLeg(next););
  158. STOP_TIME_ON_REQUEST("module:JointDynamicsProvider:correctLeg", correctLeg(next););
  159. PLOT("module:JointDynamicsProvider:supportAnkleRollDifference",
  160. toDegrees(jointDynamics.supportLeg == IndykickRequest::unspecified ? 0.0f :
  161. (jointDynamics.supportLeg == IndykickRequest::left ? stateLeftLeg[5 * 3 + 0] : stateRightLeg[5 * 3 + 0])));
  162. }
  163. STOP_TIME_ON_REQUEST("module:JointDynamicsProvider:mergeStateAndModelToJointDynamics", mergeStateAndModelToJointDynamics(jointDynamics, model););
  164. // Plot motion of left hip joint.
  165. PLOT("module:JointDynamicsProvider:leftHipPitchPosition", toDegrees(jointDynamics.joint[JointDataBH::LHipPitch][0]));
  166. PLOT("module:JointDynamicsProvider:leftHipPitchVelocity", toDegrees(jointDynamics.joint[JointDataBH::LHipPitch][1] * 1000.0f));
  167. PLOT("module:JointDynamicsProvider:leftHipPitchAcceleration", toDegrees(jointDynamics.joint[JointDataBH::LHipPitch][2] * sqrBH(1000.0f)));
  168. PLOT("module:JointDynamicsProvider:leftHipPitchPositionModel", toDegrees(velocity[JointDataBH::LHipPitch].prediction));
  169. PLOT("module:JointDynamicsProvider:leftHipPitchVelocityModel", toDegrees(velocity[JointDataBH::LHipPitch].derivative * 1000.0f));
  170. PLOT("module:JointDynamicsProvider:gyroXMeasure", gyroMeasurementInDegreesPerSecond.x);
  171. PLOT("module:JointDynamicsProvider:gyroYMeasure", gyroMeasurementInDegreesPerSecond.y);
  172. PLOT("module:JointDynamicsProvider:gyroXModel", angularVelocityInDegreesPerSecond.x);
  173. PLOT("module:JointDynamicsProvider:gyroYModel", angularVelocityInDegreesPerSecond.y);
  174. }
  175. void JointDynamicsProvider::updateModel(const JointRequestBH& next, Eigen::Vector3f model[JointDataBH::numOfJoints],
  176. Differentiator velocity[JointDataBH::numOfJoints])
  177. {
  178. for(int i = 0; i < JointDataBH::numOfJoints; ++i)
  179. {
  180. Eigen::Vector3f& m = model[i];
  181. Differentiator& vel = velocity[i];
  182. if(next.angles[i] != JointDataBH::off && next.angles[i] != JointDataBH::ignore)
  183. {
  184. const float angle = next.angles[i];
  185. vel.update(angle);
  186. m[0] = angle;
  187. m[1] = vel.derivative;
  188. m[2] = vel.derivative2;
  189. }
  190. else // Guess next model value for the off/ignored joint.
  191. {
  192. const float cycleTimeMs = cycleTime * 1000.0f; // TODO: Teach the differentiator differenct cycle times.
  193. const float nextAngle = m[0] + cycleTimeMs * m[1] + sqrBH(cycleTimeMs) / 2.0f * m[2];
  194. vel.update(nextAngle);
  195. }
  196. }
  197. }
  198. void JointDynamicsProvider::predictNoLeg(Eigen::Vector3f stateNoLeg[numOfNonLegJoints],
  199. Eigen::Matrix3f covarianceNoLeg[numOfNonLegJoints])
  200. {
  201. for(int i = 0; i < numOfNonLegJoints; ++i)
  202. {
  203. Eigen::Vector3f& s = stateNoLeg[i];
  204. Eigen::Matrix3f& cov = covarianceNoLeg[i];
  205. s = smallA * s;
  206. s[0] = normalizeBH(s[0]);
  207. cov = smallA * cov * smallAtranspose + smallCovarianceProcess;
  208. symmetrize3(cov);
  209. }
  210. }
  211. void JointDynamicsProvider::predictLeg(Eigen::Vector18f& stateLeftLeg,
  212. Eigen::Matrix18f& covarianceLeftLeg,
  213. Eigen::Vector18f& stateRightLeg,
  214. Eigen::Matrix18f& covarianceRightLeg)
  215. {
  216. STOP_TIME_ON_REQUEST("symmetrizeLeftLegCovariance", symmetrize18(covarianceLeftLeg););
  217. STOP_TIME_ON_REQUEST("symmetrizeRightLegCovariance", symmetrize18(covarianceRightLeg););
  218. STOP_TIME_ON_REQUEST("updateLeftLeg", stateLeftLeg = A * stateLeftLeg;);
  219. STOP_TIME_ON_REQUEST("updateLeftLegCovariance", covarianceLeftLeg = A * covarianceLeftLeg * Atranspose + covarianceProcess;);
  220. STOP_TIME_ON_REQUEST("updateRightLeg", stateRightLeg = A * stateRightLeg;);
  221. STOP_TIME_ON_REQUEST("updateRightLegCovariance", covarianceRightLeg = A * covarianceRightLeg * Atranspose + covarianceProcess;);
  222. /* Normalize the angles. */
  223. STOP_TIME_ON_REQUEST("normalizeStates",
  224. {
  225. for(int i = 0; i < numOfLegJoints; ++i)
  226. {
  227. const int index = i * 3;
  228. stateLeftLeg[index] = normalizeBH(stateLeftLeg[index]);
  229. stateRightLeg[index] = normalizeBH(stateRightLeg[index]);
  230. }
  231. });
  232. }
  233. void JointDynamicsProvider::correctNoLeg(const JointRequestBH& next)
  234. {
  235. for(int i = 0; i < numOfNonLegJoints; ++i)
  236. {
  237. Eigen::Vector3f& s = stateNoLeg[i];
  238. Eigen::Matrix3f& cov = covarianceNoLeg[i];
  239. /* In the JointDataBH enum, the non-leg-joints appear before the left leg and right leg joints,
  240. so the next two statements are ok. */
  241. const float measurement = theFilteredJointDataBH.angles[i];
  242. Eigen::Vector3f& m = model[i];
  243. const float covZ = cov(0, 0) + measurementVariance;
  244. const Eigen::Vector3f kalmanGain = cov.col(0) / covZ;
  245. const float innovation = normalizeBH(measurement - m[0] - s[0]);
  246. s += kalmanGain * innovation;
  247. s[0] = normalizeBH(s[0]);
  248. cov -= kalmanGain * cov.row(0);
  249. symmetrize3(cov);
  250. }
  251. }
  252. void JointDynamicsProvider::correctLeg(const JointRequestBH& next)
  253. {
  254. /* Correct left leg. */
  255. Eigen::Vector6f innovationLeft;
  256. Eigen::Vector6f innovationRight;
  257. for(int i = 0; i < numOfLegJoints; ++i)
  258. {
  259. const int jdLeftIndex = i + JointDataBH::LHipYawPitch;
  260. const int jdRightIndex = i + JointDataBH::RHipYawPitch;
  261. const int stateIndex = 3 * i;
  262. const float measurementLeft = theFilteredJointDataBH.angles[jdLeftIndex];
  263. const float measurementRight = theFilteredJointDataBH.angles[jdRightIndex];
  264. const float innovationILeft = measurementLeft - model[jdLeftIndex][0] - stateLeftLeg(stateIndex);
  265. const float innovationIRight = measurementRight - model[jdRightIndex][0] - stateRightLeg(stateIndex);
  266. innovationLeft(i) = normalizeBH(innovationILeft);
  267. innovationRight(i) = normalizeBH(innovationIRight);
  268. }
  269. correctLeg(stateLeftLeg, covarianceLeftLeg, innovationLeft);
  270. correctLeg(stateRightLeg, covarianceRightLeg, innovationRight);
  271. }
  272. void JointDynamicsProvider::correctLeg(Eigen::Vector18f& state, Eigen::Matrix18f& covariance,
  273. const Eigen::Vector6f& innovation)
  274. {
  275. const Eigen::Matrix6x18f cTimesCovariance = C * covariance;
  276. Eigen::Matrix6f covZ = cTimesCovariance * Ctranspose;
  277. for(int i = 0; i < numOfLegJoints; ++i)
  278. covZ(i, i) += measurementVariance;
  279. const Eigen::Matrix18x6f kalmanGain = cTimesCovariance.transpose() * covZ.inverse();
  280. state += kalmanGain * innovation;
  281. covariance -= kalmanGain * cTimesCovariance;
  282. symmetrize18(covariance);
  283. }
  284. void JointDynamicsProvider::update(FutureJointDynamicsBH& futureJointDynamics)
  285. {
  286. DECLARE_PLOT("module:JointDynamicsProvider:leftHipPitchFuturePosition");
  287. futureJointDynamics.supportLeg = theJointDynamicsBH.supportLeg;
  288. /* Work on copies of model, differentiators, and distribution parameters */
  289. Differentiator velocityCopies[JointDataBH::numOfJoints];
  290. for(int i = 0; i < JointDataBH::numOfJoints; ++i)
  291. {
  292. velocityCopies[i] = velocity[i];
  293. }
  294. Eigen::Vector3f stateNoLegCopies[numOfNonLegJoints];
  295. Eigen::Matrix3f covarianceNoLegCopies[numOfNonLegJoints];
  296. for(int i = 0; i < numOfNonLegJoints; ++i)
  297. {
  298. stateNoLegCopies[i] = stateNoLeg[i];
  299. covarianceNoLegCopies[i] = covarianceNoLeg[i];
  300. }
  301. Eigen::Vector18f stateLeftLegCopy = stateLeftLeg;
  302. Eigen::Matrix18f covarianceLeftLegCopy = covarianceLeftLeg;
  303. Eigen::Vector18f stateRightLegCopy = stateRightLeg;
  304. Eigen::Matrix18f covarianceRightLegCopy = covarianceRightLeg;
  305. const int frameDelay = 4;
  306. for(int i = frameDelay - 1; i >= 0; --i)
  307. {
  308. const JointRequestBH& jr = jointRequestsBuffer.getEntry(i);
  309. /* Update velocity differentiators */
  310. for(int j = 0; j < JointDataBH::numOfJoints; ++j)
  311. velocityCopies[j].update(jr.angles[j]);
  312. /* Predict non leg joints. */
  313. predictNoLeg(stateNoLegCopies, covarianceNoLegCopies);
  314. /* Predict left and right leg joints. */
  315. predictLeg(stateLeftLegCopy, covarianceLeftLegCopy, stateRightLegCopy, covarianceRightLegCopy);
  316. }
  317. /* Get model from velocity differentiator copies. */
  318. Eigen::Vector3f modelCopies[JointDataBH::numOfJoints];
  319. for(int j = 0; j < JointDataBH::numOfJoints; ++j)
  320. {
  321. Eigen::Vector3f& m = modelCopies[j];
  322. const Differentiator& v = velocityCopies[j];
  323. m[0] = jointRequestsBuffer.getEntry(0).angles[j];
  324. m[1] = v.derivative;
  325. m[2] = v.derivative2;
  326. }
  327. mergeStateAndModelToJointDynamics(futureJointDynamics, model /* modelCopies */);
  328. PLOT("module:JointDynamicsProvider:leftHipPitchFuturePosition", toDegrees(futureJointDynamics.joint[JointDataBH::LHipPitch][0]));
  329. }
  330. void JointDynamicsProvider::mergeStateAndModelToJointDynamics(JointDynamicsBH& jointDynamics,
  331. Eigen::Vector3f model[JointDataBH::numOfJoints]) const
  332. {
  333. /* Joint dynamics for non leg joints. */
  334. for(int i = 0; i < numOfNonLegJoints; ++i)
  335. {
  336. const Eigen::Vector3f& m = model[i];
  337. const Eigen::Vector3f& s = stateNoLeg[i];
  338. Vector3f& j = jointDynamics.joint[i];
  339. j[0] = m[0] + s[0];
  340. j[1] = m[1] + s[1];
  341. j[2] = m[2] + s[2];
  342. }
  343. /* Joint dynamics for leg joints. */
  344. for(int i = 0; i < numOfLegJoints; ++i)
  345. {
  346. const JointDataBH::Joint left0 = JointDataBH::LHipYawPitch;
  347. const JointDataBH::Joint right0 = JointDataBH::RHipYawPitch;
  348. Vector3f& leftJoint = jointDynamics.joint[left0 + i];
  349. Vector3f& rightJoint = jointDynamics.joint[right0 + i];
  350. const Eigen::Vector3f& leftModel = model[left0 + i];
  351. const Eigen::Vector3f& rightModel = model[right0 + i];
  352. const Eigen::Vector3f leftState = stateLeftLeg.segment<3>(i * 3);
  353. const Eigen::Vector3f rightState = stateRightLeg.segment<3>(i * 3);
  354. leftJoint[0] = leftModel[0] + leftState[0];
  355. leftJoint[1] = leftModel[1] + leftState[1];
  356. leftJoint[2] = leftModel[2] + leftState[2];
  357. rightJoint[0] = rightModel[0] + rightState[0];
  358. rightJoint[1] = rightModel[1] + rightState[1];
  359. rightJoint[2] = rightModel[2] + rightState[2];
  360. }
  361. }
  362. void JointDynamicsProvider::applyGyroMeasurementModel(JointDynamicsBH& jointDynamics)
  363. {
  364. if(jointDynamics.supportLeg == IndykickRequest::unspecified
  365. || !theInertiaSensorDataBH.calibrated
  366. || theInertiaSensorDataBH.gyro.x == InertiaSensorDataBH::off
  367. || theInertiaSensorDataBH.gyro.y == InertiaSensorDataBH::off)
  368. return;
  369. const float sign = jointDynamics.supportLeg == IndykickRequest::left ? -1.0f : 1.0f;
  370. const JointDataBH::Joint leg0 = jointDynamics.supportLeg == IndykickRequest::left
  371. ? JointDataBH::LHipYawPitch : JointDataBH::RHipYawPitch;
  372. Eigen::Matrix18f& covarianceSupportLeg = jointDynamics.supportLeg == IndykickRequest::left
  373. ? covarianceLeftLeg : covarianceRightLeg;
  374. Eigen::Vector18f& stateSupportLeg = jointDynamics.supportLeg == IndykickRequest::left
  375. ? stateLeftLeg : stateRightLeg;
  376. Eigen::Vector3f axis[numOfLegJoints];
  377. axis[0] = Eigen::Quaternionf(Eigen::AngleAxisf(-pi_4 * sign, xAxis)) * zAxis * sign;
  378. axis[1] = xAxis * sign;
  379. axis[2] = yAxis;
  380. axis[3] = yAxis;
  381. axis[4] = yAxis;
  382. axis[5] = xAxis * sign;
  383. Eigen::Quaternionf rotation[numOfLegJoints];
  384. rotation[0] = Eigen::AngleAxisf(stateSupportLeg[0] + model[leg0 + 0][0], axis[0]);
  385. for(int i = 1; i < numOfLegJoints; ++i)
  386. rotation[i] = rotation[i - 1] * Eigen::Quaternionf(Eigen::AngleAxisf(stateSupportLeg[3 * i + 0] + model[leg0 + i][0], axis[i]));
  387. /* Sum up torso rotation velocity. */
  388. Eigen::Vector3f torsoAngularVelocity = -axis[0] * (stateSupportLeg[1] + model[leg0 + 0][1]);
  389. for(int i = 1; i < numOfLegJoints; ++i)
  390. torsoAngularVelocity -= rotation[i] * axis[i] * (stateSupportLeg[3 * i + 1] + model[leg0 + i][1]);
  391. angularVelocityInDegreesPerSecond.x = toDegrees(torsoAngularVelocity(0) * 1000.0f);
  392. angularVelocityInDegreesPerSecond.y = toDegrees(torsoAngularVelocity(1) * 1000.0f);
  393. gyroMeasurementInDegreesPerSecond.x = toDegrees(theInertiaSensorDataBH.gyro.x);
  394. gyroMeasurementInDegreesPerSecond.y = toDegrees(theInertiaSensorDataBH.gyro.y);
  395. Eigen::Matrix2x18f C = Eigen::Matrix2x18f::Zero();
  396. for(int i = 0; i < numOfLegJoints; ++i)
  397. {
  398. const Eigen::Vector3f s = -(rotation[i] * axis[i]);
  399. const int column = 3 * i + 1;
  400. C(0, column) = s(0);
  401. C(1, column) = s(1);
  402. }
  403. const Eigen::Matrix18x2f Ctranspose = C.transpose();
  404. const Eigen::Matrix18x2f covCtranspose = covarianceSupportLeg * Ctranspose;
  405. const Eigen::Vector2f innovation(theInertiaSensorDataBH.gyro.x / 1000.0f - torsoAngularVelocity(0),
  406. theInertiaSensorDataBH.gyro.y / 1000.0f - torsoAngularVelocity(1));
  407. const Eigen::Matrix2f covZ = C * covCtranspose + covarianceGyro;
  408. const Eigen::Matrix18x2f kalmanGain = covCtranspose * covZ.inverse();
  409. stateSupportLeg += kalmanGain * innovation;
  410. covarianceSupportLeg -= kalmanGain * covCtranspose.transpose();
  411. symmetrize18(covarianceSupportLeg);
  412. }
  413. void JointDynamicsProvider::symmetrize3(Eigen::Matrix3f& matrix)
  414. {
  415. const int n = 3;
  416. for(int i = 0; i < n - 1; ++i)
  417. for(int j = i + 1; j < n; ++j)
  418. {
  419. const float t = (matrix(i, j) + matrix(j, i)) / 2;
  420. if(std::abs(t) < 1e-25f)
  421. {
  422. matrix(i, j) = 0.0f;
  423. matrix(j, i) = 0.0f;
  424. }
  425. else
  426. {
  427. matrix(i, j) = t;
  428. matrix(j, i) = t;
  429. }
  430. }
  431. }
  432. void JointDynamicsProvider::symmetrize18(Eigen::Matrix18f& matrix)
  433. {
  434. const int n = 18;
  435. for(int i = 0; i < n - 1; ++i)
  436. for(int j = i + 1; j < n; ++j)
  437. {
  438. const float t = (matrix(i, j) + matrix(j, i)) / 2;
  439. if(std::abs(t) < 1e-25f)
  440. {
  441. matrix(i, j) = 0.0f;
  442. matrix(j, i) = 0.0f;
  443. }
  444. else
  445. {
  446. matrix(i, j) = t;
  447. matrix(j, i) = t;
  448. }
  449. }
  450. }
  451. void JointDynamicsProvider::serialize(In* in, Out* out)
  452. {
  453. const float currentPositionStddev = positionStddev;
  454. const float currentVelocityStddev = velocityStddev;
  455. const float currentAccelerationStddev = accelerationStddev;
  456. const float currentGyroStddevX = gyroStddev.x;
  457. const float currentGyroStddevY = gyroStddev.y;
  458. // Convert all angles to degrees before streaming.
  459. positionStddev = toDegrees(positionStddev);
  460. velocityStddev = toDegrees(velocityStddev);
  461. accelerationStddev = toDegrees(accelerationStddev);
  462. gyroStddev.x = toDegrees(gyroStddev.x);
  463. gyroStddev.y = toDegrees(gyroStddev.y);
  464. STREAM_REGISTER_BEGIN
  465. STREAM_BASE(JointDynamicsProviderBase)
  466. STREAM_REGISTER_FINISH
  467. // Convert all angles from degrees to randians after streaming.
  468. positionStddev = fromDegrees(positionStddev);
  469. velocityStddev = fromDegrees(velocityStddev);
  470. accelerationStddev = fromDegrees(accelerationStddev);
  471. gyroStddev.x = fromDegrees(gyroStddev.x);
  472. gyroStddev.y = fromDegrees(gyroStddev.y);
  473. covariancesNeedUpdate |= currentPositionStddev != positionStddev
  474. || currentVelocityStddev != velocityStddev
  475. || currentAccelerationStddev != accelerationStddev
  476. || currentGyroStddevX != gyroStddev.x
  477. || currentGyroStddevY != gyroStddev.y;
  478. }