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

Revision 141, 8.7 KB checked in by jdalbey, 9 years ago (diff)

FEPSim.cpp Removed 'Adding' msg. Added 'Verify network connection' in client failed error msg.

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