Warning: Can't use blame annotator:
svn blame failed on branches/fep_rpc_client/NetworkReader.cpp: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator/branches/fep_rpc_client/NetworkReader.cpp @ 77

Revision 77, 8.5 KB checked in by jtorres, 9 years ago (diff)

fep_rpc_client: NetworkReader? complete. All cpp code is commented and cleaned. Added tinyxml lib.

RevLine 
1#include "NetworkReader.h"
2/**
3 * Constructor
4 * @param networkFileName input xml file
5 */
6NetworkReader::NetworkReader(const char * networkFileName)
7{
8    ldsIndex = 0;
9    loadLines(networkFileName);
10}
11
12/**
13 * Parses a station xml element into an "LDS_LOOP"
14 *
15 * @param stationElem the station xml element
16 * @param the parent line
17 * @return the new station
18 */
19LDS_LOOP NetworkReader::parseStation(TiXmlElement *stationElem, FEP_LINE line)
20{
21    LDS_LOOP station;
22   
23    TiXmlElement *stationSubElem = stationElem->FirstChildElement();
24    cout << "Station id: " << stationSubElem->GetText() << endl;
25    station.lds = atol(stationSubElem->GetText());
26    line.lds.push_back(station.lds);
27    line.ldsIndex.push_back(ldsIndex++);
28    stationSubElem = stationSubElem->NextSiblingElement();
29    station.line_num = atoi(stationSubElem->GetText());
30    stationSubElem = stationSubElem->NextSiblingElement();
31    station.drop = atoi(stationSubElem->GetText());
32    stationSubElem = stationSubElem->NextSiblingElement();
33    stationSubElem = stationSubElem->NextSiblingElement(); // skip location
34    stationSubElem = stationSubElem->NextSiblingElement(); // skip postmile
35    stationSubElem = stationSubElem->NextSiblingElement(); // skip direction
36    stationSubElem = stationSubElem->NextSiblingElement(); // skip freeway
37    station.MlTotVol = atoi(stationSubElem->GetText());
38    stationSubElem = stationSubElem->NextSiblingElement();
39    station.OppTotVol = atoi(stationSubElem->GetText());
40
41    station.pos = 0;
42    // Add loops to station
43    TiXmlElement *loopsElem = stationSubElem->NextSiblingElement();
44    TiXmlElement *loopElem = loopsElem->FirstChildElement(); 
45    TiXmlElement *saveLoopElem = loopElem;
46    // get number of loops in station and assign to station.num
47    station.num = 0;
48    for(loopElem; loopElem; loopElem = loopElem->NextSiblingElement())
49    {
50        station.num += 1;
51    }
52   
53    // get loopIDS and locations
54    long int loopIDS[station.num];
55    char * loopLocs[station.num];
56    int index = 0;
57    for(saveLoopElem; saveLoopElem; saveLoopElem = saveLoopElem->NextSiblingElement() )
58    {
59        TiXmlElement *subLoopElem = saveLoopElem->FirstChildElement();
60        loopIDS[index] = atoi(subLoopElem->GetText());
61        subLoopElem = subLoopElem->NextSiblingElement();
62        loopLocs[index++] = (char *) subLoopElem->GetText();
63    }
64    station.loopID = loopIDS;
65    station.loop_loc = loopLocs;
66
67    // Data pack ATMS message
68    station.length = station.num * 2 + CONTROL_DATA_LEN;
69    station.dataPack = msgDataPack(station);
70   
71    return station;
72}
73
74/**
75 * Parses a "Line" xml element into an FEP_LINE
76 * @param lineElem the xml element
77 * @return FEP_LINE
78 */
79FEP_LINE NetworkReader::parseLine(TiXmlElement *lineElem)
80{
81    FEP_LINE line;
82    TiXmlElement *lineSubElem = lineElem->FirstChildElement();
83    line.lineNum = atoi(lineSubElem->GetText());
84    cout << "Line: " << line.lineNum << endl;
85    lineSubElem = lineSubElem->NextSiblingElement();
86    line.count = atoi(lineSubElem->GetText());
87    lineSubElem = lineSubElem->NextSiblingElement();
88    line.schedule = atoi(lineSubElem->GetText());
89    lineSubElem = lineSubElem->NextSiblingElement();
90    line.lineInfo = atoi(lineSubElem->GetText());
91    lineSubElem = lineSubElem->NextSiblingElement();
92    line.systemKey = atol(lineSubElem->GetText());
93    lineSubElem = lineSubElem->NextSiblingElement();
94    line.globalSeq = atol(lineSubElem->GetText());
95    lineSubElem = lineSubElem->NextSiblingElement();
96    line.schedleSeq = atol(lineSubElem->GetText());
97
98    TiXmlElement *stationsElem = lineSubElem->NextSiblingElement();
99    TiXmlElement *stationElem = stationsElem->FirstChildElement();
100    for(stationElem; stationElem; stationElem = stationElem->NextSiblingElement())
101    {
102        stations.push_back(parseStation(stationElem, line));
103    }
104    return line;
105}
106
107/**
108 * Loads FEPLines from a specified xml file
109 * @param networkFileName the input xml file
110 */
111void NetworkReader::loadLines(const char * networkFileName)
112{
113    // Load network xml file
114    TiXmlDocument doc(networkFileName);
115    if(!doc.LoadFile())
116    {
117        cerr << "TiXmlDocument did not load network file..." << endl;
118        return;
119    }
120
121    // grab <Network> element
122    TiXmlHandle hDoc(&doc);
123    TiXmlElement *networkElem = hDoc.FirstChildElement().Element();
124
125    // grab first <Line> element
126    TiXmlElement *lineElem = networkElem->FirstChildElement();
127
128    // iterate through each line element to create FEP_LINE list
129    for(lineElem; lineElem; lineElem=lineElem->NextSiblingElement())
130    {
131        lines.push_back(parseLine(lineElem));
132    }
133}
134
135// determine if a loop has data based on lane config data
136bool NetworkReader::DataAvail(char flag, int num)
137{
138        int mag, fel;
139
140        // find mask value
141        if (num == 1)
142                mag = 0x01;
143        else if (num == 2)
144                mag = 0x02;
145        else if (num == 3)
146                mag = 0x04;
147        else if (num == 4)
148                mag = 0x08;
149        else if (num == 5)
150                mag = 0x10;
151        else if (num == 6)
152                mag = 0x20;
153        else if (num == 7)
154                mag = 0x40;
155        else if (num == 8)
156                mag = 0x80;
157
158        fel = flag & mag;
159        fel = fel >> (num - 1);
160
161        if (fel == 1)
162                return true;
163        else
164                return false;
165}
166
167// Initializes the LDS_LOOP dataPack with all necessary static data and default dynamic data
168unsigned char * NetworkReader::msgDataPack(LDS_LOOP loop)
169{
170        int j;
171        // Allocate memory for dataPack
172        unsigned char *dataPack = (unsigned char *) malloc(sizeof(unsigned char) * loop.length);
173
174        // dataPack 5-8: lane config
175        char d5 = 0, d6 = 0, d7 = 0, d8 = 0;
176        for (j = 0; j < loop.num; j++)
177        {
178                for (int k = 0; k < 8; k++)
179                {
180                        if (strcmp(loop.loop_loc[j], dp5[k]) == 0)
181                                d5 += pow(2, k);
182                        if (strcmp(loop.loop_loc[j], dp6[k]) == 0)
183                                d6 += pow(2, k);
184                        if (strcmp(loop.loop_loc[j], dp7[k]) == 0)
185                                d7 += pow(2, k);
186                        if (strcmp(loop.loop_loc[j], dp8[k]) == 0)
187                                d8 += pow(2, k);
188                }
189        }
190        dataPack[5-1] = d5;
191        dataPack[6-1] = d6;
192        dataPack[7-1] = d7;
193        dataPack[8-1] = d8;
194
195        // dataPack 1: Drop number, i.e. station address
196        dataPack[1-1] = loop.drop;
197
198        // dataPack2 (2 bytes per loop)
199        dataPack[2-1] = loop.num * 2 + Fixed_Byte_To_Checksum;
200
201        // dataPacket 3 (lowbyte: # of mainline loops, highbyte: # of opposite loops)
202        int low = 0, high = 0;
203        for (j = 1; j <= 6; j++)
204        {
205                low += DataAvail(dataPack[5-1], j);
206                high += DataAvail(dataPack[6-1], j);
207        }
208        high = high << 4;
209        dataPack[3-1] = high | low;
210
211        // dataPack4 (Miscl. flags: samples are: 80, A0, E0, 00)
212        dataPack[4-1] = 0xA0;
213
214        // dataPack 9: initialized as 00 (meaning no metering); need to be updated every 30 sec
215        dataPack[9-1] = 0;
216
217        // datadataPack 10-13: lane malfunction? Assuming all functional
218        dataPack[10-1] = 0;
219        dataPack[11-1] = 0;
220        dataPack[12-1] = 0;
221        dataPack[13-1] = 0;
222
223        // dataPack 14-22: ramp metering data
224        // BYTE 16 and 22 need to be updated every 30 sec
225        bool found = false;
226        for (j = 0; j < loop.num; j++)
227        {
228                if (strcmp(loop.loop_loc[j], "DEMAND") == 0)
229                {
230                        found = true;
231                        break;
232                }
233        }
234        if (found)
235        {
236                // BYTE 14: mostly 07, some are 05, 03, 00
237                dataPack[14-1] = 0x07;
238                // mostly 06(TOD table 1); some are 0B (No metering) or 05(traffic responsive)
239                dataPack[15-1] = 0x06;
240                // most 00, some are 01 (queue override) or 80(Meter ON sign)
241                dataPack[16-1] = 0x00;
242                // Field Manual Rate
243                dataPack[17-1] = 0xFF;
244                // TOC Manual Rate
245                dataPack[18-1] = 0xFF;
246                // PSO Manual Rate
247                dataPack[19-1] = 0xFF;
248                // CORM Rate
249                dataPack[20-1] = 0xFF;
250                // Local Responsive Rate. DON'T UNDERSTAND YET
251                dataPack[21-1] = 0x00;
252                // TOD Rate: need to query RAMP plugin!
253                dataPack[22-1] = 0x00;
254        }
255        // LDS: NO Metering
256        else
257        {
258                dataPack[14-1] = 0x00;
259                dataPack[15-1] = 0x0B;
260                dataPack[16-1] = 0x00;
261                dataPack[17-1] = 0xFF;
262                dataPack[18-1] = 0xFF;
263                dataPack[19-1] = 0xFF;
264                dataPack[20-1] = 0xFF;
265                dataPack[21-1] = 0x00;
266                dataPack[22-1] = 0x00;
267        }
268
269        // dataPack 23-24: sum of mainline/Oppsite traffic data; need to be updated every 30 sec
270        loop.MlTotVol = 0;
271        loop.OppTotVol = 0;
272        dataPack[23-1] = loop.MlTotVol;
273        dataPack[24-1] = loop.OppTotVol;
274
275        // dataPack 25-26: BYTE 25 is fixed, i.e. 03; BYTE 26 is either 0xA2 or 0x84
276        dataPack[25-1] = 0x03;
277        dataPack[26-1] = 0x84;
278
279        /* printf("lds=%d (%d), p1=%2X, p2=%2X, p3=%2X, p5=%2X, p6=%X, p7=%X, p8=%2X\n",
280                loop.lds, loop.length, dataPack[1-1], dataPack[2-1],
281                dataPack[3-1], dataPack[5-1],
282                dataPack[6-1], dataPack[7-1], dataPack[8-1]);
283    */
284        return dataPack;
285}
286
287/**
288 * Getter for lines
289 * @return List of FEP_LINES
290 */
291vector<FEP_LINE> NetworkReader::getLines()
292{
293    return lines;
294}
295
296/**
297 * Getter for stations
298 * @return List of LDS_LOOPs
299 */
300vector<LDS_LOOP> NetworkReader::getStations()
301{
302    return stations;
303}
304
305NetworkReader::~NetworkReader()
306{
307
308}
Note: See TracBrowser for help on using the repository browser.