📄 client.c
字号:
/* -*- Mode: C++ -*- *//* client.C * CMUnited99 (soccer client for Robocup99) * Peter Stone <pstone@cs.cmu.edu> * Computer Science Department * Carnegie Mellon University * Copyright (C) 1999 Peter Stone * * CMUnited-99 was created by Peter Stone, Patrick Riley, and Manuela Veloso * * You may copy and distribute this program freely as long as you retain this notice. * If you make any changes or have any comments we would appreciate a message. * For more information, please see http://www.cs.cmu.edu/~robosoccer/ */#include "client.h"#include "types.h"#include "netif.h"#include "Memory.h"#include "parse.h"#include "utils.h"#include "behave.h"void send_initialize_message();void parse_initialize_message(char *);Bool wait_for_signals(sigset_t *);sigset_t init_handler();void sigio_handler(); void sigalrm_handler();void send_action();void resend_last_action();/* Global variables -- don't want to reallocate buffers each time */sigset_t sigiomask, sigalrmask;//Memory Global_Mem;//Memory *const Mem = &Global_Mem;Memory *Mem;char recvbuf[MAXMESG]; char sendbuf[MAXMESG]; char *GLOBAL_sense_body_message = "(sense_body)";int alrsigs_since_iosig=0;/****************************************************************************************/main(int argc, char *argv[]){ Mem = new Memory(); if ( Mem == NULL ){ my_error("couldn't allocate Mem"); exit(0); } Mem->GetOptions(argc,argv); Socket sock = init_connection(Mem->SP_host,Mem->SP_port); Mem->sock = &sock; if(Mem->sock->socketfd == -1) { cerr << "Can't open connection for player" << endl; exit(-1); } send_initialize_message(); if ( wait_message(recvbuf, Mem->sock) == 0 ) my_error("wait_message failed"); parse_initialize_message(recvbuf); Mem->Initialize(); sigset_t sigfullmask = init_handler(); while ( Mem->ServerAlive == TRUE && wait_for_signals(&sigfullmask) ); if (Mem->sock->socketfd != -1) close_connection(Mem->sock); printf("Shutting down player %d\n",Mem->MyNumber);}/****************************************************************************************//****************************************************************************************//****************************************************************************************//* Send initialize message */void send_initialize_message(){ if (Mem->IP_reconnect) sprintf(sendbuf, "(reconnect %s %d)", Mem->MyTeamName, Mem->IP_reconnect); else if ( Mem->CP_goalie == TRUE && Mem->SP_version >= 4.00){ sprintf(sendbuf, "(init %s (version %.2f) (goalie))", Mem->MyTeamName, Mem->SP_version); } else sprintf(sendbuf, "(init %s (version %.2f))", Mem->MyTeamName, Mem->SP_version); if(send_message(sendbuf, Mem->sock) == -1) abort(); }/****************************************************************************************//* Parse initialize message */void parse_initialize_message(char *recvbuf){ char mode[100]; if ( !(strncmp(recvbuf,"(init",4)) ) { /* It's an init msg */ sscanf(recvbuf,"(init %c %d %[^)]",&Mem->MySide, &Mem->MyNumber, mode); Mem->ServerAlive = TRUE; } else if ( !(strncmp(recvbuf,"(reconnect",4)) ) { /* It's a reconnect msg */ sscanf(recvbuf,"(reconnect %c %[^)]",&Mem->MySide, mode); Mem->MyNumber = Mem->IP_reconnect; printf("reconnecting to %d on side %c!\n",Mem->MyNumber,Mem->MySide); Mem->ServerAlive = TRUE; } else { my_error("Didn't get an init message: '%s'",recvbuf); Mem->ServerAlive = FALSE; } if ( Mem->CP_goalie && Mem->FP_goalie_number != Mem->MyNumber ) my_error("goalie number inconsistent with me being goalie"); if ( !Mem->CP_goalie && Mem->FP_goalie_number == Mem->MyNumber ) my_error("I should be the goalie"); if ( mode[0] == 'b' ){ /* Before_kick_off */ Mem->SetPlayMode(PM_Before_Kick_Off); if ( Mem->MySide == 'l' ) Mem->KickOffMode = KO_Mine; else Mem->KickOffMode = KO_Theirs; } else /* Act as if the game's in progress */ Mem->SetPlayMode(PM_Play_On);}/****************************************************************************************//****************************************************************************************//****************************************************************************************//* set time interval between the sensor receiving and command sending */ inline void set_timer() { struct itimerval itv; itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = Mem->TimerInterval * 1000; itv.it_value.tv_sec = 0; itv.it_value.tv_usec = Mem->TimerInterval * 1000; setitimer(ITIMER_REAL, &itv, NULL);}inline void set_timer(int usec) { struct itimerval itv; itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = Mem->TimerInterval * 1000; itv.it_value.tv_sec = 0; itv.it_value.tv_usec = usec; setitimer(ITIMER_REAL, &itv, NULL);}/****************************************************************************************/sigset_t init_handler() { sigemptyset(&sigalrmask); sigaddset(&sigalrmask, SIGALRM); sigemptyset(&sigiomask); sigaddset(&sigiomask, SIGIO); struct sigaction sigact; sigact.sa_flags = 0; sigact.sa_mask = sigiomask;#ifdef Solaris sigact.sa_handler = (void (*)(int))sigalrm_handler; #else sigact.sa_handler = (void (*)(int))sigalrm_handler; #endif sigaction(SIGALRM, &sigact, NULL); sigact.sa_mask = sigalrmask;#ifdef Solaris sigact.sa_handler = (void (*)(int))sigio_handler; #else sigact.sa_handler = (void (*)(int))sigio_handler; #endif sigaction(SIGIO, &sigact, NULL); set_timer(); sigprocmask(SIG_UNBLOCK, &sigiomask, NULL); sigprocmask(SIG_UNBLOCK, &sigalrmask, NULL); sigset_t sigsetmask; sigprocmask(SIG_BLOCK, NULL, &sigsetmask); /* Get's the currently unblocked signals */ return sigsetmask; }/****************************************************************************************//* suspend the process until one of the signals comes through *//* could check for situation to kill client, return FALSE *//* i.e. too many actions with no sensory input coming in */Bool wait_for_signals(sigset_t *mask){ sigsuspend(mask); return TRUE;}/****************************************************************************************//* SIGIO handler: receive and parse messages from server */void sigio_handler() { sigprocmask(SIG_BLOCK, &sigalrmask, NULL); int counter = 0; Time StartTime = Mem->CurrentTime; while (receive_message(recvbuf, Mem->sock) == 1) { Parse(recvbuf); counter++; } if ( Mem->CurrentTime - StartTime > 1 && StartTime.s == 0 && Mem->CurrentTime.s == 0 ) my_error("Received several steps at once -- missing action ops!!! (%d %d)", StartTime.t,StartTime.s); sigprocmask(SIG_UNBLOCK, &sigalrmask, NULL); alrsigs_since_iosig=0; // if (counter>1) printf("Got %d messages\n",counter);}/****************************************************************************************//* SIGALRM handler: extract and send first command in commandlist */void sigalrm_handler() { sigprocmask(SIG_BLOCK, &sigiomask, NULL); if ( Mem->LastInterruptTime != Mem->CurrentTime ){ if ( !Mem->ClockStopped && Mem->CurrentTime-1 != Mem->LastInterruptTime ) my_error("Missed a cycle??"); if ( !Mem->ClockStopped && Mem->InterruptsThisCycle < Mem->CP_interrupts_per_cycle-1 ) my_error("Only %d interrupts last cycle",Mem->InterruptsThisCycle); Mem->LastInterruptTime = Mem->CurrentTime; Mem->InterruptsThisCycle = 0; //cout << endl; } Mem->InterruptsThisCycle++; //cout << "."; /* Don't act until near the end of a cycle */ /* there's some leeway in case there aren't enough interrupts in the cycle */ if ( !Mem->ClockStopped && Mem->CP_interrupts_per_cycle - Mem->InterruptsThisCycle > Mem->CP_interrupts_left_to_act) return; if (Mem->ClockStopped) Mem->StoppedClockMSec += Mem->TimerInterval; if (alrsigs_since_iosig++ > Mem->CP_interrupts_per_cycle * 20){ Mem->ServerAlive = FALSE; return; } /* If a sight is definitely coming every cycle, don't act until getting the sight */ /* Don't wait if we're in transition to a longer sight interval */ if ( Mem->MySightInterval() < Mem->SP_simulator_step && Mem->LastSightTime < Mem->CurrentTime && !((Mem->ChangeView.valid() || Mem->ChangeView.valid(Mem->CurrentTime-1)) && (Mem->ChangeView.width > Mem->ViewWidth || Mem->ChangeView.qual > Mem->ViewQuality)) ) { Mem->LogAction4(200,"Waiting for sight... (%d %d)", Mem->ChangeView.valid(),Mem->ChangeView.valid(Mem->CurrentTime-1)); return; } if ( Mem->CurrentTime > Mem->LastActionOpTime ){ if ( !Mem->ClockStopped && Mem->CurrentTime-1 != Mem->LastActionOpTime && Mem->LastActionOpTime != 0 ) my_error("Missed a cycle!! (%d %d)",Mem->LastActionOpTime.t,Mem->LastActionOpTime.s); if ( Mem->NewSight ) Mem->FirstActionOpSinceLastSight = TRUE;/*if ( 0 && Mem->MyCurrentFormationType() != FT_433 ){ my_error("?? pre-update %d\n"); dump_core("dump"); }*/ Mem->update(); behave();/*if ( 0 && Mem->MyCurrentFormationType() != FT_433 ){ my_error("?? post-behave %d\n"); dump_core("dump"); }*/ Mem->LastActionOpTime = Mem->CurrentTime; Mem->FirstActionOpSinceLastSight = FALSE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -