PageRenderTime 447ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/private/DynamicMultiBodyTree.cpp

https://github.com/jrl-umi3218/jrl-dynamics
C++ | 418 lines | 270 code | 71 blank | 77 comment | 44 complexity | c92c50b0864cdeb33ac8db3ba2a52ba6 MD5 | raw file
  1. /*
  2. * Copyright 2009, 2010,
  3. *
  4. * Francois Keith
  5. * Florent Lamiraux
  6. * Olivier Stasse
  7. *
  8. * JRL/LAAS, CNRS/AIST
  9. *
  10. * This file is part of dynamicsJRLJapan.
  11. * dynamicsJRLJapan is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Lesser General Public License as published by
  13. * the Free Software Foundation, either version 3 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * dynamicsJRLJapan is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Lesser Public License for more details.
  20. * You should have received a copy of the GNU Lesser General Public License
  21. * along with dynamicsJRLJapan. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. * Research carried out within the scope of the Associated
  24. * International Laboratory: Joint Japanese-French Robotics
  25. * Laboratory (JRL)
  26. *
  27. */
  28. /*! System includes */
  29. #include <iostream>
  30. #include <sstream>
  31. #include <fstream>
  32. #include <string.h>
  33. #include "Debug.h"
  34. /*! Local library includes. */
  35. #include "jrl/mal/matrixabstractlayer.hh"
  36. #include "jrl/dynamics/dynamicbody.hh"
  37. #include "DynMultiBodyPrivate.h"
  38. #include "abstract-robot-dynamics/body.hh"
  39. #include "fileReader.h"
  40. using namespace dynamicsJRLJapan;
  41. void DynMultiBodyPrivate::SpecifyTheRootLabel(int ID)
  42. {
  43. labelTheRoot = ID;
  44. m_listOfBodies[ID]->setLabelMother(-1);
  45. // Right now it is assume that the first body is the world,
  46. // and that this body is related to another body.
  47. // Thus links[ID].size() should be equal to one.
  48. if (links[ID].size()!=1)
  49. {
  50. cout << "Wrong assumption concerning the initial body: " << links[ID].size()<< endl;
  51. return;
  52. }
  53. int ld = links[ID][0].link;
  54. m_RootOfTheJointsTree = listInternalLinks[ld].aJoint;
  55. m_RootOfTheJointsTree->setLinkedBody(*m_listOfBodies[ID]);
  56. ODEBUG(" m_RootOfTheJointsTree->m_globalConfiguration"<<
  57. m_RootOfTheJointsTree->initialPosition());
  58. //specify the type of the root joint
  59. // Start the vector of joints.
  60. m_JointVector.clear();
  61. m_JointVector.insert(m_JointVector.end(),m_RootOfTheJointsTree);
  62. int lVRMLID = m_RootOfTheJointsTree->getIDinActuated();
  63. if (m_NbOfVRMLIDs < lVRMLID)
  64. m_NbOfVRMLIDs = lVRMLID;
  65. // Find out the next body to be examine.
  66. ReLabelling(ID,ld);
  67. // Once finished we initialize the child and the sister.
  68. for(unsigned int i=0;i<m_listOfBodies.size();i++)
  69. {
  70. int lMother,lElderSister;
  71. if ((lMother=m_listOfBodies[i]->getLabelMother()) != -1)
  72. {
  73. if ((lElderSister=m_listOfBodies[lMother]->child) == -1)
  74. {
  75. // Mother, I am your daughter !
  76. m_listOfBodies[lMother]->child = i;
  77. }
  78. else
  79. {
  80. // I have an elder sister !
  81. while (m_listOfBodies[lElderSister]->sister != -1)
  82. // I have another elder sister !
  83. lElderSister = m_listOfBodies[lElderSister]->sister;
  84. // I am your younger sister !
  85. m_listOfBodies[lElderSister]->sister = i;
  86. }
  87. }
  88. }
  89. for (unsigned int i = 0; i< m_listOfBodies.size();i++)
  90. m_listOfBodies[i]->massCoef(m_listOfBodies[i]->mass()/mass());
  91. }
  92. void DynMultiBodyPrivate::UpdateBodyParametersFromJoint(int BodyID, int JointID, int)
  93. // cID : corps identifier
  94. // lD : liaison destination
  95. {
  96. ODEBUG( "Update body :" << BodyID << " from Joint " << JointID);
  97. // Update the rotation axis.
  98. m_listOfBodies[BodyID]->a = listInternalLinks[JointID].aJoint->axis();
  99. ODEBUG(" axis: " << m_listOfBodies[BodyID]->a);
  100. // Update the translation vector
  101. listInternalLinks[JointID].aJoint->getStaticTranslation(m_listOfBodies[BodyID]->b);
  102. ODEBUG(" JointID: " << JointID << "BodyID: " << BodyID << ", static translation: " << m_listOfBodies[BodyID]->b);
  103. // Update the rotation matrix
  104. listInternalLinks[JointID].aJoint->getStaticRotation(m_listOfBodies[BodyID]->R_static);
  105. ODEBUG(" Rotation matrix: " << endl << m_listOfBodies[BodyID]->R_static);
  106. listInternalLinks[JointID].aJoint->setLinkedBody(*m_listOfBodies[BodyID]);
  107. m_listOfBodies[BodyID]->joint( listInternalLinks[JointID].aJoint);
  108. }
  109. void DynMultiBodyPrivate::ReLabelling(int currentBody, int sourceLink)
  110. {
  111. // This one has been nicely clean-up
  112. for (unsigned int i=0; i<links[currentBody].size(); i++)
  113. {
  114. int destinationLink = links[currentBody][i].link;
  115. if ((destinationLink == sourceLink) &&
  116. (currentBody!=labelTheRoot))
  117. continue;
  118. int corps1 = listInternalLinks[destinationLink].indexCorps1;
  119. int corps2 = listInternalLinks[destinationLink].indexCorps2;
  120. int corpsMother,corpsSon;
  121. if ((currentBody == corps1) && (currentBody != corps2))
  122. {
  123. corpsSon = corps2;
  124. corpsMother = corps1;
  125. }
  126. else
  127. {
  128. corpsSon = corps1;
  129. corpsMother = corps2;
  130. }
  131. m_listOfBodies[corpsSon]->setLabelMother(corpsMother);
  132. if(listInternalLinks[destinationLink].aJoint->getIDinActuated()!=-1)
  133. {
  134. // Update the connections between the Joints.
  135. int lIDinActuated = listInternalLinks[destinationLink].aJoint->getIDinActuated();
  136. if (lIDinActuated!=-1)
  137. {
  138. ConvertIDInActuatedToBodyID[lIDinActuated] = corpsSon;
  139. }
  140. listInternalLinks[sourceLink].aJoint->addChildJoint(*listInternalLinks[destinationLink].aJoint);
  141. listInternalLinks[destinationLink].aJoint->SetFatherJoint(listInternalLinks[sourceLink].aJoint);
  142. // Update the vector of joints.
  143. ODEBUG("Inside Relabelling :" << listInternalLinks[destinationLink].aJoint->getName().c_str());
  144. ODEBUG("JointRankFromName :" << JointRankFromName(listInternalLinks[destinationLink].aJoint));
  145. if (JointRankFromName(listInternalLinks[destinationLink].aJoint)!=-1)
  146. m_JointVector.insert(m_JointVector.end(),listInternalLinks[destinationLink].aJoint);
  147. int lVRMLID = listInternalLinks[destinationLink].aJoint->getIDinActuated();
  148. if (m_NbOfVRMLIDs < lVRMLID)
  149. m_NbOfVRMLIDs = lVRMLID;
  150. }
  151. // TODO : It is important to do the relabelling after the
  152. // TODO : recursive call to the relabelling as set father build
  153. // TODO : up the JointFromRootToThis vector. Should be fixed at the Joint object level.
  154. ReLabelling(corpsSon, destinationLink);
  155. UpdateBodyParametersFromJoint(corpsSon,destinationLink,sourceLink);
  156. }
  157. }
  158. void DynMultiBodyPrivate::CreatesTreeStructure(const char * option)
  159. {
  160. m_listOfBodies.resize(listBodies.size());
  161. DynamicBodyPrivate *dbody;
  162. for(unsigned int i=0;i<listBodies.size();i++)
  163. {
  164. dbody = dynamic_cast<DynamicBodyPrivate *>(listBodies[i]);
  165. if (!dbody)
  166. {
  167. dbody = new DynamicBodyPrivate();
  168. *dbody = *listBodies[i];
  169. }
  170. m_listOfBodies[i] = dbody;
  171. }
  172. if (option!=0)
  173. {
  174. ReadLinkJointNameAndRank(option);
  175. }
  176. ConvertIDInActuatedToBodyID.resize(m_listOfBodies.size());
  177. SpecifyTheRootLabel(0);
  178. ComputeNumberOfJoints();
  179. BuildStateVectorToJointAndDOFs();
  180. BuildLinkFromActuatedIDs();
  181. UpdateTheSizeOfJointsJacobian();
  182. for(unsigned int i=0;i<m_JointVector.size();i++)
  183. {
  184. JointPrivate *aJP = dynamic_cast<JointPrivate *>(m_JointVector[i]);
  185. if (aJP!=0)
  186. aJP->computeLocalAndGlobalPose();
  187. }
  188. MAL_VECTOR_RESIZE(m_Configuration,m_NbDofs); MAL_VECTOR_FILL(m_Configuration, 0);
  189. MAL_VECTOR_RESIZE(m_Velocity,m_NbDofs); MAL_VECTOR_FILL(m_Velocity, 0);
  190. MAL_VECTOR_RESIZE(m_Acceleration,m_NbDofs); MAL_VECTOR_FILL(m_Acceleration, 0);
  191. MAL_MATRIX_RESIZE(m_Forces ,m_NbDofs,3); MAL_MATRIX_FILL(m_Forces, 0);
  192. MAL_MATRIX_RESIZE(m_Torques,m_NbDofs,3); MAL_MATRIX_FILL(m_Torques, 0);
  193. MAL_VECTOR_RESIZE(m_pastConfiguration,m_NbDofs); MAL_VECTOR_FILL(m_pastConfiguration, 0);
  194. MAL_VECTOR_RESIZE(m_pastVelocity,m_NbDofs); MAL_VECTOR_FILL(m_pastVelocity, 0);
  195. }
  196. void DynMultiBodyPrivate::InitializeFromJointsTree()
  197. {
  198. /* The goal of this method is to recreate the undirected
  199. graph, to restart the sequence of initialization. */
  200. vector<Body *> vectorOfBodies;
  201. int Depth=0;
  202. int NbOfBodies=0;
  203. internalLink CurrentLink ;
  204. /* Initialize the reading. */
  205. // Default initialization to 30 bodies for one branch.
  206. vectorOfBodies.resize(30);
  207. vectorOfBodies[0] = new DynamicBodyPrivate();
  208. vectorOfBodies[0]->setLabel(NbOfBodies++);
  209. addBody(*vectorOfBodies[0]);
  210. Depth++;
  211. // Go through the Joints tree.
  212. JointPrivate *CurrentJoint = m_RootOfTheJointsTree;
  213. JointPrivate *NextCurrentJoint=0,*FatherJoint;
  214. double mi[9]={ 1.0,1.0,1.0, 1.0,1.0,1.0, 1.0,1.0,1.0};
  215. CurrentLink.label = 0;
  216. CurrentLink.aJoint = m_RootOfTheJointsTree;
  217. CurrentLink.indexCorps1 = 0;
  218. CurrentLink.indexCorps2 = 0;
  219. int lIDinActuated=-1;
  220. unsigned int lRank=0;
  221. while(CurrentJoint!=0)
  222. {
  223. // Deal with the current joint.
  224. // Update the joint value of the current link.
  225. CurrentLink.aJoint = CurrentJoint;
  226. // Update the joint ID value in case there is none.
  227. if (CurrentLink.aJoint->getIDinActuated()==-1)
  228. CurrentLink.aJoint->setIDinActuated(lIDinActuated);
  229. lIDinActuated++;
  230. if (m_FileLinkJointRank.size()==0)
  231. // Create a relation between the name and the rank.
  232. {
  233. NameAndRank_t aNameAndRank;
  234. if (CurrentLink.aJoint->getName() == "")
  235. {
  236. char buf[64];
  237. if (CurrentLink.aJoint->type() == JointPrivate::FIX_JOINT)
  238. {
  239. sprintf(buf, "FIXED_%02d", lRank);
  240. }
  241. else
  242. {
  243. sprintf(buf, "JOINT_%02d", lRank);
  244. }
  245. string name(buf);
  246. CurrentLink.aJoint->setName(name);
  247. }
  248. strcpy(aNameAndRank.LinkName,
  249. CurrentLink.aJoint->getName().c_str());
  250. aNameAndRank.RankInConfiguration = lRank;
  251. m_LinksBetweenJointNamesAndRank.insert(m_LinksBetweenJointNamesAndRank.end(),
  252. aNameAndRank);
  253. lRank+= CurrentLink.aJoint->numberDof();
  254. }
  255. // Take care of the body.
  256. // extend the size of vectorOfBodies if necessary.
  257. if (Depth>(int)vectorOfBodies.size())
  258. {
  259. Body *aBody=NULL;
  260. vectorOfBodies.push_back(aBody);
  261. }
  262. /*
  263. If a body has already been attached to the joint,
  264. keep inertial information
  265. */
  266. DynamicBodyPrivate* lCurrentBody = NULL;
  267. CjrlBody* jrlBody = CurrentJoint->linkedBody();
  268. if (jrlBody != NULL) {
  269. lCurrentBody = dynamic_cast<DynamicBodyPrivate*>(jrlBody);
  270. if (lCurrentBody) {
  271. lCurrentBody->localCenterOfMass(jrlBody->localCenterOfMass());
  272. }
  273. else if (DynamicBody* dBody = dynamic_cast<DynamicBody*>(jrlBody)) {
  274. lCurrentBody = dynamic_cast<DynamicBodyPrivate*>(dBody->m_privateObj.get());
  275. } else {
  276. std::cerr <<
  277. "dynamicsJRLJapan: body is not of ab expected type."
  278. << std::endl;
  279. throw(0);
  280. }
  281. }
  282. else
  283. {
  284. lCurrentBody = new DynamicBodyPrivate();
  285. lCurrentBody->setInertie(mi);
  286. lCurrentBody->setMass(1.0);// 1 kg per default.
  287. vector3d cm;cm[0] = cm[1] =cm[2]=0.0;
  288. lCurrentBody->localCenterOfMass(cm);
  289. }
  290. vectorOfBodies[Depth] = lCurrentBody;
  291. lCurrentBody->setLabel(NbOfBodies++);
  292. string lCurrentBodyName=CurrentJoint->getName();
  293. lCurrentBodyName = "BODY_" + lCurrentBodyName;
  294. lCurrentBody->setName(lCurrentBodyName.c_str());
  295. lCurrentBody->setLabelMother(vectorOfBodies[Depth-1]->getLabel());
  296. addBody(*lCurrentBody);
  297. addLink(*vectorOfBodies[Depth-1],
  298. *lCurrentBody,
  299. CurrentLink);
  300. // Find the next one.
  301. // 1. A children.
  302. NextCurrentJoint = (dynamicsJRLJapan::JointPrivate *)CurrentJoint->childJoint(0);
  303. Depth++;
  304. // No child.
  305. if (NextCurrentJoint==0)
  306. {
  307. // If a father exist.
  308. FatherJoint = (dynamicsJRLJapan::JointPrivate *)CurrentJoint->parentJoint();
  309. Depth--;
  310. while( (FatherJoint!=0) &&
  311. (NextCurrentJoint==0))
  312. {
  313. // Find the location of the current node
  314. // in the father tree.
  315. int NbOfChildren= FatherJoint->countChildJoints();
  316. int CurrentJointPosition=-1;
  317. for(int li=0;li<NbOfChildren;li++)
  318. if (FatherJoint->childJoint(li)==CurrentJoint)
  319. {
  320. CurrentJointPosition = li;
  321. break;
  322. }
  323. // If a sibling has not been explored
  324. if(CurrentJointPosition<NbOfChildren-1)
  325. {
  326. // take it !
  327. NextCurrentJoint = (dynamicsJRLJapan::JointPrivate *)FatherJoint->
  328. childJoint(CurrentJointPosition+1);
  329. }
  330. else
  331. {
  332. // otherwise move upward.
  333. CurrentJoint =FatherJoint;
  334. FatherJoint=(dynamicsJRLJapan::JointPrivate *)FatherJoint->parentJoint();
  335. Depth--;
  336. }
  337. }
  338. // If finally FatherJoint==0 then NextCurrentJoint too is equal to 0.
  339. }
  340. CurrentJoint=NextCurrentJoint;
  341. }
  342. /* Initialize the data structures needed for the Newton-Euler algorithm. */
  343. if (m_FileLinkJointRank.size()==0)
  344. CreatesTreeStructure(0);
  345. else
  346. CreatesTreeStructure(m_FileLinkJointRank.c_str());
  347. }