//User-defined procedures static float checkTarget (float other[12], int n) { //BEGIN::PROC::checkTarget /* * checkTarget returns a value * between 1 and 2: an high * value means that the player * "other" is headed towards * the point "c". */ float v[3]={0,0,0}; float a[3]; float c[4][3]= { {-0.5f,+0.31f,-0.55f}, {+0.5f,-0.31f,+0.55f}, {0,-0.35f,-0.2f}, {0,0.35f,0.2f} }; mathVecAdd (v,v,other+3,3); mathVecSubtract (a,c[n],other,3); mathVecNormalize(v, 3); mathVecNormalize(a, 3); mathVecAdd (a,a,v,3); return mathVecMagnitude (a,3); //END::PROC::checkTarget }
static int revDir (float state[12], float c[3]) { //BEGIN::PROC::revDir /* * revDir () returns a value * between -1, 0 and 1: * if 0 is returned, our * opponent is not revolving, * otherwise the number returned * is related to the direction * of the revolving (clockwise * or counterclockwise) */ float asse[3]; float direction[3]; float result[3]; float directionAsteroid[3]; PgetAsteroidNormal(asse); mathVecCross(direction, state+3, asse); mathVecNormalize(direction,3); mathVecSubtract(directionAsteroid, c, state,3); mathVecNormalize(directionAsteroid,3); mathVecAdd(result, direction, directionAsteroid,3); if(mathVecMagnitude(result, 3) > 1.85) { return 1; } else if(mathVecMagnitude(result, 3) < 0.15){ return -1; } else return 0; //END::PROC::revDir }
float angleBetween(float pt1[3], float pt2[3]){ float dot; float vectorBetweenS1[3], vectorBetweenS2[3]; mathVecSubtract(vectorBetweenS1,pt1, origin ,3); mathVecNormalize(vectorBetweenS1,3); mathVecSubtract(vectorBetweenS2,pt2,origin,3); mathVecNormalize(vectorBetweenS2,3); dot = mathVecInner(vectorBetweenS1, vectorBetweenS2, 3); return acosf(dot); }
void loop(){ api.getMyZRState(me); api.getOtherZRState(other); for(int i = 0; i < 9; i++){ if(itemBool[i] && game.hasItem(i) != -1){ itemBool[i] = 0; } } switch(state) { case 0: mathVecSubtract(facing,other,me,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); //api.setPositionTarget(target); if(game.isCameraOn() && game.posInLight(other) && game.isFacingOther()){ DEBUG(("TAKING PICTURES")); game.takePic(); } if(game.getMemoryFilled() == 2) state = 1; break; case 1: game.uploadPics(); if(game.getMemoryFilled() == 0) state = 0; break; case 2: mathVecSubtract(facing,target,other,3); mathVecNormalize(facing,2); api.setAttitudeTarget(facing); setPositionTarget(target,3); if(distance(me,target) < 0.1){ setPositionTarget(target,8); } if(distance(me,target) < 0.03){ state = 0; target[0] = 0.0; target[1] = 0.6; target[2] = 0.0; } break; } }
int CheckPath(float WayPoint[3]) //checks if any debris is on path to a point { int DebID; float Path[3]; mathVecSubtract(Path, WayPoint, self, 3); mathVecNormalize(Path, 3); float VectorBetween[3]; for(DebID = 0; DebID < 16; DebID++) { if(!(game.haveDebris(0, DebID) == true || game.haveDebris(1, DebID) == true)) { mathVecSubtract(VectorBetween, debrisArr[DebID], self, 3); if(dotproduct(Path, VectorBetween) >= 0) { float PathProjection[3] = {dotproduct(Path,VectorBetween) * Path[0],dotproduct(Path,VectorBetween) * Path[1],dotproduct(Path,VectorBetween)* Path[2]}; mathVecSubtract(PathProjection, VectorBetween, PathProjection, 3); if(mathVecMagnitude(PathProjection, 3) < 0.15f) { return DebID; } } } } return -1; }
int which_he_lookin_at( ZRState someone, float locs[][3], int num_locs ) { // Returns the index of the location such that the vector from someone to that // location makes the smallest possible angle with someone's attitude. float min_angle = 10; // any number bigger than PI int ans = num_locs; float angle; float to_loc[3]; // Get the attitude vector. float attitude[3]; memcpy(attitude, &someone[6], 3*sizeof(float)); while (num_locs > 0) { // Construct the vector from someone to loc[i]. to_loc[0] = locs[num_locs][0] - someone[0]; to_loc[1] = locs[num_locs][1] - someone[1]; to_loc[2] = locs[num_locs][2] - someone[2]; mathVecNormalize(to_loc, 3); // Find the angle between attitute and to_loc. angle = acosf(mathVecInner(attitude, to_loc, 3)); // If this is the smallest angle so far, update ans and min_angle. if (angle < min_angle) { ans = num_locs; min_angle = angle; } num_locs--; } // Return the index of the location in locs that produced the smallest angle. return ans; }
void moveTo(float target[3]){ float cross[3]; float sub[3]; float o = zrstate[0] * target[0] + zrstate[1] * target[1] + zrstate[2] * target[2]; mathVecCross(cross,zrstate,target); mathVecSubtract(sub,zrstate,target,3); float d = mathVecMagnitude(cross,3) / mathVecMagnitude(sub,3); if (d > 0.33 || o > 0.1){ //change o > _ to get difference tolerances api.setPositionTarget(target); }else{ float tmp[3]; float loc[3]; loc[0] = zrstate[0]; loc[1] = zrstate[1]; loc[2] = zrstate[2]; //mathVecAdd(tmp,target,?,3); findTangPoint(tmp,loc,target,0.33); DEBUG(("COLLISION COURSE -> NEW COURSE (%f, %f, %f)\n",tmp[0],tmp[1],tmp[2])); mathVecNormalize(sub,3); int i = 0; for (;i < 3;i++){ sub[i] = 0.2 * sub[i]; } mathVecAdd(tmp,tmp,sub,3); api.setPositionTarget(tmp); } }
void calcNewTarget(float newTarget[], float target[]) { float magMe, meToTarget[3], normal[3], theta, rotationMatrix[3][3], test1[3], test2[3]; magMe = mathVecMagnitude(me, 3); mathVecSubtract(meToTarget, target, me, 3); mathVecCross(normal, me, meToTarget); // normal to the plane containing Me, target, and origin mathVecNormalize(normal, 3); // normalize the normal theta = asinf((0.33 - minDistanceFromOrigin(target)) / sqrtf(magMe * magMe - 0.33 * 0.33)); // angle between meToTarget and "me to tangent point" DEBUG(("theta = %f radians\n", theta)); // THIS IS THE ERROR!!! mathVecRotate(rotationMatrix, normal, theta); DEBUG(("rotationMatrix = {{%f, %f, %f}, {%f, %f, %f}, {%f, %f, %f}}\n", rotationMatrix[0][0], rotationMatrix[0][1], rotationMatrix[0][2], rotationMatrix[1][0], rotationMatrix[1][1], rotationMatrix[1][2], rotationMatrix[2][0], rotationMatrix[2][1], rotationMatrix[2][2])); // creates the rotation matrix about the normal by an angle of theta mathMatVecMult(test1, rotationMatrix, meToTarget); // rotates meToTarget by an angle theta mathVecAdd(test1, test1, me, 3); mathVecRotate(rotationMatrix, normal, -theta); // creates the rotation matrix about the normal by the opposite angle mathMatVecMult(test2, rotationMatrix, meToTarget); // rotates meToTarget by an angle theta mathVecAdd(test2, test2, me, 3); if (minDistanceFromOrigin(test1) > 0.32) { for (int i = 0; i < 3; i++) newTarget[i] = test1[i]; } else { for (int i = 0; i < 3; i++) newTarget[i] = test2[i]; } }
void moveTo(float target[]) { float disp[3]; float dist, speed; mathVecSubtract(disp, target, me, 3); dist = mathVecNormalize(disp, 3); //disp normalized to unit vector, holds direction of desired velocity /* Condition here is based off of equation: d = (1/2)at^2 + vt * a = 0.01, which is the approx maximum acceleration I have experimentally found of a SPHERE * I assume t = 8s, which works and is faster then api.setPositionTarget * You can change t if there is an overshoot */ if (dist > 0.5*0.01*64+mathVecMagnitude(me+3,3)*8) { speed = dist; for(n = 0; n < 3; n++) { //scale velocity (disp) to speed disp[n] *= speed; } api.setVelocityTarget(disp); } else { api.setPositionTarget(target); } }
//--------------------------------------HELPER METHODS-------------------------------------------// void facePos(float target[3], float myPos[3]){ //Rotate to target float attTarget[3]; mathVecSubtract(attTarget,target,myPos,3); mathVecNormalize(attTarget,3); api.setAttitudeTarget(attTarget); if (distanceVec(myPos, target)< 0.50) { //DEBUG(("The SPHERE is close enough to take a picture. ")); // if (game.alignLine(targetPOI)==true) { if (timeSinceArrival > 4) //5 seconds between pictures, 5 seconds after arriving at POI { DEBUG(("\n Pictures: %d", picturesTaken+1)); // game.takePic(targetPOI); picturesTaken++; timeSinceArrival = 0; } timeSinceArrival++; } } //return distance(attTarget, myPos); }
float facePos(float target[3]){ //Points sphere to passed target //Rotate to target float attTarget[3]; mathVecSubtract(attTarget,target,myState,3); mathVecNormalize(attTarget,3); api.setAttitudeTarget(attTarget); return distance(attTarget,&myState[6]); }
void calcularattitude(){ float vect[3]; game.getPOILoc(posicionPOI, PoiID); api.getMyZRState(posicionSatelite); mathVecSubtract(norm,posicionPOI,posicionSatelite,3); mathVecNormalize(norm,3); DEBUG(("Vector calculado.\n")); }
void drift(float target[3], float speed) { float diff[3]; mathVecSubtract(diff,target,self,3); mathVecNormalize(diff,3); for(int i = 0; i < 3; i ++) { diff[i] *= speed; } api.setVelocityTarget(diff); }
void findTangPoint(float result[3], float point[3],float targ[3], float r) { float DNorms[3]; float D = mathVecMagnitude(point,3); mathVecNormalize(point,3); mathVecNormalize(targ,3); mathVecSubtract(DNorms,targ,point,3); mathVecNormalize(DNorms,3); float alpha = acosf(r/D); float beta = angleBetween(point,DNorms); float theta = beta - alpha; float dist = sinf(alpha)/sinf(theta); DNorms[0] = DNorms[0]*dist; DNorms[1] = DNorms[1]*dist; DNorms[2] = DNorms[2]*dist; mathVecAdd(result,point,DNorms,3); mathVecNormalize(result,3); result[0] = result[0] * r; result[1] = result[1] * r; result[2] = result[2] * r; }
//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 arcMove(float posTarget2[3]) { float midpoint[3] = {(myPos[0]+posTarget2[0])/2, (myPos[1]+posTarget2[1])/2, (myPos[2]+posTarget2[2])/2}; if (mathVecMagnitude(midpoint,3) < 0.35) { mathVecNormalize(midpoint,3); for (int i = 0; i<3; i++) { midpoint[i] *= 0.45; } api.setPositionTarget(midpoint); DEBUG((" | Heading to waypoint | ")); } else { api.setPositionTarget(posTarget2); } }
bool isAligned(){ api.getMyZRState(posicionSatelite); game.getPOILoc(posicionPOI, PoiID); float dir[3]; mathVecSubtract(dir,posicionPOI,posicionSatelite,3); mathVecNormalize(dir,3); float dotProd; dotProd = mathVecInner(dir,&posicionSatelite[6],3); if(dotProd>.985){ return true; } else{ return false; } }
static void leaveOrbit (float myState[12], float asteroidLoc[3], float mPanel[3]) { //BEGIN::PROC::leaveOrbit #define SinAngle(a, b) sqrt(1 - mathSquare(mathVecInner((a), (b), 3)/(mathVecMagnitude((a), 3) * mathVecMagnitude((b), 3)))) float targetVel[3]; float r, toMS; float desiredMag; float vecToAst[3]; float vecToMS[3]; int i; for(i = 0; i < 3; i++){ vecToAst[i] = asteroidLoc[i] - myState[i]; vecToMS[i] = mPanel[i] - myState[i]; } toMS = mathVecMagnitude(vecToMS, 3); r = sqrt(mathVecInner(vecToAst, vecToAst, 3)); for(i = 0; i < 3; i++) targetVel[i] = mPanel[i] - myState[i]; if(toMS < .19){ if(mathVecMagnitude(&myState[3], 3) > 0.01) desiredMag = 0.002; else desiredMag = 0.01; } else if(toMS < 0.25) desiredMag = toMS/12; else if(toMS < 0.35) desiredMag = toMS/7; else desiredMag = r*3.141592/(45*SinAngle(vecToAst, &myState[3])); if(desiredMag > toMS/6) desiredMag = toMS/6; mathVecNormalize(targetVel, 3); for(i = 0; i < 3; i++) targetVel[i] *= desiredMag; ZRSetVelocityTarget(targetVel); //ZRSetAttitudeTarget(att); //END::PROC::leaveOrbit }
static void CoastToTarget(float* myPos, float* coastTarget, float magnitude) { float temp[3]; if (magnitude > 0.04) magnitude = 0.04; Vfunc(2, (coastTarget), (myPos), (temp), 0); if (mathVecMagnitude((temp), 3) < (mathSquare(mathVecMagnitude((&myPos[3]), 3)) * 50.0 + 0.08)) { ZRSetPositionTarget(coastTarget); } else { mathVecNormalize((temp), 3); Vfunc(4, (temp), NULL, (temp), (magnitude)); if (Vfunc(6, (temp), (&myPos[3]), NULL, 0) > 0.02) ZRSetVelocityTarget(temp); } }
void target_enemy(){ api.getMyZRState(me); api.getOtherZRState(other); float temp[3]; //stores vector between me and other temp[0] = other[0] - me[0]; temp[1] = other[1] - me[1]; temp[2] = other[2] - me[2]; enemy_distance = mathVecNormalize(temp, 3); enemy_direction[0] = temp[0]; enemy_direction[1] = temp[1]; enemy_direction[2] = temp[2]; enemy_position[0] = other[0]; enemy_position[1] = other[1]; enemy_position[2] = other[2]; }
static float Vfunc(int which, float * v1, float * v2, float * vresult, float scalar) { int i; float vtemp[3]; if (which == 2) { // vresult = v1 - v2 Vfunc(4,v2,NULL,vtemp,-1); mathVecAdd(vresult,v1,vtemp,3); return 0; } if (which == 3) { // vresult = v1 / |v1|; if |v1| == 0, returns 0, else 1 memcpy(vresult, v1, sizeof(float)*3); mathVecNormalize(vresult,3); return 0; } if (which == 4) { // vresult = scalar * v1 for (i = 0; i < 3; ++i) vresult[i] = scalar * v1[i]; return 0; } if (which == 5) { // returns dot product: v1 * v2 return mathVecInner(v1,v2,3); } if (which == 6) { // returns distance between v1 and v2 float v3[3]; Vfunc(2,v1,v2,v3,0); // v3 = v1 - v2 return mathVecMagnitude(v3,3); } if (which == 8) { // angle between two vectors float dot = Vfunc(5,v1,v2,NULL,0)/(mathVecMagnitude(v1,3)*mathVecMagnitude(v2,3)); return acos(dot)*180.0/3.14159265; } if (which == 9) { // unit vector pointing from v1 toward v2 float v9[3]; Vfunc(2,v2,v1,v9,0); return Vfunc(3,v9,NULL,vresult,0); } }
bool isInShot(){ float currentAimVector[3]; currentAimVector[0] = self[6]; currentAimVector[1] = self[7]; currentAimVector[2] = self[8]; mathVecNormalize(currentAimVector, 3); float VectorBetween[3]; mathVecSubtract(VectorBetween, arbState, self, 3); if(dotproduct(currentAimVector, VectorBetween) >= 0) { float PathProjection[3] = {dotproduct(currentAimVector,VectorBetween) * currentAimVector[0],dotproduct(currentAimVector,VectorBetween) * currentAimVector[1],dotproduct(currentAimVector,VectorBetween)* currentAimVector[2]}; mathVecSubtract(PathProjection, VectorBetween, PathProjection, 3); if(mathVecMagnitude(PathProjection, 3) < 0.07f) { return true; } } return false; }
void doOrbit(float targetPos[3],float speed){ float angle = 0.0f; float radius = mathVecMagnitude(myState,3); //Safety if(radius>.6f) radius = .6f; //Calculate Current Angle angle = acosf(myState[0]/(sqrtf(powf(myState[0],2)+powf(myState[1],2)+powf(myState[2],2)))); if(myState[1]<0){ angle=2*PI-angle; } mathVecSubtract(tempVec,targetPos,myState,3); if(tempVec[0]==0) tempVec[0]=-1; if(tempVec[1]==0) tempVec[1]=-1; //Calc Orbit Direction if(fabsf(tempVec[1])/tempVec[1]*fabsf(tempVec[0])/tempVec[0]>0){ angle-=(20*PI/180);//clockwise } else{ angle+=(20*PI/180); } //Calculate position on orbit circle targetPos[0] = radius * cosf(angle); targetPos[1] = radius * sinf(angle); //Rotate to 3D mathVecAdd(tempVec,myState,otherState,3); mathVecNormalize(tempVec,3); float xAxis[3] = {1.0f,0.0f,0.0f}; float yAxis[3] = {0.0f,1.0f,0.0f}; float zAxis[3] = {0.0f,0.0f,1.0f}; float rots[3] = {mathVecInner(tempVec,xAxis,3),mathVecInner(tempVec,yAxis,3),mathVecInner(tempVec,zAxis,3)}; rotate(targetPos,targetPos,rots); setPos(targetPos,speed); }
/* MAIN ***********************************************************************/ void loop() { //blah(); updateGameState(); changeState(); if (game.getEnergy() < ENERGY_SHUTDOWN_THRESHOLD) { api.setVelocityTarget(origin); return; } switch (att_state) { case FACE_OTHER: mathVecSubtract(temp, other, me, 3); api.setAttitudeTarget(temp); if (checkPhoto()) { game.takePic(); } break; case UPLOAD: temp[0] = 0.0f; temp[1] = 0.0f; temp[2] = 1.0f; api.setAttitudeTarget(temp); if (checkUpload()) { game.uploadPics(); } break; } switch (move_state) { case GET_SCORE_PACKS: if (game.getScore() == 0) { mathVecAdd(temp, me, me + 3, 3); // where we will be if (!game.posInDark(temp)) { api.setVelocityTarget(origin); // steady... } else { temp[0] = game.getCurrentTime(); if (temp[0] < 4 || temp[0] > 17) { api.setPositionTarget(items[itemID]); } } } else { api.setPositionTarget(items[itemID]); } break; case END_GAME: memcpy(temp, other, 3 * sizeof(float)); mathVecNormalize(temp, 3); mathVecMultiply(temp, -0.3, 3); mathVecAdd(target, temp, other, 3); api.setPositionTarget(target); break; case TO_ORIGIN: api.setPositionTarget(origin); break; } }
void loop() { api.getMyZRState(me); if(api.getTime() % 60 == 0 && state != 4) state = 0; DEBUG(("State = %d\n", state)); picNum = game.getMemoryFilled(); // Solar Storm Evasion if (api.getTime() == (solarFlareBegin - 1)) { DEBUG(("I shall now reboot.\n")); game.turnOff(); game.turnOn(); state = 0; } else if (api.getTime() >= (solarFlareBegin) && api.getTime() <= (solarFlareBegin + 2)) { DEBUG(("Ah shit, it's a flare!\n")); } else if (game.getNextFlare() != -1) { solarFlareBegin = api.getTime() + game.getNextFlare(); DEBUG(("Next solar flare will occur at %ds.\n", solarFlareBegin)); } else { DEBUG(("I don't know when the next flare is, so stop asking.\n")); solarFlareBegin = 1000; // fixes a glitch that makes game.getNextFlare() //return 30s at some random point in the beginning of the game, //and from then on returns -1 until the next actual flare, so that the //SPHERE reboots for no reason } switch (state) { case 0: // POI Selection game.getPOILoc(POI,0); game.getPOILoc(otherPOI,1); if (distance(me,otherPOI) <= distance(me,POI)) { POIID = 1; for (int i = 0; i < 3; i++) POI[i] = otherPOI[i]; } else POIID = 0; DEBUG(("POI Coors = %f,%f,%f\n",POI[0],POI[1],POI[2])); for (int i = 0; i < 3; i++) { brakingPos[i] = POI[i] * 2.0; } state = 1; break; case 1: // Orbit Function here if (velocity(me) < 0.001) state = 2; else { setPositionTarget(brakingPos); mathVecSubtract(facing,POI,me,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); } break; case 2: // Legacy Code to me setPositionTarget(brakingPos); mathVecSubtract(facing,POI,me,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); game.takePic(POIID); if (picNum > 0) { DEBUG(("%d picture(s) have been taken\n", picNum)); for (int i = 0; i < 3; i++) { uploadPos[i] = me[i] / mathVecMagnitude(me, 3) * 0.6; } setPositionTarget(uploadPos); state = 3; } break; case 3: // Taking pic in outer zone for (int i = 0; i < 3; i++) { brakingPos[i] = POI[i] * 2.5; } if (picNum > 1) { DEBUG(("%d picture(s) have been taken.\n", picNum)); for (int i = 0; i < 3; i++) { uploadPos[i] = me[i] / mathVecMagnitude(me, 3) * 0.6; } setPositionTarget(uploadPos); state = 4; } else { api.setPositionTarget(brakingPos); mathVecSubtract(facing,POI,me,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); game.takePic(POIID); } case 4: // Upload the picture if (velocity(me) < 0.01 && distance(me,uploadPos) < 0.05) { game.uploadPic(); DEBUG(("I just uploaded %d picture(s).\n", picNum)); DEBUG(("I am in state %d.\n", state)); //Why the f**k does it say it's in State 3??? state = 0; } else { mathVecSubtract(facing,POI,me,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); api.setPositionTarget(uploadPos); game.takePic(POIID); } break; } if (api.getTime() >= (solarFlareBegin - 3)) { setPositionTarget(me); DEBUG(("Screw the mission; I'm staying here!\n")); } // prevents crashing during reboot }
void setMagnitude(float vector[3], float magnitude) { // Normalising a vector is to make its magnitude one, but preserve its direction. // As such, if you normalise it, its magnitude is now one, and so if you then multiply it by a particular amount, that will be the magnitude. mathVecNormalize(vector, 3); multiplyVectorByScalar(vector, vector, magnitude); }
void loop() { api.getMyZRState(myState); time = api.getTime(); picNum = game.getMemoryFilled(); DEBUG(("%d picture(s) have been taken\n", picNum)); DEBUG(("STATE = %d\n",state)); DEBUG(("ARRAY = %d,%d,%d\n",goodPOI[0],goodPOI[1],goodPOI[2])); DEBUG(("TARGET = %f,%f,%f\n",target[0],target[1],target[2])); if(takePic > -1){ //takePic is used to make sure you take an accurate picture. takePic--; } if(time%60 == 0){ for(int i = 0; i < 3; i++){ goodPOI[i] = 1; } state = ST_GET_POI; } if((time > solarFlareBegin - 25)&&(time < solarFlareBegin)){ if((state < ST_SHADOW)||(state > ST_SHADOW + 9)){ state = ST_SHADOW; //if not in shadow state go there. } } else if(time == solarFlareBegin + 3){ state = ST_GET_POI + 1; } else if (game.getNextFlare() != -1) { solarFlareBegin = api.getTime() + game.getNextFlare(); DEBUG(("Next solar flare will occur at %ds.\n", solarFlareBegin)); } switch(state){ case ST_GET_POI: //POI selection closestPOI(goodPOI,POI,23); getPOILoc(POIproj, POIID, 23); takePic = 23; //25 probably needs to be changed. only good for the first cycle. DEBUG(("POI Coors = %f,%f,%f\n",POI[0],POI[1],POI[2])); state = ST_OUTER; break; case ST_GET_POI + 1: //if coming from shadow zone closestPOI(goodPOI,POI,30); getPOILoc(POIproj, POIID, 30); takePic = 30; //25 probably needs to be changed. only good for the first cycle. DEBUG(("POI Coors = %f,%f,%f\n",POI[0],POI[1],POI[2])); state = ST_OUTER; break; case ST_OUTER: //outer picture wp = false; //find closest place to take picture memcpy(target, POIproj, 3*sizeof(float)); //copy the projected POI location to target for(int i = 0; i < 3; i++){ target[i] *= 0.465/mathVecMagnitude(POI,3); //dilate target to outer zone } mathVecSubtract(facing,origin,target,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); if(pathToTarget(myState,target,waypoint)){ setWaypoint(waypoint,originalVecBetween); state = ST_OUTER + 1; for (int i = 0; i < 3; i++) tempTarget[i] = target[i]; } else{ state = ST_OUTER + 2; } break; case ST_OUTER + 1: //something is in the way so go to waypoint wp = true; mathVecSubtract(facing,POIproj,target,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); if(goToWaypoint(target,waypoint,tempTarget,originalVecBetween)){ goToWaypoint(target,waypoint,tempTarget,originalVecBetween); } else{ state = ST_OUTER + 2; } break; case ST_OUTER + 2://go to target mathVecSubtract(facing,origin,myState,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); toTarget(); if(takePic == 0){ game.takePic(POIID); } if(game.getMemoryFilled() > checkNum){ checkNum++; getPOILoc(POIproj, POIID, 5); state = ST_INNER; } break; case ST_INNER: //inner picture wp = false; memcpy(target, POIproj, 3*sizeof(float)); for(int i = 0; i < 3; i++){ target[i] *= 0.34/mathVecMagnitude(POI,3); } mathVecSubtract(facing,POIproj,target,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); haulAssTowardTarget(target,8); state = ST_INNER + 1; break; case ST_INNER + 1: //after outer picture is taken, rush to inner zone. mathVecSubtract(facing,POIproj,myState,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); if(distance(myState,target)<0.02){ haulAssTowardTarget(target,10); } else{ haulAssTowardTarget(target,2); } if(game.alignLine(POIID)){ game.takePic(POIID); } if(game.getMemoryFilled() > checkNum){ checkNum++; state = ST_UPLOAD; } break; case ST_SHADOW: //shadow zone wp = false; target[0] = 0.39; //arbitrary point in the shadow zone target[1] = 0.00; target[2] = 0.00; if(pathToTarget(myState,target,waypoint)){ setWaypoint(waypoint,originalVecBetween); goToWaypoint(target,waypoint,tempTarget,originalVecBetween); state = 31; } else{ state = 32; } break; case ST_SHADOW + 1: wp = true; if(goToWaypoint(target,waypoint,tempTarget,originalVecBetween)){ goToWaypoint(target,waypoint,tempTarget,originalVecBetween); } else{ toTarget(); state = 32; } break; case ST_SHADOW + 2: mathVecSubtract(facing,earth,myState,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); toTarget(); game.uploadPic(); break; case ST_UPLOAD: //upload, needs to be fixed for(int i = 0; i < 3; i++){ uploadPos[i] = myState[i] / mathVecMagnitude(myState, 3) * 0.65; } mathVecSubtract(facing,earth,uploadPos,3); mathVecNormalize(facing,3); api.setAttitudeTarget(facing); haulAssTowardTarget(uploadPos,1.8); state = ST_UPLOAD + 1; break; case ST_UPLOAD + 1: //get to the closest place, keep trying to upload api.setAttitudeTarget(facing); if(distance(myState,origin)>0.54){ api.setPositionTarget(myState); game.uploadPic(); } else{ if(distance(myState,origin)>0.51){ api.setPositionTarget(uploadPos); } else{ haulAssTowardTarget(uploadPos,1.8); } } if(picNum == 0){ DEBUG(("LOOKING FOR POI")); state = ST_GET_POI; } break; } }
void attToTarget (vec satPos, vec targetPos, vec att) { mathVecSubtract(att, targetPos, satPos, 3); mathVecNormalize(att, 3); }
void displace(float p1[], float p2[]){ mathVecSubtract(temp,p1,p2,3); mathVecNormalize(temp,3); memcpy(tarVec,temp,3*sizeof(float)); }
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 }