|
@@ -16,7 +16,6 @@ size_t nv = nth + N;
|
|
|
size_t ndlt = nv + N;
|
|
|
|
|
|
size_t nobs=ndlt+N;
|
|
|
-size_t nwmg=nobs+N;
|
|
|
|
|
|
class FG_eval_half_agv {
|
|
|
public:
|
|
@@ -36,16 +35,11 @@ class FG_eval_half_agv {
|
|
|
fg[0] = 0;
|
|
|
double dt=m_condition[0];
|
|
|
double ref_v=m_condition[1];
|
|
|
+ double obs_w=m_condition[2];
|
|
|
+ double obs_h=m_condition[3];
|
|
|
+
|
|
|
double v=m_statu[0];
|
|
|
double delta=m_statu[1];
|
|
|
- double obs_x=m_statu[2];
|
|
|
- double obs_y=m_statu[3];
|
|
|
-
|
|
|
- double obs_distance=sqrt(obs_x*obs_x+obs_y*obs_y);
|
|
|
-
|
|
|
- // Reference State Cost
|
|
|
- // Below defines the cost related the reference state and
|
|
|
- // any anything you think may be beneficial.
|
|
|
|
|
|
// Weights for how "important" each cost is - can be tuned
|
|
|
const double y_cost_weight = 5000;
|
|
@@ -74,12 +68,8 @@ class FG_eval_half_agv {
|
|
|
//目标速度loss
|
|
|
fg[0]+=v_cost_weight*CppAD::pow(vars[nv+t]-ref_v,2);
|
|
|
|
|
|
- //loss 加上车位姿与障碍物的距离
|
|
|
- /*if(obs_distance<4.0)
|
|
|
- fg[0]+=obs_distance_weight*(16.0-(CppAD::pow(vars[nx+t]-obs_x,2)));*/
|
|
|
|
|
|
}
|
|
|
- // Costs for steering (delta) and acceleration (a)
|
|
|
|
|
|
for (int t = 0; t < N-1; t++) {
|
|
|
//速度,加速度,前轮角 weight loss
|
|
@@ -107,8 +97,6 @@ class FG_eval_half_agv {
|
|
|
CppAD::AD<double> th0 = vars[nth + t-1];
|
|
|
CppAD::AD<double> v0 = vars[nv + t-1];
|
|
|
|
|
|
- //CppAD::AD<double> w_0=vars[nv+t-1]/wheelbase*CppAD::tan(vars[ndlt+t-1]);
|
|
|
-
|
|
|
// Setting up the rest of the model constraints
|
|
|
fg[1 + nx + t] = x1 - (x0 + v0 * CppAD::cos(th0) * dt);
|
|
|
fg[1 + ny + t] = y1 - (y0 + v0 * CppAD::sin(th0) * dt);
|
|
@@ -123,28 +111,38 @@ class FG_eval_half_agv {
|
|
|
fg[1+nv+t]=(vars[nv+t]-vars[nv+t-1])/dt;
|
|
|
fg[1+ndlt+t]=(vars[ndlt+t]-vars[ndlt+t-1])/dt;
|
|
|
}
|
|
|
- //与障碍物的距离
|
|
|
- for(int t=0;t<N;++t)
|
|
|
- {
|
|
|
- fg[1+nobs+t]=CppAD::pow(vars[nx+t]-obs_x,2)+CppAD::pow(vars[ny+t]-obs_y,2);
|
|
|
+
|
|
|
+
|
|
|
+ if(m_statu.size()==2+8){
|
|
|
+ //与障碍物的距离
|
|
|
+ for(int i=0;i<4;++i) {
|
|
|
+ double ox=m_statu[2+i*2];
|
|
|
+ double oy=m_statu[2+i*2+1];
|
|
|
+ for (int t = 0; t < N; ++t) {
|
|
|
+ /*第i点的矩形方程为: {[(x-xi)cos(Θi)-(y-yi)sin(Θi)]/1.35}**8 +
|
|
|
+ * {[(x-xi)sin(Θi)+(y-yi)cos(Θi)]/0.75}**8 = 1.0
|
|
|
+ *
|
|
|
+ * */
|
|
|
+ CppAD::AD<double> ra=(ox-vars[nx+t])*CppAD::cos(vars[nth+t]) -(oy-vars[ny+t])*CppAD::sin(vars[nth+t]);
|
|
|
+ CppAD::AD<double> rb=(ox-vars[nx+t])*CppAD::sin(vars[nth+t]) +(oy-vars[ny+t])*CppAD::cos(vars[nth+t]);
|
|
|
+ fg[1 + nobs + N*i+t] = CppAD::pow(ra/obs_w,8)+CppAD::pow(rb/obs_w,8);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- //转弯半径
|
|
|
- /*for(int t=0;t<N;++t)
|
|
|
- {
|
|
|
- fg[1+nwmg+t]=CppAD::pow(vars[ndlt+t],2)/(CppAD::pow(vars[nv+t],2)+1e-10);
|
|
|
- }*/
|
|
|
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-LoadedMPC::LoadedMPC(const Pose2d& obs,double min_velocity,double max_velocity){
|
|
|
+LoadedMPC::LoadedMPC(const Pose2d& obs,double obs_w,double obs_h,double min_velocity,double max_velocity){
|
|
|
min_velocity_=min_velocity;
|
|
|
max_velocity_=max_velocity;
|
|
|
obs_relative_pose_=obs;
|
|
|
+ obs_w_=obs_w;
|
|
|
+ obs_h_=obs_h;
|
|
|
}
|
|
|
LoadedMPC::~LoadedMPC(){}
|
|
|
|
|
|
-bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu,MPC_parameter mpc_param,
|
|
|
+MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu,MPC_parameter mpc_param,
|
|
|
std::vector<double>& out,Trajectory& select_traj,Trajectory& optimize_trajectory)
|
|
|
{
|
|
|
auto start=std::chrono::steady_clock::now();
|
|
@@ -166,7 +164,7 @@ bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu
|
|
|
if (filte_Path(pose_agv, target, trajectory, filte_poses, 10) == false)
|
|
|
{
|
|
|
printf( "filte path failed ...\n");
|
|
|
- return false;
|
|
|
+ return failed;
|
|
|
}
|
|
|
select_traj= Trajectory(filte_poses);
|
|
|
|
|
@@ -182,7 +180,6 @@ bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu
|
|
|
Eigen::VectorXd coef = fit_path(transform_poses);
|
|
|
|
|
|
//优化
|
|
|
- bool ok = true;
|
|
|
typedef CPPAD_TESTVECTOR(double) Dvector;
|
|
|
|
|
|
//根据当前点和目标点距离,计算目标速度
|
|
@@ -205,6 +202,7 @@ bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu
|
|
|
double max_acc_dlt=mpc_param.acc_angular*M_PI/180.0;
|
|
|
|
|
|
size_t n_vars = N * 5;
|
|
|
+
|
|
|
Dvector vars(n_vars);
|
|
|
for (int i = 0; i < n_vars; i++)
|
|
|
{
|
|
@@ -234,7 +232,14 @@ bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu
|
|
|
}
|
|
|
|
|
|
// Lower and upper limits for the constraints
|
|
|
- size_t n_constraints = N * (5+1);
|
|
|
+ size_t n_constraints = N * 5;
|
|
|
+ /*
|
|
|
+ * 障碍物是否进入 碰撞检测范围内
|
|
|
+ */
|
|
|
+ float distance=Pose2d::distance(obs_relative_pose_,Pose2d(0,0,0));
|
|
|
+ if(distance<5){
|
|
|
+ n_constraints = N * (5+4);
|
|
|
+ }
|
|
|
Dvector constraints_lowerbound(n_constraints);
|
|
|
Dvector constraints_upperbound(n_constraints);
|
|
|
for (int i = 0; i < n_constraints; i++)
|
|
@@ -254,13 +259,15 @@ bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu
|
|
|
constraints_lowerbound[i] = -max_acc_dlt;
|
|
|
constraints_upperbound[i] = max_acc_dlt;
|
|
|
}
|
|
|
- // 与障碍物保持距离
|
|
|
- double dobs=1.6;
|
|
|
- for(int i=nobs;i<nobs+N;++i)
|
|
|
- {
|
|
|
- constraints_lowerbound[i] = dobs*dobs;//pow(float(nobs+N-i)/float(N)*dobs,2);
|
|
|
- constraints_upperbound[i] = 1e19;
|
|
|
+
|
|
|
+ // 与障碍物保持距离的约束
|
|
|
+ if(distance<5) {
|
|
|
+ for (int i = nobs; i < nobs + 4*N; ++i) {
|
|
|
+ constraints_lowerbound[i] = 1.0;
|
|
|
+ constraints_upperbound[i] = 1e19;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
//限制最小转弯半径,
|
|
|
/*for(int i=nwmg;i<nwmg+N;++i)
|
|
|
{
|
|
@@ -268,34 +275,33 @@ bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu
|
|
|
constraints_upperbound[i] = 1.0/(radius*radius);
|
|
|
}*/
|
|
|
|
|
|
-
|
|
|
- Eigen::VectorXd statu_velocity(4);
|
|
|
- if(line_velocity>max_velocity_)
|
|
|
- {
|
|
|
+ if(line_velocity>max_velocity_){
|
|
|
line_velocity=max_velocity_;
|
|
|
- //printf(" input +v limited\n");
|
|
|
}
|
|
|
- if(line_velocity<-max_velocity_)
|
|
|
- {
|
|
|
+ if(line_velocity<-max_velocity_){
|
|
|
line_velocity=-max_velocity_;
|
|
|
- //printf(" input -v limited\n");
|
|
|
}
|
|
|
-
|
|
|
- if(angular>max_dlt)
|
|
|
- {
|
|
|
+ if(angular>max_dlt){
|
|
|
angular = max_dlt;
|
|
|
- printf(" input +dlt limited\n");
|
|
|
}
|
|
|
- if(angular<-max_dlt)
|
|
|
- {
|
|
|
+ if(angular<-max_dlt){
|
|
|
angular = -max_dlt;
|
|
|
- printf(" input -dlt limited\n");
|
|
|
}
|
|
|
|
|
|
- statu_velocity << line_velocity, angular,obs_relative_pose_.x(),obs_relative_pose_.y();
|
|
|
+ Eigen::VectorXd statu_velocity(2);
|
|
|
+ if(distance<5){
|
|
|
+ statu_velocity=Eigen::VectorXd(2+8);
|
|
|
+ std::vector<Pose2d> vertexs=Pose2d::generate_rectangle_vertexs(obs_relative_pose_,2.5,1.3);
|
|
|
+ for(int i=0;i<vertexs.size();++i){
|
|
|
+ statu_velocity[2+i*2]=vertexs[i].x();
|
|
|
+ statu_velocity[2+i*2+1]=vertexs[i].y();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ statu_velocity[0]= line_velocity;
|
|
|
+ statu_velocity[1]=angular;
|
|
|
|
|
|
- Eigen::VectorXd condition(2);
|
|
|
- condition << dt, ref_velocity;
|
|
|
+ Eigen::VectorXd condition(4);
|
|
|
+ condition << dt, ref_velocity,obs_w_,obs_h_;
|
|
|
FG_eval_half_agv fg_eval(coef, statu_velocity, condition);
|
|
|
|
|
|
// options for IPOPT solver
|
|
@@ -317,12 +323,14 @@ bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu
|
|
|
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(now - start);
|
|
|
double time = double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
|
|
|
|
|
|
- ok &= solution.status == CppAD::ipopt::solve_result<Dvector>::success;
|
|
|
- if (ok == false)
|
|
|
+ solution.status == CppAD::ipopt::solve_result<Dvector>::success; // invalid_number_detected
|
|
|
+ if (solution.status != CppAD::ipopt::solve_result<Dvector>::success)
|
|
|
{
|
|
|
printf(" mpc failed statu : %d input: %.4f %.5f(%.5f) relative:(%f,%f) \n",solution.status,line_velocity,
|
|
|
wmg,angular,obs_relative_pose_.x(),obs_relative_pose_.y());
|
|
|
- return false;
|
|
|
+ if (solution.status == CppAD::ipopt::solve_result<Dvector>::invalid_number_detected)
|
|
|
+ return no_solution;
|
|
|
+ return failed;
|
|
|
}
|
|
|
|
|
|
// Cost
|
|
@@ -358,7 +366,7 @@ bool LoadedMPC::solve(Trajectory trajectory, Pose2d target,Eigen::VectorXd statu
|
|
|
Pose2d pose(solution.x[nx + i], solution.x[ny + i], solution.x[nth + i]);
|
|
|
optimize_trajectory.push_point(pose_agv+pose.rotate(pose_agv.theta()));
|
|
|
}
|
|
|
- return true;
|
|
|
+ return success;
|
|
|
}
|
|
|
|
|
|
bool LoadedMPC::filte_Path(const Pose2d& point,Pose2d target,Trajectory trajectory,
|