generator  1.2
XmlWriter.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 <iomanip>
18 #include <iostream>
19 #include <fstream>
20 #include <stdexcept>
21 #include "Settings.h"
22 #include "XmlWriter.h"
23 
24 using namespace std;
25 
26 ostream& operator<<(ostream& out, const Indent& indent) {
27  out<<string(4*indent.mIndent, ' ');
28  return out;
29 }
30 
31 void XmlWriter::writeXmlFile(string filename) {
32  ofstream ofile(filename.c_str());
33  if (!ofile) {
34  throw invalid_argument("bool XmlWriter::writeXmlFile(...): Cannot open the output file!");
35  }
36  ofile.setf(ios::fixed, ios::floatfield);
37 
38  if (Settings::VERBOSE && !mLines.empty())
39  cout<<"Writing instances to xml file:"<<endl;
40 
41  uint32_t lineId = 0;
42  ofile<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
43  ofile<<"<dataset xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"dataset.xsd\">"<<endl;
44  if (!Settings::DATASET_TITLE.empty())
45  ofile<<Indent(1)<<"<name>"<<Settings::DATASET_TITLE<<"</name>"<<endl;
46 
47  for (RoboticLine *line : mLines) {
48  writeInstanceXmlPart(ofile, line, lineId++, 1);
49  if (Settings::VERBOSE) {
50  cout<<" 0 % ["<<setfill('#')<<setw(50)<<string(50*(mLines.size()-lineId)/mLines.size(),' ')<<"] ";
51  cout<<setprecision(2)<<fixed<<100.0*lineId/mLines.size()<<" %"<<'\r';
52  cout.flush();
53  }
54  }
55  ofile<<"</dataset>"<<endl;
56 
57  if (Settings::VERBOSE && !mLines.empty())
58  cout<<endl;
59 
60  ofile.close();
61 }
62 
63 void XmlWriter::writeInstanceXmlPart(ostream& out, RoboticLine* line, const uint32_t& lineId, uint32_t length) {
64  out<<Indent(length++)<<"<instance>\n";
65 
66  out<<Indent(length)<<"<name>Robotic line "<<lineId<<"</name>\n";
67 
68  out<<Indent(length++)<<"<robots>\n";
69  for (uint32_t r = 0; r < line->robots().size(); ++r)
70  writeRobotXmlPart(out, line->robots()[r], r, length);
71  out<<Indent(--length)<<"</robots>\n";
72 
73  writeInterRobotOperationsXmlPart(out, line, length);
74  writeCollisionsXmlPart(out, line, length);
75 
76  out<<Indent(length)<<"<production-cycle-time>"<<line->productionCycleTime()<<"</production-cycle-time>\n";
77 
78  out<<Indent(--length)<<"</instance>"<<endl;
79 }
80 
81 void XmlWriter::writeRobotXmlPart(ostream& out, Robot* robot, const uint32_t& robotId, uint32_t length) {
82  out<<Indent(length++)<<"<robot>\n";
83 
84  out<<Indent(length)<<"<name>Robot "<<robotId<<"</name>\n";
85 
86  out<<Indent(length++)<<"<activities>\n";
87  for (Activity *a : robot->activities()) {
88  if (a->type() != MOVEMENT) {
89  StaticActivity *sa = dynamic_cast<StaticActivity*>(a);
90  if (sa != nullptr)
91  writeStaticActivityXmlPart(out, sa, length);
92  else
93  throw runtime_error("void XmlWriter::writeRobotXmlPart(...): Invalid cast to the static activity!");
94  }
95  }
96 
97  for (Activity *a : robot->activities()) {
98  if (a->type() == MOVEMENT) {
99  DynamicActivity *da = dynamic_cast<DynamicActivity*>(a);
100  if (da != nullptr)
101  writeDynamicActivityXmlPart(out, da, length);
102  else
103  throw runtime_error("void XmlWriter::writeRobotXmlPart(...): Invalid cast to the dynamic activity!");
104  }
105  }
106  out<<Indent(--length)<<"</activities>\n";
107 
108  out<<Indent(length++)<<"<power-saving-modes>\n";
109  const vector<RobotPowerMode*>& rpm = robot->robotModes();
110  for (uint32_t p = 0; p < rpm.size(); ++p) {
111  out<<Indent(length++)<<"<power-mode pid=\""<<p<<"\">\n";
112  out<<Indent(length)<<"<name>"<<rpm[p]->powerSaveModeName()<<"</name>\n";
113  out<<Indent(length)<<"<minimal-idle-time>"<<rpm[p]->minimalDelay()<<"</minimal-idle-time>\n";
114  if (rpm[p]->expectedInputPower() != -1.0)
115  out<<Indent(length)<<"<expected-input-power>"<<rpm[p]->expectedInputPower()<<"</expected-input-power>\n";
116  out<<Indent(--length)<<"</power-mode>\n";
117  }
118  out<<Indent(--length)<<"</power-saving-modes>\n";
119 
120 
121  out<<Indent(--length)<<"</robot>\n";
122 }
123 
124 void XmlWriter::writeStaticActivityXmlPart(ostream& out, StaticActivity* a, uint32_t length) {
125  out<<Indent(length++)<<"<static-activity aid=\""<<a->aid()<<"\""<<(a->type() == WAIT ? " last_in_cycle=\"true\"" : "")<<">\n";
126 
127  out<<Indent(length)<<"<min-duration>"<<a->minAbsDuration()<<"</min-duration>\n";
128  out<<Indent(length)<<"<max-duration>"<<a->maxAbsDuration()<<"</max-duration>\n";
129 
130  uint32_t modeId = 0;
131  out<<Indent(length++)<<"<locations>\n";
132  for (Location* pt : a->locations()) {
133  out<<Indent(length++)<<"<location lid=\""<<modeId++<<"\">\n";
134  out<<Indent(length)<<"<point>"<<pt->point()<<"</point>\n";
135 
136  if (!pt->locationDependentPowerConsumption().empty()) {
137  out<<Indent(length++)<<"<location-dependent-power-consumption>\n";
138  for (const LocationDependentPowerConsumption& ld : pt->locationDependentPowerConsumption())
139  out<<Indent(length)<<"<consumption pid=\""<<ld.robotModeRef()->pid()<<"\" input_power=\""<<ld.inputPower()<<"\" />\n";
140  out<<Indent(--length)<<"</location-dependent-power-consumption>\n";
141  }
142 
143  out<<Indent(--length)<<"</location>\n";
144  }
145  out<<Indent(--length)<<"</locations>\n";
146 
147  out<<Indent(--length)<<"</static-activity>\n";
148 }
149 
150 void XmlWriter::writeDynamicActivityXmlPart(ostream& out, DynamicActivity* a, uint32_t length) {
151  out<<Indent(length++)<<"<dynamic-activity aid=\""<<a->aid()<<"\">\n";
152 
153  uint32_t modeId = 0;
154  Activity *from = nullptr, *to = nullptr;
155 
156  if (!a->predecessors().empty() && !a->successors().empty()) {
157  from = a->predecessors().front();
158  to = a->successors().front();
159  } else {
160  throw runtime_error("void XmlWriter::writeDynamicActivityXmlPart(...): Predecessors and successors of the activity are unset!");
161  }
162 
163  out<<Indent(length++)<<"<movements from_aid=\""<<from->aid()<<"\" to_aid=\""<<to->aid()<<"\">\n";
164  for (Movement* mv : a->movements()) {
165  out<<Indent(length++)<<"<movement mid=\""<<modeId++<<"\">\n";
166 
167  out<<Indent(length)<<"<from-point>"<<mv->from()<<"</from-point>\n";
168  out<<Indent(length)<<"<to-point>"<<mv->to()<<"</to-point>\n";
169  out<<Indent(length)<<"<min-duration>"<<mv->minDuration()<<"</min-duration>\n";
170  out<<Indent(length)<<"<max-duration>"<<mv->maxDuration()<<"</max-duration>\n";
171 
172  out<<Indent(length++)<<"<energy-function>\n";
173  for (const Monomial& m : mv->energyFunction())
174  out<<Indent(length)<<"<monomial degree=\""<<m.degree<<"\" coeff=\""<<m.coeff<<"\"/>\n";
175  out<<Indent(--length)<<"</energy-function>\n";
176 
177  out<<Indent(--length)<<"</movement>\n";
178  }
179  out<<Indent(--length)<<"</movements>\n";
180 
181  out<<Indent(--length)<<"</dynamic-activity>\n";
182 }
183 
184 void XmlWriter::writeInterRobotOperationsXmlPart(ostream& out, RoboticLine* line, uint32_t length) {
185 
186  if (!line->interRobotOperations().empty()) {
187  out<<Indent(length++)<<"<inter-robot-operations>\n";
188  for (const InterRobotOperation& op : line->interRobotOperations()) {
189 
190  out<<Indent(length++)<<"<operation oid=\""<<op.oid()<<"\">\n";
191  out<<Indent(length)<<"<name>"<<op.name()<<"</name>\n";
192 
193  out<<Indent(length++)<<"<time-compatibility>\n";
194  for (const TimeLag& e : op.timeLags()) {
195  out<<Indent(length++)<<"<time-lag>\n";
196  out<<Indent(length)<<"<from-activity>"<<e.from()->aid()<<"</from-activity>\n";
197  out<<Indent(length)<<"<to-activity>"<<e.to()->aid()<<"</to-activity>\n";
198  out<<Indent(length)<<"<length>"<<e.length()<<"</length>\n";
199  out<<Indent(length)<<"<height>"<<e.height()<<"</height>\n";
200  out<<Indent(--length)<<"</time-lag>\n";
201  }
202  out<<Indent(--length)<<"</time-compatibility>\n";
203 
204  if (!op.spatialCompatibility().empty()) {
205  out<<Indent(length++)<<"<spatial-compatibility>\n";
206  for (const Pair& spc : op.spatialCompatibility()) {
207  out<<Indent(length++)<<"<compatible-pair>\n";
208  out<<Indent(length)<<"<location aid=\""<<spc.activity1()->aid()<<"\" lid=\""<<spc.mode1()<<"\" />\n";
209  out<<Indent(length)<<"<location aid=\""<<spc.activity2()->aid()<<"\" lid=\""<<spc.mode2()<<"\" />\n";
210  out<<Indent(--length)<<"</compatible-pair>\n";
211  }
212  out<<Indent(--length)<<"</spatial-compatibility>\n";
213  }
214 
215  out<<Indent(--length)<<"</operation>\n";
216  }
217  out<<Indent(--length)<<"</inter-robot-operations>\n";
218  }
219 }
220 
221 void XmlWriter::writeCollisionsXmlPart(std::ostream& out, RoboticLine* line, uint32_t length) {
222  if (!line->collisions().empty()) {
223  out<<Indent(length++)<<"<collision-zones>\n";
224  for (const Pair& c : line->collisions()) {
225  out<<Indent(length++)<<"<collision-pair>\n";
226  vector<pair<Activity*, uint32_t> > pairs = {{c.activity1(), c.mode1()}, {c.activity2(), c.mode2()}};
227 
228  for (const auto& p : pairs) {
229  if (p.first->type() == MOVEMENT)
230  out<<Indent(length)<<"<movement aid=\""<<p.first->aid()<<"\" mid=\""<<p.second<<"\" />\n";
231  else
232  out<<Indent(length)<<"<location aid=\""<<p.first->aid()<<"\" lid=\""<<p.second<<"\" />\n";
233  }
234 
235  out<<Indent(--length)<<"</collision-pair>\n";
236  }
237  out<<Indent(--length)<<"</collision-zones>\n";
238  }
239 }
240 
The class represents the robot movement between two coordinates.
Definition: RoboticLine.h:70
Auxiliary class encapsulating two activities to form collision or spatial compatibility pair...
Definition: RoboticLine.h:453
void writeRobotXmlPart(std::ostream &out, Robot *robot, const uint32_t &robotId, uint32_t length)
It writes a part of the xml file corresponding to one robot.
Definition: XmlWriter.cpp:81
The base class incorporating common properties for robot operations and movements.
Definition: RoboticLine.h:193
void writeCollisionsXmlPart(std::ostream &out, RoboticLine *line, uint32_t length)
It writes a part of the xml file corresponding to the spatial collisions.
Definition: XmlWriter.cpp:221
The class specifies input power of the robot for a particular robot configuration.
Definition: RoboticLine.h:142
Instance of the class includes all the data structures and methods related to a robot.
Definition: RoboticLine.h:297
It primarily defines XmlWriter class for writing the generated instances to the file.
void writeDynamicActivityXmlPart(std::ostream &out, DynamicActivity *a, uint32_t length)
It writes a part of the xml file corresponding to one dynamic activity.
Definition: XmlWriter.cpp:150
Collection of movements between two static activities.
Definition: RoboticLine.h:270
STL namespace.
void writeInstanceXmlPart(std::ostream &out, RoboticLine *line, const uint32_t &lineId, uint32_t length)
It writes a part of the xml file corresponding to one robotic cell.
Definition: XmlWriter.cpp:63
void writeXmlFile(std::string filename=Settings::OUTPUT_FILE)
It transforms the instances of the robotic cells to the form of the xml file.
Definition: XmlWriter.cpp:31
Collection of locations in which a robot operation can be performed.
Definition: RoboticLine.h:241
It represents the part of energy functions, i.e. where is the duration of the movement.
Definition: RoboticLine.h:37
It declares the namespace for program settings.
Auxiliary structure corresponding to the tabulator in an xml file.
Definition: XmlWriter.h:38
Instance of TimeLag class defines a time relation between two different robots.
Definition: RoboticLine.h:423
void writeInterRobotOperationsXmlPart(std::ostream &out, RoboticLine *line, uint32_t length)
It writes a part of the xml file corresponding to the inter-robot operations.
Definition: XmlWriter.cpp:184
The inter-robot operation corresponding to the workpiece/weldment handling.
Definition: RoboticLine.h:512
std::ostream & operator<<(std::ostream &out, const Interval< T > &t)
Overloading of the output operator for the Interval class.
Definition: Interval.h:89
It represents the location of robotic work.
Definition: RoboticLine.h:166
The robotic cell corresponds to an instance of this class.
Definition: RoboticLine.h:553
void writeStaticActivityXmlPart(std::ostream &out, StaticActivity *a, uint32_t length)
It writes a part of the xml file corresponding to one static activity.
Definition: XmlWriter.cpp:124