generator  1.2
RoboticLine.cpp
1 /*
2  This file is part of the GeneratorOfDatasets program.
3 
4  GeneratorOfDatasets is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  GeneratorOfDatasets is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with GeneratorOfDatasets. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include <algorithm>
18 #include <functional>
19 #include <iostream>
20 #include <limits>
21 #include <numeric>
22 #include <iterator>
23 #include <functional>
24 #include <stdexcept>
25 #include <random>
26 #include <unordered_set>
27 #include "RoboticLine.h"
28 
29 using namespace std;
30 
31 random_device rd;
32 default_random_engine generator(rd());
33 
34 Movement::Movement(const uint32_t& from, const uint32_t& to, const ProjectParameters& par) : mFrom(from), mTo(to) {
35  uniform_real_distribution<double> durMin(par.minDurationOfMovement.from(), par.minDurationOfMovement.to());
36  uniform_real_distribution<double> prolongation(par.prolongationOfMovement.from(), par.prolongationOfMovement.to());
37  mMinDuration = durMin(generator);
38  mMaxDuration = mMinDuration+prolongation(generator);
39 
40  for (int32_t degree = par.degreeOfCoefficients.from(), i = 0; degree <= par.degreeOfCoefficients.to(); ++degree, ++i) {
41  uniform_real_distribution<double> coeff(par.energyFunctionCoefficients[i].from(), par.energyFunctionCoefficients[i].to());
42  mEnergyFunction.push_back({degree, coeff(generator)});
43  }
44 }
45 
47  uniform_real_distribution<double> inputPower(par.inputPowerOfModes[modeIdx].from(), par.inputPowerOfModes[modeIdx].to());
48  mInputPower = inputPower(generator);
49 }
50 
51 Location::Location(const uint32_t& point, const vector<RobotPowerMode*>& robotModes, const ProjectParameters& par) : mPoint(point) {
52  for (uint32_t m = 0; m < robotModes.size(); ++m) {
53  if (par.inputPowerOfModes[m].from() < par.inputPowerOfModes[m].to())
54  mLocationDependentPowerConsumption.emplace_back(robotModes[m], m, par);
55  }
56 }
57 
58 StaticActivity::StaticActivity(const uint32_t& aid, uint32_t& fromPoint, const ActivityType& type,
59  const vector<RobotPowerMode*>& robotModes, const ProjectParameters& par) : Activity(aid, type) {
60 
61  uniform_int_distribution<uint32_t> pt(par.numberOfPoints.from(), par.numberOfPoints.to());
62  uniform_real_distribution<double> minDur(par.minDurationOfOperation.from(), par.minDurationOfOperation.to());
63  uniform_real_distribution<double> prolongation(par.prolongationOfOperation.from(), par.prolongationOfOperation.to());
64 
65  mMinAbsDuration = minDur(generator);
66  mMaxAbsDuration = mMinAbsDuration+prolongation(generator);
67  uint32_t numberOfPoints = pt(generator);
68 
69  for (uint32_t p = fromPoint; p < fromPoint+numberOfPoints; ++p) {
70  Location *sp = new Location(p, robotModes, par);
71  mLocations.push_back(sp);
72  }
73 
74  double minPowerModeDelay = numeric_limits<double>::max();
75  for (RobotPowerMode *m : robotModes)
76  minPowerModeDelay = min(minPowerModeDelay, m->minimalDelay());
77 
78  if (mMaxAbsDuration < minPowerModeDelay)
79  throw runtime_error("Location::Location(...): Instance is infeasible due to power-save mode delays!");
80 
81  mMinAbsDuration = max(mMinAbsDuration, minPowerModeDelay);
82  fromPoint += numberOfPoints;
83 }
84 
86  for (Location *sp : mLocations)
87  delete sp;
88 }
89 
90 DynamicActivity::DynamicActivity(const uint32_t& aid, StaticActivity* fromActivity,
91  StaticActivity* toActivity, const ProjectParameters& par) : Activity(aid, MOVEMENT) {
92 
93  vector<pair<uint32_t,uint32_t> > movements;
94  size_t s1 = fromActivity->locations().size();
95  size_t s2 = toActivity->locations().size();
96 
97  for (uint32_t i = 0; i < s1; ++i)
98  for (uint32_t j = 0; j < s2; ++j)
99  movements.emplace_back(i,j);
100 
101  shuffle(movements.begin(), movements.end(), generator);
102  vector<bool> fromCovered(s1, false), toCovered(s2, false);
103 
104  for (const auto& c : movements) {
105  Movement *mv = new Movement(fromActivity->locations()[c.first]->point(), toActivity->locations()[c.second]->point(), par);
106  mMinAbsDuration = min(mMinAbsDuration, mv->minDuration());
107  mMaxAbsDuration = max(mMaxAbsDuration, mv->maxDuration());
108  mMovements.push_back(mv);
109  fromCovered[c.first] = true;
110  toCovered[c.second] = true;
111 
112  if (count(fromCovered.cbegin(), fromCovered.cend(), false) + count(toCovered.cbegin(), toCovered.cend(), false) == 0)
113  break;
114  }
115 
116  fromActivity->addSuccessor(this);
117  toActivity->addPredecessor(this);
118 
119  addSuccessor(toActivity);
120  addPredecessor(fromActivity);
121 }
122 
124  for (Movement *mv : mMovements)
125  delete mv;
126 }
127 
128 Robot::Robot(uint32_t& fromActivityId, uint32_t& fromPointId, const uint32_t& numberOfInputs,
129  const uint32_t& numberOfOutputs, const ProjectParameters& par) : mParameters(par) {
130 
131  uniform_int_distribution<uint32_t> psm(1u, (uint32_t) par.minDelayOfModes.size());
132 
133  uint32_t numberOfPowerSaveModes = psm(generator);
134  for (uint32_t m = 0; m < numberOfPowerSaveModes; ++m) {
135  uniform_real_distribution<double> delay(par.minDelayOfModes[m].from(), par.minDelayOfModes[m].to());
136  RobotPowerMode *rpwr = new RobotPowerMode(m, delay(generator));
137  rpwr->powerSaveModeName("power mode "+numberToString(m));
138  if (par.inputPowerOfModes[m].from() == par.inputPowerOfModes[m].to())
139  rpwr->expectedInputPower(par.inputPowerOfModes[m].from());
140  mRobotModes.push_back(rpwr);
141  }
142 
143  // Create operations for the robot.
144  vector<mCompositeBlock> operations;
145  uint32_t numberOfOperations = min(numberOfInputs, numberOfOutputs);
146  for (uint32_t op = 0; op+1 < numberOfOperations; ++op)
147  operations.push_back(createSerialSequence(fromActivityId, fromPointId));
148 
149  int32_t diffDeg = numberOfOutputs-numberOfInputs;
150  if (diffDeg > 0)
151  operations.push_back(createDisassemblyBlock(fromActivityId, fromPointId, abs(diffDeg)+1));
152  else if (diffDeg < 0)
153  operations.push_back(createAssemblyBlock(fromActivityId, fromPointId, abs(diffDeg)+1));
154  else
155  operations.push_back(createSerialSequence(fromActivityId, fromPointId));
156 
157 
158  mCompositeBlock operationsBlock = mergeBlocks(operations);
159  for (uint32_t opOut = 0; opOut < operations.size(); ++opOut) {
160  for (uint32_t opIn = 0; opIn < operations.size(); ++opIn) {
161  if (opOut != opIn)
162  connect(fromActivityId, operationsBlock, operations[opOut].out, operations[opIn].in);
163  }
164  }
165 
166  StaticActivity *waitToNextCycle = new StaticActivity(fromActivityId++, fromPointId, WAIT, mRobotModes, mParameters);
167  connect(fromActivityId, operationsBlock, operationsBlock.out, {waitToNextCycle});
168  connect(fromActivityId, operationsBlock, {waitToNextCycle}, operationsBlock.in);
169 
170  mActivities.insert(mActivities.end(), operationsBlock.in.cbegin(), operationsBlock.in.cend());
171  mActivities.insert(mActivities.end(), operationsBlock.w.cbegin(), operationsBlock.w.cend());
172  mActivities.insert(mActivities.end(), operationsBlock.out.cbegin(), operationsBlock.out.cend());
173  mActivities.push_back(waitToNextCycle);
174  mActivities.insert(mActivities.end(), operationsBlock.mv.cbegin(), operationsBlock.mv.cend());
175 
176  sort(mActivities.begin(), mActivities.end(), [](const Activity* a, const Activity* b) { return a->aid() < b->aid() ? true : false; });
177 }
178 
180  double sumOfDurations = 0.0;
181  size_t numberOfStatAct = 0;
182  vector<double> durationOfMovements;
183  for (const Activity* a : mActivities) {
184  if (a->type() != MOVEMENT) {
185  sumOfDurations += a->minAbsDuration();
186  ++numberOfStatAct;
187  } else {
188  durationOfMovements.push_back(a->minAbsDuration());
189  }
190  }
191 
192  sort(durationOfMovements.begin(), durationOfMovements.end());
193  sumOfDurations += accumulate(durationOfMovements.begin(), durationOfMovements.begin()
194  + min(numberOfStatAct, durationOfMovements.size()), 0.0);
195 
196  return sumOfDurations;
197 }
198 
200  for (RobotPowerMode *m : mRobotModes)
201  delete m;
202  for (Activity* a : mActivities)
203  delete a;
204 }
205 
206 Robot::mCompositeBlock Robot::createSerialSequence(uint32_t& fromActivityId, uint32_t& fromPointId) const {
207 
208  mCompositeBlock block = createBlockOfOperations(fromActivityId, fromPointId, IN, OUT, {1, 1},
210 
211  return block;
212 }
213 
214 
215 Robot::mCompositeBlock Robot::createAssemblyBlock(uint32_t& fromActivityId, uint32_t& fromPointId, const uint32_t& numberOfInputs) const {
216  return createComplexBlockHelper(fromActivityId, fromPointId, numberOfInputs, "assembly");
217 }
218 
219 Robot::mCompositeBlock Robot::createDisassemblyBlock(uint32_t& fromActivityId, uint32_t& fromPointId, const uint32_t& numberOfOutputs) const {
220  return createComplexBlockHelper(fromActivityId, fromPointId, numberOfOutputs, "disassembly");
221 }
222 
223 Robot::mCompositeBlock Robot::createComplexBlockHelper(uint32_t& fromActivityId, uint32_t& fromPointId, const uint32_t& numberOfSeq, const string& op) const {
224 
225  mCompositeBlock block, block1, block2, block3;
226 
227  if (op == "assembly") {
228  block1 = createBlockOfOperations(fromActivityId, fromPointId, IN, INNER, {numberOfSeq, numberOfSeq}, {2,2});
229  block3 = createBlockOfOperations(fromActivityId, fromPointId, OUT, OUT, {1, 1}, {1, 1});
230  } else if (op == "disassembly") {
231  block1 = createBlockOfOperations(fromActivityId, fromPointId, IN, IN, {1, 1}, {1, 1});
232  block3 = createBlockOfOperations(fromActivityId, fromPointId, INNER, OUT, {numberOfSeq, numberOfSeq}, {2, 2});
233  } else {
234  throw runtime_error("Robot::mCompositeBlock Robot::createComplexBlockHelper(...): Requested operation is not supported!");
235  }
236 
237  block2 = createBlockOfOperations(fromActivityId, fromPointId, INNER, INNER, mParameters.numberOfSequences, mParameters.sequenceLength);
238 
239  block = mergeBlocks({block1, block2, block3});
240 
241  connect(fromActivityId, block, block1.con2, block2.con1);
242  connect(fromActivityId, block, block2.con2, block3.con1);
243 
244  return block;
245 }
246 
247 Robot::mCompositeBlock Robot::createBlockOfOperations(uint32_t& fromActivityId, uint32_t& fromPointId, const ActivityType& t1, const ActivityType& t2,
248  const Interval<uint32_t>& numSeq, const Interval<uint32_t>& seqLength) const {
249 
250  uniform_int_distribution<uint32_t> sl(seqLength.from(), seqLength.to());
251  uniform_int_distribution<uint32_t> ns(numSeq.from(), numSeq.to());
252 
253  mCompositeBlock blockActivities;
254  uint32_t numberOfSequences = ns(generator);
255 
256  function<void(StaticActivity*)> storeActivity = [&blockActivities](StaticActivity *a) {
257  switch (a->type()) {
258  case IN:
259  blockActivities.in.push_back(a);
260  break;
261  case INNER:
262  blockActivities.w.push_back(a);
263  break;
264  default:
265  blockActivities.out.push_back(a);
266  }
267  };
268 
269 
270  for (uint32_t i = 0; i < numberOfSequences; ++i) {
271 
272  uint32_t sequenceLength = sl(generator);
273 
274  StaticActivity *op1 = new StaticActivity(fromActivityId++, fromPointId, t1, mRobotModes, mParameters);
275  blockActivities.con1.push_back(op1);
276  storeActivity(op1);
277 
278  StaticActivity *op2 = nullptr;
279  for (uint32_t l = 0; l+2 < sequenceLength; ++l) {
280  op2 = new StaticActivity(fromActivityId++, fromPointId, INNER, mRobotModes, mParameters);
281  DynamicActivity *op2op = new DynamicActivity(fromActivityId++, op1, op2, mParameters);
282  blockActivities.w.push_back(op2);
283  blockActivities.mv.push_back(op2op);
284  op1 = op2;
285  }
286 
287  if (sequenceLength == 1) {
288  if (t1 == t2) {
289  op2 = op1;
290  } else {
291  throw runtime_error("Robot::mCompositeBlock Robot::createBlockOfOperations(...): "
292  "Sequence of unit length must have the same types of the first and last activity");
293  }
294  } else {
295  op2 = new StaticActivity(fromActivityId++, fromPointId, t2, mRobotModes, mParameters);
296  DynamicActivity *op2op = new DynamicActivity(fromActivityId++, op1, op2, mParameters);
297  blockActivities.mv.push_back(op2op);
298  storeActivity(op2);
299  }
300 
301  blockActivities.con2.push_back(op2);
302  }
303 
304  connect(fromActivityId, blockActivities, blockActivities.con2, blockActivities.con1, false);
305 
306  return blockActivities;
307 }
308 
309 void Robot::connect(uint32_t& fromActivityId, mCompositeBlock& b, const vector<StaticActivity*>& from, const vector<StaticActivity*>& to, bool fullyConnected) const {
310  for (uint32_t i1 = 0; i1 < from.size(); ++i1) {
311  for (uint32_t i2 = 0; i2 < to.size(); ++i2) {
312  if (fullyConnected || i1 != i2) {
313  DynamicActivity *mv = new DynamicActivity(fromActivityId++, from[i1], to[i2], mParameters);
314  b.mv.push_back(mv);
315  }
316  }
317  }
318 }
319 
320 Robot::mCompositeBlock Robot::mergeBlocks(const vector<mCompositeBlock>& blocks) const {
321  mCompositeBlock ret;
322  for (const mCompositeBlock& b : blocks) {
323  copy(b.in.cbegin(), b.in.cend(), back_inserter(ret.in));
324  copy(b.w.cbegin(), b.w.cend(), back_inserter(ret.w));
325  copy(b.out.cbegin(), b.out.cend(), back_inserter(ret.out));
326  copy(b.mv.cbegin(), b.mv.cend(), back_inserter(ret.mv));
327  }
328 
329  return ret;
330 }
331 
332 bool Pair::operator==(const Pair& p) const {
333  if (mActivity1 == p.mActivity1 && mActivity2 == p.mActivity2 && mMode1 == p.mMode1 && mMode2 == p.mMode2)
334  return true;
335  else
336  return false;
337 }
338 
339 InterRobotOperation::InterRobotOperation(uint32_t oid, Activity* out, Activity* in, const ProjectParameters& par) : mOid(oid) {
340 
341  uniform_real_distribution<double> handover(0.0, 100.0);
342 
343  if (handover(generator) < par.percentageOfTableHandover) {
344  // bench
345  for (Activity *succ : out->successors())
346  mTimeLags.emplace_back(succ, in, 0, 0);
347  for (Activity *succ : in->successors())
348  mTimeLags.emplace_back(succ, out, 0, 1);
349 
350  name("Inter-robot operation "+numberToString(oid)+" - bench handover");
351  } else {
352  // gripper-to-gripper
353  mTimeLags.emplace_back(out, in, 0, 0);
354  mTimeLags.emplace_back(in, out, 0, 0);
355  for (Activity *inSucc : in->successors()) {
356  for (Activity *outSucc : out->successors()) {
357  mTimeLags.emplace_back(inSucc, outSucc, 0, 0);
358  mTimeLags.emplace_back(outSucc, inSucc, 0, 0);
359  }
360  }
361 
362  name("Inter-robot operation "+numberToString(oid)+" - gripper-to-gripper handover");
363  }
364 
366 }
367 
369 
370  StaticActivity *sa1 = dynamic_cast<StaticActivity*>(a1);
371  StaticActivity *sa2 = dynamic_cast<StaticActivity*>(a2);
372  if (sa1 == nullptr || sa2 == nullptr)
373  throw invalid_argument("void InterRobotOperation::generateSpatialCompatibilityPairs(...): Input activities must be static ones!");
374 
375  vector<Location*> loc1 = sa1->locations(), loc2 = sa2->locations();
376  if (loc1.empty() || loc2.empty())
377  throw runtime_error("void InterRobotOperation::generateSpatialCompatibilityPairs(...): Static activity without interior locations!?");
378 
379 
380  vector<pair<uint32_t, uint32_t> > possibleLocPairs;
381  for (uint32_t i = 0; i < loc1.size(); ++i)
382  for (uint32_t j = 0; j < loc2.size(); ++j)
383  possibleLocPairs.emplace_back(i,j);
384 
385  vector<bool> usedLoc1(loc1.size(), false), usedLoc2(loc2.size(), false);
386  shuffle(possibleLocPairs.begin(), possibleLocPairs.end(), generator);
387 
388  for (auto it = possibleLocPairs.cbegin(); it != possibleLocPairs.cend(); ++it) {
389  usedLoc1[it->first] = usedLoc2[it->second] = true;
390  mSpatialCompatibility.emplace_back(a1, it->first, a2, it->second);
391 
392  if (count(usedLoc1.begin(), usedLoc1.end(), false) + count(usedLoc2.begin(), usedLoc2.end(), false) == 0)
393  break;
394  }
395 }
396 
397 
399 
400  uint32_t nr = par.numberOfRobots;
401  vector<pair<uint32_t, uint32_t> > possibleInterconnections;
402  uniform_real_distribution<double> graphDeg(par.minimalVertexDegree.from(), par.minimalVertexDegree.to());
403 
404  for (uint32_t r1 = 0; r1 < nr; ++r1) {
405  for (uint32_t r2 = 0; r2 < nr; ++r2) {
406  if (r1 != r2 && r2 != 0 && r1+1 != nr)
407  possibleInterconnections.emplace_back(r1, r2);
408  }
409  }
410 
411  uint32_t sumOfDegrees = 0;
412  shuffle(possibleInterconnections.begin(), possibleInterconnections.end(), generator);
413  double minimalAverageDegree = graphDeg(generator), averageDegree = 0.0, inf = numeric_limits<double>::infinity();
414  vector<vector<double> > distMatrix(nr, vector<double>(nr, inf));
415 
416  for (const auto& interconnection : possibleInterconnections) {
417 
418  auto distMatrixCopy = distMatrix;
419  uint32_t r1 = interconnection.first, r2 = interconnection.second;
420 
421  distMatrix[r1][r2] = 1.0;
422 
423  for (uint32_t k : {r1, r2}) {
424  for (uint32_t i = 0; i < nr; ++i) {
425  for (uint32_t j = 0; j < nr; ++j) {
426  if (distMatrix[i][k]+distMatrix[k][j] < distMatrix[i][j])
427  distMatrix[i][j] = distMatrix[i][k]+distMatrix[k][j];
428  }
429  }
430  }
431 
432  bool acyclic = true;
433  for (uint32_t i = 0; i < nr; ++i) {
434  if (distMatrix[i][i] < inf) {
435  acyclic = false;
436  break;
437  }
438  }
439 
440  if (!acyclic) {
441  // backtrack: only acyclic graphs are allowed
442  distMatrix = distMatrixCopy;
443  continue;
444  }
445 
446  bool connectedEnough = true;
447  for (uint32_t r = 0; r < nr && connectedEnough; ++r) {
448  bool robotConnected = false;
449  for (uint32_t rb = 0; rb < nr; ++rb) {
450  if (distMatrix[rb][r] < inf || r == 0) {
451  robotConnected = true;
452  break;
453  }
454  }
455 
456  robotConnected = (distMatrix[r][nr-1] < inf || r+1 == nr) ? robotConnected : false;
457  connectedEnough = (connectedEnough && robotConnected) ? true : false;
458  }
459 
460  sumOfDegrees += 2;
461  averageDegree = ((double) sumOfDegrees)/((double) nr);
462 
463  if (connectedEnough == true && averageDegree >= minimalAverageDegree)
464  break;
465  }
466 
467  if (averageDegree < minimalAverageDegree) {
468  mWarnings.push_back("The average degree of nodes (desired "+numberToString(minimalAverageDegree)
469  +", obtained "+numberToString(averageDegree)+") cannot be reached.");
470  }
471 
472  uint32_t fromActivityId = 0, fromPointId = 0;
473  for (uint32_t r1 = 0; r1 < nr; ++r1) {
474  uint32_t numberOfInputs = 0, numberOfOutputs = 0;
475  for (uint32_t r2 = 0; r2 < nr; ++r2) {
476  if (r1 != r2 && distMatrix[r1][r2] < inf)
477  ++numberOfOutputs;
478  if (r1 != r2 && distMatrix[r2][r1] < inf)
479  ++numberOfInputs;
480  }
481 
482  if (r1 == 0)
483  ++numberOfInputs;
484  if (r1+1 == par.numberOfRobots)
485  ++numberOfOutputs;
486 
487  if (numberOfInputs == 0 || numberOfOutputs == 0)
488  throw runtime_error("RoboticLine::RoboticLine(...): Each robot has to have at least one input and one output activity!");
489 
490  mRobots.push_back(new Robot(fromActivityId, fromPointId, numberOfInputs, numberOfOutputs, par));
491  }
492 
493  vector<vector<Activity*> > robotIn, robotOut;
494  for (uint32_t r = 0; r < nr; ++r) {
495  vector<Activity*> inActivities, outActivities;
496  vector<Activity*> activities = mRobots[r]->activities();
497  copy_if(activities.cbegin(), activities.cend(), back_inserter(inActivities),
498  [](Activity* const& a) { return (a->type() == IN ? true : false); });
499  copy_if(activities.cbegin(), activities.cend(), back_inserter(outActivities),
500  [](Activity* const& a) { return (a->type() == OUT ? true : false); });
501  shuffle(inActivities.begin(), inActivities.end(), generator);
502  shuffle(outActivities.begin(), outActivities.end(), generator);
503  robotIn.push_back(inActivities); robotOut.push_back(outActivities);
504  }
505 
506  uint32_t opId = 0;
507  for (uint32_t r1 = 0; r1 < nr; ++r1) {
508  for (uint32_t r2 = 0; r2 < nr; ++r2) {
509  if (r1 != r2 && distMatrix[r1][r2] < inf) {
510  vector<Activity*>& out = robotOut[r1], & in = robotIn[r2];
511  if (!out.empty() && !in.empty()) {
512  mInterRobotOperations.emplace_back(opId++, out.back(), in.back(), par);
513  out.pop_back(); in.pop_back();
514  } else {
515  throw runtime_error("RoboticLine::RoboticLine(...): Not enough IN and OUT inter-robot activities!");
516  }
517  }
518  }
519  }
520 
521  generateCollisions(par);
523 }
524 
526 
527  unordered_set<Pair> addedCollisions;
528  uint32_t numberOfGeneratedCollisions = 0, iter = 0;
529  uniform_int_distribution<uint32_t> robotId(0, par.numberOfRobots-1);
530  uniform_int_distribution<uint32_t> numCol(par.numberOfCollisions.from(), par.numberOfCollisions.to());
531 
532  const uint32_t desiredNumberOfCollisions = numCol(generator);
533  const uint32_t maxNumberOfIterations = 10*desiredNumberOfCollisions;
534 
535  while (numberOfGeneratedCollisions < desiredNumberOfCollisions) {
536 
537  uint32_t robotId1 = robotId(generator), robotId2 = robotId(generator);
538 
539  if (robotId1 != robotId2) {
540  uniform_int_distribution<uint32_t> a1(0, ((int32_t) mRobots[robotId1]->activities().size())-1);
541  uniform_int_distribution<uint32_t> a2(0, ((int32_t) mRobots[robotId2]->activities().size())-1);
542 
543  Activity *activity1 = mRobots[robotId1]->activities()[a1(generator)];
544  Activity *activity2 = mRobots[robotId2]->activities()[a2(generator)];
545 
546  uniform_int_distribution<uint32_t> modeIdx1(0, ((int32_t) activity1->numberOfModes())-1);
547  uniform_int_distribution<uint32_t> modeIdx2(0, ((int32_t) activity2->numberOfModes())-1);
548 
549  Pair collision = {activity1, modeIdx1(generator), activity2, modeIdx2(generator)};
550 
551  if (addedCollisions.count(collision) == 0) {
552  mCollisions.push_back(collision);
553  addedCollisions.insert(collision);
554  ++numberOfGeneratedCollisions;
555  }
556  }
557 
558 
559  if (iter > maxNumberOfIterations) {
560  mWarnings.push_back("Cannot generate the requested number of collisions!");
561  break;
562  }
563 
564  ++iter;
565  }
566 }
567 
569  double productionCycleTime = 0;
570  uniform_real_distribution<double> dilFactor(par.dilatationFactor.from(), par.dilatationFactor.to());
571 
572  for (Robot *r : mRobots)
573  productionCycleTime = max(productionCycleTime, r->lowerBoundOfCycleTime());
574 
575  mProductionCycleTime = dilFactor(generator)*productionCycleTime;
576 }
577 
579  for (Robot *r : mRobots)
580  delete r;
581 }
582 
The class represents the robot movement between two coordinates.
Definition: RoboticLine.h:70
double mProductionCycleTime
The calculated production cycle time for *this robotic cell.
Definition: RoboticLine.h:591
mCompositeBlock createBlockOfOperations(uint32_t &fromActivityId, uint32_t &fromPointId, const ActivityType &t1, const ActivityType &t2, const Interval< uint32_t > &numSeq, const Interval< uint32_t > &seqLength) const
It is a core method for the decomposition of the robot work to well-defined blocks.
Interval< double > dilatationFactor
Multiplicative factor by which the lower estimation of the cycle time will be adjusted.
Interval< uint32_t > numberOfPoints
The interval of the number of points (i.e. robot configurations) for each robot operation.
Auxiliary class encapsulating two activities to form collision or spatial compatibility pair...
Definition: RoboticLine.h:453
Activity * mActivity2
Second activity.
Definition: RoboticLine.h:480
void generateSpatialCompatibilityPairs(Activity *a1, Activity *a2)
It is an auxiliary method for the constructor that helps to generate the compatibility pairs...
The base class incorporating common properties for robot operations and movements.
Definition: RoboticLine.h:193
The structure with desired properties for the generated instances.
std::vector< Interval< double > > minDelayOfModes
The time interval of minimal duration for each power saving mode.
Instance of the class includes all the data structures and methods related to a robot.
Definition: RoboticLine.h:297
Location(const uint32_t &point, const std::vector< RobotPowerMode * > &robotModes, const ProjectParameters &par)
It constructs the object representing a location of an operation from the robot point of view...
Definition: RoboticLine.cpp:51
bool operator==(const Pair &p) const
It compares two Pair data-structures and returns the result of comparison.
std::vector< InterRobotOperation > mInterRobotOperations
Inter-robot operations for a weldment/workpiece passing.
Definition: RoboticLine.h:587
std::vector< Location * > mLocations
The collection of possible robot configurations, i.e. locations, for this operation.
Definition: RoboticLine.h:261
~Robot()
It frees the memory occupied by dynamically allocated activities and power saving modes...
std::vector< Interval< double > > energyFunctionCoefficients
Intervals of energy function coefficients.
Collection of movements between two static activities.
Definition: RoboticLine.h:270
void generateCollisions(const ProjectParameters &par)
It generates collisions between robots.
STL namespace.
Interval< int32_t > degreeOfCoefficients
The degree of coefficients, e.g. results to where are energy function coefficients.
ProjectParameters mParameters
Desired properties of generated instances defined in the input configuration file.
Definition: RoboticLine.h:410
std::vector< RobotPowerMode * > mRobotModes
Available power saving modes for this robot.
Definition: RoboticLine.h:414
std::vector< std::string > mWarnings
Warnings produced during the generation of this robotic cell. Written to the console later to not mix...
Definition: RoboticLine.h:594
std::vector< Pair > mCollisions
Collisions between robots.
Definition: RoboticLine.h:589
std::vector< Robot * > mRobots
Robots incorporated in the robotic cell.
Definition: RoboticLine.h:585
uint32_t mMode2
The mode of the second activity, i.e. a movement or location identification.
Definition: RoboticLine.h:484
InterRobotOperation(uint32_t oid, Activity *out, Activity *in, const ProjectParameters &par)
It creates the inter-robot operation according the desired parameters stated in ProjectParameters dat...
virtual ~DynamicActivity() override
It frees the memory occupied by dynamically allocated movements.
ActivityType
Definition: RoboticLine.h:49
Interval< double > minimalVertexDegree
The interval of the desired average node degree for the graph of robot interconnections.
Movement(const uint32_t &from, const uint32_t &to, const ProjectParameters &par)
The constructor creates the movement according to the desired properties given in the project configu...
Definition: RoboticLine.cpp:34
virtual ~StaticActivity() override
It frees the memory occupied by dynamically allocated locations.
Definition: RoboticLine.cpp:85
std::vector< Interval< double > > inputPowerOfModes
For each power saving mode of the robot the interval of input power is defined.
Collection of locations in which a robot operation can be performed.
Definition: RoboticLine.h:241
Interval< double > prolongationOfOperation
The time interval of the additive part to the minimal operation duration.
~RoboticLine()
It frees all the memory occupied by robots.
It represents the power saving mode of the robot.
Definition: RoboticLine.h:107
double mMaxAbsDuration
The maximal absolute duration of the activity to remain feasible.
Definition: RoboticLine.h:233
double mMinDuration
The minimal possible duration of the robot movement.
Definition: RoboticLine.h:91
StaticActivity(const uint32_t &aid, uint32_t &fromPoint, const ActivityType &type, const std::vector< RobotPowerMode * > &robotModes, const ProjectParameters &par)
It generates the static activity, i.e. robot operation, according to the configuration.
Definition: RoboticLine.cpp:58
The structure containing the activities in a block.
Definition: RoboticLine.h:307
Interval< uint32_t > numberOfCollisions
The interval of the number of generated collisions between robots.
void connect(uint32_t &fromActivityId, mCompositeBlock &b, const std::vector< StaticActivity * > &from, const std::vector< StaticActivity * > &to, bool fullyConnected=true) const
It interconnects two sub-blocks and adds the generated dynamic activities to the block b...
double percentageOfTableHandover
The probability that the workpiece/weldment is handed over to other robot by using a bench...
Activity * mActivity1
First activity.
Definition: RoboticLine.h:478
Interval< double > prolongationOfMovement
The interval of prolongation for the fastest robot movements.
std::vector< LocationDependentPowerConsumption > mLocationDependentPowerConsumption
It defines the power consumption for the robot power saving modes that input power is dependent on th...
Definition: RoboticLine.h:184
Robot(uint32_t &fromActivityId, uint32_t &fromPointId, const uint32_t &numberOfInputs, const uint32_t &numberOfOutputs, const ProjectParameters &par)
It constructs the robot according to the desired parameters.
mCompositeBlock createDisassemblyBlock(uint32_t &fromActivityId, uint32_t &fromPointId, const uint32_t &numberOfOutputs) const
It creates a block composed of disassembling/cutting the workpiece and taking its parts to other robo...
mCompositeBlock createComplexBlockHelper(uint32_t &fromActivityId, uint32_t &fromPointId, const uint32_t &numberOfSeq, const std::string &op) const
It is an auxiliary method wrapping complex calls to createBlockOfOperations method.
LocationDependentPowerConsumption(RobotPowerMode *mode, const uint32_t &modeIdx, const ProjectParameters &par)
It constructs the object encapsulating the information about the input power for the given robot conf...
Definition: RoboticLine.cpp:46
double mMaxDuration
The maximal duration of the movement.
Definition: RoboticLine.h:93
Interval< uint32_t > sequenceLength
The interval of the number of robot sub-operations for each atomic sequence.
Interval< double > minDurationOfOperation
The interval of minimal duration of the robot operation, e.g. welding, assembling, ...
std::vector< Monomial > mEnergyFunction
Definition: RoboticLine.h:98
double mInputPower
Input power of the robot for a given robot configuration, see also the Location class.
Definition: RoboticLine.h:158
mCompositeBlock mergeBlocks(const std::vector< mCompositeBlock > &blocks) const
It copies the activities (their pointers) in blocks to the one composite block.
mCompositeBlock createAssemblyBlock(uint32_t &fromActivityId, uint32_t &fromPointId, const uint32_t &numberOfInputs) const
It creates a block composed of gathering required parts to a bench and their assembly/welding to one ...
Interval< uint32_t > numberOfSequences
The interval of the number of atomic sequences in each (dis)assembling/welding/cutting operation...
double mMinAbsDuration
The minimal absolute duration of the activity to remain feasible.
Definition: RoboticLine.h:231
It represents the location of robotic work.
Definition: RoboticLine.h:166
std::vector< Activity * > mActivities
A collection of activities belonging to the robot.
Definition: RoboticLine.h:412
mCompositeBlock createSerialSequence(uint32_t &fromActivityId, uint32_t &fromPointId) const
The method creates a block of a fixed sequence of operations, e.g. welding, cutting, without alternatives and updates the identification values.
The file contains various classes devoted to abstract representation of the robotic cell...
std::string numberToString(const T &number)
It converts the number to string.
Definition: RoboticLine.h:61
void calculateProductionCycleTime(const ProjectParameters &par)
It calculates production cycle time with respect to the desired dilatation factor.
double lowerBoundOfCycleTime() const
The method calculates an estimation of cycle time.
std::vector< Pair > mSpatialCompatibility
Spatial compatibility pairs, i.e. a handover takes place at the right location for both involved robo...
Definition: RoboticLine.h:545
uint32_t numberOfRobots
The number of robots in the robotic cell.
RoboticLine(const ProjectParameters &par)
It generates all the required data-structures for the robotic cell, i.e. an instance of a robotic cel...
uint32_t mMode1
The mode of the first activity, i.e. a movement or location identification.
Definition: RoboticLine.h:482
std::vector< Movement * > mMovements
The collection of movements between two static activities.
Definition: RoboticLine.h:289
Interval< double > minDurationOfMovement
The interval of minimal duration of robot movements (defines the fastest movement).
DynamicActivity(const uint32_t &aid, StaticActivity *fromActivity, StaticActivity *toActivity, const ProjectParameters &par)
It generates the dynamic activity with respect to the desired properties.
Definition: RoboticLine.cpp:90
std::vector< TimeLag > mTimeLags
Time lags ensuring the correct time synchronization between robots.
Definition: RoboticLine.h:543