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

Revision 78, 15.2 KB checked in by jtorres, 9 years ago (diff)

All green dots are showing. This is a checkpoint before adding dynamic data packing.

Line 
1#include "NetworkReader.h"
2
3/**
4 * Constructor
5 * @param networkFileName input xml file
6 */
7NetworkReader::NetworkReader(const char * networkFileName) {
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    LDS_LOOP station;
21
22    TiXmlElement *stationSubElem = stationElem->FirstChildElement();
23    cout << "Station id: " << stationSubElem->GetText() << endl;
24    station.lds = atol(stationSubElem->GetText());
25    line->lds.push_back(station.lds);
26    line->ldsIndex.push_back(ldsIndex++);
27    stationSubElem = stationSubElem->NextSiblingElement();
28    station.line_num = atoi(stationSubElem->GetText());
29    stationSubElem = stationSubElem->NextSiblingElement();
30    station.drop = atoi(stationSubElem->GetText());
31    stationSubElem = stationSubElem->NextSiblingElement();
32    stationSubElem = stationSubElem->NextSiblingElement(); // skip location
33    stationSubElem = stationSubElem->NextSiblingElement(); // skip postmile
34    stationSubElem = stationSubElem->NextSiblingElement(); // skip direction
35    stationSubElem = stationSubElem->NextSiblingElement(); // skip freeway
36    station.MlTotVol = atoi(stationSubElem->GetText());
37    stationSubElem = stationSubElem->NextSiblingElement();
38    station.OppTotVol = atoi(stationSubElem->GetText());
39
40    station.pos = 0;
41    // Add loops to station
42    TiXmlElement *loopsElem = stationSubElem->NextSiblingElement();
43    TiXmlElement *loopElem = loopsElem->FirstChildElement();
44    TiXmlElement *saveLoopElem = loopElem;
45    // get number of loops in station and assign to station.num
46    station.num = 0;
47    for (loopElem; loopElem; loopElem = loopElem->NextSiblingElement()) {
48        station.num += 1;
49    }
50
51    // get loopIDS and locations
52    long int loopIDS[station.num];
53    char * loopLocs[station.num];
54    int index = 0;
55    for (saveLoopElem; saveLoopElem; saveLoopElem = saveLoopElem->NextSiblingElement()) {
56        TiXmlElement *subLoopElem = saveLoopElem->FirstChildElement();
57        loopIDS[index] = atoi(subLoopElem->GetText());
58        subLoopElem = subLoopElem->NextSiblingElement();
59        loopLocs[index++] = (char *) subLoopElem->GetText();
60    }
61    station.loopID = loopIDS;
62    station.loop_loc = loopLocs;
63
64    // Data pack ATMS message
65    station.length = station.num * 2 + CONTROL_DATA_LEN;
66    station.dataPack = staticDataPack(station);
67/*
68    // fill in dynamic data to dataPack[]
69    for (i = 0; i < g_ldsNum; i++) {
70        // Loop detector data
71        int pos = 26;
72        pos = pp_data_packing(i, 5, pos);
73        pos = pp_data_packing(i, 6, pos);
74        pos = pp_data_packing(i, 7, pos);
75        pos = pp_data_packing(i, 8, pos);
76
77        // Update data for BYTE 9, 16, 21, 22, 23, 24
78
79        // what is the current metering rate?
80        // check each LDS, if there is demand detector, the downstream node the
81        // ldsMap[i].dataPack[22-1] = ldsMap[i].dataPack[9-1] = ;
82
83        // will need to check if queue override is enabled (Currently, no queue
84        // ldsMap[i].dataPack[16-1] = ;
85
86        // byte 23: MAINLINE total volume
87        ldsMap[i].dataPack[23 - 1] = ldsMap[i].MlTotVol;
88
89        // byte 24: opposite total volume
90        ldsMap[i].dataPack[24 - 1] = ldsMap[i].OppTotVol;
91
92        // last BYTE: checksum
93        ldsMap[i].dataPack[ldsMap[i].length - 1] =
94                chksum(ldsMap[i].dataPack, ldsMap[i].length - 1 - 1);
95
96        // print out
97        // print out
98        for (j = 0; j < ldsMap[i].length; j++) {
99            fprintf(fi_lds, "%02X", ldsMap[i].dataPack[j]);
100        }
101        fprintf(fi_lds, "\n");
102        fflush(fi_lds);
103*/
104
105        return station;
106    }
107
108    /**
109     * Parses a "Line" xml element into an FEP_LINE
110     * @param lineElem the xml element
111     * @return FEP_LINE
112     */
113    FEP_LINE NetworkReader::parseLine(TiXmlElement * lineElem) {
114        FEP_LINE line;
115        TiXmlElement *lineSubElem = lineElem->FirstChildElement();
116        line.lineNum = atoi(lineSubElem->GetText());
117        cout << "Line: " << line.lineNum << endl;
118        lineSubElem = lineSubElem->NextSiblingElement();
119        line.count = atoi(lineSubElem->GetText());
120        lineSubElem = lineSubElem->NextSiblingElement();
121        line.schedule = atoi(lineSubElem->GetText());
122        lineSubElem = lineSubElem->NextSiblingElement();
123        line.lineInfo = atoi(lineSubElem->GetText());
124        lineSubElem = lineSubElem->NextSiblingElement();
125        line.systemKey = atol(lineSubElem->GetText());
126        lineSubElem = lineSubElem->NextSiblingElement();
127        line.globalSeq = atol(lineSubElem->GetText());
128        lineSubElem = lineSubElem->NextSiblingElement();
129        line.schedleSeq = atol(lineSubElem->GetText());
130
131        TiXmlElement *stationsElem = lineSubElem->NextSiblingElement();
132        TiXmlElement *stationElem = stationsElem->FirstChildElement();
133        for (stationElem; stationElem; stationElem = stationElem->NextSiblingElement()) {
134            stations.push_back(parseStation(stationElem, &line));
135        }
136        return line;
137    }
138
139    /**
140     * Loads FEPLines from a specified xml file
141     * @param networkFileName the input xml file
142     */
143    void NetworkReader::loadLines(const char * networkFileName) {
144        // Load network xml file
145        TiXmlDocument doc(networkFileName);
146        if (!doc.LoadFile()) {
147            cerr << "TiXmlDocument did not load network file..." << endl;
148            return;
149        }
150
151        // grab <Network> element
152        TiXmlHandle hDoc(&doc);
153        TiXmlElement *networkElem = hDoc.FirstChildElement().Element();
154
155        // grab first <Line> element
156        TiXmlElement *lineElem = networkElem->FirstChildElement();
157
158        // iterate through each line element to create FEP_LINE list
159        for (lineElem; lineElem; lineElem = lineElem->NextSiblingElement()) {
160            lines.push_back(parseLine(lineElem));
161        }
162    }
163
164    // determine if a loop has data based on lane config data
165
166    bool NetworkReader::DataAvail(char flag, int num) {
167        int mag, fel;
168
169        // find mask value
170        if (num == 1)
171            mag = 0x01;
172        else if (num == 2)
173            mag = 0x02;
174        else if (num == 3)
175            mag = 0x04;
176        else if (num == 4)
177            mag = 0x08;
178        else if (num == 5)
179            mag = 0x10;
180        else if (num == 6)
181            mag = 0x20;
182        else if (num == 7)
183            mag = 0x40;
184        else if (num == 8)
185            mag = 0x80;
186
187        fel = flag & mag;
188        fel = fel >> (num - 1);
189
190        if (fel == 1)
191            return true;
192        else
193            return false;
194    }
195/*
196    int pp_data_packing(int index, int packNo, int pos) {
197        int i, j, k, vol, occ, lane, haveData;
198        LOOPAGG in;
199        DETECTOR *aaa;
200        VOLOCC bbb;
201        long loop;
202
203        i = index;
204
205        //used for data byte 23 and 24
206        ldsMap[i].MlTotVol = 0;
207        ldsMap[i].OppTotVol = 0;
208
209        for (j = 1; j <= 8; j++) {
210            if (DataAvail(ldsMap[i].dataPack[packNo - 1], j)) {
211                // loop at bit j has data
212                for (k = 0; k < ldsMap[i].num; k++) {
213                    // what's the corresponding loop of bit j
214                    if (packNo == 5)
215                        haveData = strcmp(ldsMap[i].loop_loc[k], dp5[j - 1]);
216                    else if (packNo == 6)
217                        haveData = strcmp(ldsMap[i].loop_loc[k], dp6[j - 1]);
218                    else if (packNo == 7)
219                        haveData = strcmp(ldsMap[i].loop_loc[k], dp7[j - 1]);
220                    else if (packNo == 8)
221                        haveData = strcmp(ldsMap[i].loop_loc[k], dp8[j - 1]);
222                    else
223                        return -1;
224
225                    if (haveData == 0) {
226                        loop = ldsMap[i].loopID[k];
227                        if (strcmp(chu[loop].paramicsName, "?") == 0) {
228                            {
229                                vol = 0;
230                                occ = 900;
231                            } else {
232                                aaa = qpg_NET_detector(chu[loop].paramicsName);
233                                Bool status = uci_loop_aggregation(qpg_DTC_index(aaa), POLLING
234                                if (status) {
235                                    if (chu[loop].paramicsLane == 0)
236                                            lane = 0;
237                                    else
238                                        lane = chu[loop].paramicsLane - 1;
239                                            vol = in.vol[lane];
240                                            occ = (int) (in.occ[lane] * 900 + 0.5);
241                                            //                   qps_GUI_printf("%d(%s), lane=%d, vol=%d(%d), occ=%.3f(%.3f,
242                                            //                      qpg_DTC_index(aaa), chu[loop].paramicsName, in.lane, in.
243                                            //                      vol, in.g_occ, in.occ[lane], occ);
244                                    } else
245                                    qps_GUI_printf("Data query error for %s\n", chu[loop].param
246                                }
247
248                            bbb = pp_vol_occ_word(vol, occ);
249                                    pos++;
250                                    ldsMap[i].dataPack[pos - 1] = bbb.high;
251                                    pos++;
252                                    ldsMap[i].dataPack[pos - 1] = bbb.low;
253
254                            if (packNo == 5) {
255                                ldsMap[i].MlTotVol += vol;
256                            } else if (packNo == 6) {
257
258                                ldsMap[i].OppTotVol += vol;
259                            }
260
261                            fprintf(fi_lds, "lds=%d, loop=%d, paramics=%s, lane=%d, vol=%d(%X
262                                    ldsMap[i].lds, loop, chu[loop].paramicsName, chu[loop].paramic
263                                    bbb.high, occ, bbb.low);
264                                    fflush(fi_lds);
265                        }
266                    }
267                }
268            }
269
270            return pos;
271        }
272 */
273        // Initializes the LDS_LOOP dataPack with all necessary static data and default dynamic data
274        unsigned char * NetworkReader::staticDataPack(LDS_LOOP loop) {
275            int j;
276                    // Allocate memory for dataPack
277                    unsigned char *dataPack = (unsigned char *) calloc(1, sizeof (unsigned char) * loop.length);
278
279                    // dataPack 5-8: lane config
280                    char d5 = 0, d6 = 0, d7 = 0, d8 = 0;
281            for (j = 0; j < loop.num; j++) {
282                for (int k = 0; k < 8; k++) {
283                    if (strcmp(loop.loop_loc[j], dp5[k]) == 0)
284                            d5 += pow(2, k);
285                        if (strcmp(loop.loop_loc[j], dp6[k]) == 0)
286                                d6 += pow(2, k);
287                            if (strcmp(loop.loop_loc[j], dp7[k]) == 0)
288                                    d7 += pow(2, k);
289                                if (strcmp(loop.loop_loc[j], dp8[k]) == 0)
290                                        d8 += pow(2, k);
291                                }
292            }
293            dataPack[5 - 1] = d5;
294                    dataPack[6 - 1] = d6;
295                    dataPack[7 - 1] = d7;
296                    dataPack[8 - 1] = d8;
297
298                    // dataPack 1: Drop number, i.e. station address
299                    dataPack[1 - 1] = loop.drop;
300
301                    // dataPack2 (2 bytes per loop)
302                    dataPack[2 - 1] = loop.num * 2 + Fixed_Byte_To_Checksum;
303
304                    // dataPacket 3 (lowbyte: # of mainline loops, highbyte: # of opposite loops)
305                    int low = 0, high = 0;
306            for (j = 1; j <= 6; j++) {
307                low += DataAvail(dataPack[5 - 1], j);
308                        high += DataAvail(dataPack[6 - 1], j);
309            }
310            high = high << 4;
311                    dataPack[3 - 1] = high | low;
312
313                    // dataPack4 (Miscl. flags: samples are: 80, A0, E0, 00)
314                    dataPack[4 - 1] = 0xA0;
315
316                    // dataPack 9: initialized as 00 (meaning no metering); need to be updated every 30 sec
317                    dataPack[9 - 1] = 0;
318
319                    // datadataPack 10-13: lane malfunction? Assuming all functional
320                    dataPack[10 - 1] = 0;
321                    dataPack[11 - 1] = 0;
322                    dataPack[12 - 1] = 0;
323                    dataPack[13 - 1] = 0;
324
325                    // dataPack 14-22: ramp metering data
326                    // BYTE 16 and 22 need to be updated every 30 sec
327                    bool found = false;
328            for (j = 0; j < loop.num; j++) {
329                if (strcmp(loop.loop_loc[j], "DEMAND") == 0) {
330                    found = true;
331                    break;
332                }
333            }
334            if (found) {
335                // BYTE 14: mostly 07, some are 05, 03, 00
336                dataPack[14 - 1] = 0x07;
337                        // mostly 06(TOD table 1); some are 0B (No metering) or 05(traffic responsive)
338                        dataPack[15 - 1] = 0x06;
339                        // most 00, some are 01 (queue override) or 80(Meter ON sign)
340                        dataPack[16 - 1] = 0x00;
341                        // Field Manual Rate
342                        dataPack[17 - 1] = 0xFF;
343                        // TOC Manual Rate
344                        dataPack[18 - 1] = 0xFF;
345                        // PSO Manual Rate
346                        dataPack[19 - 1] = 0xFF;
347                        // CORM Rate
348                        dataPack[20 - 1] = 0xFF;
349                        // Local Responsive Rate. DON'T UNDERSTAND YET
350                        dataPack[21 - 1] = 0x00;
351                        // TOD Rate: need to query RAMP plugin!
352                        dataPack[22 - 1] = 0x00;
353            }                // LDS: NO Metering
354            else {
355                dataPack[14 - 1] = 0x00;
356                        dataPack[15 - 1] = 0x0B;
357                        dataPack[16 - 1] = 0x00;
358                        dataPack[17 - 1] = 0xFF;
359                        dataPack[18 - 1] = 0xFF;
360                        dataPack[19 - 1] = 0xFF;
361                        dataPack[20 - 1] = 0xFF;
362                        dataPack[21 - 1] = 0x00;
363                        dataPack[22 - 1] = 0x00;
364            }
365
366            // dataPack 23-24: sum of mainline/Oppsite traffic data; need to be updated every 30 sec
367            loop.MlTotVol = 0;
368                    loop.OppTotVol = 0;
369                    dataPack[23 - 1] = loop.MlTotVol;
370                    dataPack[24 - 1] = loop.OppTotVol;
371
372                    // dataPack 25-26: BYTE 25 is fixed, i.e. 03; BYTE 26 is either 0xA2 or 0x84
373                    dataPack[25 - 1] = 0x03;
374                    dataPack[26 - 1] = 0x84;
375
376            return dataPack;
377        }
378
379        /**
380         * Getter for lines
381         * @return List of FEP_LINES
382         */
383        vector<FEP_LINE> NetworkReader::getLines() {
384
385            return lines;
386        }
387
388        /**
389         * Getter for stations
390         * @return List of LDS_LOOPs
391         */
392        vector<LDS_LOOP> NetworkReader::getStations() {
393
394            return stations;
395        }
396
397        NetworkReader::~NetworkReader() {
398
399        }
Note: See TracBrowser for help on using the repository browser.