SPYSpheres
|
This class defines the hidden game implementation. More...
#include <ZRGameInternal.h>
Classes | |
struct | Camera |
struct | ChallengeInfo |
struct | Light |
struct | OtherInfo |
struct | Picture |
struct | PlayerInfo |
(Required) Runs initialization fo the ZR game at the start of a test. More... | |
Public Member Functions | |
void | init (void) |
bool | update (float forceTorqueOut[6]) |
(Required) Runs an update of the game rules and calls the user function loop(). | |
bool | updateGameModeManeuver (float forceTorqueOut[6]) |
bool | updateGameOverManeuver (float forceTorqueOut[6], unsigned char &finalScore) |
void | updateStates () |
bool | enforceBoundaries (float forceTorque[6]) |
(Required) Called on every gspControl control cycle. | |
void | limitDirection (state_vector ctrlState, float ctrlControl[6], unsigned int idx, float dir) |
Limits the direction in which the programmed SPHERE can travel and slows down the velocity if it travels in the direction of the limit. | |
void | sendDebug (void) |
(Required) Called on every gspControl control cycle, It should be used to send debug and telemetry information to the ground. | |
void | sendInit (void) |
for Corona SPHERES: sends POI & Solar Flare info to Sat 2 at start of game | |
void | processRXData (default_rfm_packet packet) |
(Required) Processes SPHERES telemetry data | |
void | breakTie () |
void | modify2DForceTorque (float forceTorque[6]) |
void | resolveCollision (float zrState[12], float forceTorqueOut[6]) |
float | dist3d (float *pos1, float *pos2) const |
bool | photoBomb (float zrState[12], float poiLoc[3]) |
void | initItems () |
float | randomizeStartingLocs (int itemID, int coord) |
bool | itemPickUp (int objectNum) |
void | initCamera () |
void | disableCamera () |
void | activateCamera () |
void | memoryLoss () |
bool | isFacingPos (float position[]) |
bool | isFacingOther () |
bool | isFacingEarth () |
float | takePicImpl () |
Returns the score value of the picture, or 0 if taking the picture failed. | |
float | picPointsImpl () |
void | resetPicsTaken () |
int | sphereInSwitchingArea (float position[]) |
int | sphereInMovingArea (float position[]) |
bool | sphereInLight (float position[]) |
bool | sphereInDark (float position[]) |
void | switchLightDirection () |
void | initLight () |
void | updateLight () |
void | initEnergy () |
void | updateEnergy () |
bool | tryToUseEnergy (float amount) |
ZeroRoboticsGameImpl (ZeroRoboticsAPIImpl &apiImpl) | |
Constructor for binding an API implementation. | |
Static Public Member Functions | |
static ZeroRoboticsGameImpl & | instance () |
Retrieves singleton instance of the game implementation. | |
Public Attributes | |
ChallengeInfo | challInfo |
ZeroRoboticsAPIImpl & | apiImpl |
Reference to ZR API instance. | |
ZeroRoboticsGame * | game |
Back pointer to the game instance. | |
Static Public Attributes | |
static const state_vector | initState |
(Required) Initial state where the satellite is initialized. |
This class defines the hidden game implementation.
Any internal utility functions or game ru//les functsions hould be put here. You may also override any of the standard GSP functions by implementing them here. The functions init(), update(), and sendDebug() are required.
Definition at line 25 of file ZRGameInternal.h.
ZeroRoboticsGameImpl::ZeroRoboticsGameImpl | ( | ZeroRoboticsAPIImpl & | apiImpl | ) |
Constructor for binding an API implementation.
Definition at line 56 of file ZRGameInternal.cpp.
void ZeroRoboticsGameImpl::activateCamera | ( | ) |
void ZeroRoboticsGameImpl::breakTie | ( | ) |
void ZeroRoboticsGameImpl::disableCamera | ( | ) |
Definition at line 21 of file ZRCamera.cpp.
float ZeroRoboticsGameImpl::dist3d | ( | float * | pos1, |
float * | pos2 | ||
) | const |
Definition at line 428 of file ZRGameInternal.cpp.
{ float tmpVec[3]; mathVecSubtract(tmpVec,static_cast<float*>(pos1),static_cast<float*>(pos2),3); return mathVecMagnitude(tmpVec,3); }
bool ZeroRoboticsGameImpl::enforceBoundaries | ( | float | forceTorque[6] | ) |
(Required) Called on every gspControl control cycle.
It should be used to send debug and telemetry information to the ground.
Definition at line 383 of file ZRGameInternal.cpp.
{ state_vector sphState; apiImpl.api->getMySphState(sphState); bool retValue = false; //Run velocity controller to stop motion out of volume //Zero out any controls that are leading the user out of the volume for (int i=0; i<3; i++) { if (sphState[POS_X+i] > limits[i]) { limitDirection(sphState, forceTorqueOut, i, 1.0f); retValue = true; } else if (sphState[POS_X+i] < -limits[i]) { limitDirection(sphState, forceTorqueOut, i, -1.0f); retValue = true; } } return retValue; }
void ZeroRoboticsGameImpl::init | ( | void | ) |
Definition at line 70 of file ZRGameInternal.cpp.
{ /* Game Initialization setup. * Then set the locations of the memory packs. */ apiImpl.gameTime = GAME_TIME; memset(&challInfo,0,sizeof(ChallengeInfo)); // general clear of challInfo to 0 = false = empty // update the state data on challInfo updateStates(); challInfo.me.score = START_SCORE; // Lights, Camera, Action! initLight(); initCamera(); initEnergy(); initItems(); // send information to ground and sat2 at the end of init sendDebug(); }
void ZeroRoboticsGameImpl::initCamera | ( | ) |
Definition at line 13 of file ZRCamera.cpp.
{ challInfo.camera.memoryFilled = 0; challInfo.camera.memorySize = CAMERA_DEFAULT_MEMORY; challInfo.camera.cameraOn = true; challInfo.camera.cameraBlocked = false; }
void ZeroRoboticsGameImpl::initEnergy | ( | ) |
Definition at line 33 of file ZREnergy.cpp.
{ challInfo.me.energy = STARTING_ENERGY; }
void ZeroRoboticsGameImpl::initItems | ( | ) |
Definition at line 15 of file ZRItems.cpp.
{ #ifndef ALLIANCE for(int i = 0; i<NUM_ITEMS; i++) { challInfo.me.mpTime[i] = MP_EMPTY; challInfo.other.mpTime[i] = MP_EMPTY; for(int j = 0; j<3; j++) challInfo.mpLoc[i][j] = ITEM_LOC[i][j]; } #else float r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[0][0] = r * 0.25f + 0.05; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[0][1] = r * 0.3f; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[0][2] = r * 0.5f; challInfo.mpLoc[1][0] = -challInfo.mpLoc[0][0]; challInfo.mpLoc[1][1] = challInfo.mpLoc[0][1]; challInfo.mpLoc[1][2] = challInfo.mpLoc[0][2]; challInfo.mpLoc[2][0] = 0.0f; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[2][1] = r * 0.3f; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[2][2] = r * 0.5f; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[3][0] = r * 0.25f + 0.05f; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[3][1] = r * 0.2f + 0.4; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[3][2] = r - 0.5f; challInfo.mpLoc[4][0] = -challInfo.mpLoc[3][0]; challInfo.mpLoc[4][1] = challInfo.mpLoc[3][1]; challInfo.mpLoc[4][2] = challInfo.mpLoc[3][2]; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[5][0] = r * 0.25f + 0.05f; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[5][1] = r * 0.2f + 0.4; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[5][2] = r - 0.5f; challInfo.mpLoc[6][0] = -challInfo.mpLoc[5][0]; challInfo.mpLoc[6][1] = challInfo.mpLoc[5][1]; challInfo.mpLoc[6][2] = challInfo.mpLoc[5][2]; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[7][0] = r * 0.2f + 0.3; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[7][1] = r * 0.3f; r = (float) (rand() % 10000) / (10000.0); challInfo.mpLoc[7][2] = r * 0.2f - 0.5f; challInfo.mpLoc[8][0] = -challInfo.mpLoc[7][0]; challInfo.mpLoc[8][1] = challInfo.mpLoc[7][1]; challInfo.mpLoc[8][2] = challInfo.mpLoc[7][2]; for(int i = 0; i<NUM_ITEMS; i++) { challInfo.me.mpTime[i] = MP_EMPTY; challInfo.other.mpTime[i] = MP_EMPTY; //printf("Item %d at (%f,%f,%f)\n", i, challInfo.mpLoc[i][0], challInfo.mpLoc[i][1], challInfo.mpLoc[i][2]); } #endif challInfo.me.mirrors = STARTING_MIRRORS; challInfo.me.mirrorTime = 0; challInfo.other.mirrorTime = 0; }
void ZeroRoboticsGameImpl::initLight | ( | ) |
Definition at line 16 of file ZRLight.cpp.
{ challInfo.light.direction = 1; #ifdef ALLIANCE #if (SPHERE_ID == SPHERE1) //float s = ((float) rand()) / ((float) RAND_MAX); challInfo.light.center = -0.2; //s * 1.6 - 0.8; challInfo.light.nextSwitchTime = -1; // shouldn't be utilized #endif challInfo.light.greyWidth = LIGHT_GREY_WIDTH*.5; challInfo.light.lightWidth = LIGHT_WIDTH; #else #if (SPHERE_ID == SPHERE1) challInfo.light.center = 0.0; challInfo.light.nextSwitchTime = ((unsigned int) rand()) % 30 + 30; #endif challInfo.light.greyWidth = LIGHT_GREY_WIDTH; #endif }
ZeroRoboticsGameImpl & ZeroRoboticsGameImpl::instance | ( | ) | [static] |
Retrieves singleton instance of the game implementation.
Singleton instance of the game implementation
Definition at line 38 of file ZRGameInternal.cpp.
{ ///Singleton instance of the game implementation static ZeroRoboticsGameImpl gameImplInstance(ZeroRoboticsAPIImpl::instance()); return gameImplInstance; }
bool ZeroRoboticsGameImpl::isFacingEarth | ( | ) |
Definition at line 196 of file ZRCamera.cpp.
{ float earth [3]; memcpy(earth, EARTH, 3 * sizeof(float)); return mathVecInner(&challInfo.me.zrState[ZR_ATT_X], earth, 3) > MAX_FACING_ANGLE; }
bool ZeroRoboticsGameImpl::isFacingOther | ( | ) |
Definition at line 186 of file ZRCamera.cpp.
{ bool facing = isFacingPos(challInfo.other.zrState); //GAME_TRACE(("isFacingOther: facing = %d| ", facing)); return facing; }
bool ZeroRoboticsGameImpl::isFacingPos | ( | float | position[] | ) |
Definition at line 174 of file ZRCamera.cpp.
{ float relativePos[3]; mathVecSubtract(relativePos, position, challInfo.me.zrState, 3); mathVecNormalize(relativePos, 3); //Check if generally pointing at the other satellite (dot product) and //if within a small margin of error (to account for noise) //after bugfix, increased allowed error to 0.25f from 0.0575f // MAX_FACING_ANGLE = 0.968912f is cosf(0.25f) bool facing = mathVecInner(&challInfo.me.zrState[ZR_ATT_X], relativePos, 3) > MAX_FACING_ANGLE; return facing; }
bool ZeroRoboticsGameImpl::itemPickUp | ( | int | objectNum | ) |
Definition at line 135 of file ZRItems.cpp.
{ /* This function will replicate that of the 2013 game's item PickUp function with a few minor changes. */ state_vector sphState; apiImpl.api->getMySphState(sphState); float dist,speed; dist = dist3d(sphState, challInfo.mpLoc[mpNum]); speed = mathVecMagnitude(&sphState[3],3); // VEL_X needs to be changed. - 3 if (speed<MP_SPEED && dist<=MP_RADIUS) { if (challInfo.me.mpTime[mpNum] == MP_EMPTY && challInfo.other.mpTime[mpNum] == MP_EMPTY){ challInfo.me.mpTime[mpNum] = apiImpl.api->getTime(); switch (ITEM_TYPES[mpNum]){ case ITEM_TYPE_ADD_SCORE : {challInfo.me.score = challInfo.me.score + ITEM_SCORE; GAME_TRACE(("Score item picked up")); break; } /*case ITEM_TYPE_ADD_MEMORY : {challInfo.camera.memorySize = challInfo.camera.memorySize + ITEM_MEMORY_SIZE; GAME_TRACE(("memory item picked up")); break;} */ case ITEM_TYPE_ADD_ENERGY: {challInfo.me.energy = challInfo.me.energy + ITEM_ENERGY; if (challInfo.me.energy > MAX_ENERGY) { challInfo.me.energy = MAX_ENERGY; } GAME_TRACE(("energy item picked up")); break;} case ITEM_TYPE_MIRROR:{ challInfo.me.mirrors += 1; GAME_TRACE(("Mirror picked up")); break; } } GAME_TRACE(("score: %f, energy: %f, memorySize: %d", challInfo.me.score, challInfo.me.energy, challInfo.camera.memorySize)); } /* if (!challInfo.me.acquiringMP[mpNum] && mathVecMagnitude(&sphState[RATE_X],3) <= MAX_START_MP) { challInfo.me.acquiringMP[mpNum] = true; memcpy(challInfo.me.initQuat,&sphState[QUAT_1],4*sizeof(float)); } if (challInfo.me.acquiringMP[mpNum] && fabsf(mathVecInner(challInfo.me.initQuat,&sphState[QUAT_1],4)) < MP_ROTATION_ANGLE) { challInfo.me.acquiringMP[mpNum] = false; //Check for item pickup: item not already picked up by either player, //and item conditions have been met if (challInfo.me.mpTime[mpNum] == MP_EMPTY && challInfo.other.mpTime[mpNum] == MP_EMPTY) { //Record pickup time with game time challInfo.me.mpTime[mpNum] = apiImpl.api->getTime(); //challInfo.camera.memorySize++; challInfo.me.score = challInfo.me.score + ITEM_SCORE; GAME_TRACE(("[%d] picked up item %d | ", apiImpl.api->getTime(), mpNum)); } } */ } else { challInfo.me.acquiringMP[mpNum] = false; } return false; // return true; }
void ZeroRoboticsGameImpl::limitDirection | ( | state_vector | ctrlState, |
float | ctrlControl[6], | ||
unsigned int | idx, | ||
float | dir | ||
) |
Limits the direction in which the programmed SPHERE can travel and slows down the velocity if it travels in the direction of the limit.
Definition at line 407 of file ZRGameInternal.cpp.
void ZeroRoboticsGameImpl::memoryLoss | ( | ) |
Definition at line 35 of file ZRCamera.cpp.
{ memset(challInfo.camera.memory,0,CAMERA_MAX_MEMORY*sizeof(Picture)); // erase memory challInfo.camera.memoryFilled = 0; // reset counter GAME_TRACE(("[%d] memory CLEARED | ", apiImpl.api->getTime())); }
void ZeroRoboticsGameImpl::modify2DForceTorque | ( | float | forceTorque[6] | ) |
Definition at line 166 of file ZRGameInternal.cpp.
{ state_vector myState, targetState; apiImpl.api->getMySphState(myState); memcpy(targetState, myState, sizeof(state_vector)); targetState[POS_Z] = 0.0f; targetState[VEL_Z] = 0.0f; targetState[10] = 0.0f; targetState[11] = 0.0f; targetState[12] = 0.0f; float q_sw[4], q_tw[4]; float axis[3] = {0.0f, 0.0f, -1.0f}; swingTwistDecomposition(&targetState[QUAT_1], q_sw, q_tw, axis); quatToPositive(q_tw); memcpy(&targetState[QUAT_1], q_tw, 4*sizeof(float)); state_vector error; findStateError(error, myState, targetState); float newForces[6] = {0}; ctrlPositionPD(KPpositionPD, KDpositionPD, error, newForces); ctrlAttitudeNLPIDwie(KPattitudePID, KIattitudePID, KDattitudePID, KPattitudePID, KIattitudePID, KDattitudePID, KPattitudePID, KIattitudePID, KDattitudePID, 1.0f, error, newForces); forceTorque[FORCE_Z] = newForces[FORCE_Z]; forceTorque[TORQUE_X] = newForces[TORQUE_X]; forceTorque[TORQUE_Y] = newForces[TORQUE_Y]; }
bool ZeroRoboticsGameImpl::photoBomb | ( | float | zrState[12], |
float | poiLoc[3] | ||
) |
float ZeroRoboticsGameImpl::picPointsImpl | ( | ) |
Definition at line 79 of file ZRCamera.cpp.
{ // check if other in light or grey zone, camera is on, the spheres are facing bool isCameraOn = challInfo.camera.cameraOn; bool isFacingOtherResult = isFacingOther(); bool isOppNotInDarkZone = !sphereInDark(challInfo.other.zrState); bool myMirror = challInfo.me.mirrorTime != 0 && challInfo.me.mirrorTime + ITEM_MIRROR_DURATION > challInfo.currentTime; bool otherMirror = challInfo.other.mirrorTime != 0 && challInfo.other.mirrorTime + ITEM_MIRROR_DURATION > challInfo.currentTime; float picturePointValue = 0; if (isCameraOn && isFacingOtherResult && isOppNotInDarkZone && !myMirror) { float bet[3], distance; mathVecSubtract(bet, challInfo.me.zrState, challInfo.other.zrState, 3); distance = mathVecMagnitude(bet, 3); if (distance < PHOTO_MIN_DISTANCE) { GAME_TRACE(("Not a good shot: too close to the other satellite | ")); return 0.0; } picturePointValue = 2.0 + 0.1/(distance - PHOTO_MIN_DISTANCE + 0.1); if(otherMirror){ #ifdef ZR2D picturePointValue = 0; #else picturePointValue = -1*picturePointValue; #endif GAME_TRACE(("Not a good shot: Opposing mirror active %f|", picturePointValue)); } } else if(!isCameraOn){ GAME_TRACE(("Not a good shot: camera off |")); } else if(myMirror){ GAME_TRACE(("Not a good shot: my mirror's in the way |")); } else if(!isFacingOtherResult) { GAME_TRACE(("Not a good shot: not facing the other satellite | ")); } else if(!isOppNotInDarkZone){ GAME_TRACE(("Not a good shot: opponent in dark zone |")); } return picturePointValue; }
void ZeroRoboticsGameImpl::processRXData | ( | default_rfm_packet | packet | ) |
(Required) Processes SPHERES telemetry data
Definition at line 11 of file ZRCommRoutines.cpp.
{ if (packet[PKT_CM] == COMM_CMD_DBG_SHORT_SIGNED) { dbg_short_packet DebugVecShort; memcpy(DebugVecShort, &packet[PKT_DATA], sizeof(dbg_short_packet)); if (ctrlManeuverNumGet() > 2) { for (int i = 0; i < NUM_ITEMS; i++){ challInfo.other.mpTime[i] = DebugVecShort[i+1]; } // copy general data during game run challInfo.other.mirrorTime = DebugVecShort[14]; challInfo.other.message = DebugVecShort[15]; } else { // initialization data for items if (DebugVecShort[0] == 0){ #if (SPHERE_ID == SPHERE1) // get data from SPHERE2 for (int i = 0; i < NUM_ITEMS - 5; i++){ challInfo.mpLoc[i + 5][0] = DebugVecShort[3*i + 1] / 10000.0f; challInfo.mpLoc[i + 5][1] = DebugVecShort[3*i + 2] / 10000.0f; challInfo.mpLoc[i + 5][2] = DebugVecShort[3*i + 3] / 10000.0f; } #else // get data from SPHERE1 for (int i = 0; i < 5; i++){ challInfo.mpLoc[i][0] = DebugVecShort[3*i + 1] / 10000.0f; challInfo.mpLoc[i][1] = DebugVecShort[3*i + 2] / 10000.0f; challInfo.mpLoc[i][2] = DebugVecShort[3*i + 3] / 10000.0f; } #endif } } } else if (packet[PKT_CM] == COMM_CMD_DBG_SHORT_UNSIGNED) { dbg_ushort_packet DebugVecUShort; memcpy(DebugVecUShort, &packet[PKT_DATA], sizeof(dbg_ushort_packet)); int cmn = ctrlManeuverNumGet(); // printf("cmn %d\n",cmn); // recieve initialization packet (control maneuver 1) if (cmn < 3){ #if (SPHERE_ID == SPHERE2) // printf("Init DebugVecShort Received by Sphere 2: %d (should be 0), %d\n", DebugVecShort[0], cmn); // make sure its one of our initialization packets, all other debugVecShort[0] are time * 10, so they are larger than 0 if (DebugVecUShort[0] == 0) { challInfo.light.nextSwitchTime = (int) DebugVecUShort[1]; } #endif } //challInfo.other.mpTime[0] = DebugVecUShort[1]; //challInfo.other.mpTime[1] = DebugVecUShort[2]; } else if (packet[PKT_CM] == COMM_CMD_DBG_FLOAT) { dbg_float_packet DebugVecFloat; memcpy(DebugVecFloat, &packet[PKT_DATA], sizeof(dbg_float_packet)); int cmn = ctrlManeuverNumGet(); if (cmn < 3) { #if (SPHERE_ID == SPHERE2) //printf("Init DebugVecFloat Received by Sphere 2: %f (should be -1), %d\n", DebugVecFloat[0], cmn); // make sure its one of our initialization packets. tstep should be nonnegative, I think. if (DebugVecFloat[0] == 0.0f) { challInfo.light.center = DebugVecFloat[1]; challInfo.light.direction = DebugVecFloat[2]; return; } #endif } challInfo.other.score = DebugVecFloat[1]; challInfo.other.energy = DebugVecFloat[3]; } }
float ZeroRoboticsGameImpl::randomizeStartingLocs | ( | int | itemID, |
int | coord | ||
) |
void ZeroRoboticsGameImpl::resetPicsTaken | ( | ) |
void ZeroRoboticsGameImpl::resolveCollision | ( | float | zrState[12], |
float | forceTorqueOut[6] | ||
) |
Definition at line 417 of file ZRGameInternal.cpp.
{ for (int i=0; i<3; i++) { if (zrState[i] > 0) limitDirection(zrState, forceTorqueOut, i, -1.0f); else if (zrState[i] < 0) limitDirection(zrState, forceTorqueOut, i, 1.0f); } }
void ZeroRoboticsGameImpl::sendDebug | ( | void | ) |
(Required) Called on every gspControl control cycle, It should be used to send debug and telemetry information to the ground.
Definition at line 94 of file ZRCommRoutines.cpp.
{ dbg_short_packet DebugVecShort; // short[16] dbg_ushort_packet DebugVecUShort; // ushort[16] dbg_float_packet DebugVecFloat; // float[8] unsigned int tstep; // send debug after estimator convergence if (ctrlManeuverNumGet() < 3) { sendInit(); } if (ctrlManeuverNumGet() > 1) { // normal game packages tstep = apiImpl.api->getTime(); if (!tstep) return; // only send starting with time 1, since time 0 can cause problems with initialization // initialize all packets to 0 memset(DebugVecShort, 0, sizeof(dbg_short_packet)); memset(DebugVecUShort, 0, sizeof(dbg_ushort_packet)); memset(DebugVecFloat, 0, sizeof(dbg_float_packet)); // debug short: POIs currently visible, other sat message, flare status DebugVecShort[0] = (short)(tstep*10); //Timestamp DebugVecShort[13] = game->getMirrorTimeRemaining(); DebugVecShort[14] = challInfo.me.mirrorTime; //items for (int i = 0; i < NUM_ITEMS; i++){ DebugVecShort[i + 1] = (unsigned short) challInfo.me.mpTime[i]; } DebugVecShort[15] = challInfo.me.message; //message sent between players // unsigned short debug packet: status of game variables, known flare times DebugVecUShort[0] = (unsigned short)(tstep*10); //Timestamp DebugVecUShort[7] = (unsigned short) (sphereInLight(challInfo.me.zrState)); DebugVecUShort[7] <<= 1; DebugVecUShort[7] += (unsigned short) (sphereInDark(challInfo.me.zrState)); DebugVecUShort[8] = (challInfo.light.direction > 0); DebugVecUShort[9] = (unsigned short) (challInfo.camera.tookPicture); DebugVecUShort[10] = (unsigned short) (challInfo.camera.uploadedPictures); DebugVecUShort[11] = (unsigned short) (challInfo.camera.cameraOn); DebugVecUShort[13] = (unsigned short) (challInfo.camera.memorySize); DebugVecUShort[14] = (unsigned short) (challInfo.camera.memoryFilled); //Float debug packet: score, fuel, forces DebugVecFloat[0] = (float)tstep; DebugVecFloat[1] = game->getScore(); DebugVecFloat[2] = game->getFuelRemaining() / ((double)PROP_ALLOWED_SECONDS); DebugVecFloat[3] = challInfo.me.energy; DebugVecFloat[4] = challInfo.light.center; memcpy(&DebugVecFloat[5], challInfo.me.userForces, 3*sizeof(float)); //Forces for reference //Send packets to other SPHERES/ground/sim; do not modify below this line commSendPacket(COMM_CHANNEL_STL, BROADCAST, 0, COMM_CMD_DBG_SHORT_SIGNED, (unsigned char *) DebugVecShort,0); commSendPacket(COMM_CHANNEL_STL, BROADCAST, 0, COMM_CMD_DBG_FLOAT, (unsigned char *) DebugVecFloat,0); commSendPacket(COMM_CHANNEL_STL, BROADCAST, 0, COMM_CMD_DBG_SHORT_UNSIGNED, (unsigned char *) DebugVecUShort,0); #ifdef ZRSIMULATION apiImpl.ZRUserDbgVec[0] = (float)tstep; commSendPacket(COMM_CHANNEL_STL, GROUND, sysIdentityGet(), COMM_CMD_DBG_ZRUSER, (unsigned char *) apiImpl.ZRUserDbgVec,0); #endif } }
void ZeroRoboticsGameImpl::sendInit | ( | void | ) |
for Corona SPHERES: sends POI & Solar Flare info to Sat 2 at start of game
Definition at line 166 of file ZRCommRoutines.cpp.
{ #if (SPHERE_ID == SPHERE1) dbg_short_packet DebugVecShort; dbg_ushort_packet DebugVecUShort; dbg_float_packet DebugVecFloat; // sends light information to second satellite memset(DebugVecShort, 0, sizeof(dbg_short_packet)); // initialize packets to 0 memset(DebugVecUShort, 0, sizeof(dbg_ushort_packet)); memset(DebugVecFloat, 0, sizeof(dbg_float_packet)); DebugVecShort[0] = 0; int upTo = 5; if (NUM_ITEMS < upTo) { upTo = NUM_ITEMS; } for (int i = 0; i < upTo; i++) { DebugVecShort[3*i + 1] = 10000 * challInfo.mpLoc[i][0]; DebugVecShort[3*i + 2] = 10000 * challInfo.mpLoc[i][1]; DebugVecShort[3*i + 3] = 10000 * challInfo.mpLoc[i][2]; } DebugVecUShort[0] = 0; DebugVecUShort[1] = (short)0 + (challInfo.light.nextSwitchTime); #ifdef ALLIANCE DebugVecUShort[2] = 3; #else #ifdef ZR3D DebugVecUShort[2] = 2; #else #ifdef ZR2D DebugVecUShort[2] = 1; #else DebugVecUShort[2] = 0; #endif #endif #endif DebugVecUShort[3] = NUM_ITEMS; for (int i = 0; i < NUM_ITEMS; i++) { DebugVecUShort[4 + i] = ITEM_TYPES[i]; } DebugVecFloat[0] = 0.0f; DebugVecFloat[1] = challInfo.light.center; DebugVecFloat[2] = challInfo.light.direction; commSendPacket(COMM_CHANNEL_STL, BROADCAST, 0, COMM_CMD_DBG_SHORT_SIGNED, (unsigned char *) DebugVecShort,0); commSendPacket(COMM_CHANNEL_STL, BROADCAST, 0, COMM_CMD_DBG_SHORT_UNSIGNED, (unsigned char *) DebugVecUShort,0); commSendPacket(COMM_CHANNEL_STL, BROADCAST, 0, COMM_CMD_DBG_FLOAT, (unsigned char *) DebugVecFloat,0); #endif #if (SPHERE_ID == SPHERE2) dbg_short_packet DebugVecShort; DebugVecShort[0] = 0; for (int i = 0; i < NUM_ITEMS - 5; i++) { DebugVecShort[3*i + 1] = 10000 * challInfo.mpLoc[i+5][0]; DebugVecShort[3*i + 2] = 10000 * challInfo.mpLoc[i+5][1]; DebugVecShort[3*i + 3] = 10000 * challInfo.mpLoc[i+5][2]; } commSendPacket(COMM_CHANNEL_STL, BROADCAST, 0, COMM_CMD_DBG_SHORT_SIGNED, (unsigned char *) DebugVecShort,0); #endif }
bool ZeroRoboticsGameImpl::sphereInDark | ( | float | position[] | ) |
Definition at line 103 of file ZRLight.cpp.
{ #ifdef ALLIANCE return sphereInMovingArea(position) == -1; #else return sphereInSwitchingArea(position) == -1; #endif }
bool ZeroRoboticsGameImpl::sphereInLight | ( | float | position[] | ) |
Definition at line 95 of file ZRLight.cpp.
{ #ifdef ALLIANCE return sphereInMovingArea(position) == 1; #else return sphereInSwitchingArea(position) == 1; #endif }
int ZeroRoboticsGameImpl::sphereInMovingArea | ( | float | position[] | ) |
Definition at line 71 of file ZRLight.cpp.
{ float interface = challInfo.light.center; // Start of Light Zone float outerface = interface + challInfo.light.lightWidth; // End of light zone if(outerface > ZONE_pY) outerface -= 2*ZONE_pY; // Wraparound float halfWidth = challInfo.light.greyWidth*.5; // Grey width on either side if ((interface - halfWidth <= position[1] && interface + halfWidth >= position[1]) || // In the first grey zone (outerface - halfWidth <= position[1] && outerface + halfWidth >= position[1]) || // In the second gray zone (position[0] >= ZONE_pX || position[1] >= ZONE_pY || position[2] >= ZONE_pZ) || // Out of bounds positive (position[0] <= ZONE_nX || position[1] <= ZONE_nY || position[2] <= ZONE_nZ)) // Out of bounds negatively { return 0; // Gray } else if ((outerface > position[1] && (interface < position[1] || outerface < interface)) || // before the end of the light zone and Either after the beginning or the end has wrapped around (interface < position[1] && outerface < interface)) // or it's after the beginning and the end has wrapped { return 1; //Light } return -1; // Dark }
int ZeroRoboticsGameImpl::sphereInSwitchingArea | ( | float | position[] | ) |
Definition at line 61 of file ZRLight.cpp.
Definition at line 57 of file ZRLight.cpp.
float ZeroRoboticsGameImpl::takePicImpl | ( | ) |
Returns the score value of the picture, or 0 if taking the picture failed.
Definition at line 128 of file ZRCamera.cpp.
{ challInfo.me.score += 0.01f; GAME_TRACE(("[%d] attempting to take picture... ", challInfo.currentTime)); bool enoughSpace = challInfo.camera.memoryFilled < challInfo.camera.memorySize; // uses the energy even if the picture can't be taken // (if not enough space or not facing other sphere) bool usedEnergy = tryToUseEnergy(ENERGY_COST_TAKE_PICTURE); float pictureValue = picPointsImpl(); if(enoughSpace && usedEnergy && pictureValue != 0) // check if it can take a picture { challInfo.camera.tookPicture = true; // apply score modifiers etc challInfo.me.score += 0.1f; // Very small value. Subject to change. challInfo.camera.memory[challInfo.camera.memoryFilled].picStored = true; challInfo.camera.memory[challInfo.camera.memoryFilled].value = pictureValue; // End of scoring challInfo.camera.memory[challInfo.camera.memoryFilled].round = 1; challInfo.camera.memoryFilled++; GAME_TRACE(("[%d] took picture (round %d) valued %4.2f points | ", apiImpl.api->getTime(), challInfo.camera.memory[challInfo.camera.memoryFilled-1].round, challInfo.camera.memory[challInfo.camera.memoryFilled-1].value)); } else if(!enoughSpace && pictureValue != 0 ){ GAME_TRACE(("Failed to take a picture: memory filled up | ")); } else if(!usedEnergy && pictureValue != 0 ){ GAME_TRACE(("Failed to take a picture: not enough energy | ")); } disableCamera(); return pictureValue; }
bool ZeroRoboticsGameImpl::tryToUseEnergy | ( | float | amount | ) |
Definition at line 17 of file ZREnergy.cpp.
bool ZeroRoboticsGameImpl::update | ( | float | forceTorqueOut[6] | ) |
(Required) Runs an update of the game rules and calls the user function loop().
The return value for this function indicates if the forceTorqueOut vector should be mixed into thruster firings. The function should return 0 if the user does not activate any ZR API movement commands or implements their own thruster firing logic.
Here we update player's scores
/param forceTorqueOut forces and torques to be mixed into thruster firings /return return 1 if forceTorqueOut should be mixed into thruster firings and 0 otherwise
Definition at line 110 of file ZRGameInternal.cpp.
{ updateStates(); updateLight(); updateEnergy(); // empty the userForces array memset(challInfo.me.userForces,0,sizeof(float)*6); // declare a static finalResult variable // updateGameOverManuever will change it static unsigned char finalResult = 0; unsigned char useForces = false; // maneuver 3 = game mode // maneuver 202 = end game (get final score) // maneuver 204 = terminate switch (ctrlManeuverNumGet()) { case 3: useForces = updateGameModeManeuver(forceTorqueOut); break; //------End main game code------// case 202: // Endgame scenario useForces = updateGameOverManeuver(forceTorqueOut, finalResult); break; case 203: // terminate test after determining final score { ctrlTestTerminate(finalResult); } break; } //Store user forces for sending to ground memcpy(challInfo.me.userForces, forceTorqueOut, sizeof(float)*6); #ifdef ZR2D memset(&challInfo.me.userForces[2], 0, sizeof(float)*3); #endif //Send Telemetry sendDebug(); return useForces; }
void ZeroRoboticsGameImpl::updateEnergy | ( | ) |
Definition at line 37 of file ZREnergy.cpp.
{ if (!sphereInLight(challInfo.me.zrState)) return; challInfo.me.energy += ENERGY_GAIN_RATE; if (challInfo.me.energy > MAX_ENERGY) { challInfo.me.energy = MAX_ENERGY; } }
bool ZeroRoboticsGameImpl::updateGameModeManeuver | ( | float | forceTorqueOut[6] | ) |
Definition at line 231 of file ZRGameInternal.cpp.
{ float collisionInfo[2]; // get state-of-health of other satellite (mainly for end of test) comm_payload_soh soh_partner; #if (SPHERE_ID == SPHERE1) commBackgroundSOHGet(SPHERE2, &soh_partner); #else commBackgroundSOHGet(SPHERE1, &soh_partner); #endif // determine current speed of satellite, use to determine collision avoidance motion float speed = mathVecMagnitude(&challInfo.me.sphState[3],3); unsigned char useForces = false; // if camera was used (so it can't be used again for 3 seconds), check when to enable it again if((!challInfo.camera.cameraOn) && ((challInfo.currentTime - challInfo.camera.cameraOffTime) > DISABLE_CAMERA_TIME)) { activateCamera(); } // Run user's "loop" function. apiImpl is used because we are accessing // a private part of the API containing a pointer to the user's API apiImpl.zruser->loop(); //Check if items are being picked up for (int i = 0; i < NUM_ITEMS; i++) itemPickUp(i); useForces = useForces || apiImpl.getForceTorque(forceTorqueOut); prop_time tent_times; #ifdef ZRFLATFLOOR ctrlMixWLoc(&tent_times, forceTorqueOut, challInfo.me.sphState, 10, 40.0f, FORCE_FRAME_INERTIAL); #else ctrlMixWLoc(&tent_times, forceTorqueOut, challInfo.me.sphState, 10, 20.0f, FORCE_FRAME_INERTIAL); #endif float tent_time_sum = 0; for (int i = 0; i < 12; i++) { tent_time_sum += tent_times.off_time[i]-tent_times.on_time[i]; } //Check for fuel or energy out at this point if((game->getFuelRemaining() <= 0.0f || game->getEnergy() <= tent_time_sum * ENERGY_COST_THRUSTERS)) { memset(forceTorqueOut,0,6*sizeof(float)); // anything the user has commanded is ignored, only firings would be from out-of-bounds or collission avoidance useForces = false; // assume there will be no firings } //Enforce boundaries of the game if (enforceBoundaries(forceTorqueOut)) { //challInfo.me.fuelUsed += OFFSIDES_PENALTY; GAME_TRACE(("[%d] out of bounds penalty | ", apiImpl.api->getTime())); useForces = true; } //Collision avoidance //check to see that its speed is not neglible. if (speed > 0.01f) { challInfo.me.collisionActive = ctrlAvoidWithOverride(challInfo.me.sphState,&challInfo.other.sphState,1,forceTorqueOut,collisionInfo,3); } //------Thruster control------// // Run standard mixer to get fuel consumption prop_time times; ctrlMixWLoc(×, forceTorqueOut, challInfo.me.sphState, 10, 20.0f, FORCE_FRAME_INERTIAL); //Tally fuel and energy used for firing thrusters for (int i=0; i<12; i++) { float thrusterTime = times.off_time[i]-times.on_time[i]; challInfo.me.fuelUsed += thrusterTime / 1000.0f; tryToUseEnergy(thrusterTime * ENERGY_COST_THRUSTERS); //Protect against NAN or INF hacking if (challInfo.me.fuelUsed < 0.0f) { DEBUG(("WARNING: invalid forces/torques applied to satellite at t=%d. Fuel will be set to 0. Check your code for errors.\n", challInfo.currentTime)); challInfo.me.fuelUsed = PROP_ALLOWED_SECONDS; } } #ifdef ZR2D modify2DForceTorque(forceTorqueOut); useForces = true; #endif //------Game end conditions------// if (challInfo.currentTime >= (MAX_GAME_TIME)) ctrlManeuverNumSet(202); return useForces; }
bool ZeroRoboticsGameImpl::updateGameOverManeuver | ( | float | forceTorqueOut[6], |
unsigned char & | finalScore | ||
) |
Definition at line 331 of file ZRGameInternal.cpp.
{ unsigned char useForces = false; int result; float collisionInfo[2]; // get state-of-health of other satellite (mainly for end of test) comm_payload_soh soh_partner; #if (SPHERE_ID == SPHERE1) commBackgroundSOHGet(SPHERE2, &soh_partner); #else commBackgroundSOHGet(SPHERE1, &soh_partner); #endif float myScore; float otherScore; myScore = game->getScore(); otherScore = game->getOtherScore(); useForces = ctrlAvoidWithOverride(challInfo.me.sphState, &challInfo.other.sphState, 1, forceTorqueOut, collisionInfo, 3) > 0; useForces = useForces || enforceBoundaries(forceTorqueOut); // break ties by making a tiny change based on the random state if (myScore == otherScore) { challInfo.me.score -= (0.01f * sqrtf((challInfo.me.zrState[0]*challInfo.me.zrState[0]) +(challInfo.me.zrState[1]*challInfo.me.zrState[1])+(challInfo.me.zrState[2]*challInfo.me.zrState[2]))); GAME_TRACE (("Tie Breaker (%12.10f = %12.10f), new score = %12.10f | ", myScore, otherScore, challInfo.me.score)); } // get final score if ((soh_partner.last_test_result || (soh_partner.maneuver_number > 200) || (NUM_SPHERES == 1))) { result = 10*floorf(myScore); if (result < 10) result = 10; if (result > 220) result = 220; if (myScore > otherScore) result += 10; finalResult = (result + apiImpl.getTeamId() + 1); useForces = false; } // terminate after we find the final result & timeout (4s) if (finalResult && (ctrlManeuverTimeGet() > 4000)) { GAME_TRACE (("GAME ENDED! Final Score Float: %10.8f / Integer: %d | Test Result %d | ", myScore, result, finalResult)); ctrlManeuverTerminate(); } return useForces; }
void ZeroRoboticsGameImpl::updateLight | ( | ) |
Definition at line 38 of file ZRLight.cpp.
{ #ifdef ALLIANCE challInfo.light.center += LIGHT_SPEED; if (challInfo.light.center > ZONE_pY) { challInfo.light.center -= 2*ZONE_pY; } #else if (challInfo.currentTime < challInfo.light.nextSwitchTime) return; GAME_TRACE(("Light switching now")); switchLightDirection(); challInfo.light.nextSwitchTime = challInfo.currentTime + LIGHT_SWITCH_PERIOD; #endif }
void ZeroRoboticsGameImpl::updateStates | ( | ) |
Definition at line 97 of file ZRGameInternal.cpp.
{ apiImpl.api->getMyZRState(challInfo.me.zrState); apiImpl.api->getOtherZRState(challInfo.other.zrState); apiImpl.api->getMySphState(challInfo.me.sphState); apiImpl.api->getOtherSphState(challInfo.other.sphState); challInfo.currentTime = apiImpl.api->getTime(); challInfo.camera.tookPicture = false; challInfo.camera.uploadedPictures = false; }
ZeroRoboticsAPIImpl& ZeroRoboticsGameImpl::apiImpl |
Reference to ZR API instance.
Definition at line 224 of file ZRGameInternal.h.
Definition at line 105 of file ZRGameInternal.h.
Back pointer to the game instance.
Definition at line 227 of file ZRGameInternal.h.
const state_vector ZeroRoboticsGameImpl::initState [static] |
(Required) Initial state where the satellite is initialized.
Definition at line 162 of file ZRGameInternal.h.