void ZRUser(float myState[12], float otherState[12], float time) { if (time < 150) { //TODO: move to center of panel initialization circle, instead of //assuming that position from the start float attitude[3] = {0, 1, 0}; ZRSetAttitudeTarget(attitude); //TODO: rotate around the circle to find the panel; in this case, //panel angle is 0 so we automatically see it after the attitude change if (isPanelFound() && time > 20) { float velocity[3] = {0, 0.01, 0}; ZRSetVelocityTarget(velocity); } if (iHavePanel() && time > 70 && time < 75) { float stop[3] = {0, 0, 0}; ZRSetVelocityTarget(stop); } if (iHavePanel() && time > 75 && time < 150) { float station[3] = {-.7, 0, 0}; ZRSetPositionTarget(station); } } if (iHavePanel() && time == 150) { float searchStation[3] = {0, 0.1, 0}; ZRSetTorques(searchStation); } if (isStationInSync() && time > 150) { float stop[3] = {0, 0, 0}; float velocity[3] = {0, 0, .01}; ZRSetTorques(stop); ZRSetVelocityTarget(velocity); } }
void CoastToAttitude(float* myState, float* attitudeTarget) { float intermediate[3]; if (VAngle(&myState[6], attitudeTarget) < (COASTING_VELOCITY * 1.5)) VCopy(attitudeTarget, intermediate); else VRotate(&myState[6], COASTING_VELOCITY, attitudeTarget, intermediate); ZRSetAttitudeTarget(intermediate); }
void alignToPlusY() { // Performs initial alignment to +Y axis prior to rotateTau() // Requires a "stage" global variable initialized to 0; // In my case, this came before stage 3, hence the assignment to the number 3; float attTarget[3] = {0.0, 1.0, 0.0}; ZRSetAttitudeTarget(attTarget); if (Vfunc(8, att1Target, myState+6, NULL, 0) < 0.75) { stage = 3; // Ties in to stage global variable effective / used in ZRUser(). } }
static void spin (float myState[12]) { //BEGIN::PROC::spin float dirs[3]; dirs[2] = 1.872459067 + atan2f(myState[7], myState[6]); dirs[0] = sinf(PI/2 - dirs[2]); dirs[1] = sinf(dirs[2]); dirs[2] = 0; ZRSetAttitudeTarget(dirs); //END::PROC::spin }
//User-defined procedures static void shoot (float myState[12], float target[3], unsigned int fire) { //BEGIN::PROC::shoot float direction[3]; mathVecSubtract(direction, target, myState, 3); mathVecNormalize(direction, 3); ZRSetAttitudeTarget(direction); if (fire && (acos(mathVecInner(&myState[6], direction, 3) / mathVecMagnitude(&myState[6], 3)) < (0.1))) Plaser(); //END::PROC::shoot }
void rotate_closedLoop(int param_t) { // Rotates by parametrically assigning the y and z components of the attitude vector. The x attitude component obviously // remains 0; // Observed and unexpected behavior: Appears that although I assign attitude targets with y and z components only, the sphere // also rotates about the y component (therefore creating a non-zero x attitude component)... // Nevertheless, leaning towards this method as more reliable and foolproof... float PI = 4 * atan(1); float rotation_rate_k = 10.05; // higher k-value = faster (?) rotation... float set_x = 0; float set_y = cos(rotation_rate_k * param_t * PI / 180); float set_z = -sin(rotation_rate_k * param_t * PI / 180); float set[3] = {set_x, set_y, set_z}; printf("%d, %f, %f, %f, %f \n", param_t, PI, set[0], set[1], set[2]); ZRSetAttitudeTarget(set); }
static void RotateTarget(float * myState, float * pos) { #define VLen(a) mathVecMagnitude((a), 3) #define VAdd(a, b, result) mathVecAdd(result, (a), (b), 3) #define VSub(a, b, result) Vfunc(2, (a), (b), (result), 0) #define VUnit(a, result) Vfunc(3, (a), NULL, (result), 0) #define VMult(a, b, result) Vfunc(4, (a), NULL, (result), (b)) #define VDot(a, b) Vfunc(5, (a), (b), NULL, 0) #define VDist(a, b) Vfunc(6, (a), (b), NULL, 0) #define VCopy(a, result) memcpy((result), (a), sizeof(float)*3) #define VAngle(a, b) Vfunc(8, (a), (b), NULL, 0) #define VPoint(a, b, result) Vfunc(9, (a), (b), (result), 0) #define Deg2Rad(Deg) (Deg*PI/180.0) #define Rad2Deg(Rad) (Rad*180.0/PI) // do ZRSetAttitudeTarget(current_att + AngleForward) #define AngleForward 30 float temp[3], target_att[3], current_att[3]; float current_theta, target_theta; ZRSetPositionTarget(pos); VCopy(myState+6,current_att); current_theta = atan2(current_att[2],current_att[1]); if (current_theta < 0) current_theta = current_theta + 2*PI; target_theta = current_theta + Deg2Rad(AngleForward); temp[0] = -5.0*current_att[0]; temp[1] = cos(target_theta); temp[2] = sin(target_theta); VUnit(temp,target_att); //printf("time: %2.0f, current_att: (%5.2f, %5.2f, %5.2f), target: (%5.2f, %5.2f, %5.2f), to_target: %5.1f", //procvar[0],current_att[0],current_att[1],current_att[2],target_att[0],target_att[1],target_att[2], //VAngle(current_att,target_att)); //printf(" rates: (%5.2f, %5.2f, %5.2f)\n", myState[9],myState[10],myState[11]); //printf( " out-of-plane: %5.2f\n",asin(current_att[0])*180/3.14159); ZRSetAttitudeTarget(target_att); }
static void meltIce (float state[12], float other[12], float time) { //BEGIN::PROC::meltIce /* * meltIce melts the * ice sheet on Opulens * (no shit!) */ float x[3]={0,-0.35,-0.2}; if (PiceHits()+PotherIceHits()>18 || time<47) { revolve (x,state,other); } else { ZRSetPositionTarget (state); mathVecSubtract(x,x,state,3); ZRSetAttitudeTarget(x); } if (time>59) Plaser(); //END::PROC::meltIce }
static void spin (float c[3], float mystate[12]) { //BEGIN::PROC::spin /* * mmh.. Do I really need to * exaplain what this function * is for? */ float v[3]; char i; float cosalfa=0; if (ok<3) { PgetAsteroidNormal(v); for(i=0;i<3;i++) cosalfa+=v[i]*mystate[i+6]; if(cosalfa<0) mathVecMul (v,v,-1); ZRSetAttitudeTarget(v); if (fabs(cosalfa)>0.986f) ok++; } else { v[0]=(0.5236f - mystate[9])/50; v[1]=0; v[2]=0; ZRSetTorques(v); } ZRSetPositionTarget(c); //END::PROC::spin }
void ZRUser(float* myState, float* otherState, float time) { float target[3]; float station[4]; float baseAngle; float angleDiff; float baseRadius; float to_opponent[3]; float sun[3] = {0,0,0}; float tolerance=.02; float a1, a2; float s1 = 0; float s2 = 0; //s1 = score 1 second ago. s2 = current score DEBUG(("time: %4.0f, state: %d\n", time, state)); switch (state) { case 0: //Code to initialize the sphere, then search for the panel... state = 1; break; case 1: //Code to move towards panel initialization circle... if (fabs(myState[0] - (getPanelSide() * 0.7)) < 0.1) state = 2; baseAngle = atan2f(myState[2], myState[1]); target_pos[0] = (getPanelSide() * 0.7); target_pos[1] = cosf(baseAngle) * 0.7; target_pos[2] = sinf(baseAngle) * 0.7; ZRSetPositionTarget(target_pos); Vfunc(9, (sun), (myState), (target_att), 0); ZRSetAttitudeTarget(target_att); //Code to find tangent lines... baseAngle = atan2f(-target_pos[2], -target_pos[1]); angleDiff = asinf(0.5 / sqrtf(mathSquare(target_pos[1]) + mathSquare(target_pos[2]))); tangentPoints[0] = baseAngle - angleDiff; tangentPoints[1] = baseAngle + angleDiff; tangentPoints[2] = tangentPoints[0]; break; case 2: if (getPercentChargeRemaining() >= 95) { state = 3; break; } else { // calc vector from current position back toward sun Vfunc(9, (sun), (myState), (target_att), 0); ZRSetPositionTarget(target_pos); ZRSetAttitudeTarget(target_att); } break; case 3: //Code to wait for the opponent to get into their panel's plane Vfunc(9, (myState), (otherState), (to_opponent), 0); if(fabs(otherState[0] - (getPanelSide() * -0.7) > .10)){ state = 5; break; } else { ZRSetAttitudeTarget(to_opponent); if(fabs(otherState[0] - (getPanelSide() * -0.7)) < .005){ state = 4; break; } } break; case 4: ZRSetPositionTarget(target_pos); Vfunc(9, (myState), (otherState), (to_opponent), 0); if (Vfunc(8, (to_opponent), (myState+6), NULL, 0) < 5 && getPercentChargeRemaining() > 0 && fabs(otherState[0]) > .68 && fabs(otherState[0]) < .81) { DEBUG(("time: %4.0f, (BLUE): ZAPPING ++++++++++++++++++++\n",time)); ZRRepel(); } else { if (getPercentChargeRemaining() < 1) { state = 5; break; } Vfunc(9, (myState), (otherState), (to_opponent), 0); DEBUG(("time: %4.0f, (BLUE): angle to opponent: %f\n",time,Vfunc(8, (to_opponent), (myState+3), NULL, 0))); ZRSetAttitudeTarget(to_opponent); } break; case 5: //Code to search for panel... //Check if panel was found. if (isPanelFound()) { getPanelState(panelState); panelState[4] = panelState[0]; baseAngle = atan2f(panelState[2], panelState[1]); baseRadius = sqrtf(mathSquare(panelState[1]) + mathSquare(panelState[2])) - 0.03; panelState[5] = cosf(baseAngle) * baseRadius; panelState[6] = sinf(baseAngle) * baseRadius; state = 6; break; } //Code to find tangent lines... baseAngle = atan2f(-myState[2], -myState[1]); angleDiff = asinf(0.5 / sqrtf(mathSquare(myState[1]) + mathSquare(myState[2]))); tangentPoints[0] = baseAngle - angleDiff; tangentPoints[1] = baseAngle + angleDiff; //Point in the direction of tangentPoints[2] target_att[0] = 0; target_att[1] = cosf(tangentPoints[2]); target_att[2] = sinf(tangentPoints[2]); ZRSetAttitudeTarget(target_att); if(fabs(otherState[0] - (getPanelSide() * -0.7) < .05 && getPercentChargeRemaining() > 0)){ state = 3; break; } tangentPoints[2] += scanTarget * 0.1; if ((scanTarget == 1) && (tangentPoints[2] >= tangentPoints[1])) scanTarget = -1; else if ((scanTarget == -1) && (tangentPoints[2] <= tangentPoints[0])) scanTarget = 1; target_pos[0] = getPanelSide() * 0.7; target_pos[1] = myState[1]; target_pos[2] = myState[2]; ZRSetPositionTarget(target_pos); break; case 6: //Code to move to panel... if (iHavePanel()) { state = 7; scanTarget = 0; break; } ZRSetPositionTarget(&panelState[4]); Vfunc(7, (panelState), NULL, (target_pos), 0); target_pos[0] = 0; Vfunc(3, (target_pos), NULL, (target_pos), 0); ZRSetAttitudeTarget(target_pos); break; case 7: //Code to beeline towards the station... if (s2 - s1 == 0 && s2 > 0){ state = 8; break; } else { s1 = s2; s2 = getOtherCurrentScore(); getStationState(station); Vfunc(7, (station), NULL, (target_att), 0); target_att[1] += cosf(station[3]) * 0.03; target_att[2] += sinf(station[3]) * 0.03; CoastToTarget(myState, target_att); target_att[0] = 0; target_att[1] = cosf(station[3]); target_att[2] = sinf(station[3]); ZRSetAttitudeTarget(target_att); } break; case 8: //Code to beeline towards the station... target[0] = (getPanelSide() * 0.7); target[1] = 0; target[2] = 0; CoastToTarget(myState, target); break; } }
void ZRUser01(float *myState, float *otherState, float time) { //BEGIN::PROC::ZRUser float opulens[3] = {0.0, -0.6, 0.0}; float Laser[3] = {0.4, 0.0, 0.0}; float shield[3] = {0.0, 0.4, 0.0}; float disrupt[3] = {0.0,0.2,0.0}; float zero[3] = {0.0, 0.0, 0.0}; float difference[3]; float facing[3]; float Asteroid[3] = {0.0, -0.6, 0.0}; int recieved; switch((int)time) { case 0: SphereNumber = !!(myState[0] < 0) + 1; Station[0] = (SphereNumber == 1) ? 0.6 : -0.6; //station closer to where you started break; case 30: getUp = (otherState[1] <= 0); break; case 61: case 66: Spin = PisRevolving(otherState) ? 1 : 0; break; case 75: if(PinAsteroid(otherState) == 1) asteroid = 1; } Laser[0] = ((SphereNumber == 1) - (PotherHasLaser() == SphereNumber)) ? 0.4 : -0.4; recieved = (int)PgetMessage(); switch(recieved) { case 6: if(!(Station[0] < 0.0) && switchedStation++ < 3) Station[0] = -0.6; break; case 7: if(!(Station[0] > 0.0) && switchedStation++ < 3) Station[0] = 0.6; break; case 2: case 3: if(time < 45) asteroid = 1; break; case 4: case 5: if(time < 45) asteroid = 0; break; } if(time <= 120) PsendMessage(4 - 2*asteroid + (Spin == 0)); else PsendMessage((Station[0] < 0) + 6); Asteroid[1] = asteroid ? -0.6 : 0.6; switch(state) { case 0: ZRSetPositionTarget(Laser); shoot(myState, opulens, 0); if(PhaveLaser() || PgetPhase() == 2) state = 1; break; case 1: if(!getUp) { shield[1] = .3; disrupt[1] = .3; } ZRSetPositionTarget(disrupt); shoot(myState, opulens, 0); if(PotherDisruptorUpgraded() || PdisruptorUpgraded()) state = 2; if(PgetPhase() == 2) state = 3; break; case 2: ZRSetPositionTarget(shield); shoot(myState, opulens, 0); if(PotherHasShield() || PhaveShield() || PgetPhase() == 2) state = 3; break; case 3: if(PiceHits() < 15 && !asteroid) shoot(myState, opulens, (PgetPhase() > 1)); if(!(PiceMelted()) && asteroid) { mathVecSubtract(difference, myState, opulens, 3); if(mathVecMagnitude(difference, 3) > .8) ZRSetPositionTarget(opulens); else if(!Spin) ZRSetVelocityTarget(zero); shoot(myState, opulens, (PgetPhase() > 1)); return; } if(Spin){ ZRSetPositionTarget(Asteroid); spin(myState); } else orbit(myState, Asteroid, Station[0] == -0.6); if((!Spin && (time + timeToMS(myState, Station) >= 165)) || (Spin && (time >= 156))) state = 4; break; default: leaveOrbit(myState, Asteroid, Station); mathVecSubtract(facing, otherState, myState, 3); mathVecNormalize(facing, 3); ZRSetAttitudeTarget(facing); if (acos(mathVecInner(&myState[6], facing, 3) / mathVecMagnitude(&myState[6], 3)) < (0.1)) Ptractor(); break; } //END::PROC::ZRUser }
static void revolve (float c[3], float mystate[12], float other[12]) { //BEGIN::PROC::revolve /* * Revolving function */ float v[4]; float q[4]; float a[4]; float a2[4]; float asse[3]; float d; float b; float b2; int dir=sp; if (PisRevolving (other)) { dir = revDir (other,c); if (!dir) dir=sp; } PgetAsteroidNormal(asse); v[3]=0; mathVecSubtract (v,c,mystate,3); d=mathVecMagnitude(v, 3); if(d >= 0.3f) { d=0.2355f/d; // (pi/2)*(0.3/distance) } else { d= 1.57f - 2.615f*d; // pi - (pi/2)*(distance/0.25) } // This creates the quaternion // (yeah, a quaternion, that's cool right?) b=d-1.57f; b2=b*b*b; q[3]=(-b + b2/6 - b2*b*b/120); b2=d*d*d; mathVecMul (q,asse,dir*(d - b2/6 + b2*d*d/120)); // v[] is rotated according to the quaternion funz(a2,q,v); mathVecMul(q,q,-1); funz(a,a2,q); //then it's normalized and converted in velocity mathVecNormalize(a, 3); mathVecMul(a,a,0.0232f); ZRSetVelocityTarget(a); q[3]=1; mathVecMul(q,asse,-dir*0.043619f); funz(a2,q,v); mathVecMul(q,q,-1); funz(a,a2,q); ZRSetAttitudeTarget(a); //END::PROC::revolve }
//User01: blakeelias Team: Stuy-Naught Project: Kill-Retreat void ZRUser01(float *myState, float *otherState, float time) { #define position procvar #define attitude (procvar+3) #define panel_location (procvar+6) memcpy(vOtherPrev, vOther, sizeof(float)*3); //original value copied to previous value memcpy(vOther, otherState+3, sizeof(float)*3); // this is set to the current value // Wait for them to run out of fuel (constant velocity) if ((Vfunc(6, vOther, vOtherPrev, NULL, 0)) <= 0.01) counter++; else counter = 0; DEBUG(("time: %3.0f, SPH%d: state %i\n", time, getPanelSide() == 1 ? 1 : 2, state)); if (state == 1) { //Zapping // Get between the opponent and the sun memcpy(position, otherState, sizeof(float)*3); mathVecNormalize(position, 3); Vfunc(4, position, NULL, position, 0.1); CoastToTarget(myState, position, 0.04); // Face the opponent Vfunc(9, myState, otherState, attitude, 0); ZRSetAttitudeTarget(attitude); // Zap once we see them if (fabs (Vfunc(8, myState+6, attitude, NULL, 0)) < 6.0) { ZRRepel(); } //DEBUG(("Counter = %i \n", counter)); if(iHavePanel()) { if (counter >= 15 || getPercentFuelRemaining() < 10) state = 6; } else { if (counter >= 15 || time > 100) state = 2; else if (getPercentFuelRemaining() < 20) state = 3; } } if (state == 2) { //Moving to panel circle, they're dead if (isPanelFound()) state = 5; else { attitude[0] = 0; attitude[1] = 1*getPanelSide(); attitude[2] = 0; position[0] = .7*getPanelSide(); position[1] = 0; position[2] = 0; CoastToTarget(myState, position, 0.04); ZRSetAttitudeTarget(attitude); if (Vfunc(6, myState, position, NULL, 0) < 0.03) state = 4; } } if (state == 3) { // Retreating to panel, they are alive if (isPanelFound()) state = 5; else { position[0] = .7*getPanelSide(); position[1] = 0; position[2] = 0; CoastToTarget(myState, position, 0.04); } if (Vfunc(6, position, myState, NULL, 0) < 0.03) state = 4; } if (state == 4) { //Finding panel RotateTarget(myState, position); if (isPanelFound()) state = 5; if (iHavePanel()) state = 6; } if (state == 5) { //Get the panel getPanelState(position); attitude[0] = 0.7*getPanelSide(); attitude[1] = attitude[2] = 0; Vfunc(9, attitude, position, attitude, 0); ZRSetAttitudeTarget(attitude); CoastToTarget(myState, position, 0.04); if (iHavePanel()) state++; } if (state == 6) { //Stop if (counter < 15) state = 1; position[0] = position[1] = position[2] = 0; ZRSetVelocityTarget(position); } }