bool Protocol::accely(int idx, double val){ //Set the desired accelaration in x axis to the specified value in hovertank mode. char char_buff[20]; sprintf(char_buff, "accely %d %f", idx, val); sendLine(char_buff); readAck(); return readBool(); }
bool Protocol::speed(int idx, double val){ //Set the desired speed to the specified value. char char_buff[20]; sprintf(char_buff, "speed %d %f", idx, val); sendLine(char_buff); readAck(); return readBool(); }
bool Protocol::angvel(int idx, double val){ //Set the desired angular velocity to the specified value. char char_buff[20]; sprintf(char_buff, "angvel %d %f", idx, val); sendLine(char_buff); readAck(); return readBool(); }
//Tank commands bool Protocol::shoot(int idx){ //Perform a shoot request. char char_buff[20]; sprintf(char_buff, "shoot %d", idx); sendLine(char_buff); readAck(); return readBool(); }
int sendCommand(int fd, unsigned cmd) { unsigned char data[2]; data[0] = cmd; data[1] = cmd ^ 0xFF; if (write(fd, data, 2) != 2) return -1; if (readAck(fd)) return -1; return 0; }
int eraseFlash(int fd) { unsigned data[2] = { 0xFF, 0x00 }; if (sendCommand(fd, 0x43)) return -1; if (write(fd, data, 2) != 2) return -1; if (readAck(fd)) return -1; return 0; }
int sendLength(int fd, unsigned len) { unsigned char data[2]; if ((len < 1) || (len > 256)) return -1; len--; data[0] = len; data[1] = len ^ 0xFF; if (write(fd, data, 2) != 2) return -1; if (readAck(fd)) return -1; return 0; }
int sendAddress(int fd, unsigned addr) { unsigned char data[5]; data[0] = addr >> 24; data[1] = addr >> 16; data[2] = addr >> 8; data[3] = addr; data[4] = data[0] ^ data[1] ^ data[2] ^ data[3]; if (write(fd, data, 5) != 5) return -1; if (readAck(fd)) return -1; return 0; }
int sendData(int fd, void *ptr, unsigned len) { unsigned char x; unsigned char check; unsigned char *data = ptr; unsigned n; if ((len < 1) || (len > 256)) return -1; check = x = (len - 1); for (n = 0; n < len; n++) { check ^= data[n]; } if (write(fd, &x, 1) != 1) return -1; if (write(fd, data, len) != len) return -1; if (write(fd, &check, 1) != 1) return -1; if (readAck(fd)) return -1; return 0; }
bool Protocol::updateGrid(Board &board){ //Update not needed if (board.gc.usegrid && !board.grid->isStable()) return true; vector<string> v; for (int i=0; i < board.tanks.size(); i++){ //Would it be worth it to get a grid value here? if (board.tanks[i]->mode == DEAD) continue; int posx = board.tanks[i]->pos[0]; int posy = board.tanks[i]->pos[1]; if (board.grid->isStable(posx, posy)) continue; //Get grid for a single tank char char_buff[13]; sprintf(char_buff, "occgrid %d", i); sendLine(char_buff); readAck(); v = readArr(); if (v.at(0) != "begin") return false; //Get occgrid dimensions v = readArr(); int rx, ry, rw, rh; if (sscanf(v.at(1).c_str(), "%d,%d", &rx, &ry) != 2) return false; v = readArr(); if (sscanf(v.at(1).c_str(), "%dx%d", &rw, &rh) != 2) return false; int half = (int) (board.gc.worldsize/2.0); ry += half; rx += half; //Read raw values into buffer for (int x=0; x<rw; x++){ v = readArr(); string& occ = v.at(0); if (occ.size() != rh) return false; for (int y=0; y<rh; y++) board.grid->buffer[x*rh+y] = occ[y] == '1'; } //Blur the buffer int radius = OCC_BLUR; int diam = radius*2+1; int half_cells = diam*diam/2; diam--; //Sum vertically for (int x=0; x<rw; x++){ int v=0, y=0; //We only use border cells for averaging for (; y<diam; y++) v += board.grid->buffer[x*rh+y]; //Swap out old value with the sum for (; y<rh; y++){ v += board.grid->buffer[x*rh+y]; int t = board.grid->buffer[x*rh+y-radius]; board.grid->buffer[x*rh+y-radius] = v; v -= t; } } //Sum horizontally for (int y=radius; y<rh-radius; y++){ int v=0, x=0; //Skip border cells, like before for (; x<diam; x++) v += board.grid->buffer[x*rh+y]; for (; x<rw; x++){ v += board.grid->buffer[x*rh+y]; //Update cell with blurred value board.grid->updateCell(ry+y, rx+x, v > half_cells); v -= board.grid->buffer[(x-radius)*rh+y]; } } //End occgrid command v = readArr(); if (v.at(0) != "end") return false; } return true; }
//Fetch information bool Protocol::updateBoard(double delta_t, Board &board){ //Update tank positions sendLine("mytanks"); readAck(); vector<string> v = readArr(); if (v.at(0) != "begin") return false; v.clear(); v = readArr(); vector<AbstractTank*>::iterator tank_iter = board.tanks.begin(); while(v.at(0) == "mytank"){ //Update alive/dead status bool alive = v.at(3) == board.gc.tankalive; if (alive){ //Used to be dead; needs to be assigned a goal if ((*tank_iter)->mode == DEAD) (*tank_iter)->mode = IDLE; //Update dynamics (*tank_iter)->updateDynamics( delta_t, atof(v.at(7).c_str()), atof(v.at(8).c_str()), atof(v.at(9).c_str()) ); /* REPLACED BY KALMAN FILTER //Update velocities (*tank_iter)->vel_linear = Vector2d( atof(v.at(10).c_str()), atof(v.at(11).c_str()) ); (*tank_iter)->vel_angular = atof(v.at(12).c_str()); */ //MyTank.shots_avail=atoi(v.at(4).c_str()); //MyTank.time_to_reload=atof(v.at(5).c_str()); //MyTank.flag=v.at(6); } else (*tank_iter)->mode = DEAD; tank_iter++; v.clear(); v=readArr(); } if (v.at(0) != "end") return false; //Update enemy tanks sendLine("othertanks"); readAck(); v = readArr(); if (v.at(0) != "begin") return false; v.clear(); v = readArr(); tank_iter = board.enemy_tanks.begin(); while (v.at(0) == "othertank"){ //Update alive/dead status bool alive = v.at(3) == board.gc.tankalive; (*tank_iter)->mode = alive ? IDLE : DEAD; if (alive){ //Update dynamics (*tank_iter)->updateDynamics( delta_t, atof(v.at(5).c_str()), atof(v.at(6).c_str()), atof(v.at(7).c_str()) ); } //OtherTank.flag=v.at(4); tank_iter++; v.clear(); v = readArr(); } if (v.at(0) != "end") return false; //Update flag positions and possession sendLine("flags"); readAck(); v = readArr(); if (v.at(0) != "begin") return false; v.clear(); v = readArr(); vector<Flag*>::iterator flags_iter = board.flags.begin(); vector<Flag*>::iterator enemy_flags_iter = board.enemy_flags.begin(); while (v.at(0) == "flag"){ Vector2d pos = Vector2d( atof(v.at(3).c_str()), atof(v.at(4).c_str()) ); bool isPossessed = v.at(2) != "none"; bool havePosession = v.at(2) == board.gc.mycolor; //vector<Flag*>::iterator &ref = v.at(1) == gc.mycolor ? flags_iter : enemy_flags_iter; if (v.at(1) == board.gc.mycolor){ (*flags_iter)->loc = pos; (*flags_iter)->isPossessed = isPossessed; (*flags_iter)->havePosession = havePosession; flags_iter++; } else{ (*enemy_flags_iter)->loc = pos; (*enemy_flags_iter)->isPossessed = isPossessed; (*enemy_flags_iter)->havePosession = havePosession; enemy_flags_iter++; } v.clear(); v = readArr(); } if (v.at(0) != "end") return false; //Hooray, there were no errors! return true; }
int main(int argc, char**argv){ struct addrinfo hints, *result; int sock; if (argc < 3) { fprintf(stderr, "Usage: %s port filename\n", argv[0]); exit(EXIT_FAILURE); } file_path = argv[2]; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; if(getaddrinfo(NULL, argv[1], &hints, &result)==-1){ perror("getaddrinfo"); exit(EXIT_FAILURE); } sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if(sock == -1){ perror("socket creation"); exit(EXIT_FAILURE); } if(bind(sock,(struct sockaddr *) result->ai_addr, sin6len)==-1){ perror("bind"); exit(EXIT_FAILURE); } if(readsync(sock)==-1){ perror("Sync error on reading sync"); exit(EXIT_FAILURE); } if(sendMsg(sock, PTYPE_SYN, 0, 0) ==-1){ perror("Sync error on first send"); exit(EXIT_FAILURE); } if(sendMsg(sock, PTYPE_ACK, 0, 0) ==-1){ perror("Sync error on first ack"); exit(EXIT_FAILURE); } if(readAck(sock)== -1){ perror("Acknoledgement reading"); exit(EXIT_FAILURE); } if(receiveFile(sock)==-1){ perror("Error while receiving file"); exit(EXIT_FAILURE); } freeaddrinfo(result); close(sock); exit(EXIT_SUCCESS); }