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

source: tmcsimulator/branches/WorkingFEPSimulator/DataPacker.cpp @ 107

Revision 107, 7.7 KB checked in by jtorres, 9 years ago (diff)

Added branches/WorkingFEPSimulator: hopefully working, that is

RevLine 
1#include "DataPacker.h";
2
3unsigned char * DataPacker::msg;
4
5unsigned char * DataPacker::packData(STATION *station) {
6    int pos = 26;
7    DataPacker packer;
8    msg = packer.staticDataPack(station);
9    pos = packer.dynamicDataPack(station, 5, pos);   
10    pos = packer.dynamicDataPack(station, 6, pos);
11    pos = packer.dynamicDataPack(station, 7, pos);
12    pos = packer.dynamicDataPack(station, 8, pos);
13    // Update data for BYTE 9, 16, 21, 22, 23, 24
14
15    // what is the current metering rate?
16    // check each LDS, if there is demand detector, the downstream node the
17    // ldsMap[i].dataPack[22-1] = ldsMap[i].dataPack[9-1] = ;
18
19    // will need to check if queue override is enabled (Currently, no queue
20    // ldsMap[i].dataPack[16-1] = ;
21
22    // byte 23: MAINLINE total volume
23    msg[23 - 1] = station->MlTotVol;
24
25    // byte 24: opposite total volume
26    msg[24 - 1] = station->OppTotVol;
27
28    // last BYTE: checksum
29    msg[station->length - 1] =
30            packer.chksum(msg, station->length - 1 - 1);
31   
32    /*
33    for (int j = 0; j < station->length; j++) {
34        printf("%02X", msg[j]);
35    }
36    printf("\n");
37    */
38}
39
40int DataPacker::dynamicDataPack(STATION *station, int packNo, int pos) {
41    int i, j, vol, occ, haveData;
42    //used for data byte 23 and 24
43    station->MlTotVol = 0;
44    station->OppTotVol = 0;
45
46    for (j = 1; j <= 8; j++) {
47       
48        if (DataAvail(msg[packNo - 1], j)) {
49            // loop at bit j has data
50            for (int lane = 0; lane < station->loops.size(); lane++) {
51                // what's the corresponding loop of bit j
52                char * currLoopLoc = station->loops.at(lane)->loop_loc;
53                if (packNo == 5)
54                    haveData = strcmp(currLoopLoc, dp5[j - 1]);
55                else if (packNo == 6)
56                    haveData = strcmp(currLoopLoc, dp6[j - 1]);
57                else if (packNo == 7)
58                    haveData = strcmp(currLoopLoc, dp7[j - 1]);
59                else if (packNo == 8)
60                    haveData = strcmp(currLoopLoc, dp8[j - 1]);
61                else
62                    return -1;
63
64                if (haveData == 0) {
65                    LOOP *currLoop = station->loops.at(lane);
66                    vol = currLoop->vol;
67                    occ = (int) (currLoop->occ * 900 + 0.5);
68
69                    VOLOCC packedVOLOCC = packVOLOCC(vol, occ);
70                    pos++;
71                    msg[pos - 1] = packedVOLOCC.high;
72                    pos++;
73                    msg[pos - 1] = packedVOLOCC.low;
74
75                    if (packNo == 5) {
76                        station->MlTotVol += vol;
77                    } else if (packNo == 6) {
78                        station->OppTotVol += vol;
79                    }
80                }
81            }
82        }
83    }
84    return pos;
85}
86
87unsigned char * DataPacker::staticDataPack(STATION *station) {
88    int j;
89    // Allocate memory for dataPack
90    unsigned char *dataPack = (unsigned char *) calloc(sizeof(unsigned char), station->length);
91
92    // dataPack 5-8: lane config
93    char d5 = 0, d6 = 0, d7 = 0, d8 = 0;
94    for (j = 0; j < station->loops.size(); j++) {
95        for (int k = 0; k < 8; k++) {
96            char * currLoopLoc = station->loops.at(j)->loop_loc;
97            if (strcmp(currLoopLoc, dp5[k]) == 0)
98                d5 += pow(2, k);
99            if (strcmp(currLoopLoc, dp6[k]) == 0)
100                d6 += pow(2, k);
101            if (strcmp(currLoopLoc, dp7[k]) == 0)
102                d7 += pow(2, k);
103            if (strcmp(currLoopLoc, dp8[k]) == 0)
104                d8 += pow(2, k);
105        }
106    }
107    dataPack[5 - 1] = d5;
108    dataPack[6 - 1] = d6;
109    dataPack[7 - 1] = d7;
110    dataPack[8 - 1] = d8;
111
112    // dataPack 1: Drop number, i.e. station address
113    dataPack[1 - 1] = station->drop;
114    // dataPack2 (2 bytes per loop)
115    dataPack[2 - 1] = station->loops.size() * 2 + Fixed_Byte_To_Checksum;
116
117    // dataPacket 3 (lowbyte: # of mainline loops, highbyte: # of opposite loops)
118    int low = 0, high = 0;
119    for (j = 1; j <= 6; j++) {
120        low += DataAvail(dataPack[5 - 1], j);
121        high += DataAvail(dataPack[6 - 1], j);
122    }
123    high = high << 4;
124    dataPack[3 - 1] = high | low;
125
126    // dataPack4 (Miscl. flags: samples are: 80, A0, E0, 00)
127    dataPack[4 - 1] = 0xA0;
128
129    // dataPack 9: initialized as 00 (meaning no metering); need to be updated every 30 sec
130    dataPack[9 - 1] = 0;
131
132    // datadataPack 10-13: lane malfunction? Assuming all functional
133    dataPack[10 - 1] = 0;
134    dataPack[11 - 1] = 0;
135    dataPack[12 - 1] = 0;
136    dataPack[13 - 1] = 0;
137
138    // dataPack 14-22: ramp metering data
139    // BYTE 16 and 22 need to be updated every 30 sec
140    bool found = false;
141    for (j = 0; j < station->loops.size(); j++) {
142        if (strcmp(station->loops.at(j)->loop_loc, "DEMAND") == 0) {
143            found = true;
144            break;
145        }
146    }
147    if (found) {
148        // BYTE 14: mostly 07, some are 05, 03, 00
149        dataPack[14 - 1] = 0x07;
150        // mostly 06(TOD table 1); some are 0B (No metering) or 05(traffic responsive)
151        dataPack[15 - 1] = 0x06;
152        // most 00, some are 01 (queue override) or 80(Meter ON sign)
153        dataPack[16 - 1] = 0x00;
154        // Field Manual Rate
155        dataPack[17 - 1] = 0xFF;
156        // TOC Manual Rate
157        dataPack[18 - 1] = 0xFF;
158        // PSO Manual Rate
159        dataPack[19 - 1] = 0xFF;
160        // CORM Rate
161        dataPack[20 - 1] = 0xFF;
162        // Local Responsive Rate. DON'T UNDERSTAND YET
163        dataPack[21 - 1] = 0x00;
164        // TOD Rate: need to query RAMP plugin!
165        dataPack[22 - 1] = 0x00;
166    }// LDS: NO Metering
167    else {
168        dataPack[14 - 1] = 0x00;
169        dataPack[15 - 1] = 0x0B;
170        dataPack[16 - 1] = 0x00;
171        dataPack[17 - 1] = 0xFF;
172        dataPack[18 - 1] = 0xFF;
173        dataPack[19 - 1] = 0xFF;
174        dataPack[20 - 1] = 0xFF;
175        dataPack[21 - 1] = 0x00;
176        dataPack[22 - 1] = 0x00;
177    }
178
179    // dataPack 23-24: sum of mainline/Opp traffic data; need to be updated every 30 sec
180    station->MlTotVol = 0;
181    station->OppTotVol = 0;
182    dataPack[23 - 1] = station->MlTotVol;
183    dataPack[24 - 1] = station->OppTotVol;
184
185    // dataPack 25-26: BYTE 25 is fixed, i.e. 03; BYTE 26 is either 0xA2 or 0x84
186    dataPack[25 - 1] = 0x03;
187    dataPack[26 - 1] = 0x84;
188
189    return dataPack;
190}
191
192bool DataPacker::DataAvail(char flag, int num) {
193    int mag, fel;
194
195    // find mask value
196    if (num == 1)
197        mag = 0x01;
198    else if (num == 2)
199        mag = 0x02;
200    else if (num == 3)
201        mag = 0x04;
202    else if (num == 4)
203        mag = 0x08;
204    else if (num == 5)
205        mag = 0x10;
206    else if (num == 6)
207        mag = 0x20;
208    else if (num == 7)
209        mag = 0x40;
210    else if (num == 8)
211        mag = 0x80;
212
213    fel = flag & mag;
214    fel = fel >> (num - 1);
215
216    if (fel == 1)
217        return true;
218    else
219        return false;
220}
221
222// checksum based on data from byte 1 (after 0DOA) to the second last byte (the
223char DataPacker::chksum(unsigned char *dataptr, int len) {
224    int i;
225    unsigned char checksum = 0;
226
227    for (i = 0; i < len; i++)
228        checksum += dataptr[i];
229
230    return checksum;
231}
232
233// convert vol and occ data to a two-byte data packet
234VOLOCC DataPacker::packVOLOCC(int vol, int occ)
235{
236   int bit, i;
237   int   high, low; 
238   int high_high = 0, high_low = 0;
239   VOLOCC com;
240   
241   // occ data: 10 bits
242   low = 0;
243   for (i=9; i>=0; i--) 
244   {
245      if (i >= 8)
246      {
247         bit = ((occ >> i) & 1);
248         high_low += pow(2, (i - 8)) * bit; 
249      }
250      // lower byte
251      else
252      {
253         bit = ((occ >> i) & 1);
254         low += pow(2, i) * bit;
255      }
256   }
257
258   // vol: 6 bits (1. vol, shift to the left for two times; 2. combine data)
259   high_high = vol << 2;
260   high = high_high | high_low;
261
262   com.high = high;
263   com.low = low;
264
265   return com;
266}
Note: See TracBrowser for help on using the repository browser.