24 #include "SolverConfig.h" 
   32         assert(duration >= 0.0 && mMinDuration <= duration+
TIME_ERR && duration <= mMaxDuration+
TIME_ERR && 
"Invalid duration of the movement!");
 
   34         double consumption = 0.0;
 
   35         for (
const Monomial& m : mEnergyFunction)
 
   36                 consumption += m.coeff*pow(duration, m.degree);
 
   42         double inputPower = 0.0;
 
   44                 inputPower = m->expectedInputPower();
 
   46                 throw InvalidArgument(caller(), 
"Malicious attempt to pass a null pointer as an argument!");
 
   48         for (
const auto& ldpc : mLocationDependentPowerConsumption)     {
 
   49                 if (ldpc.robotPowerMode() == m)
 
   50                         inputPower = ldpc.inputPower();
 
   57         assert(duration >= 0.0 && m->minimalDelay() <= duration+
TIME_ERR && mParent->minAbsDuration() <= duration+
TIME_ERR && 
"Invalid duration for the location!");
 
   58         return inputPower(m)*duration;
 
   73         string msg = 
"Cannot find dynamic activity " + to_string(mAid) + 
"'s movement with 'mid=" + to_string(mid) + 
"'!";
 
   79         const vector<Activity*>& related = (prefix == 
"suc" ? mSuccessors : mPredecessors);
 
   81         if (related.size() == 1)        {
 
   86                         string msg = 
"The " + prefix + 
"cessor of the dynamic activity " + to_string(mAid) + 
" must be static activity!";
 
   90                 string msg = 
"Dynamic activity " + to_string(mAid) + 
" must have exactly one " + prefix + 
"cessor!";
 
   96         if (mPredecessors.size() == 1)
 
   97                 return (predecessor()->successors().size() == 1) ? 
true : 
false;
 
  102 void DynamicActivity::parent(
Robot *r) {
 
  108 void DynamicActivity::freeAllocatedMemory()     {
 
  114         map<Location*, vector<Movement*> > enteringMovements, leavingMovements;
 
  115         for (
Activity *a : predecessors())      {
 
  118                         for (
Movement *mv : da->movements())
 
  119                                 enteringMovements[mv->to()].push_back(mv);
 
  121                         string pa = to_string(a->aid()), ca = to_string(aid());
 
  122                         string msg = 
"Static activity "+ca+
"'s predecessor "+pa+
" should be dynamic activity!";
 
  130                         for (
Movement* mv : da->movements())
 
  131                                 leavingMovements[mv->from()].push_back(mv);
 
  133                         string sa = to_string(a->aid()), ca = to_string(aid());
 
  134                         string msg = 
"Static activity "+ca+
"'s successor "+sa+
" should be dynamic activity!";
 
  140                 auto ite = enteringMovements.find(loc);
 
  141                 auto itl = leavingMovements.find(loc);
 
  142                 if (ite != enteringMovements.cend() && itl != leavingMovements.cend())  {
 
  143                         vector<Movement*>& entMvs = ite->second, &leavMvs = itl->second;
 
  145                         sort(entMvs.begin(), entMvs.end());
 
  146                         sort(leavMvs.begin(), leavMvs.end());
 
  147                         loc->enteringMovements(entMvs);
 
  148                         loc->leavingMovements(leavMvs);
 
  150                         string ca = to_string(aid()), pt = to_string(loc->point());
 
  151                         string msg = 
"Static activity "+ca+
" has isolated point "+pt+
"!";
 
  163         string msg = 
"Cannot find static activity " + to_string(mAid) + 
"'s location with 'lid=" + to_string(lid) + 
"'!";
 
  168         assert(mParent != 
nullptr && 
"Pointers should be initialized by the InstancesReader class!");
 
  172         const vector<RobotPowerMode*>& modes = mParent->powerModes();
 
  173         auto sit = find_if(modes.cbegin(), modes.cend(), [&pid](
RobotPowerMode* m) { 
return m->pid() == pid; });
 
  174         if (sit != modes.cend())
 
  183         assert(duration >= 0.0 && 
"Invalid duration value!");
 
  184         return inputPower(lid, pid)*duration;
 
  187 void StaticActivity::parent(
Robot *r)   {
 
  193 void StaticActivity::freeAllocatedMemory()      {
 
  201                 if (fastest == 
nullptr || fastest->minimalDelay() > pwrm->minimalDelay())
 
  205         assert(fastest != 
nullptr && 
"Invalid data-structure! Each robot has to have some power saving modes!");
 
  223                         for (
Movement* mv : da->movements())    {
 
  224                                 const auto& points = getValue(movementToPoints, mv, caller());
 
  225                                 uint32_t from = points.first, to = points.second;
 
  226                                 auto fSit = pointToLocation.find(from), tSit = pointToLocation.find(to);
 
  227                                 if (fSit == pointToLocation.cend() || tSit == pointToLocation.cend())   {
 
  228                                         string msg = 
"Invalid movement "+to_string(mv->mid());
 
  229                                         msg += 
" from point "+to_string(from)+
" to point "+to_string(to)+
"!";
 
  230                                         msg += 
"\nThe point is not connected with the static activity!";
 
  234                                 assert(fSit->second->parent() != 
nullptr && tSit->second->parent() != 
nullptr && 
"Should be set by XmlReader class!");
 
  235                                 Activity* a1 = fSit->second->parent(), *a2 = tSit->second->parent();
 
  237                                 if (sa1 == 
nullptr || sa2 == 
nullptr)   {
 
  240                                         if (sa1 == 
nullptr || sa2 == 
nullptr)   {
 
  241                                                 string msg = 
"Dynamic activity "+to_string(da->aid());
 
  242                                                 msg += 
" must be interconnected by two static activities!";
 
  243                                                 msg += 
"\nCheck type of activities "+to_string(a1->aid())+
" and "+to_string(a2->aid())+
".";
 
  247                                         if (sa1 != a1 || sa2 != a2)     {
 
  248                                                 string msg = 
"Dynamic activity "+to_string(da->aid());
 
  249                                                 msg += 
" can interconnect only two static activities!";
 
  254                                 mv->from(fSit->second);
 
  255                                 mv->to(tSit->second);
 
  258                         if (sa1 != 
nullptr && sa2 != 
nullptr)   {
 
  259                                 sa1->addSuccessor(da);
 
  260                                 da->addPredecessor(sa1);
 
  261                                 da->addSuccessor(sa2);
 
  262                                 sa2->addPredecessor(da);
 
  264                                 string msg = 
"There are no movements for the dynamic activity "+to_string(da->aid())+
"!";
 
  277 void Robot::freeAllocatedMemory()       {
 
  279                 a->freeAllocatedMemory();
 
  287 mutex refCounterMutex;
 
  290 RoboticLine::RoboticLine() : mRefCounter(new int64_t(1)), mProductionCycleTime(-1) {
 
  291         refCounterMutex.lock();
 
  292         liveInstances[mRefCounter].insert(
this);
 
  293         refCounterMutex.unlock();
 
  297         refCounterMutex.lock();
 
  300         refCounterMutex.unlock();
 
  301         copyDataStructures(l);
 
  306                 refCounterMutex.lock();
 
  310                 freeAllocatedMemory();
 
  311                 refCounterMutex.unlock();
 
  312                 copyDataStructures(l);
 
  331 void RoboticLine::copyDataStructures(
const RoboticLine& l)      {
 
  337 RoboticLine::~RoboticLine()     {
 
  338         refCounterMutex.lock();
 
  340         freeAllocatedMemory();
 
  341         refCounterMutex.unlock();
 
  344 void RoboticLine::freeAllocatedMemory() {
 
  347                         r->freeAllocatedMemory();
 
  360                         refCounterMutex.unlock();
 
  361                         throw SolverException(caller(), 
"Corrupted robotic cell data-structure, memory handling is invalid!");
 
The instance of the class corresponds to a robot movement between two coordinates. 
 
double mProductionCycleTime
Production cycle time, also called robot cycle time. 
 
The base class incorporating common properties of robot operations and movements. ...
 
The instance of this class specifies input power of the robot for a particular robot configuration an...
 
double inputPower(RobotPowerMode *m) const 
 
std::vector< std::pair< ActivityMode *, ActivityMode * > > mCollisions
Collisions between robots defined as time disjunctive pairs. 
 
Instance of this class includes all the data structures and methods related to a robot. 
 
std::string mDescription
Description of the robotic cell. 
 
Collection of movements between two static activities. 
 
A general exception of the program. 
 
std::vector< Robot * > mRobots
Robots located in this cell. 
 
Various auxiliary functions used across the program. 
 
void findMovementsForLocations()
Method assigns entering and leaving movements to each location in mLocations. 
 
int64_t * mRefCounter
Counter of references, the number of shallow copies sharing the same data. 
 
Movement * findMovement(const uint32_t &mid) const 
It finds a movement according to its identification. 
 
constexpr double TIME_ERR
Minimal recognizable difference in the time. 
 
Thrown if the dataset file contains ill-specified robotic cells. 
 
The file defines extended exceptions for the better error handling in the program. 
 
std::vector< InterRobotOperation * > mInterRobotOperations
Inter-robot operations between robots. 
 
Exception is thrown if a method is given invalid parameters or a user provides invalid program argume...
 
Collection of locations in which a robot operation (or waiting) can be performed. ...
 
static std::map< int64_t *, std::set< RoboticLine * > > liveInstances
Track of dynamically created instances, needed for managing the memory. 
 
A part of the energy function of a movement. 
 
double energyConsumption(double duration, const uint32_t &lid, const uint32_t &pid) const 
 
It represents the power saving mode of the robot. 
 
std::string mName
Name of the robotic cell. 
 
StaticActivity * cessor(const std::string &prefix) const 
 
double inputPower(const uint32_t &lid, const uint32_t &pid) const 
 
double energyConsumption(const double &duration) const 
 
Location * findLocation(const uint32_t &lid) const 
It finds a location according to its identification. 
 
The inter-robot operation corresponding to the workpiece/weldment handling. 
 
virtual bool mandatory() const 
It returns whether this dynamic activity has to be performed. 
 
The file defines allowed inaccuracies in a solution and constants for floats. 
 
void initialiseDataStructures(const std::map< uint32_t, Location * > &pointToLocation, const std::map< Movement *, std::pair< uint32_t, uint32_t >> &movementToPoints)
It recursively sets parents and initializes relations between activities. 
 
void setActivitiesRelations(const std::map< uint32_t, Location * > &pointToLocation, const std::map< Movement *, std::pair< uint32_t, uint32_t >> &movementToPoints)
It initializes precedences between activities (successors, predecessors). 
 
Location of the robot used either during work (welding) or waiting. 
 
The robotic cell corresponds to an instance of this class. 
 
RobotPowerMode * fastestPowerSavingMode() const 
The power saving mode with the minimal time for an application is returned. 
 
double energyConsumption(const double &duration, RobotPowerMode *m) const 
 
The file contains various classes devoted to abstract representation of the robotic cell...
 
void setParentOfChildren(RoboticLine *rl)
This method is propagated through all the parts of the robotic cell in order to set parents...