source: tmcsimulator/branches/FEPSimulator/DataPacker.cpp @ 202

Revision 202, 8.7 KB checked in by jtorres, 9 years ago (diff)

Further progress on condensed format reader, not all green dots showing

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