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...