libmove3d-planners
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros Groups Pages
GridCube.hpp
1 #ifndef GRIDCUBE_H
2 #define GRIDCUBE_H
3 
4 class Cube {
5 public:
6  std::vector<Node*> mNodes;
7  int mTries;
8  int mFound;
9  int mIndex;
10  GridGraph* mG;
11  bool mDisabled;
12  SamplingAPI* mSampler;
13 
14  Cube(int index, GridGraph* graph, int tries = 0, int found = 0);
15  Cube(const Cube& other) {}
16  Cube& operator = (const Cube& other) { return(*this); }
17  ~Cube();
18 
19  int sample(std::vector<Node*>& new_nodes, int n, int limit);
20  void addNode(Node* N);
21  double edgeMean();
22  double outgoingMean();
23 
24 };
25 
26 template<class T, class STREAM>
27  void print_vector(std::vector<T>& v, STREAM& stream)
28 {
29  if(v.size() > 0)
30  {
31  stream << v[0];
32  for(typename std::vector<T>::iterator it = v.begin()+1, end = v.end(); it < end; it++)
33  {
34  stream << " " << (*it);
35  }
36  }
37  stream << std::endl;
38 }
39 template<class T, class STREAM>
40  void read_vector(std::vector<T>& v, STREAM& stream)
41 {
42  T tmp;
43  while(stream.peek() != '\n')
44  {
45  stream >> tmp;
46  v.push_back(tmp);
47  }
48  stream.ignore(1);
49 }
50 
51 typedef bool (*Compare)(p3d_node* n1, p3d_node* n2);
52 
53 extern void p3d_shoot_bounded(p3d_rob* R, std::vector<DofSpec>& params, shared_ptr<Configuration> q, bool sample_passive);
54 
55 class GridGraph : public Graph
56 {
57 public:
58  double mLength;
59  std::vector<double> mOrig, mEnd;
60  std::vector<uint> mDegrees;
61  std::vector<uint> mFactor;
62  std::vector<uint> mCumulFactor;
63  uint mDim;
64  std::vector<Cube*> mCubes;
65  std::vector<bool> mFreeSpace;
66  uint mFreeSpaceN;
67  uint mCubesN;
68  double mMaxDist;
69 
70  GridGraph(double length, std::vector<double> orig, std::vector<double> end, std::vector<uint> degrees,
71  p3d_graph* g, Robot* r, LocalpathFactory* pathFactory, SamplingAPI* sampler, double maxDist = P3D_HUGE) :
72  Graph(g, r, pathFactory, sampler),
73  mLength(length), mOrig(orig), mEnd(end), mDegrees(degrees),
74  mDim(mDegrees.size()), mFreeSpaceN(0), mMaxDist(maxDist)
75  {
76  for(uint i = 0; i < mDim; i++)
77  {
78  mFactor.push_back((uint)((mEnd[i] - mOrig[i]) / mLength) + 1);
79  mCumulFactor.push_back(i == 0 ? 1 : mCumulFactor[i-1] * mFactor[i-1]);
80  }
81 
82  mCubesN = mDim == 0 ? 0 : mCumulFactor.back() * mFactor.back();
83 
84  for(uint i(0); i < mCubesN; i++)
85  {
86  mCubes.push_back(new Cube(i, this));
87  mFreeSpace.push_back(false);
88  }
89  this->initSampler();
90  }
91 
92  GridGraph(const char* filename, p3d_graph* g, Robot* r, LocalpathFactory* pathFactory, SamplingAPI* sampler, double maxDist = P3D_HUGE) :
93  Graph(g, r, pathFactory, sampler),
94  mFreeSpaceN(0), mMaxDist(maxDist)
95  {
96  shared_ptr<std::fstream> gridFile = open_file(filename, std::ios_base::in);
97  int tries;
98  int found;
99  *gridFile >> mDim;
100  *gridFile >> mCubesN;
101  *gridFile >> mLength;
102  (*gridFile).ignore(1);
103  read_vector(mDegrees, *gridFile);
104  read_vector(mOrig, *gridFile);
105  read_vector(mEnd, *gridFile);
106  read_vector(mFactor, *gridFile);
107  read_vector(mCumulFactor, *gridFile);
108  uint freeCube;
109  while(*gridFile >> freeCube) {
110  *gridFile >> tries;
111  *gridFile >> found;
112  for(uint i = mCubes.size(); i < freeCube && i < mCubesN; i++) {
113  mCubes.push_back(new Cube(i, this, 0, 0));
114  mFreeSpace.push_back(false);
115  }
116  mCubes.push_back(new Cube(freeCube, this, tries, found));
117  mFreeSpace.push_back(true);
118  mFreeSpaceN++;
119  }
120  this->initSampler();
121  }
122 
123  ~GridGraph()
124  {
125  for(uint i(0); i < mCubes.size(); i++)
126  delete(mCubes[i]);
127  this->Graph::freeResources();
128  }
129 
130  void initSampler()
131  {
132  std::vector<DofSpec> params;
133  for(uint i(0); i < mDim; i++) {
134  params.push_back(DofSpec(mDegrees[i], mOrig[i], mEnd[i]));
135  }
136  mSampler = new GridSampler(mR, mR->copyConfig(mR->mR->ROBOT_GOTO), params, true);
137  }
138 
139  void writeGrid(const char* filename)
140  {
141  shared_ptr<std::fstream> gridFile = open_file(filename, std::ios_base::out);
142  *gridFile << mDim << endl;
143  *gridFile << mCubesN << endl;
144  *gridFile << mLength << endl;
145  print_vector(mDegrees, *gridFile);
146  print_vector(mOrig, *gridFile);
147  print_vector(mEnd, *gridFile);
148  print_vector(mFactor, *gridFile);
149  print_vector(mCumulFactor, *gridFile);
150  for(uint i = 0; i < mCubesN; i++)
151  {
152  if(mFreeSpace[i])
153  {
154  *gridFile << i << " " << mCubes[i]->mTries << " " << mCubes[i]->mFound << endl;
155  }
156  }
157  }
158 
159  bool withinBounds(std::vector<double> point)
160  {
161  bool b(false);
162 
163  for(uint i(0); i < mDim && !b; i++)
164  {
165  b = b || (point[i] < mOrig[i] || point[i] > mEnd[i]);
166  }
167 
168  return(!b);
169  }
170 
171  int coords_to_n(Configuration& q)
172  {
173  int n(0);
174 
175  for(uint i(0); i < mDim; i++)
176  {
177  n += int ((q.mQ[mDegrees[i]] - mOrig[i]) / mLength) * mCumulFactor[i];
178  }
179 
180  if(n < 0 || n >= (int) mCubesN)
181  return(-1);
182  else
183  return(n);
184  }
185 
186  std::vector<double> n_to_coords(int n)
187  {
188  std::vector<double> coords(mDim);
189 
190  for(int i = mDim - 1; i >= 0; i--)
191  {
192  coords[i] = (double) (n / mCumulFactor[i]) * mLength + mOrig[i];
193  n = n % mCumulFactor[i];
194  }
195  return(coords);
196  }
197 
198  void sampleGrid(int tries)
199  {
200  int remaining(tries);
201  double completion(0.01);
202  while(remaining > 0)
203  {
204  if(p3d_GetStopValue())
205  {
206  return;
207  }
208 
209  remaining--;
210  shared_ptr<Configuration> q = mSampler->sample();
211  if(!mR->isInCollision(*q))
212  this->markCubeFree(*q);
213  // some completion feedback for the user
214  if(completion < ((double) tries - (double) remaining) / (double) tries)
215  {
216  cout << "done: " << completion << endl;
217  completion += 0.01;
218  }
219  }
220  }
221 
222  int markCubeFree(Configuration& q)
223  {
224  std::vector<double> coords;
225 
226  for(uint i = 0; i < mDim; i++)
227  {
228  coords.push_back(q.mQ[mDegrees[i]]);
229  }
230  if(this->withinBounds(coords))
231  {
232  int n = this->coords_to_n(q);
233  if(!mFreeSpace[n]) {
234  mFreeSpace[n] = true;
235  mFreeSpaceN++;
236  cout << "cube " << mFreeSpaceN;
237  for(uint i = 0; i < mDim; i++)
238  {
239  cout << ", " << coords[i];
240  }
241  cout << endl;
242  }
243  return(n);
244  }
245  else
246  { cout << "out of bounds";
247  for(uint i = 0; i < mDim; i++)
248  { cout << ", " << coords[i]; }
249  cout << endl;
250  return(-1);
251  }
252  }
253 
254  void sampleUnderThreshold(std::vector<Node*>& newNodes, double max_neighbours, int max_tries, uint max_nodes, int tries) {
255  for(uint i = 0; i < mCubes.size(); i++)
256  {
257  if(mFreeSpace[i])
258  {
259  double cube_mean = mCubes[i]->outgoingMean();
260  if(! terminationCube(*mCubes[i], max_neighbours, max_tries, max_nodes))
261  {
262  mCubes[i]->sample(newNodes, 1, tries);
263  }
264  cout << "cube: " << i << ", mean: " << cube_mean << ", size: " << mCubes[i]->mNodes.size() << endl;
265  }
266  }
267  }
268 
269  void sampleIso(std::vector<Node*>& newNodes, uint n_per_cube, int tries)
270  {
271  for(uint i(0); i < mCubes.size(); i++)
272  {
273  if(mFreeSpace[i])
274  {
275  mCubes[i]->sample(newNodes, n_per_cube, tries);
276  }
277  }
278  }
279 
280  bool terminationCube(Cube& c, double max_neighbours, int max_tries, uint max_nodes)
281  {
282  return((! (c.outgoingMean() < max_neighbours &&
283  c.mTries < max_tries && c.mNodes.size() < max_nodes)) ||
284  c.mDisabled);
285  }
286 
287  bool terminationCondition(double max_neighbours, int max_tries, uint max_nodes)
288  {
289  for(uint i(0); i < mCubes.size(); i++)
290  {
291  if(mFreeSpace[i] && ! this->terminationCube(*mCubes[i], max_neighbours, max_tries, max_nodes))
292  {
293  return(false);
294  }
295  }
296  return(true);
297  }
298 
299  Node* insertNode(shared_ptr<Configuration> q)
300  {
301  int n;
302  Node* node(NULL);
303 
304  if((n = this->coords_to_n(*q)) != -1)
305  {
306  int cube_n = this->markCubeFree(*q);
307 
308  if(cube_n >= 0)
309  {
310  node = this->Graph::insertNode(q);
311  mCubes[cube_n]->addNode(node);
312 
313  }
314  }
315  return(node);
316  }
317 };
318 
319 #endif // GRIDCUBE_H
Classe représentant un Node d'un Graph.
Definition: node.hpp:39
Definition: graph.hpp:28
Definition: GridCube.hpp:55
This class holds a the robot represented by a kinematic chain.
Definition: robot.hpp:42
Node * insertNode(Node *node)
insert un Node dans le Graph
Definition: graph.cpp:700
Definition: GridCube.hpp:4
The sampling API.
Definition: sampling_api.hpp:19
Classe représentant une Configuration d'un Robot.
Definition: configuration.hpp:25
Creares local paths.
Definition: localpath_factory.hpp:16