velocityCtrl.c
Go to the documentation of this file.00001
00010 #include "velocityCtrl.h"
00011 #include "isqrt.h"
00012 #include "iatan2.h"
00013 #include "isincos.h"
00014
00015
00016 void initVelocityCtrlInfo(velocityCtrlInfo_t *velCtrl) {
00017 velCtrl->ref_vel = 0;
00018 velCtrl->current_vel = 0;
00019 velCtrl->acc = 0;
00020 velCtrl->current_pos = 0;
00021 velCtrl->circle_r = 500;
00022 velCtrl->stable = CONTROL_UNSTABLE;
00023 }
00024
00025
00026 void getFirstHoldVelocity(velocityCtrlInfo_t *velCtrl, int vel) {
00027 velCtrl->current_vel = vel * 1000;
00028 }
00029
00030
00031
00032 int holdVelocityCtrl(velocityCtrlInfo_t *velCtrl) {
00033 int diff = (velCtrl->ref_vel * 1000) - velCtrl->current_vel;
00034
00035 if (diff > +velCtrl->acc) {
00036 velCtrl->current_vel += velCtrl->acc;
00037 } else if (diff < -velCtrl->acc) {
00038 velCtrl->current_vel -= velCtrl->acc;
00039 } else {
00040 velCtrl->stable = CONTROL_STABLE;
00041 return velCtrl->ref_vel;
00042 }
00043
00044 return velCtrl->current_vel / 1000;
00045 }
00046
00047
00048
00049 int holdPositionCtrl(velocityCtrlInfo_t *velCtrl, int stable_shift) {
00050 int pos_sign, pos_abs;
00051 int vel_sign, vel_abs;
00052 int ret_value;
00053 int store_ref_vel = velCtrl->ref_vel;
00054
00055 pos_sign = (velCtrl->current_pos < 0) ? -1 : +1;
00056 pos_abs = pos_sign * velCtrl->current_pos;
00057 vel_sign = (velCtrl->current_vel < 0) ? -1 : +1;
00058 vel_abs = vel_sign * velCtrl->current_vel / 1000;
00059
00060 if ((isqrt(velCtrl->acc << 1) * isqrt(pos_abs)) > (unsigned)(vel_abs)) {
00061 velCtrl->ref_vel = - pos_sign * velCtrl->ref_vel;
00062 } else {
00063 velCtrl->ref_vel =
00064 - pos_sign * isqrt(velCtrl->acc << 1) * isqrt(pos_abs);
00065 }
00066 ret_value = holdVelocityCtrl(velCtrl);
00067 velCtrl->ref_vel = store_ref_vel;
00068 velCtrl->stable = ((pos_abs >> stable_shift) == 0) ?
00069 CONTROL_STABLE : CONTROL_UNSTABLE;
00070
00071 if ((isqrt(velCtrl->acc << 1) * isqrt(pos_abs)) > (unsigned)(vel_abs)) {
00072 return ret_value;
00073 } else {
00074 return (1000 * ret_value) >> 10;
00075 }
00076 }
00077
00078
00079 int followLineCtrl(velocityCtrlInfo_t *velCtrl, int follow_r,
00080 velocityInfo_t *velInfo, int run_crd_div16) {
00081 int set_current_pos;
00082 int l = velCtrl->current_pos;
00083 int l_sign, l_abs;
00084 int vel_sign = (velInfo->straight_mm_sec_vel < 0) ? -1 : +1;
00085 int r = follow_r;
00086 int rl_diff;
00087 int ret_value;
00088
00089 l_sign = (l < 0) ? -1 : +1;
00090 l_abs = (l < 0) ? -l : +l;
00091
00092 if (l_abs >= r) {
00093 set_current_pos = l_sign * (0x10000 >> 2);
00094 } else {
00095 int vel_adjust =
00096 l_sign * iatan2(vel_sign * velInfo->straight_mm_sec_vel, r);
00097 rl_diff = (l_sign > 0) ? r - l : r + l;
00098 set_current_pos =
00099 l_sign * ((0x10000 >> 2)
00100 - vel_sign * iatan2(rl_diff, isqrt(r*r - rl_diff*rl_diff)));
00101
00102
00103 set_current_pos -= vel_sign * vel_adjust >> 1;
00104 }
00105
00106
00107 if (vel_sign < 0) {
00108 set_current_pos -= l_sign * (0x10000 >> 1);
00109 }
00110
00111
00112 if (l_abs < (r >> 2)) {
00113 set_current_pos >>= 1;
00114 if (l_abs < (r >> 5)) {
00115 set_current_pos >>= 1;
00116 }
00117 }
00118
00119 velCtrl->current_pos =
00120 getSignedDiv16((set_current_pos + run_crd_div16) & 0xffff);
00121 ret_value = holdPositionCtrl(velCtrl, DIV16_STABLE_SHIFT);
00122 if (velCtrl->stable == CONTROL_STABLE) {
00123 velCtrl->stable = ((l_abs >> (MM_STABLE_SHIFT + 2)) == 0)
00124 ? CONTROL_STABLE : CONTROL_UNSTABLE;
00125 }
00126 return ret_value;
00127 }
00128
00129
00130 int followCircleCtrl(velocityCtrlInfo_t *velCtrl, int follow_r, int x, int y,
00131 velocityInfo_t *velInfo, int run_crd_div16) {
00132 int r = isqrt(x*x + y*y);
00133 int sign = (velCtrl->circle_r < 0) ? -1 : +1;
00134 int offset = iatan2(y, x);
00135 int ret_value;
00136 int diff = 0;
00137
00138 velCtrl->current_pos = (sign * r) - velCtrl->circle_r;
00139 if (velCtrl->circle_r != 0) {
00140 diff = - (int)(0x10000 / (2 * M_PI))
00141 * velInfo->straight_mm_sec_vel / velCtrl->circle_r;
00142 }
00143 ret_value = followLineCtrl(velCtrl, follow_r, velInfo,
00144 run_crd_div16
00145 - getSignedDiv16(offset - sign * (0x10000 >> 2)));
00146
00147 return ret_value + diff;
00148 }
00149