00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <string.h>
00023 #include <math.h>
00024
00025 #include <robot_system.h>
00026 #include <position_manager.h>
00027
00029 void position_init(struct robot_position * pos)
00030 {
00031 uint8_t flags;
00032 IRQ_LOCK(flags);
00033 memset(pos, 0, sizeof(struct robot_position));
00034 IRQ_UNLOCK(flags);
00035 }
00036
00038 void position_set(struct robot_position * pos, int16_t x, int16_t y, int16_t a)
00039 {
00040 uint8_t flags;
00041 IRQ_LOCK(flags);
00042 pos->pos_d.a = ((double)a * M_PI)/ 180.0;
00043 pos->pos_d.x = x;
00044 pos->pos_d.y = y;
00045 pos->pos_s16.x = x;
00046 pos->pos_s16.y = y;
00047 pos->pos_s16.a = a;
00048 IRQ_UNLOCK(flags);
00049 }
00050
00056 void position_set_related_robot_system(struct robot_position * pos, struct robot_system * rs)
00057 {
00058 uint8_t flags;
00059 IRQ_LOCK(flags);
00060 pos->rs = rs;
00061 IRQ_UNLOCK(flags);
00062 }
00063
00069 void position_set_physical_params(struct robot_position * pos, double track_cm,
00070 double distance_imp_per_cm)
00071 {
00072 uint8_t flags;
00073 IRQ_LOCK(flags);
00074 pos->phys.track_cm = track_cm;
00075 pos->phys.distance_imp_per_cm = distance_imp_per_cm;
00076 IRQ_UNLOCK(flags);
00077 }
00078
00079 void position_use_ext(struct robot_position * pos)
00080 {
00081 struct rs_polar encoders;
00082 uint8_t flags;
00083
00084 IRQ_LOCK(flags);
00085 encoders.distance = rs_get_ext_distance(pos->rs);
00086 encoders.angle = rs_get_ext_angle(pos->rs);
00087 pos->prev_encoders = encoders;
00088 pos->use_ext = 1;
00089 IRQ_UNLOCK(flags);
00090 }
00091
00092 #ifdef CONFIG_MODULE_ROBOT_SYSTEM_MOT_AND_EXT
00093 void position_use_mot(struct robot_position * pos)
00094 {
00095 struct rs_polar encoders;
00096 uint8_t flags;
00097
00098 IRQ_LOCK(flags);
00099 encoders.distance = rs_get_mot_distance(pos->rs);
00100 encoders.angle = rs_get_mot_angle(pos->rs);
00101 pos->prev_encoders = encoders;
00102 pos->use_ext = 0;
00103 IRQ_UNLOCK(flags);
00104 }
00105 #endif
00106
00112 void position_manage(struct robot_position * pos)
00113 {
00114 double x, y, a, r, arc_angle;
00115 s16 x_s16, y_s16, a_s16;
00116 struct rs_polar encoders;
00117 struct rs_polar delta;
00118 struct robot_system * rs;
00119 uint8_t flags;
00120
00121 IRQ_LOCK(flags);
00122 if( !(rs = pos->rs) ) {
00123 IRQ_UNLOCK(flags);
00124
00125 return;
00126 }
00127
00128 IRQ_UNLOCK(flags);
00129
00130 #ifdef CONFIG_MODULE_ROBOT_SYSTEM_MOT_AND_EXT
00131 if(pos->use_ext) {
00132 encoders.distance = rs_get_ext_distance(rs);
00133 encoders.angle = rs_get_ext_angle(rs);
00134 }
00135 else {
00136 encoders.distance = rs_get_mot_distance(rs);
00137 encoders.angle = rs_get_mot_angle(rs);
00138 }
00139 #else
00140 encoders.distance = rs_get_ext_distance(rs);
00141 encoders.angle = rs_get_ext_angle(rs);
00142 #endif
00143
00144
00145
00146
00147 delta.distance = encoders.distance - pos->prev_encoders.distance;
00148 delta.angle = encoders.angle - pos->prev_encoders.angle;
00149
00150 pos->prev_encoders = encoders;
00151
00152
00153 IRQ_LOCK(flags);
00154 a = pos->pos_d.a;
00155 x = pos->pos_d.x;
00156 y = pos->pos_d.y;
00157 IRQ_UNLOCK(flags);
00158
00159 if (delta.angle == 0) {
00160
00161 x = x + cos(a) * ((double) delta.distance / (pos->phys.distance_imp_per_cm)) ;
00162 y = y + sin(a) * ((double) delta.distance / (pos->phys.distance_imp_per_cm)) ;
00163 }
00164 else {
00165
00166 r = (double)delta.distance * pos->phys.track_cm / ((double) delta.angle * 2);
00167 arc_angle = 2 * (double) delta.angle / (pos->phys.track_cm * pos->phys.distance_imp_per_cm);
00168
00169 x += r * (-sin(a) + sin(a+arc_angle));
00170 y += r * (cos(a) - cos(a+arc_angle));
00171 a += arc_angle;
00172 }
00173
00174 if (a < -M_PI)
00175 a += (M_PI*2);
00176 else if (a > (M_PI))
00177 a -= (M_PI*2);
00178
00179
00180 x_s16 = (int16_t)x;
00181 y_s16 = (int16_t)y;
00182 a_s16 = (int16_t)(a * (360.0/(M_PI*2)));
00183
00184 IRQ_LOCK(flags);
00185 pos->pos_d.a = a;
00186 pos->pos_d.x = x;
00187 pos->pos_d.y = y;
00188 pos->pos_s16.x = x_s16;
00189 pos->pos_s16.y = y_s16;
00190 pos->pos_s16.a = a_s16;
00191 IRQ_UNLOCK(flags);
00192 }
00193
00194
00198 int16_t position_get_x_s16(struct robot_position *pos)
00199 {
00200 return pos->pos_s16.x;
00201 }
00202
00206 int16_t position_get_y_s16(struct robot_position *pos)
00207 {
00208 return pos->pos_s16.y;
00209 }
00210
00214 int16_t position_get_a_deg_s16(struct robot_position *pos)
00215 {
00216 return pos->pos_s16.a;
00217 }
00218
00219
00220
00224 double position_get_x_double(struct robot_position *pos)
00225 {
00226 return pos->pos_d.x;
00227 }
00228
00232 double position_get_y_double(struct robot_position *pos)
00233 {
00234 return pos->pos_d.y;
00235 }
00236
00240 double position_get_a_rad_double(struct robot_position *pos)
00241 {
00242 return pos->pos_d.a;
00243 }
00244