#include "NetworkReader.h" // Constructor NetworkReader::NetworkReader(string networkFile) { this->networkFile = networkFile; } // determine if a loop has data based on lane config data bool NetworkReader::DataAvail(char flag, int num) { int mag, fel; // find mask value if (num == 1) mag = 0x01; else if (num == 2) mag = 0x02; else if (num == 3) mag = 0x04; else if (num == 4) mag = 0x08; else if (num == 5) mag = 0x10; else if (num == 6) mag = 0x20; else if (num == 7) mag = 0x40; else if (num == 8) mag = 0x80; fel = flag & mag; fel = fel >> (num - 1); if (fel == 1) return true; else return false; } // Initializes the LDS_LOOP dataPack with all necessary static data and default dynamic data unsigned char * NetworkReader::msgDataPack(LDS_LOOP loop) { int j; // Allocate memory for dataPack unsigned char *dataPack = (unsigned char *) malloc(sizeof(unsigned char) * loop.length); // dataPack 5-8: lane config char d5 = 0, d6 = 0, d7 = 0, d8 = 0; for (j = 0; j < loop.num; j++) { for (int k = 0; k < 8; k++) { if (strcmp(loop.loop_loc[j], dp5[k]) == 0) d5 += pow(2, k); if (strcmp(loop.loop_loc[j], dp6[k]) == 0) d6 += pow(2, k); if (strcmp(loop.loop_loc[j], dp7[k]) == 0) d7 += pow(2, k); if (strcmp(loop.loop_loc[j], dp8[k]) == 0) d8 += pow(2, k); } } dataPack[5-1] = d5; dataPack[6-1] = d6; dataPack[7-1] = d7; dataPack[8-1] = d8; // dataPack 1: Drop number, i.e. station address dataPack[1-1] = loop.drop; // dataPack2 (2 bytes per loop) dataPack[2-1] = loop.num * 2 + Fixed_Byte_To_Checksum; // dataPacket 3 (lowbyte: # of mainline loops, highbyte: # of opposite loops) int low = 0, high = 0; for (j = 1; j <= 6; j++) { low += DataAvail(dataPack[5-1], j); high += DataAvail(dataPack[6-1], j); } high = high << 4; dataPack[3-1] = high | low; // dataPack4 (Miscl. flags: samples are: 80, A0, E0, 00) dataPack[4-1] = 0xA0; // dataPack 9: initialized as 00 (meaning no metering); need to be updated every 30 sec dataPack[9-1] = 0; // datadataPack 10-13: lane malfunction? Assuming all functional dataPack[10-1] = 0; dataPack[11-1] = 0; dataPack[12-1] = 0; dataPack[13-1] = 0; // dataPack 14-22: ramp metering data // BYTE 16 and 22 need to be updated every 30 sec bool found = false; for (j = 0; j < loop.num; j++) { if (strcmp(loop.loop_loc[j], "DEMAND") == 0) { found = true; break; } } if (found) { // BYTE 14: mostly 07, some are 05, 03, 00 dataPack[14-1] = 0x07; // mostly 06(TOD table 1); some are 0B (No metering) or 05(traffic responsive) dataPack[15-1] = 0x06; // most 00, some are 01 (queue override) or 80(Meter ON sign) dataPack[16-1] = 0x00; // Field Manual Rate dataPack[17-1] = 0xFF; // TOC Manual Rate dataPack[18-1] = 0xFF; // PSO Manual Rate dataPack[19-1] = 0xFF; // CORM Rate dataPack[20-1] = 0xFF; // Local Responsive Rate. DON'T UNDERSTAND YET dataPack[21-1] = 0x00; // TOD Rate: need to query RAMP plugin! dataPack[22-1] = 0x00; } // LDS: NO Metering else { dataPack[14-1] = 0x00; dataPack[15-1] = 0x0B; dataPack[16-1] = 0x00; dataPack[17-1] = 0xFF; dataPack[18-1] = 0xFF; dataPack[19-1] = 0xFF; dataPack[20-1] = 0xFF; dataPack[21-1] = 0x00; dataPack[22-1] = 0x00; } // dataPack 23-24: sum of mainline/Oppsite traffic data; need to be updated every 30 sec loop.MlTotVol = 0; loop.OppTotVol = 0; dataPack[23-1] = loop.MlTotVol; dataPack[24-1] = loop.OppTotVol; // dataPack 25-26: BYTE 25 is fixed, i.e. 03; BYTE 26 is either 0xA2 or 0x84 dataPack[25-1] = 0x03; dataPack[26-1] = 0x84; /* printf("lds=%d (%d), p1=%2X, p2=%2X, p3=%2X, p5=%2X, p6=%X, p7=%X, p8=%2X\n", loop.lds, loop.length, dataPack[1-1], dataPack[2-1], dataPack[3-1], dataPack[5-1], dataPack[6-1], dataPack[7-1], dataPack[8-1]); */ return dataPack; } // TEST DATA // lds_id line drop sch lineinfo system_key sch_seq glo_seq count freeway Dir ca_pm lds_name // 1208926 29 4 28 28 1123006080 26480 1357609 13 73 S 23.7 MACARTHUR 1 vector NetworkReader::getLines() { vector lines; FEP_LINE line; line.lineNum = 29; line.lds.push_back(1208926); line.ldsIndex.push_back(0); line.ldsNum = 1; line.count = 13; line.schedule = 28; line.globalSeq = 1357609; line.schedleSeq = 26480; lines.push_back(line); return lines; } // TEST DATA //FWY Dir POSTMI LDS_ID VDS_ID LOOP_ID LOC LANE LOOP_LOC PARAMICS_NAME PARAMICS_LANE //73 S 23.7 1208926 1210494 1210490 ML 1 ML_1 ? 0 //73 S 23.7 1208926 1210494 1210492 ML 2 ML_2 ? 0 //73 S 23.7 1208926 1210494 1210493 ML 3 ML_3 ? 0 //73 S 23.7 1208926 1210770 1210769 OR 1 RAMP_ON ? 0 vector NetworkReader::getLoops() { /* Read loop meta data */ vector lds_map; LDS_LOOP loop; loop.lds = 1208926; loop.line_num = 29; loop.drop = 4; loop.num = 4; // Loop ids long *loopIDs = (long *) calloc(sizeof(long), loop.num); loopIDs[0] = 1210490; loopIDs[1] = 1210492; loopIDs[2] = 1210493; loopIDs[3] = 1210769; loop.loopID = loopIDs; // Loop locations char *one = "ML_1"; char *two = "ML_2"; char *three = "ML_3"; char *four = "RAMP_ON"; char **loc = (char **) calloc(sizeof(char *), loop.num); loc[0] = one; loc[1] = two; loc[2] = three; loc[3] = four; loop.loop_loc = loc; // Data pack ATMS message loop.length = loop.num * 2 + CONTROL_DATA_LEN; loop.dataPack = msgDataPack(loop); loop.pos = 0; loop.MlTotVol = 0; loop.OppTotVol = 0; lds_map.push_back(loop); return lds_map; }