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

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

Revision 233, 9.6 KB checked in by jtorres, 8 years ago (diff)

FEPSim: finalized comments, added to both header and source files.

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