00001 #include "FRICheck_legacy.hh"
00002
00003 #include <string.h>
00004 #include <math.h>
00005
00006 #define DEG *M_PI/180.0
00007 #define RAD /M_PI*180.0
00008
00009
00010
00011
00012 const float FRICheck_legacy::lim_low[7] = {-169.5 DEG, -119.5 DEG, -169.5 DEG, -119.5 DEG, -169.5 DEG, -119.5 DEG, -169.5 DEG};
00013 const float FRICheck_legacy::lim_high[7] = { 169.5 DEG, 119.5 DEG, 169.5 DEG, 119.5 DEG, 169.5 DEG, 119.5 DEG, 169.5 DEG};
00014
00015 const float FRICheck_legacy::lim_vel[7] = {120 DEG, 120 DEG, 160 DEG, 160 DEG, 250 DEG, 220 DEG, 220 DEG};
00016 const float FRICheck_legacy::lim_acc[7] = {1200, 1200, 1600, 1600, 2500, 4400, 4400};
00017
00018
00019 void safety_check(float *vel, float *vel_old, float *pos, float rate);
00020
00021
00022
00023 FRICheck_legacy::FRICheck_legacy() :
00024 j5_angles(0), j6_min(0), j6_max(0), length(0)
00025 {
00026 memset(pos_, 0, sizeof(float)*7);
00027 memset(vel_old_, 0, sizeof(float)*7);
00028 }
00029
00030
00031 void FRICheck_legacy::setPos(float* pos)
00032 {
00033 memcpy(pos_, pos, sizeof(float)*7);
00034 }
00035
00036
00037
00038 void FRICheck_legacy::adjust(float *pos, float rate)
00039 {
00040
00041 float vel[16];
00042
00043
00044 for(int i=0; i < 7; i++)
00045 vel[i] = pos[i] - pos_[i];
00046
00047
00048 safety_check(vel, vel_old_, pos_, rate);
00049
00050
00051 for(int i=0; i < 7; i++)
00052 pos[i] = pos_[i] + vel[i];
00053
00054
00055 memcpy(pos_, pos, sizeof(float)*7);
00056 memcpy(vel_old_, vel, sizeof(float)*7);
00057 }
00058
00059
00060
00061
00062 #include <stdio.h>
00063 #include <stdlib.h>
00064
00065
00066 double j5_angles_left[]={-120.0 DEG, -100 DEG, -80 DEG, -60 DEG, -40 DEG, -35 DEG, -30 DEG, -25 DEG, -20 DEG, -10 DEG, 0 DEG, 10 DEG, 20 DEG, 30 DEG, 40 DEG, 50 DEG, 60 DEG, 70 DEG, 80 DEG,100 DEG, 120 DEG};
00067 double j6_min_left[]={-170 DEG, -170 DEG, -170 DEG, -170 DEG,-170 DEG,-170 DEG,-170 DEG,-170 DEG,-170 DEG,-170 DEG,-170 DEG,-160 DEG,-150 DEG,-140 DEG,-105 DEG,-90 DEG,-85 DEG,-85 DEG,-80 DEG,-75 DEG,-75 DEG};
00068 double j6_max_left[]={-4 DEG, -4 DEG, 0 DEG, 0 DEG, 10 DEG, 30 DEG, 50 DEG, 60 DEG, 65 DEG, 70 DEG, 80 DEG, 80 DEG, 85 DEG, 90 DEG, 90 DEG, 90 DEG, 90 DEG, 90 DEG, 90 DEG, 90 DEG, 90 DEG};
00069 int length_left = 21;
00070
00071 double j5_angles_right[] = {-120 DEG, -100 DEG, -80 DEG, -60 DEG, -40 DEG, -35 DEG, -30 DEG, -25 DEG, -20 DEG, -10 DEG, 0 DEG, 10 DEG, 20 DEG, 30 DEG, 40 DEG, 50 DEG, 60 DEG, 70 DEG, 80 DEG, 100 DEG, 120 DEG};
00072 double j6_max_right[] = { 84 DEG, 84 DEG, 90 DEG, 90 DEG, 100 DEG, 120 DEG, 140 DEG, 150 DEG, 155 DEG, 160 DEG, 170 DEG, 170 DEG, 170 DEG, 170 DEG, 170 DEG, 170 DEG, 170 DEG, 170 DEG, 170 DEG, 170 DEG, 170 DEG};
00073 double j6_min_right[] = {-80 DEG, -80 DEG, -80 DEG, -80 DEG, -80 DEG, -80 DEG, -80 DEG, -80 DEG, -80 DEG, -80 DEG, -80 DEG, -70 DEG, -60 DEG, -50 DEG, -15 DEG, 0 DEG, 5 DEG, 5 DEG, 10 DEG, 15 DEG, 15 DEG};
00074 int length_right = 21;
00075
00076
00077 double liml[7] = {-169.5 DEG, -119.5 DEG, -169.5 DEG, -119.5 DEG, -169.5 DEG, -119.5 DEG, -169.5 DEG};
00078 double limh[7] = { 169.5 DEG, 119.5 DEG, 169.5 DEG, 119.5 DEG, 169.5 DEG, 119.5 DEG, 169.5 DEG};
00079
00080
00081
00082 double FRICheck_legacy::interpolate(double x, double x1, double y1, double x2, double y2)
00083 {
00084 double diff_y=y2 - y1;
00085 double diff_x=x2 - x1;
00086 double dx=x - x1;
00087 return(y1 + (diff_y/diff_x)*dx);
00088 }
00089
00090 int FRICheck_legacy::find_index(float j5){
00091
00092
00093 int i=0;
00094
00095
00096 if ( (j5 < j5_angles[0]) || (j5 > j5_angles[length-1]) ){
00097 printf("%f not in [%f .. %f]: ", j5, j5_angles[0],j5_angles[length-1]);
00098 printf("Error, check the input value.\n");
00099 return(-1);
00100 }
00101
00102
00103
00104 int index=0;
00105 for (i=0; i<= length-1 ; i++){
00106 if ((j5 > j5_angles[i]) & (j5 <= j5_angles[i+1] )){
00107 index=i;
00108 break;
00109 }
00110 }
00111
00112 return(index);
00113 }
00114
00115 double FRICheck_legacy::min_j6(float j5, int index)
00116 {
00117 float min_lim = interpolate(j5,
00118 j5_angles[index], j6_min[index],
00119 j5_angles[index+1],j6_min[index+1]);
00120 return(min_lim);
00121 }
00122
00123 double FRICheck_legacy::max_j6(float j5, int index)
00124 {
00125 float max_lim = interpolate(j5,
00126 j5_angles[index], j6_max[index],
00127 j5_angles[index+1],j6_max[index+1]);
00128 return(max_lim);
00129 }
00130
00131
00132 void FRICheck_legacy::safety_check(float *vel, float *vel_old, float *pos, float rate)
00133 {
00134 if(length == 0 || j5_angles == 0 || j6_min == 0 || j6_max == 0) {
00135 printf("arm side for safety limits checking not set, panicking...\n");
00136 exit(-1);
00137 }
00138
00139
00140 double vel_max = (100 DEG) * rate;
00141 double acc_max = (600 DEG) * rate * rate;
00142
00143
00144 double acc_max_hard[7];
00145 acc_max_hard[0]=(1200 DEG) * rate * rate;
00146 acc_max_hard[1]=(1200 DEG) * rate * rate;
00147 acc_max_hard[2]=(1600 DEG) * rate * rate;
00148 acc_max_hard[3]=(1600 DEG) * rate * rate;
00149 acc_max_hard[4]=(2500 DEG) * rate * rate;
00150 acc_max_hard[5]=(4400 DEG) * rate * rate;
00151 acc_max_hard[6]=(4400 DEG) * rate * rate;
00152
00153
00154 for (unsigned int i=0; i <7 ; i++) {
00155 acc_max_hard[i]=acc_max_hard[i]*0.9;
00156 }
00157
00158
00159
00160 double newpos5=pos[5]+vel[5];
00161 int index = find_index(newpos5);
00162 double min_lim6=min_j6(newpos5,index);
00163 double max_lim6=max_j6(newpos5,index);
00164 int n_cycles=5;
00165
00166 if(index == -1) {
00167 vel[5] = 0.0;
00168 vel[6] = 0.0;
00169 }
00170
00171
00172 if ( ( pos[6]+vel[6] < min_lim6 ) && (pos[6]+n_cycles*vel[6] < min_lim6 ) ) {
00173 vel[6] = (0.0 > vel_old[6] + acc_max) ? vel_old[6] + acc_max : 0.0;
00174
00175 vel[5] = (0.0 > vel_old[5] + acc_max) ? vel_old[5] + acc_max : 0.0;
00176 vel[5] = (0.0 < vel_old[5] - acc_max) ? vel_old[5] - acc_max : 0.0;
00177 }
00178
00179
00180 if (( pos[6]+vel[6] > max_lim6 ) && ( pos[6]+n_cycles*vel[6] > max_lim6 ) ) {
00181 vel[6] = (0.0 < vel_old[6] - acc_max) ? vel_old[6] - acc_max : 0.0;
00182
00183 vel[5] = (0.0 > vel_old[5] + acc_max) ? vel_old[5] + acc_max : 0.0;
00184 vel[5] = (0.0 < vel_old[5] - acc_max) ? vel_old[5] - acc_max : 0.0;
00185 }
00186
00187
00188
00189 for(int i=0; i < 7; i++) {
00190
00191
00192 vel[i] = (vel[i] > vel_max) ? vel_max : vel[i];
00193 vel[i] = (vel[i] < -vel_max) ? -vel_max : vel[i];
00194
00195
00196 vel[i] = (vel[i] > vel_old[i] + acc_max) ? vel_old[i] + acc_max : vel[i];
00197 vel[i] = (vel[i] < vel_old[i] - acc_max) ? vel_old[i] - acc_max : vel[i];
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 if (vel[i] > 0.0) {
00215 double dist_to_limit = limh[i] - pos[i];
00216 if (dist_to_limit > 0.0) {
00217 double vel_max = -acc_max_hard[i] + sqrt(acc_max_hard[i]*(2*dist_to_limit+acc_max_hard[i]));
00218
00219 vel[i] = ( vel[i] > vel_max ) ? vel_max : vel[i];
00220 }
00221 } else {
00222 double dist_to_limit = pos[i] - liml[i];
00223 if (dist_to_limit > 0.0) {
00224 double vel_max = -acc_max_hard[i] + sqrt(acc_max_hard[i]*(2*dist_to_limit+acc_max_hard[i]));
00225
00226 vel[i] = ( vel[i] < -vel_max ) ? -vel_max : vel[i];
00227 }
00228 }
00229
00230
00231
00232 if( ( (pos[i]) < liml[i] ) && ( vel[i] < 0.0 ) ) {
00233 vel[i] = (0.0 > vel_old[i] + acc_max_hard[i]) ? vel_old[i] + acc_max_hard[i] : 0.0;
00234 }
00235 if( ( (pos[i]) > limh[i] ) && ( vel[i] > 0.0 ) ){
00236 vel[i] = (0.0 < vel_old[i] - acc_max_hard[i]) ? vel_old[i] - acc_max_hard[i] : 0.0;
00237 }
00238 }
00239 }
00240
00241
00242 int FRICheck_legacy::safety_set_side(int side)
00243 {
00244 switch(side) {
00245 case SAFETY_LEFT:
00246 j5_angles = j5_angles_left;
00247 j6_min = j6_min_left;
00248 j6_max = j6_max_left;
00249 length = length_left;
00250 return 1;
00251 case SAFETY_RIGHT:
00252 j5_angles = j5_angles_right;
00253 j6_min = j6_min_right;
00254 j6_max = j6_max_right;
00255 length = length_right;
00256 return 1;
00257 default:
00258 return 0;
00259 }
00260 }