NTRT Simulator
 All Classes Files Functions Variables Typedefs Friends Pages
tgRigidAutoCompound.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2012, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The NASA Tensegrity Robotics Toolkit (NTRT) v1 platform is licensed
7  * under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * http://www.apache.org/licenses/LICENSE-2.0.
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
15  * either express or implied. See the License for the specific language
16  * governing permissions and limitations under the License.
17 */
18 
26 #include "tgRigidAutoCompound.h"
27 
28 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
29 #include "tgCompoundRigidInfo.h"
30 #include <map>
31 
32 // Debugging
33 #include <iostream>
34 #include "tgUtil.h"
35 
36 using namespace std;
37 
38 
39 // @todo: we want to start using this and get rid of the set-based constructor, but until we can refactor...
40 tgRigidAutoCompound::tgRigidAutoCompound(std::vector<tgRigidInfo*> rigids)
41 {
42  m_rigids.insert(m_rigids.end(), rigids.begin(), rigids.end());
43 }
44 
45 tgRigidAutoCompound::tgRigidAutoCompound(std::deque<tgRigidInfo*> rigids) : m_rigids(rigids)
46 {}
47 
48 std::vector< tgRigidInfo* > tgRigidAutoCompound::execute() {
49 
50  // Determine the grouping of our rigids
51  groupRigids();
52 
53  // Create the compounds as necessary
54  createCompounds();
55 
56  // Set the rigid body for the various groups
57  for(int i=0; i < m_groups.size(); i++) {
58  // Note: rigids that are not connected to anything else are placed
59  //into a group of their own, so they're represented here too
60  setRigidInfoForGroup(m_compounded[i], m_groups[i]);
61  }
62  // Need to return this so we can delete it at the appropreate time
63  return m_compounded;
64 };
65 
66 // @todo: we probably don't need this any more -- this will be taken care of in the tgRigidInfo => tgModel step
67 // @todo: NOTE: we need to have a way to check to see if a rigid has already been instantiated -- maybe just check get
68 void tgRigidAutoCompound::setRigidBodyForGroup(btRigidBody* body, std::deque<tgRigidInfo*>& group) {
69  for(int i = 0; i < group.size(); i++) {
70  group[i]->setRigidBody(body);
71  }
72 }
73 
74 void tgRigidAutoCompound::setRigidInfoForGroup(tgRigidInfo* rigidInfo, std::deque<tgRigidInfo*>& group) {
75  for(int i = 0; i < group.size(); i++) {
76  group[i]->setRigidInfoGroup(rigidInfo);
77  }
78 }
79 
80 void tgRigidAutoCompound::groupRigids()
81 {
82  std::deque<tgRigidInfo*> ungrouped = std::deque<tgRigidInfo*>(m_rigids); // Copy of m_rigids
83 
84  while(ungrouped.size() > 0) {
85  // go through each ungrouped element and find the groups for it
86  tgRigidInfo* elem = ungrouped[0]; // Note: the 0 element is removed by findGroup, so ungrouped[0] is different each iteration
87 
88  // Find all elements linked to the first item in ungrouped
89  // This will also remove the elements in the group from ungrouped
90  std::deque<tgRigidInfo*> group = findGroup(elem, ungrouped);
91 
92  // Add the group to the groups list
93  m_groups.push_back(group);
94  }
95 }
96 
97 // Find all rigids that should be in a group with the given rigid
98 // @todo: This may contain an off-by-one error (the last rigid may not be grouped properly...)
99 std::deque<tgRigidInfo*> tgRigidAutoCompound::findGroup(tgRigidInfo* rigid, std::deque<tgRigidInfo*>& ungrouped) {
100 
101  std::deque<tgRigidInfo*> group;
102 
103  // Add the rigid to the current group
104  group.push_back(rigid);
105 
106  // Remove the rigid from the ungrouped since it's now in a group
107  ungrouped.erase(std::remove(ungrouped.begin(), ungrouped.end(), rigid), ungrouped.end());
108 
109  // Recursively find linked elements
110  int i = 0;
111  while(i < ungrouped.size()) {
112  tgRigidInfo* other = ungrouped[i];
113  if(rigid->sharesNodesWith(*other)) {
114  std::deque<tgRigidInfo*> links = findGroup(other, ungrouped);
115  group.insert(group.end(), links.begin(), links.end());
116  i = 0;
117  } else {
118  i++;
119  }
120  }
121 
122  return group;
123 };
124 
125 void tgRigidAutoCompound::createCompounds() {
126  for(int i=0; i < m_groups.size(); i++) {
127  std::deque<tgRigidInfo*>& group = m_groups[i];
128  if(group.size() == 1) {
129  // Only one, no compounding necessary
130  m_compounded.push_back(group[0]);
131  } else {
132  tgRigidInfo* compound = createCompound(group);
133  m_compounded.push_back(compound);
134  }
135  }
136 }
137 
138 tgRigidInfo* tgRigidAutoCompound::createCompound(std::deque<tgRigidInfo*> rigids) {
140  for(int i = 0; i < rigids.size(); i++) {
141  c->addRigid(*rigids[i]);
142  }
143  return (tgRigidInfo*)c;
144 }
145 
146 bool tgRigidAutoCompound::rigidBelongsIn(tgRigidInfo* rigid, std::deque<tgRigidInfo*> group) {
147  for(int i = 0; i < group.size(); i++) {
148  tgRigidInfo* other = group[i];
149  if(rigid->sharesNodesWith(*other))
150  return true;
151  }
152  return false;
153 };
Definition of class tgCompoundRigidInfo.
virtual bool sharesNodesWith(const tgRigidInfo &other) const =0
void addRigid(tgRigidInfo &rigid)
Contains the definition of class tgUtil and overloaded operator<<() free functions.
Definition of class tgRigidAutoCompound.