Clone of UAS2 @ https://github.com/drudgedance/uas2

calc_funcs.c 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /* calc_funcs.c
  2. *
  3. * Calculation Functions
  4. *
  5. * Ver 1.0 1998.08.25 Keiji nagatani
  6. * Ver 3.0 2001.02.13 Ryosuke Sakai
  7. * (rsakai@andrew)
  8. * Ver 3.2 2002.05.25 Deryck Morales
  9. * <deryck@alumni.carnegiemellon.edu>
  10. * Nick Jong
  11. * <nkj@andrew.cmu.edu>
  12. */
  13. #include "calc_funcs.h"
  14. /*************************
  15. * PRIVATE PROTOTYPES *
  16. *************************/
  17. double sin_deg(double value);
  18. double cos_deg(double value);
  19. /*************************
  20. * PUBLIC FUNCTIONS *
  21. *************************/
  22. /*
  23. * Scales the given angle to its value in the range: [-180,180] degrees.
  24. * Units for "angle" are in 1/10 degree (so 180 deg = 1800)
  25. *
  26. * The scaled value in 1/10 degrees is returned.
  27. */
  28. int fix_angle(int angle)
  29. {
  30. while (angle < -1800)
  31. angle += 3600;
  32. while (angle > 1800)
  33. angle -= 3600;
  34. return(angle);
  35. }
  36. /*
  37. * Calculates angle between dir1 and dir2 and scales to the range: [1,3599]
  38. * This calculated value is then returned.
  39. * Units are in 1/10 degrees.
  40. */
  41. int calc_sup_angle(int dir1, int dir2)
  42. {
  43. if ((dir2 - dir1) > 0) return(dir2 - dir1);
  44. else return(dir2 + 3600 - dir1);
  45. }
  46. /*
  47. * The angle between x and y is scaled to the range: [0,1800]
  48. * This calculated value is then returned.
  49. * Units are in 1/10 degrees.
  50. */
  51. int calc_diff_angle(int x, int y)
  52. {
  53. int diff;
  54. diff = abs(x - y);
  55. if (diff > 1800) return(abs(diff - 3600));
  56. else return(diff);
  57. }
  58. /*
  59. * The bisector of angles dir1 and dir2 is calculated and returned.
  60. * Units are in 1/10 degrees.
  61. */
  62. int calc_middle_angle(int dir1, int dir2)
  63. {
  64. if ((dir2 - dir1) > 0){return(fix_angle((dir2 + dir1)/2));}
  65. else {return(fix_angle((dir2 + 3600 + dir1)/2));}
  66. }
  67. /*
  68. * Angle "val" is converted to (160 index), which corresponds to the ring of 16 sonar.
  69. * This index value is then returned.
  70. * Units are 1/10 degrees and 160 index (1/10th of 16).
  71. */
  72. int deg_to_index_160(int val)
  73. {
  74. int idx;
  75. idx = val * 2 / 45; /* (idx = val/22.5) */
  76. if (idx < 0) idx += 160;
  77. return(idx);
  78. }
  79. /*
  80. * 160 index value "idx" is converted to 1/10 degrees.
  81. * This angle is then returned.
  82. * Units are 1/10 degrees and 160 index. (see deg_to_index_160).
  83. */
  84. int index_160_to_deg(int idx)
  85. {
  86. return(fix_angle(idx * 45 / 2));
  87. }
  88. /*
  89. * Rotate <x,y> ==> <nx,ny> by theta
  90. * The point (x,y) is rotated about the origin by "ang" degrees.
  91. * The resultant point is stored to "nx" and "ny" (new x and y)
  92. */
  93. void calc_rotation(int x, int y, int ang, int *nx, int *ny)
  94. {
  95. double dx, dy;
  96. dx = (double)x; dy = (double)y;
  97. *nx = (int)(dx * cos_deg((double)ang/10.0) - dy*sin_deg((double)ang/10.0));
  98. *ny = (int)(dx * sin_deg((double)ang/10.0) + dy*cos_deg((double)ang/10.0));
  99. }
  100. /*
  101. * Convert <degree, value> ==> <x,y>
  102. * Polar to rectangular conversion.
  103. *
  104. * ^ \
  105. * *y | / r = val
  106. * | / deg = deg
  107. * |/\
  108. * +---> *x
  109. */
  110. void calc_XY_from_deg_val(int deg, int val, int *x, int *y)
  111. {
  112. double ddeg;
  113. /* calculate radian */
  114. ddeg = ((double)deg)*PAI/1800.0;
  115. /* calculate distance */
  116. *x = (int)(cos(ddeg)*(double)val);
  117. *y = (int)(sin(ddeg)*(double)val);
  118. }
  119. /*
  120. * Convert <vx, vy> ==> <degree>
  121. * Given vector coordinates vx,vy, calculate vector angle.
  122. * This calculated value is returned.
  123. * Units are 1/10 degrees.
  124. */
  125. int calc_vec_to_deg(int vx, int vy)
  126. {
  127. double deg;
  128. deg = atan2((double)vy, (double)vx)*1800.0 / PAI;
  129. if (deg < 0.0) deg+=3600.0;
  130. return((int)deg);
  131. }
  132. /* -------------------------------------------
  133. * calculate the point on line L<lx,ly,ldir>
  134. * which is vertical to P<px,py>
  135. * Called by:
  136. * ROBOT-FUNCS\trace.c
  137. *
  138. * point P
  139. * |
  140. * |
  141. * lineL ---L---R---------
  142. * -------------------------------------------
  143. */
  144. void calc_vertical_point_on_line(int px, /* (i) point P */
  145. int py, /* (i) point P */
  146. int lx, /* (i) point on line L */
  147. int ly, /* (i) point on line L */
  148. int ldir, /* (i) deg of line L */
  149. int *result_x, /* (o) the point on line L which is vertical to P */
  150. int *result_y) /* (o) the point on line L which is vertical to P */
  151. {
  152. int vx, vy, a, b;
  153. /* convert <degree, value> ==> <x,y>
  154. * ^ \
  155. * vy | / r = 100
  156. * | / deg = ldir
  157. * |/\
  158. * +---> vx
  159. */
  160. calc_XY_from_deg_val(ldir, /* (i) deg */
  161. 100, /* (i) radius */
  162. &vx, /* (o) vx = 100 * cos(ldir) */
  163. &vy); /* (o) vy = 100 * sin(ldir) */
  164. a = vx*px + vy*py;
  165. b = vy*lx - vx*ly;
  166. *result_x = (vx*a + vy*b ) / 10000;
  167. *result_y = (vy*a - vx*b ) / 10000;
  168. }
  169. /*************************
  170. * PRIVATE FUNCTIONS *
  171. *************************/
  172. /*
  173. * Double absolute value
  174. */
  175. double dabs(double val)
  176. {
  177. if (val < 0) return(-val);
  178. else return( val);
  179. }
  180. /*
  181. * Cosine where value is in degrees (normally radians)
  182. */
  183. double cos_deg(double value)
  184. {
  185. return(cos(value * PAI / 180.0));
  186. }
  187. /*
  188. * Sine where value is in degrees (normally radians)
  189. */
  190. double sin_deg(double value)
  191. {
  192. return(sin(value * PAI / 180.0));
  193. }
  194. /*
  195. * Returns 0 if imaginary solutions, otherwise
  196. * updates x1,x2 with equation roots and returns 1
  197. */
  198. int calc_quadratic_equation(double a, double b, double c, double *x1, double *x2)
  199. {
  200. double d;
  201. d = b*b-4*a*c;
  202. if ( d < 0.0) {
  203. return(0);
  204. }else {
  205. *x1 = (-b+sqrt(d))/(2*a);
  206. *x2 = (-b-sqrt(d))/(2*a);
  207. return(1);
  208. }
  209. }
  210. /* EOF calc_funcs.c */
  211. /********************************************************************************/