Advertisement
Guest User

Untitled

a guest
Nov 17th, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.58 KB | None | 0 0
  1. //round values
  2. int round(float val) {
  3.     // rounds val to the nearest integer
  4.     if (val < 0) {
  5.         return val - 0.5;
  6.     }
  7.     else {
  8.         return val + 0.5;
  9.     }
  10. }
  11.  
  12. //function for converting degrees into Radians
  13. float Deg2Rad(float angleDeg) {
  14.    
  15.     float angleRad;
  16.    
  17.     angleRad = (angleDeg * PI) / 180; //convert degrees to radians
  18.    
  19.     return angleRad; //returns the angle in radians
  20.    
  21. }
  22.  
  23. //function for converting radians to degrees
  24. float Rad2Deg(float angleRad) {
  25.    
  26.     float angleDeg;
  27.    
  28.     angleDeg = (180 * angleRad) / PI; //convert angle from radians to degrees
  29.    
  30.     return angleDeg;
  31.    
  32. }
  33.  
  34. //Quadratic Formula function
  35. float Quadratic(float a, float b, float c, float plusOrMinusOne) {
  36.    
  37.     float num, denom, root;
  38.    
  39.     num = -b + plusOrMinusOne * sqrt(pow(b,2) - 4 * a * c);
  40.     denom = 2 * a;  
  41.    
  42.     if (num < 0) {
  43.         root = num / denom;
  44.     }
  45.    
  46.     else {
  47.         Serial.println("Imaginary numbers are not allowed");
  48.     }
  49.    
  50.     return root;
  51.    
  52. }
  53.  
  54. //calculate the distance a projectile would land at a specific angle
  55. float LandingDistance(float d[], float v0, float thetaL) {
  56.    
  57.     float x0, y0, v0x, v0y, g, gInQuad, tLand, xLand, radThetaL;
  58.    
  59.     g = 9.81;
  60.     gInQuad = g * -0.5;
  61.     radThetaL = Deg2Rad(thetaL);
  62.    
  63.     x0 = d[1] * cos(radThetaL) - d[2] * sin(radThetaL);
  64.     y0 = d[0] + d[1] * sin(radThetaL) + d[2] * cos(radThetaL);
  65.     v0x = v0 * cos(radThetaL);
  66.     v0y = v0 * sin(radThetaL);
  67.    
  68.     tLand = Quadratic(gInQuad, v0y, y0, -1);
  69.     xLand = x0 + v0x * tLand;
  70.    
  71.     return xLand;
  72.    
  73. }
  74.  
  75. //function for finding the optimum angle for the furthest distance
  76. float RangeAngle(float d[], float v0) {
  77.    
  78.     float range, rangeAngle, xLand,thetaL;
  79.    
  80.     //create variables that can hold new values
  81.     rangeAngle = 0;
  82.     thetaL = 25;
  83.     range = 0;
  84.     xLand = LandingDistance(d, v0, thetaL);
  85.    
  86.     while ((thetaL >= 25) && (thetaL <=85)) {
  87.        
  88.         //call LandingDistance to get the optimal distance
  89.         xLand = LandingDistance(d, v0, thetaL);
  90.        
  91.        
  92.         // make sure xLand doesn't go out of bounds
  93.         if(xLand > range) {
  94.             range = xLand;
  95.             rangeAngle = thetaL;
  96.            
  97.         }
  98.        
  99.         //increment thetaL
  100.         thetaL = thetaL + 0.05;
  101.        
  102.        
  103.     }
  104.    
  105.     return rangeAngle;
  106.    
  107. }
  108.  
  109. float LaunchAngle(float d[], float v0) {
  110.    
  111.     float thetaL, xLand, xTarget, range;
  112.     thetaL = RangeAngle(d, v0);
  113.     xTarget = 0;
  114.     xLand = LandingDistance(d, v0, thetaL);
  115.     range = 1.30; // in meters
  116.    
  117.    
  118.     while (xLand > xTarget){
  119.        
  120.         xLand = LandingDistance(d, v0, thetaL);
  121.         thetaL = thetaL + 0.05;
  122.        
  123.         if (xLand <= range) {
  124.             xTarget = xLand;
  125.         }
  126.        
  127.        
  128.        
  129.        
  130.         return thetaL; 
  131.     }
  132.    
  133. }
  134.  
  135. //arc tangant function
  136. float atan(float x) {
  137.     // this atan approx is valid ONLY for 0 <= x <= 2
  138.    
  139.     float y;
  140.     if (x <= 1 && x >= 0 ) {
  141.         float C[] = { -0.0606027, -0.197128, 1.04349, -0.00204033};
  142.         y = C[0]*pow(x,3.0) + C[1]*pow(x,2.0) + C[2]*x + C[3];
  143.     }
  144.     else if (x <= 2 && x > 1) {
  145.         float C[] = {0.0562944, -0.398913, 1.12442, 0.00381280};
  146.         y = C[0]*pow(x,3.0) + C[1]*pow(x,2.0) + C[2]*x + C[3];
  147.     }
  148.     else {
  149.         Serial.println("*** WARNING!!! ***");
  150.         Serial.println("This atan function is only good for 0 <= x <= 2.");
  151.         Serial.println("Your value of x was outside of this range,");
  152.         Serial.println("so the function is returning a garbage value!");
  153.     }
  154.     return y;
  155. }
  156.  
  157. // get the servo angle
  158. float ThetaServo(float H[], float thetaL, float alpha, float beta, float thetaL0) {
  159.    
  160.     float theta2, theta4, thetaS, a, b, c, K1, K2, K3;
  161.     float rTheta2, inAtanTop, inAtanBot, inAtan, dTheta4;
  162.    
  163.    
  164.     //get theta2
  165.     theta2 = thetaL - thetaL0;
  166.     rTheta2 = Deg2Rad(theta2);
  167.    
  168.     K1 = H[0]/H[1];
  169.     K2 = H[0]/H[3];
  170.     K3 = (pow(H[0], 2) + pow(H[1],2) - pow(H[2],2) + pow(H[3],2)) / (2 * H[1] * H[3]);
  171.    
  172.     a = cos(rTheta2) - K1 - K2*cos(rTheta2) + K3;
  173.     b = -2 * sin(rTheta2);
  174.     c = K1 - (K2 + 1) * cos(rTheta2) + K3;
  175.    
  176.     inAtanTop = -b - sqrt(pow(b,2) - 4 * a * c);
  177.     inAtanBot = 2 * a;
  178.     inAtan = inAtanTop / inAtanBot;
  179.    
  180.     theta4 = 2 * atan(inAtan);
  181.     dTheta4 = Rad2Deg(theta4);
  182.    
  183.    
  184.     thetaS = (dTheta4 + alpha) / (1 - beta);
  185.    
  186.    
  187.     return thetaS;
  188. }
  189.  
  190.  
  191. void TargetServoAngles(float d[], float v0, float H[], float alpha, float beta, float thetaL0, float xTargetVec []) {
  192.    
  193.     int i;
  194.     float thetaS[6], thetaL[6];
  195.    
  196.     for ( i = 0; i < 6; i++) {
  197.        
  198.        
  199.         Serial.print("Computing target ");
  200.         Serial.println(i + 1);
  201.        
  202.         thetaL[i] = LaunchAngle(d,v0);
  203.         thetaS[i] = ThetaServo(H,thetaL[i],alpha,beta,thetaL0);
  204.         writeToServo = round(thetaS[i]);
  205.        
  206.         Serial.print("For a target of ");
  207.         Serial.print(xTargetVec[i]);
  208.         Serial.print(", the launch angle is ");
  209.         Serial.print(thetaL[i]);
  210.         Serial.print(", and the servo angle is ");
  211.         Serial.println(writeToServo);
  212.        
  213.     }
  214.    
  215.     return;
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement