///////////////////////////////////////////////// ///////////////////////////////////////////////// #include #define _USE_MATH_DEFINES #include #include #include #include #include #include using namespace std; #include "geometory.h" //#include "viewgui.h" #include "opencv_inc.h" #include "collision_detec_3d.h" //unsigned int urg_data_num=510; //double urg_range_deg=240.0; //double urg_leng_max=5.0; //double urg_leng_min=0.2; double urg_range_deg=240.0; double urg_leng_max=30.0; double urg_leng_min=0.2; double noise_odometory_v_gain=-0.10; double noise_odometory_w_gain=M_PI*0.1; double noise_urg=0.00; double Uniform( void ){ return ((double)rand()+1.0)/((double)RAND_MAX+2.0); } double rand_normal( double mu, double sigma ){ double z=sqrt( -2.0*log(Uniform()) ) * sin( 2.0*M_PI*Uniform() ); return mu + sigma*z; } void urg_noise( URG &urg_data){ for(int i=0;i> x; return x; } //時間を計測する /*double get_dtime(void){ double freq = 1000.0/cv::getTickFrequency(); static int64 old_time = cv::getTickCount(); int64 time = cv::getTickCount(); double dt_msec=(time-old_time)*freq; old_time=time; return dt_msec; } */ static double get_dtime() { struct timeval tv; gettimeofday(&tv, NULL); double n_time =tv.tv_sec + tv.tv_usec * 1e-6; static double o_time= n_time; double dt_msec=(n_time-o_time); o_time= n_time; return dt_msec; } void normal_calc(double *p1, double *p2, double *p3, double *v_nl){ double v1[3],v2[3]; double length_nl; //ベクトル計算 v1[0]=p2[0] - p1[0]; v1[1]=p2[1] - p1[1]; v1[2]=p2[2] - p1[2]; v2[0]=p3[0] - p1[0]; v2[1]=p3[1] - p1[1]; v2[2]=p3[2] - p1[2]; //外積 v_nl[0] = v1[1] * v2[2] - v1[2] * v2[1]; v_nl[1] = v1[2] * v2[0] - v1[0] * v2[2]; v_nl[2] = v1[0] * v2[1] - v1[1] * v2[0]; //正規化 length_nl = sqrt(v_nl[0]*v_nl[0]+v_nl[1]*v_nl[1]+v_nl[2]*v_nl[2]); if(length_nl != 0){ v_nl[0] = v_nl[0]/length_nl; v_nl[1] = v_nl[1]/length_nl; v_nl[2] = v_nl[2]/length_nl; } } //線分の交差判定関数 //但し,a=bだと交差判定受けるので注意. bool cross_check(double a1_x,double a1_y,double a2_x,double a2_y,double b1_x,double b1_y,double b2_x,double b2_y){ // 外積:axb = ax*by - ay*bx // 外積と使用して交差判定を行なう double v1 = (a2_x - a1_x) * (b1_y - a1_y) - (a2_y - a1_y) * (b1_x - a1_x); double v2 = (a2_x - a1_x) * (b2_y - a1_y) - (a2_y - a1_y) * (b2_x - a1_x); double m1 = (b2_x - b1_x) * (a1_y - b1_y) - (b2_y - b1_y) * (a1_x - b1_x); double m2 = (b2_x - b1_x) * (a2_y - b1_y) - (b2_y - b1_y) * (a2_x - b1_x); // +-,-+だったら-値になるのでそれぞれを掛けて確認 if((v1*v2<= 0) && (m1*m2 <= 0)){ return true; // 2つとも左右にあった }else{ //cout<<"checkerror"<1.0*M_PI){ if(fabs(goal_rad-robot_theta_fmod+4.0*M_PI)=0) turn=-1*turn_speed*turn_gain; else if((sub_rad<=0)) turn=1*turn_speed*turn_gain; //角度のかい離大きいたらその場で旋回 if(turn_speed>=M_PI/2.0) speed=0.0; if(turn_speed<=-M_PI/2.0) speed=0.0; //最大速度の規定 if(speed>2.0) speed=2.0; if(goal_l=myrobot.ac_trans_limit) ac_v=myrobot.ac_trans_limit; if(ac_w>=myrobot.ac_rot_limit) ac_w=myrobot.ac_rot_limit; if((myrobot.v-myrobot.real_v)>=0) myrobot.real_v+=ac_v*dtt; else if((myrobot.v-myrobot.real_v)<0) myrobot.real_v-=ac_v*dtt; if((myrobot.w-myrobot.real_w)>=0) myrobot.real_w+=ac_w*dtt; else if((myrobot.w-myrobot.real_w)<0) myrobot.real_w-=ac_w*dtt; //real_v+=real_v*rand_normal(0,1.0)*noise_odometory_v; //real_w+=real_w*rand_normal(0,1.0)*noise_odometory_w; myrobot.x+=myrobot.real_v*sin(-myrobot.theta)*dt; myrobot.y+=myrobot.real_v*cos(-myrobot.theta)*dt; myrobot.theta-=myrobot.real_w*dt; const double odometory_noise_liner=0.0; const double odometory_noise_liner_sigma=1.0; const double odometory_noise_angle=0.0; const double odometory_noise_angle_sigma=1.0; myrobot.x_dummy+=myrobot.real_v*sin(-myrobot.theta_dummy)*dt*(1+fabs(rand_normal(odometory_noise_liner,odometory_noise_liner_sigma))*noise_odometory_v_gain); myrobot.y_dummy+=myrobot.real_v*cos(-myrobot.theta_dummy)*dt*(1+fabs(rand_normal(odometory_noise_liner,odometory_noise_liner_sigma))*noise_odometory_v_gain); myrobot.theta_dummy-=myrobot.real_w*dt*(1+fabs(rand_normal(odometory_noise_angle,odometory_noise_angle_sigma))*noise_odometory_w_gain); } // rad角度を正規化(-pi〜PI)する double normalize_theta_rad(double theta) { double multiplier; if (theta >= -M_PI && theta < M_PI) return theta; multiplier = floor(theta / (2*M_PI)); theta = theta - multiplier*2*M_PI; if (theta >= M_PI) theta -= 2*M_PI; if (theta < -M_PI) theta += 2*M_PI; return theta; }