8 Commits 05b064a60b ... 26cf2489a6

Author SHA1 Message Date
  gf 26cf2489a6 1.自己区分前后车(未测试),并调整角度 1 year ago
  gf 8cbd55233c 1.自己区分前后车(未测试) 1 year ago
  gf 91b5780380 1.自己区分前后车(未测试) 1 year ago
  gf 4f690903d3 1.回退下发主副车角度改动 1 year ago
  gf 81b1ddb26a 1.回退下发主副车角度改动 1 year ago
  gf b2e86a700f 1.修复旋转时应下发角速度,实则下发角度bug 1 year ago
  gf c210486dd3 1.提升机构除进载车板车位,其余进库一律下降 1 year ago
  gf 85182e6a76 1.下发plc指令协议修改,下发三组线角速度 1 year ago

+ 2 - 1
MPC/custom_type.h

@@ -100,7 +100,8 @@ enum ActionType {
     eClampClose = 5,
     eClampOpen = 6,
     eLifterRise = 7,    //提升机构上升
-    eLifterDown =8
+    eLifterDown =8,
+    eClampFullyOpen = 9
 };
 ///////////////////////////////////////////////
 

+ 84 - 78
MPC/loaded_mpc.cpp

@@ -8,7 +8,8 @@
 #include <cppad/ipopt/solve.hpp>
 
 size_t N = 15;                  //优化考虑后面多少步
-size_t delay = 2;  // 发送到执行的延迟,即几个周期的时间
+size_t delay = 2;  // 预判发送到执行的延迟,即几个周期的时间
+size_t down_count = 3;//下发前多少步
 
 size_t nx = 0;
 size_t ny = nx + N;
@@ -24,10 +25,12 @@ public:
     Eigen::VectorXd m_coeffs;                 //曲线方程
     Eigen::VectorXd m_statu;                  //当前状态
     Eigen::VectorXd m_condition;              //搜索条件参数
-    FG_eval_half_agv(Eigen::VectorXd coeffs, Eigen::VectorXd statu, Eigen::VectorXd condition) {
+    bool directY_;
+    FG_eval_half_agv(Eigen::VectorXd coeffs, Eigen::VectorXd statu, Eigen::VectorXd condition,bool directY) {
         m_coeffs = coeffs;
         m_statu = statu;
         m_condition = condition;
+        directY_=directY;
     }
 
     typedef CPPAD_TESTVECTOR(CppAD::AD<double>) ADvector;
@@ -67,8 +70,14 @@ public:
         }
 
         for (int t = 0; t < N - 1; t++) {
-            //速度,加速度,前轮角 weight loss
+            //速度,加速度,角加速度 weight loss
             fg[0] += vth_cost_weight * CppAD::pow(vars[ndlt + t], 2);
+            if(t > N / 3){//前中后三段角速度权重1:2:3
+                fg[0] += vth_cost_weight * CppAD::pow(vars[ndlt + t], 2);
+            }
+            if(t > N / 3 * 2){//前中后三段角速度权重1:2:3
+                fg[0] += vth_cost_weight * CppAD::pow(vars[ndlt + t], 2);
+            }
             fg[0] += a_cost_weight * CppAD::pow(vars[nv + t + 1] - vars[nv + t], 2);
             fg[0] += ath_cost_weight * CppAD::pow(vars[ndlt + t + 1] - vars[ndlt + t], 2);
         }
@@ -106,45 +115,29 @@ public:
             fg[1 + ndlt + t] = (vars[ndlt + t] - vars[ndlt + t - 1]) / dt;
         }
 
-        if (m_statu.size() == 2 + 3) {
-            float obs_x = m_statu[2];
-            float obs_y = m_statu[3];
-            float obs_theta = m_statu[4];
-            Pose2d obs_relative_pose(obs_x, obs_y, obs_theta);
-            std::vector<Pose2d> obs_vertexes = Pose2d::generate_rectangle_vertexs(obs_relative_pose, obs_w * 2,
-                                                                                  obs_h * 2);
-            for (auto t = 0; t < N/2; ++t) {
-                CppAD::AD<double> min_distance = 1e19-1;
-                for (auto i = 0; i < 8; ++i) {
-                    CppAD::AD<double> ra = (obs_vertexes[i].x() - vars[nx + t]) * CppAD::cos(vars[nth + t]) -
-                                           (obs_vertexes[i].y() - vars[ny + t]) * CppAD::sin(vars[nth + t]);
-                    CppAD::AD<double> rb = (obs_vertexes[i].x() - vars[nx + t]) * CppAD::sin(vars[nth + t]) +
-                                           (obs_vertexes[i].y() - vars[ny + t]) * CppAD::cos(vars[nth + t]);
-                    CppAD::AD<double> distance = CppAD::pow(ra / obs_w, 8) + CppAD::pow(rb / obs_h, 8);
-                    if (distance < min_distance) min_distance = distance;
+
+        if (m_statu.size() == 2 + 16) {
+            //与障碍物的距离
+            for (int i = 0; i < 8; ++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]);
+                    if(!directY_)
+                        fg[1 + nobs + N * i + t] = CppAD::pow(ra / obs_w, 8) + CppAD::pow(rb / (obs_h*0.76), 8);
+                    else
+                        fg[1 + nobs + N * i + t] = CppAD::pow(ra / (obs_w*0.76), 8) + CppAD::pow(rb / obs_h, 8);
                 }
-                fg[1 + nobs + t] = min_distance;
             }
-//            std::cout << " fg[n_obs]: " << fg[n_obs] << " | __LINE__:" << __LINE__ << std::endl;
         }
-//        if (m_statu.size() == 2 + 3) {
-//            //与障碍物的距离
-//            for (int i = 0; i < 8; ++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_h, 8);
-//                }
-//            }
-//        }
+
     }
 };
 
@@ -159,7 +152,8 @@ LoadedMPC::LoadedMPC(const Pose2d &obs, double obs_w, double obs_h, double min_v
 LoadedMPC::~LoadedMPC() {}
 
 MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd statu, MPC_parameter mpc_param,
-                          std::vector<double> &out, Trajectory &select_traj, Trajectory &optimize_trajectory) {
+                          std::vector<double> &out, Trajectory &select_traj,
+                          Trajectory &optimize_trajectory,bool directY) {
     auto start = std::chrono::steady_clock::now();
     // State vector holds all current values neede for vars below
     Pose2d pose_agv = Pose2d(statu[0], statu[1], statu[2]);
@@ -173,10 +167,10 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
         angular = fabs(line_velocity) / radius;
         if (wmg < 0) angular = -angular;
     }
-    double max_wmg = 0.5 / radius;//fabs(line_velocity) / radius;
+    double max_wmg = fabs(line_velocity) / radius;//0.5 / radius;
 
     std::vector<Pose2d> filte_poses;
-    if (filte_Path(pose_agv, target, trajectory, filte_poses, 10) == false) {
+    if (filte_Path(pose_agv, target, trajectory, filte_poses, 20) == false) {
         printf("filte path failed ...\n");
         return failed;
     }
@@ -196,11 +190,9 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
     typedef CPPAD_TESTVECTOR(double) Dvector;
 
     //根据当前点和目标点距离,计算目标速度
+    double dis=Pose2d::distance(pose_agv, target);
+    double ref_velocity = 1.0/(1+exp(-4.*(dis-1)));
 
-    double ref_velocity = Pose2d::distance(pose_agv, target) / 2.5;
-//    std::cout<<"ref_velocity----"<<pose_agv<<" "<<target<<std::endl;
-    if (ref_velocity < 0.1)
-        ref_velocity = 0.1;
     //目标点与起点的连线 朝向与启动朝向 > M_PI/2.0
 
     Pose2d targetPoseInAGV = Pose2d::relativePose(target, pose_agv);
@@ -242,14 +234,17 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
     }
 
     // Lower and upper limits for the constraints
+    size_t n_constraints = N * 5;
     /*
      * 障碍物是否进入 碰撞检测范围内
      */
     float distance = Pose2d::distance(obs_relative_pose_, Pose2d(0, 0, 0));
-    distance = 1000;
-    bool find_obs = distance < 10;
-    if (find_obs) printf(" find obs ..............................\n");
-    size_t n_constraints = 5 * N + find_obs * N/2;
+    bool find_obs = false;
+    if (distance < 20) {
+        printf(" mpc find obs ,w=%f,h=%f\n",obs_w_,obs_h_);
+        find_obs = true;
+    }
+    if (find_obs) n_constraints = N * (5 + 8);
 
     Dvector constraints_lowerbound(n_constraints);
     Dvector constraints_upperbound(n_constraints);
@@ -272,7 +267,7 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
         constraints_lowerbound[i] = -max_acc_dlt;
         constraints_upperbound[i] = max_acc_dlt;
         //延迟处理,前delay个周期内认定为匀速运动(加速度为0)
-        if (i < nv+delay){
+        if (i < ndlt+delay){
             constraints_lowerbound[i] = 0;
             constraints_upperbound[i] = 0;
         }
@@ -280,7 +275,7 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
 
     // 与障碍物保持距离的约束
     if (find_obs) {
-        for (int i = nobs; i < nobs + N/2; ++i) {
+        for (int i = nobs; i < nobs + 8 * N; ++i) {
             constraints_lowerbound[i] = 1.0;
             constraints_upperbound[i] = 1e19;
         }
@@ -306,18 +301,23 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
         angular = -max_dlt;
     }
 
-    Eigen::VectorXd status(2 + 3 * find_obs);
-    status[0] = line_velocity;
-    status[1] = angular;
+    Eigen::VectorXd statu_velocity(2);
     if (find_obs) {
-        status[2]= obs_relative_pose_.x();
-        status[3] = obs_relative_pose_.y();
-        status[4] = obs_relative_pose_.theta();
+        statu_velocity = Eigen::VectorXd(2 + 16);
+
+        std::vector<Pose2d> vertexs = Pose2d::generate_rectangle_vertexs(obs_relative_pose_, obs_w_ * 2, obs_h_ * 2);
+        for (int i = 0; i < vertexs.size(); ++i) {
+            //std::cout<<"vetex:"<<vertexs[i]<<std::endl;
+            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(6);
     condition << dt, ref_velocity, obs_w_, obs_h_, targetPoseInAGV.x(), targetPoseInAGV.y();
-    FG_eval_half_agv fg_eval(coef, status, condition);
+    FG_eval_half_agv fg_eval(coef, statu_velocity, condition,directY);
 
     // options for IPOPT solver
     std::string options;
@@ -353,27 +353,33 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
 
     out.clear();
 
-    double solve_velocity = solution.x[nv+delay];
-    double solve_angular = solution.x[ndlt+delay];
+    double solve_velocity[down_count];
+    double solve_angular[down_count];
 
-    //纠正角速度/线速度,使其满足最小转弯半径
-    double correct_angular = solve_angular;
-    if ((solve_velocity * solve_velocity) / (solve_angular * solve_angular + 1e-9) < (radius * radius)) {
-        correct_angular = fabs(line_velocity) / radius;
-        if (solve_angular < 0) correct_angular = -correct_angular;
+    for (int i = 0; i < down_count; ++i) {
+        solve_velocity[i] = solution.x[nv + delay + i];
+        solve_angular[i] = solution.x[ndlt + delay + i];
+
+
+        //纠正角速度/线速度,使其满足最小转弯半径
+        double correct_angular = solve_angular[i];
+        if ((solve_velocity[i] * solve_velocity[i]) / (solve_angular[i] * solve_angular[i] + 1e-9) < (radius * radius)) {
+            correct_angular = fabs(line_velocity) / radius;
+            if (solve_angular[i] < 0) correct_angular = -correct_angular;
+        }
+        ///-----
+        printf(" P[%d],input:%.4f %.5f(%.5f) output:%.4f %.5f(%.5f) ref:%.3f max_v:%f time:%.3f\n",
+               i, line_velocity, wmg, angular, solve_velocity[i], solve_angular[i], correct_angular,
+               ref_velocity, max_velocity_, time);
+
+        /*if(solve_velocity>=0 && solve_velocity<min_velocity_)
+          solve_velocity=min_velocity_;
+        if(solve_velocity<0 && solve_velocity>-min_velocity_)
+          solve_velocity=-min_velocity_;*/
+
+        out.push_back(solve_velocity[i]);
+        out.push_back(correct_angular);
     }
-    ///-----
-    printf(" input:%.4f %.5f(%.5f) output:%.4f %.5f(%.5f) ref:%.3f max_v:%f time:%.3f\n",
-           line_velocity, wmg, angular, solve_velocity, solve_angular, correct_angular,
-           ref_velocity, max_velocity_, time);
-
-    /*if(solve_velocity>=0 && solve_velocity<min_velocity_)
-      solve_velocity=min_velocity_;
-    if(solve_velocity<0 && solve_velocity>-min_velocity_)
-      solve_velocity=-min_velocity_;*/
-
-    out.push_back(solve_velocity);
-    out.push_back(correct_angular);
 
 
     //计算预测轨迹

+ 2 - 1
MPC/loaded_mpc.h

@@ -23,7 +23,8 @@ public:
     virtual ~LoadedMPC();
 
     virtual MpcError solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd statu, MPC_parameter mpc_param,
-                           std::vector<double> &out, Trajectory &select_traj, Trajectory &optimize_trajectory);
+                           std::vector<double> &out, Trajectory &select_traj,
+                           Trajectory &optimize_trajectory,bool directY);
 
 
 protected:

+ 356 - 190
MPC/monitor/emqx/message.pb.cc

@@ -72,21 +72,29 @@ PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
 template <typename>
 PROTOBUF_CONSTEXPR ToAgvCmd::ToAgvCmd(
     ::_pbi::ConstantInitialized): _impl_{
-    /*decltype(_impl_.h_)*/ 0
+    /*decltype(_impl_.h1_)*/ 0
 
-  , /*decltype(_impl_.m_)*/ 0
+  , /*decltype(_impl_.m1_)*/ 0
 
-  , /*decltype(_impl_.t_)*/ 0
+  , /*decltype(_impl_.t1_)*/ 0
 
-  , /*decltype(_impl_.v_)*/ 0
+  , /*decltype(_impl_.v1_)*/ 0
 
-  , /*decltype(_impl_.w_)*/ 0
+  , /*decltype(_impl_.w1_)*/ 0
 
-  , /*decltype(_impl_.l_)*/ 0
+  , /*decltype(_impl_.v2_)*/ 0
+
+  , /*decltype(_impl_.w2_)*/ 0
 
-  , /*decltype(_impl_.p_)*/ 0
+  , /*decltype(_impl_.v3_)*/ 0
 
-  , /*decltype(_impl_.d_)*/ 0
+  , /*decltype(_impl_.w3_)*/ 0
+
+  , /*decltype(_impl_.l1_)*/ 0
+
+  , /*decltype(_impl_.p1_)*/ 0
+
+  , /*decltype(_impl_.d1_)*/ 0
 
   , /*decltype(_impl_.end_)*/ 0
 
@@ -351,14 +359,18 @@ const ::uint32_t TableStruct_message_2eproto::offsets[] PROTOBUF_SECTION_VARIABL
     ~0u,  // no _inlined_string_donated_
     ~0u,  // no _split_
     ~0u,  // no sizeof(Split)
-    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.h_),
-    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.m_),
-    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.t_),
-    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.v_),
-    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.w_),
-    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.l_),
-    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.p_),
-    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.d_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.h1_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.m1_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.t1_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.v1_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.w1_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.v2_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.w2_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.v3_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.w3_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.l1_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.p1_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.d1_),
     PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _impl_.end_),
     ~0u,  // no _has_bits_
     PROTOBUF_FIELD_OFFSET(::NavMessage::Pose2d, _internal_metadata_),
@@ -497,15 +509,15 @@ static const ::_pbi::MigrationSchema
         { 0, -1, -1, sizeof(::NavMessage::LidarOdomStatu)},
         { 13, -1, -1, sizeof(::NavMessage::AgvStatu)},
         { 27, -1, -1, sizeof(::NavMessage::ToAgvCmd)},
-        { 44, -1, -1, sizeof(::NavMessage::Pose2d)},
-        { 55, -1, -1, sizeof(::NavMessage::PathNode)},
-        { 69, -1, -1, sizeof(::NavMessage::Trajectory)},
-        { 78, 93, -1, sizeof(::NavMessage::NewAction)},
-        { 100, -1, -1, sizeof(::NavMessage::NavCmd)},
-        { 111, -1, -1, sizeof(::NavMessage::NavResponse)},
-        { 121, -1, -1, sizeof(::NavMessage::ManualCmd)},
-        { 132, 149, -1, sizeof(::NavMessage::NavStatu)},
-        { 158, 170, -1, sizeof(::NavMessage::RobotStatu)},
+        { 48, -1, -1, sizeof(::NavMessage::Pose2d)},
+        { 59, -1, -1, sizeof(::NavMessage::PathNode)},
+        { 73, -1, -1, sizeof(::NavMessage::Trajectory)},
+        { 82, 97, -1, sizeof(::NavMessage::NewAction)},
+        { 104, -1, -1, sizeof(::NavMessage::NavCmd)},
+        { 115, -1, -1, sizeof(::NavMessage::NavResponse)},
+        { 125, -1, -1, sizeof(::NavMessage::ManualCmd)},
+        { 136, 153, -1, sizeof(::NavMessage::NavStatu)},
+        { 162, 174, -1, sizeof(::NavMessage::RobotStatu)},
 };
 
 static const ::_pb::Message* const file_default_instances[] = {
@@ -528,44 +540,46 @@ const char descriptor_table_protodef_message_2eproto[] PROTOBUF_SECTION_VARIABLE
     "(\002\022\t\n\001v\030\004 \001(\002\022\013\n\003vth\030\005 \001(\002\"j\n\010AgvStatu\022\t"
     "\n\001v\030\001 \001(\002\022\t\n\001w\030\002 \001(\002\022\r\n\005clamp\030\003 \001(\005\022\023\n\013c"
     "lamp_other\030\004 \001(\005\022\016\n\006lifter\030\005 \001(\005\022\024\n\014lift"
-    "er_other\030\006 \001(\005\"o\n\010ToAgvCmd\022\t\n\001H\030\001 \001(\005\022\t\n"
-    "\001M\030\002 \001(\005\022\t\n\001T\030\003 \001(\005\022\t\n\001V\030\004 \001(\002\022\t\n\001W\030\005 \001("
-    "\002\022\t\n\001L\030\006 \001(\002\022\t\n\001P\030\007 \001(\005\022\t\n\001D\030\010 \001(\002\022\013\n\003en"
-    "d\030\t \001(\005\"-\n\006Pose2d\022\t\n\001x\030\001 \001(\002\022\t\n\001y\030\002 \001(\002\022"
-    "\r\n\005theta\030\003 \001(\002\"Q\n\010PathNode\022\t\n\001x\030\001 \001(\002\022\t\n"
-    "\001y\030\002 \001(\002\022\t\n\001l\030\003 \001(\002\022\t\n\001w\030\004 \001(\002\022\r\n\005theta\030"
-    "\005 \001(\002\022\n\n\002id\030\006 \001(\t\"/\n\nTrajectory\022!\n\005poses"
-    "\030\001 \003(\0132\022.NavMessage.Pose2d\"\345\001\n\tNewAction"
-    "\022\014\n\004type\030\001 \001(\005\022\'\n\tspaceNode\030\002 \001(\0132\024.NavM"
-    "essage.PathNode\022&\n\010passNode\030\003 \001(\0132\024.NavM"
-    "essage.PathNode\022(\n\nstreetNode\030\004 \001(\0132\024.Na"
-    "vMessage.PathNode\022\'\n\tpathNodes\030\005 \003(\0132\024.N"
-    "avMessage.PathNode\022\021\n\twheelbase\030\006 \001(\002\022\023\n"
-    "\013changedMode\030\007 \001(\005\"P\n\006NavCmd\022\016\n\006action\030\001"
-    " \001(\005\022\013\n\003key\030\002 \001(\t\022)\n\nnewActions\030\005 \003(\0132\025."
-    "NavMessage.NewAction\"(\n\013NavResponse\022\013\n\003r"
-    "et\030\001 \001(\005\022\014\n\004info\030\002 \001(\t\"B\n\tManualCmd\022\013\n\003k"
-    "ey\030\001 \001(\t\022\026\n\016operation_type\030\002 \001(\005\022\020\n\010velo"
-    "city\030\003 \001(\002\"\366\001\n\010NavStatu\022\r\n\005statu\030\001 \001(\005\022\020"
-    "\n\010main_agv\030\002 \001(\010\022\021\n\tmove_mode\030\003 \001(\005\022(\n\004o"
-    "dom\030\004 \001(\0132\032.NavMessage.LidarOdomStatu\022\013\n"
-    "\003key\030\005 \001(\t\022-\n\rselected_traj\030\006 \001(\0132\026.NavM"
-    "essage.Trajectory\022,\n\014predict_traj\030\007 \001(\0132"
-    "\026.NavMessage.Trajectory\022\020\n\010in_space\030\010 \001("
-    "\010\022\020\n\010space_id\030\t \001(\t\"Y\n\nRobotStatu\022\t\n\001x\030\001"
-    " \001(\002\022\t\n\001y\030\002 \001(\002\022\r\n\005theta\030\003 \001(\002\022&\n\010agvSta"
-    "tu\030\004 \001(\0132\024.NavMessage.AgvStatu2\302\001\n\nNavEx"
-    "cutor\0226\n\005Start\022\022.NavMessage.NavCmd\032\027.Nav"
-    "Message.NavResponse\"\000\0227\n\006Cancel\022\022.NavMes"
-    "sage.NavCmd\032\027.NavMessage.NavResponse\"\000\022C"
-    "\n\017ManualOperation\022\025.NavMessage.ManualCmd"
-    "\032\027.NavMessage.NavResponse\"\000b\006proto3"
+    "er_other\030\006 \001(\005\"\247\001\n\010ToAgvCmd\022\n\n\002H1\030\001 \001(\005\022"
+    "\n\n\002M1\030\002 \001(\005\022\n\n\002T1\030\003 \001(\005\022\n\n\002V1\030\004 \001(\002\022\n\n\002W"
+    "1\030\005 \001(\002\022\n\n\002V2\030\006 \001(\002\022\n\n\002W2\030\007 \001(\002\022\n\n\002V3\030\010 "
+    "\001(\002\022\n\n\002W3\030\t \001(\002\022\n\n\002L1\030\n \001(\002\022\n\n\002P1\030\013 \001(\005\022"
+    "\n\n\002D1\030\014 \001(\002\022\013\n\003end\030\r \001(\005\"-\n\006Pose2d\022\t\n\001x\030"
+    "\001 \001(\002\022\t\n\001y\030\002 \001(\002\022\r\n\005theta\030\003 \001(\002\"Q\n\010PathN"
+    "ode\022\t\n\001x\030\001 \001(\002\022\t\n\001y\030\002 \001(\002\022\t\n\001l\030\003 \001(\002\022\t\n\001"
+    "w\030\004 \001(\002\022\r\n\005theta\030\005 \001(\002\022\n\n\002id\030\006 \001(\t\"/\n\nTr"
+    "ajectory\022!\n\005poses\030\001 \003(\0132\022.NavMessage.Pos"
+    "e2d\"\345\001\n\tNewAction\022\014\n\004type\030\001 \001(\005\022\'\n\tspace"
+    "Node\030\002 \001(\0132\024.NavMessage.PathNode\022&\n\010pass"
+    "Node\030\003 \001(\0132\024.NavMessage.PathNode\022(\n\nstre"
+    "etNode\030\004 \001(\0132\024.NavMessage.PathNode\022\'\n\tpa"
+    "thNodes\030\005 \003(\0132\024.NavMessage.PathNode\022\021\n\tw"
+    "heelbase\030\006 \001(\002\022\023\n\013changedMode\030\007 \001(\005\"P\n\006N"
+    "avCmd\022\016\n\006action\030\001 \001(\005\022\013\n\003key\030\002 \001(\t\022)\n\nne"
+    "wActions\030\005 \003(\0132\025.NavMessage.NewAction\"(\n"
+    "\013NavResponse\022\013\n\003ret\030\001 \001(\005\022\014\n\004info\030\002 \001(\t\""
+    "B\n\tManualCmd\022\013\n\003key\030\001 \001(\t\022\026\n\016operation_t"
+    "ype\030\002 \001(\005\022\020\n\010velocity\030\003 \001(\002\"\366\001\n\010NavStatu"
+    "\022\r\n\005statu\030\001 \001(\005\022\020\n\010main_agv\030\002 \001(\010\022\021\n\tmov"
+    "e_mode\030\003 \001(\005\022(\n\004odom\030\004 \001(\0132\032.NavMessage."
+    "LidarOdomStatu\022\013\n\003key\030\005 \001(\t\022-\n\rselected_"
+    "traj\030\006 \001(\0132\026.NavMessage.Trajectory\022,\n\014pr"
+    "edict_traj\030\007 \001(\0132\026.NavMessage.Trajectory"
+    "\022\020\n\010in_space\030\010 \001(\010\022\020\n\010space_id\030\t \001(\t\"Y\n\n"
+    "RobotStatu\022\t\n\001x\030\001 \001(\002\022\t\n\001y\030\002 \001(\002\022\r\n\005thet"
+    "a\030\003 \001(\002\022&\n\010agvStatu\030\004 \001(\0132\024.NavMessage.A"
+    "gvStatu2\302\001\n\nNavExcutor\0226\n\005Start\022\022.NavMes"
+    "sage.NavCmd\032\027.NavMessage.NavResponse\"\000\0227"
+    "\n\006Cancel\022\022.NavMessage.NavCmd\032\027.NavMessag"
+    "e.NavResponse\"\000\022C\n\017ManualOperation\022\025.Nav"
+    "Message.ManualCmd\032\027.NavMessage.NavRespon"
+    "se\"\000b\006proto3"
 };
 static ::absl::once_flag descriptor_table_message_2eproto_once;
 const ::_pbi::DescriptorTable descriptor_table_message_2eproto = {
     false,
     false,
-    1475,
+    1532,
     descriptor_table_protodef_message_2eproto,
     "message.proto",
     &descriptor_table_message_2eproto_once,
@@ -1299,21 +1313,29 @@ ToAgvCmd::ToAgvCmd(const ToAgvCmd& from)
 inline void ToAgvCmd::SharedCtor(::_pb::Arena* arena) {
   (void)arena;
   new (&_impl_) Impl_{
-      decltype(_impl_.h_) { 0 }
+      decltype(_impl_.h1_) { 0 }
 
-    , decltype(_impl_.m_) { 0 }
+    , decltype(_impl_.m1_) { 0 }
 
-    , decltype(_impl_.t_) { 0 }
+    , decltype(_impl_.t1_) { 0 }
 
-    , decltype(_impl_.v_) { 0 }
+    , decltype(_impl_.v1_) { 0 }
 
-    , decltype(_impl_.w_) { 0 }
+    , decltype(_impl_.w1_) { 0 }
 
-    , decltype(_impl_.l_) { 0 }
+    , decltype(_impl_.v2_) { 0 }
+
+    , decltype(_impl_.w2_) { 0 }
+
+    , decltype(_impl_.v3_) { 0 }
 
-    , decltype(_impl_.p_) { 0 }
+    , decltype(_impl_.w3_) { 0 }
 
-    , decltype(_impl_.d_) { 0 }
+    , decltype(_impl_.l1_) { 0 }
+
+    , decltype(_impl_.p1_) { 0 }
+
+    , decltype(_impl_.d1_) { 0 }
 
     , decltype(_impl_.end_) { 0 }
 
@@ -1344,9 +1366,9 @@ void ToAgvCmd::Clear() {
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
 
-  ::memset(&_impl_.h_, 0, static_cast<::size_t>(
+  ::memset(&_impl_.h1_, 0, static_cast<::size_t>(
       reinterpret_cast<char*>(&_impl_.end_) -
-      reinterpret_cast<char*>(&_impl_.h_)) + sizeof(_impl_.end_));
+      reinterpret_cast<char*>(&_impl_.h1_)) + sizeof(_impl_.end_));
   _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
 }
 
@@ -1356,81 +1378,117 @@ const char* ToAgvCmd::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx)
     ::uint32_t tag;
     ptr = ::_pbi::ReadTag(ptr, &tag);
     switch (tag >> 3) {
-      // int32 H = 1;
+      // int32 H1 = 1;
       case 1:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 8)) {
-          _impl_.h_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+          _impl_.h1_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
           CHK_(ptr);
         } else {
           goto handle_unusual;
         }
         continue;
-      // int32 M = 2;
+      // int32 M1 = 2;
       case 2:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 16)) {
-          _impl_.m_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+          _impl_.m1_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
           CHK_(ptr);
         } else {
           goto handle_unusual;
         }
         continue;
-      // int32 T = 3;
+      // int32 T1 = 3;
       case 3:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 24)) {
-          _impl_.t_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+          _impl_.t1_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
           CHK_(ptr);
         } else {
           goto handle_unusual;
         }
         continue;
-      // float V = 4;
+      // float V1 = 4;
       case 4:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 37)) {
-          _impl_.v_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          _impl_.v1_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
           ptr += sizeof(float);
         } else {
           goto handle_unusual;
         }
         continue;
-      // float W = 5;
+      // float W1 = 5;
       case 5:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 45)) {
-          _impl_.w_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          _impl_.w1_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
           ptr += sizeof(float);
         } else {
           goto handle_unusual;
         }
         continue;
-      // float L = 6;
+      // float V2 = 6;
       case 6:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 53)) {
-          _impl_.l_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          _impl_.v2_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
           ptr += sizeof(float);
         } else {
           goto handle_unusual;
         }
         continue;
-      // int32 P = 7;
+      // float W2 = 7;
       case 7:
-        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 56)) {
-          _impl_.p_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
-          CHK_(ptr);
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 61)) {
+          _impl_.w2_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          ptr += sizeof(float);
         } else {
           goto handle_unusual;
         }
         continue;
-      // float D = 8;
+      // float V3 = 8;
       case 8:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 69)) {
-          _impl_.d_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          _impl_.v3_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
           ptr += sizeof(float);
         } else {
           goto handle_unusual;
         }
         continue;
-      // int32 end = 9;
+      // float W3 = 9;
       case 9:
-        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 72)) {
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 77)) {
+          _impl_.w3_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          ptr += sizeof(float);
+        } else {
+          goto handle_unusual;
+        }
+        continue;
+      // float L1 = 10;
+      case 10:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 85)) {
+          _impl_.l1_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          ptr += sizeof(float);
+        } else {
+          goto handle_unusual;
+        }
+        continue;
+      // int32 P1 = 11;
+      case 11:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 88)) {
+          _impl_.p1_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+          CHK_(ptr);
+        } else {
+          goto handle_unusual;
+        }
+        continue;
+      // float D1 = 12;
+      case 12:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 101)) {
+          _impl_.d1_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          ptr += sizeof(float);
+        } else {
+          goto handle_unusual;
+        }
+        continue;
+      // int32 end = 13;
+      case 13:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 104)) {
           _impl_.end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
           CHK_(ptr);
         } else {
@@ -1466,83 +1524,127 @@ failure:
   ::uint32_t cached_has_bits = 0;
   (void) cached_has_bits;
 
-  // int32 H = 1;
-  if (this->_internal_h() != 0) {
+  // int32 H1 = 1;
+  if (this->_internal_h1() != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteInt32ToArray(
-        1, this->_internal_h(), target);
+        1, this->_internal_h1(), target);
   }
 
-  // int32 M = 2;
-  if (this->_internal_m() != 0) {
+  // int32 M1 = 2;
+  if (this->_internal_m1() != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteInt32ToArray(
-        2, this->_internal_m(), target);
+        2, this->_internal_m1(), target);
   }
 
-  // int32 T = 3;
-  if (this->_internal_t() != 0) {
+  // int32 T1 = 3;
+  if (this->_internal_t1() != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteInt32ToArray(
-        3, this->_internal_t(), target);
+        3, this->_internal_t1(), target);
   }
 
-  // float V = 4;
+  // float V1 = 4;
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_v = this->_internal_v();
-  ::uint32_t raw_v;
-  memcpy(&raw_v, &tmp_v, sizeof(tmp_v));
-  if (raw_v != 0) {
+  float tmp_v1 = this->_internal_v1();
+  ::uint32_t raw_v1;
+  memcpy(&raw_v1, &tmp_v1, sizeof(tmp_v1));
+  if (raw_v1 != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteFloatToArray(
-        4, this->_internal_v(), target);
+        4, this->_internal_v1(), target);
   }
 
-  // float W = 5;
+  // float W1 = 5;
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_w = this->_internal_w();
-  ::uint32_t raw_w;
-  memcpy(&raw_w, &tmp_w, sizeof(tmp_w));
-  if (raw_w != 0) {
+  float tmp_w1 = this->_internal_w1();
+  ::uint32_t raw_w1;
+  memcpy(&raw_w1, &tmp_w1, sizeof(tmp_w1));
+  if (raw_w1 != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteFloatToArray(
-        5, this->_internal_w(), target);
+        5, this->_internal_w1(), target);
   }
 
-  // float L = 6;
+  // float V2 = 6;
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_l = this->_internal_l();
-  ::uint32_t raw_l;
-  memcpy(&raw_l, &tmp_l, sizeof(tmp_l));
-  if (raw_l != 0) {
+  float tmp_v2 = this->_internal_v2();
+  ::uint32_t raw_v2;
+  memcpy(&raw_v2, &tmp_v2, sizeof(tmp_v2));
+  if (raw_v2 != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::_pbi::WireFormatLite::WriteFloatToArray(
+        6, this->_internal_v2(), target);
+  }
+
+  // float W2 = 7;
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_w2 = this->_internal_w2();
+  ::uint32_t raw_w2;
+  memcpy(&raw_w2, &tmp_w2, sizeof(tmp_w2));
+  if (raw_w2 != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::_pbi::WireFormatLite::WriteFloatToArray(
+        7, this->_internal_w2(), target);
+  }
+
+  // float V3 = 8;
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_v3 = this->_internal_v3();
+  ::uint32_t raw_v3;
+  memcpy(&raw_v3, &tmp_v3, sizeof(tmp_v3));
+  if (raw_v3 != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::_pbi::WireFormatLite::WriteFloatToArray(
+        8, this->_internal_v3(), target);
+  }
+
+  // float W3 = 9;
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_w3 = this->_internal_w3();
+  ::uint32_t raw_w3;
+  memcpy(&raw_w3, &tmp_w3, sizeof(tmp_w3));
+  if (raw_w3 != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::_pbi::WireFormatLite::WriteFloatToArray(
+        9, this->_internal_w3(), target);
+  }
+
+  // float L1 = 10;
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_l1 = this->_internal_l1();
+  ::uint32_t raw_l1;
+  memcpy(&raw_l1, &tmp_l1, sizeof(tmp_l1));
+  if (raw_l1 != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteFloatToArray(
-        6, this->_internal_l(), target);
+        10, this->_internal_l1(), target);
   }
 
-  // int32 P = 7;
-  if (this->_internal_p() != 0) {
+  // int32 P1 = 11;
+  if (this->_internal_p1() != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteInt32ToArray(
-        7, this->_internal_p(), target);
+        11, this->_internal_p1(), target);
   }
 
-  // float D = 8;
+  // float D1 = 12;
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_d = this->_internal_d();
-  ::uint32_t raw_d;
-  memcpy(&raw_d, &tmp_d, sizeof(tmp_d));
-  if (raw_d != 0) {
+  float tmp_d1 = this->_internal_d1();
+  ::uint32_t raw_d1;
+  memcpy(&raw_d1, &tmp_d1, sizeof(tmp_d1));
+  if (raw_d1 != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteFloatToArray(
-        8, this->_internal_d(), target);
+        12, this->_internal_d1(), target);
   }
 
-  // int32 end = 9;
+  // int32 end = 13;
   if (this->_internal_end() != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteInt32ToArray(
-        9, this->_internal_end(), target);
+        13, this->_internal_end(), target);
   }
 
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
@@ -1561,67 +1663,103 @@ failure:
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
 
-  // int32 H = 1;
-  if (this->_internal_h() != 0) {
+  // int32 H1 = 1;
+  if (this->_internal_h1() != 0) {
     total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
-        this->_internal_h());
+        this->_internal_h1());
   }
 
-  // int32 M = 2;
-  if (this->_internal_m() != 0) {
+  // int32 M1 = 2;
+  if (this->_internal_m1() != 0) {
     total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
-        this->_internal_m());
+        this->_internal_m1());
   }
 
-  // int32 T = 3;
-  if (this->_internal_t() != 0) {
+  // int32 T1 = 3;
+  if (this->_internal_t1() != 0) {
     total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
-        this->_internal_t());
+        this->_internal_t1());
   }
 
-  // float V = 4;
+  // float V1 = 4;
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_v = this->_internal_v();
-  ::uint32_t raw_v;
-  memcpy(&raw_v, &tmp_v, sizeof(tmp_v));
-  if (raw_v != 0) {
+  float tmp_v1 = this->_internal_v1();
+  ::uint32_t raw_v1;
+  memcpy(&raw_v1, &tmp_v1, sizeof(tmp_v1));
+  if (raw_v1 != 0) {
     total_size += 5;
   }
 
-  // float W = 5;
+  // float W1 = 5;
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_w = this->_internal_w();
-  ::uint32_t raw_w;
-  memcpy(&raw_w, &tmp_w, sizeof(tmp_w));
-  if (raw_w != 0) {
+  float tmp_w1 = this->_internal_w1();
+  ::uint32_t raw_w1;
+  memcpy(&raw_w1, &tmp_w1, sizeof(tmp_w1));
+  if (raw_w1 != 0) {
     total_size += 5;
   }
 
-  // float L = 6;
+  // float V2 = 6;
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_l = this->_internal_l();
-  ::uint32_t raw_l;
-  memcpy(&raw_l, &tmp_l, sizeof(tmp_l));
-  if (raw_l != 0) {
+  float tmp_v2 = this->_internal_v2();
+  ::uint32_t raw_v2;
+  memcpy(&raw_v2, &tmp_v2, sizeof(tmp_v2));
+  if (raw_v2 != 0) {
+    total_size += 5;
+  }
+
+  // float W2 = 7;
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_w2 = this->_internal_w2();
+  ::uint32_t raw_w2;
+  memcpy(&raw_w2, &tmp_w2, sizeof(tmp_w2));
+  if (raw_w2 != 0) {
+    total_size += 5;
+  }
+
+  // float V3 = 8;
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_v3 = this->_internal_v3();
+  ::uint32_t raw_v3;
+  memcpy(&raw_v3, &tmp_v3, sizeof(tmp_v3));
+  if (raw_v3 != 0) {
     total_size += 5;
   }
 
-  // int32 P = 7;
-  if (this->_internal_p() != 0) {
+  // float W3 = 9;
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_w3 = this->_internal_w3();
+  ::uint32_t raw_w3;
+  memcpy(&raw_w3, &tmp_w3, sizeof(tmp_w3));
+  if (raw_w3 != 0) {
+    total_size += 5;
+  }
+
+  // float L1 = 10;
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_l1 = this->_internal_l1();
+  ::uint32_t raw_l1;
+  memcpy(&raw_l1, &tmp_l1, sizeof(tmp_l1));
+  if (raw_l1 != 0) {
+    total_size += 5;
+  }
+
+  // int32 P1 = 11;
+  if (this->_internal_p1() != 0) {
     total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
-        this->_internal_p());
+        this->_internal_p1());
   }
 
-  // float D = 8;
+  // float D1 = 12;
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_d = this->_internal_d();
-  ::uint32_t raw_d;
-  memcpy(&raw_d, &tmp_d, sizeof(tmp_d));
-  if (raw_d != 0) {
+  float tmp_d1 = this->_internal_d1();
+  ::uint32_t raw_d1;
+  memcpy(&raw_d1, &tmp_d1, sizeof(tmp_d1));
+  if (raw_d1 != 0) {
     total_size += 5;
   }
 
-  // int32 end = 9;
+  // int32 end = 13;
   if (this->_internal_end() != 0) {
     total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
         this->_internal_end());
@@ -1645,45 +1783,73 @@ void ToAgvCmd::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTO
   ::uint32_t cached_has_bits = 0;
   (void) cached_has_bits;
 
-  if (from._internal_h() != 0) {
-    _this->_internal_set_h(from._internal_h());
+  if (from._internal_h1() != 0) {
+    _this->_internal_set_h1(from._internal_h1());
   }
-  if (from._internal_m() != 0) {
-    _this->_internal_set_m(from._internal_m());
+  if (from._internal_m1() != 0) {
+    _this->_internal_set_m1(from._internal_m1());
   }
-  if (from._internal_t() != 0) {
-    _this->_internal_set_t(from._internal_t());
+  if (from._internal_t1() != 0) {
+    _this->_internal_set_t1(from._internal_t1());
   }
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_v = from._internal_v();
-  ::uint32_t raw_v;
-  memcpy(&raw_v, &tmp_v, sizeof(tmp_v));
-  if (raw_v != 0) {
-    _this->_internal_set_v(from._internal_v());
+  float tmp_v1 = from._internal_v1();
+  ::uint32_t raw_v1;
+  memcpy(&raw_v1, &tmp_v1, sizeof(tmp_v1));
+  if (raw_v1 != 0) {
+    _this->_internal_set_v1(from._internal_v1());
   }
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_w = from._internal_w();
-  ::uint32_t raw_w;
-  memcpy(&raw_w, &tmp_w, sizeof(tmp_w));
-  if (raw_w != 0) {
-    _this->_internal_set_w(from._internal_w());
+  float tmp_w1 = from._internal_w1();
+  ::uint32_t raw_w1;
+  memcpy(&raw_w1, &tmp_w1, sizeof(tmp_w1));
+  if (raw_w1 != 0) {
+    _this->_internal_set_w1(from._internal_w1());
   }
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_l = from._internal_l();
-  ::uint32_t raw_l;
-  memcpy(&raw_l, &tmp_l, sizeof(tmp_l));
-  if (raw_l != 0) {
-    _this->_internal_set_l(from._internal_l());
+  float tmp_v2 = from._internal_v2();
+  ::uint32_t raw_v2;
+  memcpy(&raw_v2, &tmp_v2, sizeof(tmp_v2));
+  if (raw_v2 != 0) {
+    _this->_internal_set_v2(from._internal_v2());
+  }
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_w2 = from._internal_w2();
+  ::uint32_t raw_w2;
+  memcpy(&raw_w2, &tmp_w2, sizeof(tmp_w2));
+  if (raw_w2 != 0) {
+    _this->_internal_set_w2(from._internal_w2());
+  }
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_v3 = from._internal_v3();
+  ::uint32_t raw_v3;
+  memcpy(&raw_v3, &tmp_v3, sizeof(tmp_v3));
+  if (raw_v3 != 0) {
+    _this->_internal_set_v3(from._internal_v3());
+  }
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_w3 = from._internal_w3();
+  ::uint32_t raw_w3;
+  memcpy(&raw_w3, &tmp_w3, sizeof(tmp_w3));
+  if (raw_w3 != 0) {
+    _this->_internal_set_w3(from._internal_w3());
+  }
+  static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
+  float tmp_l1 = from._internal_l1();
+  ::uint32_t raw_l1;
+  memcpy(&raw_l1, &tmp_l1, sizeof(tmp_l1));
+  if (raw_l1 != 0) {
+    _this->_internal_set_l1(from._internal_l1());
   }
-  if (from._internal_p() != 0) {
-    _this->_internal_set_p(from._internal_p());
+  if (from._internal_p1() != 0) {
+    _this->_internal_set_p1(from._internal_p1());
   }
   static_assert(sizeof(::uint32_t) == sizeof(float), "Code assumes ::uint32_t and float are the same size.");
-  float tmp_d = from._internal_d();
-  ::uint32_t raw_d;
-  memcpy(&raw_d, &tmp_d, sizeof(tmp_d));
-  if (raw_d != 0) {
-    _this->_internal_set_d(from._internal_d());
+  float tmp_d1 = from._internal_d1();
+  ::uint32_t raw_d1;
+  memcpy(&raw_d1, &tmp_d1, sizeof(tmp_d1));
+  if (raw_d1 != 0) {
+    _this->_internal_set_d1(from._internal_d1());
   }
   if (from._internal_end() != 0) {
     _this->_internal_set_end(from._internal_end());
@@ -1708,9 +1874,9 @@ void ToAgvCmd::InternalSwap(ToAgvCmd* other) {
   ::PROTOBUF_NAMESPACE_ID::internal::memswap<
       PROTOBUF_FIELD_OFFSET(ToAgvCmd, _impl_.end_)
       + sizeof(ToAgvCmd::_impl_.end_)
-      - PROTOBUF_FIELD_OFFSET(ToAgvCmd, _impl_.h_)>(
-          reinterpret_cast<char*>(&_impl_.h_),
-          reinterpret_cast<char*>(&other->_impl_.h_));
+      - PROTOBUF_FIELD_OFFSET(ToAgvCmd, _impl_.h1_)>(
+          reinterpret_cast<char*>(&_impl_.h1_),
+          reinterpret_cast<char*>(&other->_impl_.h1_));
 }
 
 ::PROTOBUF_NAMESPACE_ID::Metadata ToAgvCmd::GetMetadata() const {

+ 299 - 171
MPC/monitor/emqx/message.pb.h

@@ -668,97 +668,141 @@ class ToAgvCmd final :
   // accessors -------------------------------------------------------
 
   enum : int {
-    kHFieldNumber = 1,
-    kMFieldNumber = 2,
-    kTFieldNumber = 3,
-    kVFieldNumber = 4,
-    kWFieldNumber = 5,
-    kLFieldNumber = 6,
-    kPFieldNumber = 7,
-    kDFieldNumber = 8,
-    kEndFieldNumber = 9,
+    kH1FieldNumber = 1,
+    kM1FieldNumber = 2,
+    kT1FieldNumber = 3,
+    kV1FieldNumber = 4,
+    kW1FieldNumber = 5,
+    kV2FieldNumber = 6,
+    kW2FieldNumber = 7,
+    kV3FieldNumber = 8,
+    kW3FieldNumber = 9,
+    kL1FieldNumber = 10,
+    kP1FieldNumber = 11,
+    kD1FieldNumber = 12,
+    kEndFieldNumber = 13,
   };
-  // int32 H = 1;
-  void clear_h() ;
-  ::int32_t h() const;
-  void set_h(::int32_t value);
+  // int32 H1 = 1;
+  void clear_h1() ;
+  ::int32_t h1() const;
+  void set_h1(::int32_t value);
 
   private:
-  ::int32_t _internal_h() const;
-  void _internal_set_h(::int32_t value);
+  ::int32_t _internal_h1() const;
+  void _internal_set_h1(::int32_t value);
 
   public:
-  // int32 M = 2;
-  void clear_m() ;
-  ::int32_t m() const;
-  void set_m(::int32_t value);
+  // int32 M1 = 2;
+  void clear_m1() ;
+  ::int32_t m1() const;
+  void set_m1(::int32_t value);
 
   private:
-  ::int32_t _internal_m() const;
-  void _internal_set_m(::int32_t value);
+  ::int32_t _internal_m1() const;
+  void _internal_set_m1(::int32_t value);
 
   public:
-  // int32 T = 3;
-  void clear_t() ;
-  ::int32_t t() const;
-  void set_t(::int32_t value);
+  // int32 T1 = 3;
+  void clear_t1() ;
+  ::int32_t t1() const;
+  void set_t1(::int32_t value);
 
   private:
-  ::int32_t _internal_t() const;
-  void _internal_set_t(::int32_t value);
+  ::int32_t _internal_t1() const;
+  void _internal_set_t1(::int32_t value);
 
   public:
-  // float V = 4;
-  void clear_v() ;
-  float v() const;
-  void set_v(float value);
+  // float V1 = 4;
+  void clear_v1() ;
+  float v1() const;
+  void set_v1(float value);
 
   private:
-  float _internal_v() const;
-  void _internal_set_v(float value);
+  float _internal_v1() const;
+  void _internal_set_v1(float value);
 
   public:
-  // float W = 5;
-  void clear_w() ;
-  float w() const;
-  void set_w(float value);
+  // float W1 = 5;
+  void clear_w1() ;
+  float w1() const;
+  void set_w1(float value);
 
   private:
-  float _internal_w() const;
-  void _internal_set_w(float value);
+  float _internal_w1() const;
+  void _internal_set_w1(float value);
 
   public:
-  // float L = 6;
-  void clear_l() ;
-  float l() const;
-  void set_l(float value);
+  // float V2 = 6;
+  void clear_v2() ;
+  float v2() const;
+  void set_v2(float value);
 
   private:
-  float _internal_l() const;
-  void _internal_set_l(float value);
+  float _internal_v2() const;
+  void _internal_set_v2(float value);
+
+  public:
+  // float W2 = 7;
+  void clear_w2() ;
+  float w2() const;
+  void set_w2(float value);
+
+  private:
+  float _internal_w2() const;
+  void _internal_set_w2(float value);
 
   public:
-  // int32 P = 7;
-  void clear_p() ;
-  ::int32_t p() const;
-  void set_p(::int32_t value);
+  // float V3 = 8;
+  void clear_v3() ;
+  float v3() const;
+  void set_v3(float value);
 
   private:
-  ::int32_t _internal_p() const;
-  void _internal_set_p(::int32_t value);
+  float _internal_v3() const;
+  void _internal_set_v3(float value);
 
   public:
-  // float D = 8;
-  void clear_d() ;
-  float d() const;
-  void set_d(float value);
+  // float W3 = 9;
+  void clear_w3() ;
+  float w3() const;
+  void set_w3(float value);
 
   private:
-  float _internal_d() const;
-  void _internal_set_d(float value);
+  float _internal_w3() const;
+  void _internal_set_w3(float value);
 
   public:
-  // int32 end = 9;
+  // float L1 = 10;
+  void clear_l1() ;
+  float l1() const;
+  void set_l1(float value);
+
+  private:
+  float _internal_l1() const;
+  void _internal_set_l1(float value);
+
+  public:
+  // int32 P1 = 11;
+  void clear_p1() ;
+  ::int32_t p1() const;
+  void set_p1(::int32_t value);
+
+  private:
+  ::int32_t _internal_p1() const;
+  void _internal_set_p1(::int32_t value);
+
+  public:
+  // float D1 = 12;
+  void clear_d1() ;
+  float d1() const;
+  void set_d1(float value);
+
+  private:
+  float _internal_d1() const;
+  void _internal_set_d1(float value);
+
+  public:
+  // int32 end = 13;
   void clear_end() ;
   ::int32_t end() const;
   void set_end(::int32_t value);
@@ -776,14 +820,18 @@ class ToAgvCmd final :
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
   struct Impl_ {
-    ::int32_t h_;
-    ::int32_t m_;
-    ::int32_t t_;
-    float v_;
-    float w_;
-    float l_;
-    ::int32_t p_;
-    float d_;
+    ::int32_t h1_;
+    ::int32_t m1_;
+    ::int32_t t1_;
+    float v1_;
+    float w1_;
+    float v2_;
+    float w2_;
+    float v3_;
+    float w3_;
+    float l1_;
+    ::int32_t p1_;
+    float d1_;
     ::int32_t end_;
     mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
   };
@@ -2899,167 +2947,247 @@ inline void AgvStatu::_internal_set_lifter_other(::int32_t value) {
 
 // ToAgvCmd
 
-// int32 H = 1;
-inline void ToAgvCmd::clear_h() {
-  _impl_.h_ = 0;
+// int32 H1 = 1;
+inline void ToAgvCmd::clear_h1() {
+  _impl_.h1_ = 0;
 }
-inline ::int32_t ToAgvCmd::h() const {
-  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.H)
-  return _internal_h();
+inline ::int32_t ToAgvCmd::h1() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.H1)
+  return _internal_h1();
 }
-inline void ToAgvCmd::set_h(::int32_t value) {
-  _internal_set_h(value);
-  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.H)
+inline void ToAgvCmd::set_h1(::int32_t value) {
+  _internal_set_h1(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.H1)
 }
-inline ::int32_t ToAgvCmd::_internal_h() const {
-  return _impl_.h_;
+inline ::int32_t ToAgvCmd::_internal_h1() const {
+  return _impl_.h1_;
 }
-inline void ToAgvCmd::_internal_set_h(::int32_t value) {
+inline void ToAgvCmd::_internal_set_h1(::int32_t value) {
   ;
-  _impl_.h_ = value;
+  _impl_.h1_ = value;
 }
 
-// int32 M = 2;
-inline void ToAgvCmd::clear_m() {
-  _impl_.m_ = 0;
+// int32 M1 = 2;
+inline void ToAgvCmd::clear_m1() {
+  _impl_.m1_ = 0;
 }
-inline ::int32_t ToAgvCmd::m() const {
-  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.M)
-  return _internal_m();
+inline ::int32_t ToAgvCmd::m1() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.M1)
+  return _internal_m1();
 }
-inline void ToAgvCmd::set_m(::int32_t value) {
-  _internal_set_m(value);
-  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.M)
+inline void ToAgvCmd::set_m1(::int32_t value) {
+  _internal_set_m1(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.M1)
 }
-inline ::int32_t ToAgvCmd::_internal_m() const {
-  return _impl_.m_;
+inline ::int32_t ToAgvCmd::_internal_m1() const {
+  return _impl_.m1_;
 }
-inline void ToAgvCmd::_internal_set_m(::int32_t value) {
+inline void ToAgvCmd::_internal_set_m1(::int32_t value) {
   ;
-  _impl_.m_ = value;
+  _impl_.m1_ = value;
 }
 
-// int32 T = 3;
-inline void ToAgvCmd::clear_t() {
-  _impl_.t_ = 0;
+// int32 T1 = 3;
+inline void ToAgvCmd::clear_t1() {
+  _impl_.t1_ = 0;
 }
-inline ::int32_t ToAgvCmd::t() const {
-  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.T)
-  return _internal_t();
+inline ::int32_t ToAgvCmd::t1() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.T1)
+  return _internal_t1();
 }
-inline void ToAgvCmd::set_t(::int32_t value) {
-  _internal_set_t(value);
-  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.T)
+inline void ToAgvCmd::set_t1(::int32_t value) {
+  _internal_set_t1(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.T1)
 }
-inline ::int32_t ToAgvCmd::_internal_t() const {
-  return _impl_.t_;
+inline ::int32_t ToAgvCmd::_internal_t1() const {
+  return _impl_.t1_;
 }
-inline void ToAgvCmd::_internal_set_t(::int32_t value) {
+inline void ToAgvCmd::_internal_set_t1(::int32_t value) {
   ;
-  _impl_.t_ = value;
+  _impl_.t1_ = value;
 }
 
-// float V = 4;
-inline void ToAgvCmd::clear_v() {
-  _impl_.v_ = 0;
+// float V1 = 4;
+inline void ToAgvCmd::clear_v1() {
+  _impl_.v1_ = 0;
 }
-inline float ToAgvCmd::v() const {
-  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.V)
-  return _internal_v();
+inline float ToAgvCmd::v1() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.V1)
+  return _internal_v1();
 }
-inline void ToAgvCmd::set_v(float value) {
-  _internal_set_v(value);
-  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.V)
+inline void ToAgvCmd::set_v1(float value) {
+  _internal_set_v1(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.V1)
 }
-inline float ToAgvCmd::_internal_v() const {
-  return _impl_.v_;
+inline float ToAgvCmd::_internal_v1() const {
+  return _impl_.v1_;
 }
-inline void ToAgvCmd::_internal_set_v(float value) {
+inline void ToAgvCmd::_internal_set_v1(float value) {
   ;
-  _impl_.v_ = value;
+  _impl_.v1_ = value;
 }
 
-// float W = 5;
-inline void ToAgvCmd::clear_w() {
-  _impl_.w_ = 0;
+// float W1 = 5;
+inline void ToAgvCmd::clear_w1() {
+  _impl_.w1_ = 0;
 }
-inline float ToAgvCmd::w() const {
-  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.W)
-  return _internal_w();
+inline float ToAgvCmd::w1() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.W1)
+  return _internal_w1();
 }
-inline void ToAgvCmd::set_w(float value) {
-  _internal_set_w(value);
-  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.W)
+inline void ToAgvCmd::set_w1(float value) {
+  _internal_set_w1(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.W1)
 }
-inline float ToAgvCmd::_internal_w() const {
-  return _impl_.w_;
+inline float ToAgvCmd::_internal_w1() const {
+  return _impl_.w1_;
 }
-inline void ToAgvCmd::_internal_set_w(float value) {
+inline void ToAgvCmd::_internal_set_w1(float value) {
   ;
-  _impl_.w_ = value;
+  _impl_.w1_ = value;
 }
 
-// float L = 6;
-inline void ToAgvCmd::clear_l() {
-  _impl_.l_ = 0;
+// float V2 = 6;
+inline void ToAgvCmd::clear_v2() {
+  _impl_.v2_ = 0;
 }
-inline float ToAgvCmd::l() const {
-  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.L)
-  return _internal_l();
+inline float ToAgvCmd::v2() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.V2)
+  return _internal_v2();
 }
-inline void ToAgvCmd::set_l(float value) {
-  _internal_set_l(value);
-  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.L)
+inline void ToAgvCmd::set_v2(float value) {
+  _internal_set_v2(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.V2)
 }
-inline float ToAgvCmd::_internal_l() const {
-  return _impl_.l_;
+inline float ToAgvCmd::_internal_v2() const {
+  return _impl_.v2_;
 }
-inline void ToAgvCmd::_internal_set_l(float value) {
+inline void ToAgvCmd::_internal_set_v2(float value) {
   ;
-  _impl_.l_ = value;
+  _impl_.v2_ = value;
+}
+
+// float W2 = 7;
+inline void ToAgvCmd::clear_w2() {
+  _impl_.w2_ = 0;
+}
+inline float ToAgvCmd::w2() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.W2)
+  return _internal_w2();
+}
+inline void ToAgvCmd::set_w2(float value) {
+  _internal_set_w2(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.W2)
+}
+inline float ToAgvCmd::_internal_w2() const {
+  return _impl_.w2_;
+}
+inline void ToAgvCmd::_internal_set_w2(float value) {
+  ;
+  _impl_.w2_ = value;
+}
+
+// float V3 = 8;
+inline void ToAgvCmd::clear_v3() {
+  _impl_.v3_ = 0;
+}
+inline float ToAgvCmd::v3() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.V3)
+  return _internal_v3();
+}
+inline void ToAgvCmd::set_v3(float value) {
+  _internal_set_v3(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.V3)
+}
+inline float ToAgvCmd::_internal_v3() const {
+  return _impl_.v3_;
+}
+inline void ToAgvCmd::_internal_set_v3(float value) {
+  ;
+  _impl_.v3_ = value;
+}
+
+// float W3 = 9;
+inline void ToAgvCmd::clear_w3() {
+  _impl_.w3_ = 0;
+}
+inline float ToAgvCmd::w3() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.W3)
+  return _internal_w3();
+}
+inline void ToAgvCmd::set_w3(float value) {
+  _internal_set_w3(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.W3)
+}
+inline float ToAgvCmd::_internal_w3() const {
+  return _impl_.w3_;
+}
+inline void ToAgvCmd::_internal_set_w3(float value) {
+  ;
+  _impl_.w3_ = value;
+}
+
+// float L1 = 10;
+inline void ToAgvCmd::clear_l1() {
+  _impl_.l1_ = 0;
+}
+inline float ToAgvCmd::l1() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.L1)
+  return _internal_l1();
+}
+inline void ToAgvCmd::set_l1(float value) {
+  _internal_set_l1(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.L1)
+}
+inline float ToAgvCmd::_internal_l1() const {
+  return _impl_.l1_;
+}
+inline void ToAgvCmd::_internal_set_l1(float value) {
+  ;
+  _impl_.l1_ = value;
 }
 
-// int32 P = 7;
-inline void ToAgvCmd::clear_p() {
-  _impl_.p_ = 0;
+// int32 P1 = 11;
+inline void ToAgvCmd::clear_p1() {
+  _impl_.p1_ = 0;
 }
-inline ::int32_t ToAgvCmd::p() const {
-  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.P)
-  return _internal_p();
+inline ::int32_t ToAgvCmd::p1() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.P1)
+  return _internal_p1();
 }
-inline void ToAgvCmd::set_p(::int32_t value) {
-  _internal_set_p(value);
-  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.P)
+inline void ToAgvCmd::set_p1(::int32_t value) {
+  _internal_set_p1(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.P1)
 }
-inline ::int32_t ToAgvCmd::_internal_p() const {
-  return _impl_.p_;
+inline ::int32_t ToAgvCmd::_internal_p1() const {
+  return _impl_.p1_;
 }
-inline void ToAgvCmd::_internal_set_p(::int32_t value) {
+inline void ToAgvCmd::_internal_set_p1(::int32_t value) {
   ;
-  _impl_.p_ = value;
+  _impl_.p1_ = value;
 }
 
-// float D = 8;
-inline void ToAgvCmd::clear_d() {
-  _impl_.d_ = 0;
+// float D1 = 12;
+inline void ToAgvCmd::clear_d1() {
+  _impl_.d1_ = 0;
 }
-inline float ToAgvCmd::d() const {
-  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.D)
-  return _internal_d();
+inline float ToAgvCmd::d1() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.D1)
+  return _internal_d1();
 }
-inline void ToAgvCmd::set_d(float value) {
-  _internal_set_d(value);
-  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.D)
+inline void ToAgvCmd::set_d1(float value) {
+  _internal_set_d1(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.D1)
 }
-inline float ToAgvCmd::_internal_d() const {
-  return _impl_.d_;
+inline float ToAgvCmd::_internal_d1() const {
+  return _impl_.d1_;
 }
-inline void ToAgvCmd::_internal_set_d(float value) {
+inline void ToAgvCmd::_internal_set_d1(float value) {
   ;
-  _impl_.d_ = value;
+  _impl_.d1_ = value;
 }
 
-// int32 end = 9;
+// int32 end = 13;
 inline void ToAgvCmd::clear_end() {
   _impl_.end_ = 0;
 }

+ 111 - 39
MPC/monitor/monitor_emqx.cpp

@@ -29,10 +29,10 @@ void Monitor_emqx::clamp_close(int mode)
   MqttMsg msg;
   NavMessage::ToAgvCmd speed;
   heat_=(heat_+1)%255;
-  speed.set_h(heat_);
-  speed.set_t(eClampClose);
+  speed.set_h1(heat_);
+  speed.set_t1(eClampClose);
 
-  speed.set_m(mode);
+  speed.set_m1(mode);
   speed.set_end(1);
   msg.fromProtoMessage(speed);
   Publish(speedcmd_topic_,msg);
@@ -43,24 +43,38 @@ void Monitor_emqx::clamp_open(int mode)
   MqttMsg msg;
   NavMessage::ToAgvCmd speed;
   heat_=(heat_+1)%255;
-  speed.set_h(heat_);
-  speed.set_t(eClampOpen);
+  speed.set_h1(heat_);
+  speed.set_t1(eClampOpen);
 
-  speed.set_m(mode);
+  speed.set_m1(mode);
   speed.set_end(1);
   msg.fromProtoMessage(speed);
   Publish(speedcmd_topic_,msg);
 }
 
+void Monitor_emqx::clamp_fully_open(int mode)
+{
+    MqttMsg msg;
+    NavMessage::ToAgvCmd speed;
+    heat_=(heat_+1)%255;
+    speed.set_h1(heat_);
+    speed.set_t1(eClampFullyOpen);
+
+    speed.set_m1(mode);
+    speed.set_end(1);
+    msg.fromProtoMessage(speed);
+    Publish(speedcmd_topic_,msg);
+}
+
 void Monitor_emqx::lifter_rise(int mode)
 {
     MqttMsg msg;
     NavMessage::ToAgvCmd speed;
     heat_=(heat_+1)%255;
-    speed.set_h(heat_);
-    speed.set_t(eLifterRise);
+    speed.set_h1(heat_);
+    speed.set_t1(eLifterRise);
 
-    speed.set_m(mode);
+    speed.set_m1(mode);
     speed.set_end(1);
     msg.fromProtoMessage(speed);
     Publish(speedcmd_topic_,msg);
@@ -71,10 +85,10 @@ void Monitor_emqx::lifter_down(int mode)
     MqttMsg msg;
     NavMessage::ToAgvCmd speed;
     heat_=(heat_+1)%255;
-    speed.set_h(heat_);
-    speed.set_t(eLifterDown);
+    speed.set_h1(heat_);
+    speed.set_t1(eLifterDown);
 
-    speed.set_m(mode);
+    speed.set_m1(mode);
     speed.set_end(1);
     msg.fromProtoMessage(speed);
     Publish(speedcmd_topic_,msg);
@@ -92,14 +106,15 @@ void Monitor_emqx::set_speed(int mode,ActionType type,double v,double a,double L
   MqttMsg msg;
   NavMessage::ToAgvCmd speed;
   heat_=(heat_+1)%255;
-  speed.set_h(heat_);
-  speed.set_t(type);
-  speed.set_v(velocity);
-  speed.set_w(w);
-  speed.set_l(L);
+  speed.set_h1(heat_);
+  speed.set_t1(type);
+  speed.set_v1(velocity);
+  speed.set_w1(w);
+  speed.set_l1(L);
 
-  speed.set_m(mode);
+  speed.set_m1(mode);
   speed.set_end(1);
+  printf("real down(v:%f, w:%f)\n",velocity, w);
   msg.fromProtoMessage(speed);
   Publish(speedcmd_topic_,msg);
 
@@ -110,11 +125,15 @@ void Monitor_emqx::set_speed(int mode,ActionType type,double v,double a)
   MqttMsg msg;
   NavMessage::ToAgvCmd speed;
   heat_=(heat_+1)%255;
-  speed.set_h(heat_);
-  speed.set_t(type);
-  speed.set_v(v);
-  speed.set_w(w);
-  speed.set_m(mode);
+  speed.set_h1(heat_);
+  speed.set_t1(type);
+  speed.set_v1(v);
+  speed.set_w1(w);
+  speed.set_v2(v);
+  speed.set_w2(w);
+  speed.set_v3(v);
+  speed.set_w3(w);
+  speed.set_m1(mode);
   speed.set_end(1);
   msg.fromProtoMessage(speed);
   Publish(speedcmd_topic_,msg);
@@ -125,40 +144,93 @@ void Monitor_emqx::stop()
   MqttMsg msg;
   NavMessage::ToAgvCmd speed;
   heat_=(heat_+1)%255;
-  speed.set_h(heat_);
-  speed.set_t(eStop);
-  speed.set_v(0);
-  speed.set_w(0);
-  speed.set_end(1);
+  speed.set_h1(heat_);
+  speed.set_t1(eStop);
+  speed.set_v1(0);
+  speed.set_w1(0);
+  speed.set_v2(0);
+  speed.set_w2(0);
+  speed.set_v3(0);
+  speed.set_w3(0);
+
+    speed.set_end(1);
   msg.fromProtoMessage(speed);
 
   Publish(speedcmd_topic_,msg);
 }
 
-void Monitor_emqx::set_ToAgvCmd(int mode, ActionType type, double v, double w, double L, int P, double D) {
+void Monitor_emqx::set_ToAgvCmd(int mode, ActionType type, double v[], double w[], double L, int P, double D) {
 //    if(mode == eDouble && type == eVertical && fabs(L) < 1e-3)
 //    {
 //        printf(" Main agv mpc must set wheelBase\n ");
 //        return;
 //    }
-    double w_correct=fabs(w)>0.001?w:0.0;
-    double velocity=fabs(v)>0.001?v:0;
+    int count = 3;
+    double w_correct[count];
+    double velocity[count];
+    for (int i = 0; i < count; ++i) {
+        w_correct[i] =fabs(w[i])>0.0001?w[i]:0.0;
+        velocity[i] =fabs(v[i])>0.0001?v[i]:0.0;
+    }
     MqttMsg msg;
     NavMessage::ToAgvCmd agvCmd;
     heat_=(heat_+1)%255;
-    agvCmd.set_h(heat_);
-    agvCmd.set_m(mode);
-    agvCmd.set_t(type);
-    agvCmd.set_v(velocity);
-    agvCmd.set_w(w_correct);
-    agvCmd.set_l(L);
-    agvCmd.set_p(P);
-    agvCmd.set_d(D);
+    agvCmd.set_h1(heat_);
+    agvCmd.set_m1(mode);
+    agvCmd.set_t1(type);
+    agvCmd.set_v1(velocity[0]);
+    agvCmd.set_w1(w_correct[0]);
+    agvCmd.set_v2(velocity[1]);
+    agvCmd.set_w2(w_correct[1]);
+    agvCmd.set_v3(velocity[2]);
+    agvCmd.set_w3(w_correct[2]);
+    agvCmd.set_l1(L);
+    agvCmd.set_p1(P);
+    agvCmd.set_d1(D);
 
     agvCmd.set_end(1);
     msg.fromProtoMessage(agvCmd);
     Publish(speedcmd_topic_,msg);
 }
+//
+//void Monitor_emqx::set_ToAgvCmd(int mode, ActionType type, double v[], double w[], double diff_yaw[], double L, int P, double D) {
+////    if(mode == eDouble && type == eVertical && fabs(L) < 1e-3)
+////    {
+////        printf(" Main agv mpc must set wheelBase\n ");
+////        return;
+////    }
+//    int count = 3;
+//    double w_correct[count];
+//    double velocity[count];
+//    for (int i = 0; i < count; ++i) {
+//        w_correct[i] =fabs(w[i])>0.0001?w[i]:0.0;
+//        velocity[i] =fabs(v[i])>0.0001?v[i]:0.0;
+//    }
+//    for (int i = 0; i < 2; ++i) {
+//        diff_yaw[i] =fabs(diff_yaw[i])>0.0001?diff_yaw[i]:0.0;
+//    }
+//    MqttMsg msg;
+//    NavMessage::ToAgvCmd agvCmd;
+//    heat_=(heat_+1)%255;
+//    agvCmd.set_h1(heat_);
+//    agvCmd.set_m1(mode);
+//    agvCmd.set_t1(type);
+//    agvCmd.set_v1(velocity[0]);
+//    agvCmd.set_w1(w_correct[0]);
+//    agvCmd.set_v2(velocity[1]);
+//    agvCmd.set_w2(w_correct[1]);
+//    agvCmd.set_v3(velocity[2]);
+//    agvCmd.set_w3(w_correct[2]);
+//    agvCmd.set_l1(L);
+//    agvCmd.set_p1(P);
+//    agvCmd.set_y1(diff_yaw[0]);
+//    agvCmd.set_y2(diff_yaw[1]);
+//    agvCmd.set_d1(D);
+//
+//    agvCmd.set_end(1);
+//    msg.fromProtoMessage(agvCmd);
+//    Publish(speedcmd_topic_,msg);
+//}
 
 
 

+ 3 - 1
MPC/monitor/monitor_emqx.h

@@ -17,9 +17,11 @@ class Monitor_emqx : public Terminator_emqx
     void set_speedcmd_topic(std::string speedcmd);
     void set_speed(int mode,ActionType type,double v,double a);
     void set_speed(int mode,ActionType type,double v,double a,double L);
-    void set_ToAgvCmd(int mode,ActionType type,double v,double w,double L=0,int P=0,double D=0);
+    void set_ToAgvCmd(int mode,ActionType type,double v[],double w[],double L=0,int P=0,double D=0);
+//    void set_ToAgvCmd(int mode,ActionType type,double v[],double w[],double yaw_diff[], double L=0,int P=0,double D=0);
     void clamp_close(int mode);
     void clamp_open(int mode);
+    void clamp_fully_open(int mode);
     void lifter_rise(int mode);
     void lifter_down(int mode);
     void stop();

+ 399 - 165
MPC/navigation.cpp

@@ -257,6 +257,20 @@ void Navigation::ResetLifter(LifterStatus status) {
 
 void Navigation::ResetPose(const Pose2d &pose) {
     timedPose_.reset(pose, 1.0);
+    if(pose.theta()>0){
+        if(parameter_.main_agv()){
+            isFront_.reset(true,1.0);
+        }else{
+            isFront_.reset(false,1.0);
+        }
+    }else{
+        if(parameter_.main_agv()){
+            isFront_.reset(false,1.0);
+        }else{
+            isFront_.reset(true,1.0);
+        }
+    }
+
 }
 
 void Navigation::Cancel(const NavMessage::NavCmd &cmd, NavMessage::NavResponse &response) {
@@ -322,7 +336,8 @@ Navigation::Navigation() {
     move_mode_ = eSingle;
     monitor_ = nullptr;
     terminator_ = nullptr;
-
+    obs_h_=4.0;
+    obs_w_=2.0;
     timedBrotherPose_.reset(Pose2d(-100, 0, 0), 0.5);
 }
 
@@ -428,14 +443,14 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
             //发送暂停消息
             continue;
         }
-//        if (PoseTimeout()) {
-//            printf(" MPC_rotate Error:Pose is timeout \n");
-//            return eMpcFailed;
-//        }
-//        if (timedA_.timeout()) {
-//            printf(" MPC_rotate Error:v/a is timeout \n");
-//            return eMpcFailed;
-//        }
+        if (PoseTimeout()) {
+            printf(" MPC_rotate Error:Pose is timeout \n");
+            return eMpcFailed;
+        }
+        if (timedA_.timeout()) {
+            printf(" MPC_rotate Error:v/a is timeout \n");
+            return eMpcFailed;
+        }
 
         Pose2d current = timedPose_.Get();
         Pose2d target(node.x(), node.y(), node.theta());
@@ -466,7 +481,7 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
                 if (fabs(yaw_diffs[i]) < fabs(target_yaw_diff))
                     target_yaw_diff = yaw_diffs[i];
             }
-            std::cout << std::endl;
+//            std::cout << std::endl;
 //            std::cout << std::endl << " min_diff: " << current_to_target.theta() << std::endl;
         }
 
@@ -482,15 +497,30 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
         }
 
         //下发速度
-        if (fabs(target_yaw_diff) < 0.5 * M_PI / 180.0 && fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
+        if (fabs(target_yaw_diff) < 0.2 * M_PI / 180.0 && fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
             printf(" MPC_rotate | refer target completed\\n,cuv:%f\n", target_yaw_diff);
             Stop();
             return eMpcSuccess;
         } else{
-            SendMoveCmd(move_mode_, eRotation, 0, out[0]);
+            const int down_count = 3;
+            double v[down_count] = {0,0,0};
+            double w[down_count] = {out[0], out[1], out[2]};
+//            if(out[0]>=0){
+//                w[0]=1.*M_PI/180.0;
+//                w[1]=1.*M_PI/180.0;
+//                w[2]=1.*M_PI/180.0;
+//            }else{
+//                w[0]=-1.*M_PI/180.0;
+//                w[1]=-1.*M_PI/180.0;
+//                w[2]=-1.*M_PI/180.0;
+//            }
+            SendMoveCmd(move_mode_, eRotation, v, w);
             actionType_ = eRotation;
-            printf(" MPC_rotate | input anguar:%f, down:%f(%f), diff:%f anyDirect:%d\n",
-                   timedA_.Get(), out[0], out[0]/M_PI*180, target_yaw_diff, directions);
+            double input_w = timedA_.Get();
+            for (int i = 0; i < down_count; ++i) {
+                printf("  MPC_rotate |P[%d], input anguar:%f, down:%f(%f), diff:%f anyDirect:%d\n",
+                       i, input_w, w[i], w[i]/M_PI*180, target_yaw_diff, directions);
+            }
         }
         continue;
 
@@ -511,6 +541,7 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
 
 bool Navigation::MoveToTarget(NavMessage::PathNode node, Navigation::stLimit limit_v, Navigation::stLimit limit_w,
                               bool anyDirect, bool enable_rotate) {
+//    LogWriter("MoveToTarget beg");
     if (IsArrived(node)) {
         return true;
     }
@@ -581,7 +612,7 @@ bool Navigation::execute_nodes(NavMessage::NewAction action) {
         bool anyDirect = (action.type() == 3);
 
         //速度限制
-        stLimit adjust_angular = {parameter_.nodeangularlimit().min(), parameter_.nodeangularlimit().max()};
+        stLimit wmg_limit = {parameter_.nodeangularlimit().min(), parameter_.nodeangularlimit().max()};
         stLimit mpc_velocity = {parameter_.nodevelocitylimit().min(), parameter_.nodevelocitylimit().max()};
 
         for (int i = 0; i < action.pathnodes_size(); ++i) {
@@ -590,15 +621,24 @@ bool Navigation::execute_nodes(NavMessage::NewAction action) {
                 NavMessage::PathNode next = action.pathnodes(i + 1);
                 Pose2d vec(next.x() - node.x(), next.y() - node.y(), 0);
                 node.set_theta(Pose2d::vector2yaw(vec.x(), vec.y()));
-                node.set_l(0.10);
+                node.set_l(0.05);
                 node.set_w(0.10);
-
             } else {
                 node.set_theta(0);
+                node.set_l(0.03);
                 node.set_w(0.10);
-                node.set_l(0.10);
             }
-            if (MoveToTarget(node, mpc_velocity, adjust_angular, anyDirect, true) == false)
+            int directions = Direction::eForward;
+            if (anyDirect)
+                directions = Direction::eForward | Direction::eBackward |
+                             Direction::eLeft | Direction::eRight;
+            if (i > 0){
+                if (RotateReferToTarget(node, wmg_limit, directions) != eMpcSuccess){
+                    printf(" before move node  RotateReferToNone Failed!!\n");
+                    return false;
+                }
+            }
+            if (MoveToTarget(node, mpc_velocity, wmg_limit, anyDirect, true) == false)
                 return false;
             else
                 isInSpace_ = false;
@@ -609,8 +649,55 @@ bool Navigation::execute_nodes(NavMessage::NewAction action) {
     return false;
 }
 
+Navigation::MpcResult Navigation::RotateAfterOutSpace(){
+    if(move_mode_!=eDouble)
+        return eMpcSuccess;
+    Pose2d init = timedPose_.Get();
+    double diff1=fabs(M_PI/2.0-init.theta());
+    double diff2=fabs(-M_PI/2.0-init.theta());
+    double target= diff1<diff2?M_PI/2.0:-M_PI/2.0;
+    stLimit limit_rotate = {3 * M_PI / 180.0, 15 * M_PI / 180.0};
+    while (cancel_ == false) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        Pose2d current = timedPose_.Get();
+        double yawDiff = (target - current.theta());
+
+
+
+        //一次变速
+        std::vector<double> out;
+        bool ret;
+        TimerRecord::Execute([&, this]() {
+            ret = Rotation_mpc_once(Pose2d(0, 0, yawDiff), limit_rotate, out);
+        }, "Rotation_mpc_once");
+        if (ret == false) {
+            Stop();
+            return eMpcFailed;
+        }
+
+        //下发速度
+        if (fabs(yawDiff) < 0.3 * M_PI / 180.0 && fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
+            printf(" RotateBeforeEnterSpace refer target completed\\n,cuv:%f\n", yawDiff);
+            Stop();
+            return eMpcSuccess;
+        } else{
+            const int down_count = 3;
+            double v[down_count] = {0,0,0};
+            double w[down_count] = {out[0], out[1], out[2]};
+            SendMoveCmd(move_mode_, eRotation, v, w);
+            actionType_ = eRotation;
+            printf(" RotateBeforeEnterSpace | input anguar:%f, down:%f(%f), diff:%f anyDirect:false\n",
+                   timedA_.Get(), out[0], out[0]/M_PI*180, yawDiff);
+        }
+        continue;
+
+    }
+    return eMpcFailed;
+}
+
 Navigation::MpcResult
-Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target) {
+Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space,
+                                   double wheelbase, NavMessage::PathNode &target) {
 //    if (timedBrotherNavStatu_.timeout() || timedPose_.timeout()) {
     if (timedPose_.timeout()) {
         printf(" rotate failed : timedBrotherNavStatu_ or pose timeout\n");
@@ -622,27 +709,35 @@ Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase,
     double acc_angular = 20 * M_PI / 180.0;
     double dt = 0.1;
     Pose2d rotated = timedPose_.Get();
-
     double x = space.x();
     double y = space.y();
+    Pose2d vec(x - rotated.x(), y - rotated.y(), 0);
+    rotated.mutable_theta() = Pose2d::vector2yaw(vec.x(), vec.y());
+    bool isFront=isFront_.Get();
+    printf(" front__:%d  theta:%f\n",isFront,rotated.theta());
+    if(rotated.theta()<0.)
+        isFront=!isFront;
+
     //前车先到,后车进入2点,保持与前车一致的朝向
-    if (brother.in_space() && brother.space_id() == space.id()) {
-        printf("RotateBeforeEnterSpace | 前车先到, __LINE__ = %d\n", __LINE__);
-        rotated.mutable_theta() = brother.odom().theta();
+    if (isFront==false ) {
+        printf("后车 RotateBeforeEnterSpace | , __LINE__ = %d\n", __LINE__);
         if (move_mode_ == eSingle) {
             x -= wheelbase * cos(rotated.theta());
             y -= wheelbase * sin(rotated.theta());
             printf("确定车位点:eSingle\n");
         }
     } else { //当后车先到,倒车入库
-        printf("RotateBeforeEnterSpace | 后车先到, __LINE__ = %d\n", __LINE__);
-        rotated.mutable_theta() = space.theta();
-        rotated = rotated.rotate(rotated.x(), rotated.y(), M_PI);
+        printf("前车RotateBeforeEnterSpace | __LINE__ = %d\n", __LINE__);
+        //rotated.mutable_theta() = space.theta();
+        //rotated = rotated.rotate(rotated.x(), rotated.y(), M_PI);
     }
+    if(rotated.theta()<0.)
+        rotated = rotated.rotate(rotated.x(), rotated.y(), M_PI);
+
     target.set_x(x);
     target.set_y(y);
     target.set_theta(rotated.theta());
-    target.set_l(0.05);
+    target.set_l(0.02);
     target.set_w(0.05);
     target.set_id(space.id());
     printf("RotateBeforeEnterSpace | target:[x:%f,y:%f,theta:%f]\n",x,y,target.theta());
@@ -673,12 +768,15 @@ Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase,
         }
 
         //下发速度
-        if (fabs(yawDiff) < 0.5 * M_PI / 180.0 && fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
+        if (fabs(yawDiff) < 0.3 * M_PI / 180.0 && fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
             printf(" RotateBeforeEnterSpace refer target completed\\n,cuv:%f\n", yawDiff);
             Stop();
             return eMpcSuccess;
         } else{
-            SendMoveCmd(move_mode_, eRotation, 0, out[0]);
+            const int down_count = 3;
+            double v[down_count] = {0,0,0};
+            double w[down_count] = {out[0], out[1], out[2]};
+            SendMoveCmd(move_mode_, eRotation, v, w);
             actionType_ = eRotation;
             printf(" RotateBeforeEnterSpace | input anguar:%f, down:%f(%f), diff:%f anyDirect:false\n",
                    timedA_.Get(), out[0], out[0]/M_PI*180, yawDiff);
@@ -691,6 +789,8 @@ Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase,
 }
 
 bool Navigation::execute_InOut_space(NavMessage::NewAction action) {
+//    LogWriter("execute_InOut_space beg");
+
     if (action.type() != 1 && action.type() != 2) {
         printf(" Inout_space failed : msg action type must ==1\n ");
         return false;
@@ -709,11 +809,16 @@ bool Navigation::execute_InOut_space(NavMessage::NewAction action) {
     stLimit limit_w = {2 * M_PI / 180.0, 20 * M_PI / 180.0};
     //入库,起点为streetNode
     if (action.type() == 1) {
+//        LogWriter("In space beg-");
+
         Pose2d vec(action.spacenode().x() - action.streetnode().x(), action.spacenode().y() - action.streetnode().y(),
                    0);
-        action.mutable_streetnode()->set_l(0.06);
-        action.mutable_streetnode()->set_w(0.06);
+        action.mutable_streetnode()->set_l(0.02);
+        action.mutable_streetnode()->set_w(0.05);
         action.mutable_streetnode()->set_theta(Pose2d::vector2yaw(vec.x(), vec.y()));
+        /*
+         * 是否需要添加判断,距离较远才先运动到马路点==============================?????????
+         */
         if (MoveToTarget(action.streetnode(), limit_v, limit_w, true, true) == false) {
             printf(" Enter space failed type:%d: MoveTo StreetNode failed\n", action.type());
             return false;
@@ -728,78 +833,65 @@ bool Navigation::execute_InOut_space(NavMessage::NewAction action) {
             return false;
         }
 
-        //进库前提升机构上升
-        if (lifter_rise() == false){
-            printf(" Enter space | lifter rise failed. line:%d\n",__LINE__);
-        }
-
-        //移动到预入库点位,较高精度
-        NavMessage::PathNode pre_target;
-        bool jump_preenter = false;
-        if (move_mode_ == eSingle){
-            double x = action.spacenode().x();
-            double y = action.spacenode().y();
-            double theta = action.spacenode().theta();
-
-            double back_distance = 3.3 + 0.2 + 1;//距载车板靠墙侧车轮挡板距离(距离车位点距离)
-            Pose2d current = timedPose_.Get();
-            double diff = Pose2d::distance(current, Pose2d(x,y,theta));
-            if (diff < back_distance) jump_preenter = true;
-            x -= back_distance* cos(theta);
-            y -= back_distance* sin(theta);
-
-            pre_target.set_x(x);
-            pre_target.set_y(y);
-            pre_target.set_theta(theta);
-            pre_target.set_l(0.05);
-            pre_target.set_w(0.05);
-            pre_target.set_id("R_0");
-        }
-        else if (move_mode_ == eDouble){
-            double x = action.spacenode().x();
-            double y = action.spacenode().y();
-            double theta = action.spacenode().theta();
-
-            double back_distance = 3.3 + 0.2 + 1 + action.wheelbase()/2;//距载车板靠墙侧车轮挡板距离(距离车位点距离)
-            Pose2d current = timedPose_.Get();
-            double diff = Pose2d::distance(current, Pose2d(x,y,theta));
-            if (diff < back_distance) jump_preenter = true;
-            x -= back_distance* cos(theta);
-            y -= back_distance* sin(theta);
-
-            pre_target.set_x(x);
-            pre_target.set_y(y);
-            pre_target.set_theta(theta);
-            pre_target.set_l(0.05);
-            pre_target.set_w(0.05);
-            pre_target.set_id("R_0");
-        }
-        else{ return printf("PreEnter space failed. move_mode_ error!. line: %d\n", __LINE__);}
-        if (!jump_preenter) {
-            printf("PreEnter space beg...\npre_target: x:%f, y:%f, theta:%f\n",pre_target.x(),pre_target.y(),pre_target.theta());
-            if (MoveToTarget(pre_target, limit_v, limit_w, true, false) == false) {
-                printf(" PreEnter pre_space:%s failed. type:%d. line:%d\n", pre_target.id().data(), action.type(),
-                       __LINE__);
-                return false;
+        std::string id = action.spacenode().id().substr(1,action.spacenode().id().length()-1);
+        int space_id = stoi(id);
+        if (space_id>99 && space_id< 1000){
+            //进载车板库前提升机构上升
+            if (lifter_rise() == false){
+                printf(" Enter space | lifter rise failed. line:%d\n",__LINE__);
+            }
+        }
+        else{
+            //否则下降
+            if (lifter_down() == false){
+                printf(" Enter space | lifter down failed. line:%d\n",__LINE__);
             }
+
         }
 
+        if (space_id == 1101){
+            //单车进入口搬车,夹持杆打开到全开位
+
+        }
         //入库
+        Pose2d rotated = timedPose_.Get();
+        double x = new_target.x();
+        double y = new_target.y();
+        Pose2d vecSpace(x - rotated.x(), y - rotated.y(), 0);
+        rotated.mutable_theta() = Pose2d::vector2yaw(vecSpace.x(), vecSpace.y());
+        bool isFront=isFront_.Get();
+        if(rotated.theta()<0.)
+            isFront=!isFront;
+        if(isFront==false && move_mode_==eSingle){
+            while(timedBrotherNavStatu_.Get().in_space()==false){
+                if(cancel_){
+                    return false;
+                }
+                printf(" 后车 等待 前车先入库。。。\n");
+                usleep(1000*500);
+                continue;
+            }
+        }
+        isInSpace_=true;
         printf("Enter space beg...\n");
         if (MoveToTarget(new_target, limit_v, limit_w, true, false) == false) {
             printf(" Enter space:%s failed. type:%d\n",action.spacenode().id().data(), action.type());
             return false;
         }
     } else if (action.type() == 2) {
-        Pose2d space(action.spacenode().x(), action.spacenode().y(), 0);
-        Pose2d diff = Pose2d::abs(Pose2d::relativePose(space, timedPose_.Get()));
-        if (diff.x() < 0.05 || diff.y() < 0.05) {
+//        LogWriter("Out space beg-");
+        // 计算当前位置,在车位点到马路点的连线方向上,与车位点的相对位姿
+        Pose2d vec(action.streetnode().x() - action.spacenode().x(),
+                   action.streetnode().y() - action.spacenode().y(), 0);
+        float theta = Pose2d::vector2yaw(vec.x(), vec.y());
+        Pose2d space(action.spacenode().x(), action.spacenode().y(), theta);
+        Pose2d current = timedPose_.Get();
+        Pose2d diff = Pose2d::abs(Pose2d::relativePose(Pose2d(current.x(),current.y(),0),space));
+        if (diff.x() < 0.05 || diff.y() < 0.10) {
             //出库,移动到马路点,允许自由方向,不允许中途旋转
-            Pose2d vec(action.streetnode().x() - action.spacenode().x(),
-                       action.streetnode().y() - action.spacenode().y(), 0);
-            action.mutable_streetnode()->set_theta(Pose2d::vector2yaw(vec.x(), vec.y()));
-            action.mutable_streetnode()->set_l(0.2);
-            action.mutable_streetnode()->set_w(0.1);
+            action.mutable_streetnode()->set_theta(theta);
+            action.mutable_streetnode()->set_l(0.04);
+            action.mutable_streetnode()->set_w(0.06);
             std::cout << " Out space target street node:" << space << std::endl;
             if (MoveToTarget(action.streetnode(), limit_v, limit_w, true, false) == false) {
                 printf(" out space failed type:%d: MoveTo StreetNode failed\n", action.type());
@@ -810,12 +902,17 @@ bool Navigation::execute_InOut_space(NavMessage::NewAction action) {
             if (lifter_down() == false){
                 printf(" Out space | lifter down failed. line:%d\n",__LINE__);
             }
-
+//            if(RotateAfterOutSpace()!=eMpcSuccess) {
+//                printf(" after out space rotate Failed!!!\n");
+//                return false;
+//            }
+//            LogWriter("Out space end-");
         } else {
             std::cout << " Out space failed: current pose too far from space node:" << space << ",diff:" << diff
                       << std::endl;
             return false;
         }
+        isInSpace_=false;
 
     }
     return true;
@@ -864,15 +961,20 @@ bool Navigation::Rotation_mpc_once(Pose2d current_to_target, Navigation::stLimit
         printf(" Rotation_mpc solve no solution set v/w = 0\n");
         out.clear();
         out.push_back(0);
+        out.push_back(0);
+        out.push_back(0);
     } else {
 //        double min_angular_velocity = 1.0 / 180 * M_PI;
-        double min_angular_velocity = 0.00001;
-        if (fabs(out[0]) < min_angular_velocity) {
-            if (out[0] > 0)
-                out[0] = min_angular_velocity;
-            else if (out[0] < 0)
-                out[0] = -min_angular_velocity;
-            else {}
+        double min_angular_velocity = 0.01;
+        const int down_count = 3;
+        for (int i = 0; i < down_count; ++i) {
+            if (fabs(out[i]) < min_angular_velocity) {
+                if (out[i] > 0)
+                    out[i] = min_angular_velocity;
+                else if (out[i] < 0)
+                    out[i] = -min_angular_velocity;
+                else {}
+            }
         }
     }
     return ret == success || ret == no_solution;
@@ -896,6 +998,9 @@ bool Navigation::mpc_once(Trajectory traj, stLimit limit_v, std::vector<double>
     double velocity = timedV_.Get();    //从plc获取状态
     double angular = timedA_.Get();
 
+//    float diffYaw1=timedPose_.Get().m_diffYaw1;
+//    float diffYaw2=timedPose_.Get().m_diffYaw2;
+
     Eigen::VectorXd statu = Eigen::VectorXd::Zero(5);//agv状态
 
     statu[0] = pose.x();
@@ -907,8 +1012,8 @@ bool Navigation::mpc_once(Trajectory traj, stLimit limit_v, std::vector<double>
     Trajectory optimize_trajectory;
     Trajectory selected_trajectory;
     NavParameter::MPC_parameter mpc_parameter = parameter_.x_mpc_parameter();
-    double obs_w = 0.95;//0.85;
-    double obs_h = 1.55;//1.45;
+    double obs_w =obs_w_;// 0.95;//0.85;
+    double obs_h =obs_h_;// 1.55;//1.45;
 
     if (directY == true) {
         //将车身朝向旋转90°,车身朝向在(-pi,pi]
@@ -916,8 +1021,8 @@ bool Navigation::mpc_once(Trajectory traj, stLimit limit_v, std::vector<double>
         if (statu[2] > M_PI)
             statu[2] -= 2 * M_PI;
         mpc_parameter = parameter_.y_mpc_parameter();
-        obs_w = 0.95;//0.85;
-        obs_h = 1.55;//1.45;
+        obs_w = obs_h_;// 0.95;//0.85;
+        obs_h = obs_w_;//1.55;//1.45;
     }
 
     Pose2d brother = timedBrotherPose_.Get();
@@ -925,7 +1030,7 @@ bool Navigation::mpc_once(Trajectory traj, stLimit limit_v, std::vector<double>
     if (directY)
         relative = Pose2d::relativePose(brother.rotate(brother.x(), brother.y(), M_PI / 2),
                                         pose.rotate(pose.x(), pose.y(), M_PI / 2));//计算另一节在当前小车坐标系下的坐标
-    //std::cout<<"pose:"<<pose<<",  brother:"<<brother<<", relative:"<<relative<<std::endl;
+    std::cout<<"pose:"<<pose<<",  brother:"<<brother<<", relative:"<<relative<<std::endl;
     if (move_mode_ == eDouble)
         relative = Pose2d(-1e8, -1e8, 0);
 
@@ -936,7 +1041,7 @@ bool Navigation::mpc_once(Trajectory traj, stLimit limit_v, std::vector<double>
     //printf(" r:%f  dt:%f acc:%f  acc_a:%f\n",mpc_parameter.shortest_radius(),
     //       mpc_parameter.dt(),mpc_parameter.acc_velocity(),mpc_parameter.acc_angular());
     ret = MPC.solve(traj, traj[traj.size() - 1], statu, parameter,
-                    out, selected_trajectory, optimize_trajectory);
+                    out, selected_trajectory, optimize_trajectory,directY);
 
     //std::cout<<" traj size %d  %d -------- "<<selected_trajectory.size()<<","<<optimize_trajectory.size()<<std::endl;
     if (ret == no_solution) {
@@ -944,7 +1049,15 @@ bool Navigation::mpc_once(Trajectory traj, stLimit limit_v, std::vector<double>
         out.clear();
         out.push_back(0);
         out.push_back(0);
+        out.push_back(0);
+        out.push_back(0);
+        out.push_back(0);
+        out.push_back(0);
     }
+    //
+//    diff_yaw.push_back(0);
+//    diff_yaw.push_back(0);
+
     predict_traj_.reset(optimize_trajectory, 1);
     selected_traj_.reset(selected_trajectory, 1);
     return ret == success || ret == no_solution;
@@ -998,9 +1111,10 @@ void Navigation::SendMoveCmd(int mode, ActionType type,
     }
 }
 
-void Navigation::SendMoveCmd(int mode, ActionType type, double v, double angular, int space_id, double distance) {
+void Navigation::SendMoveCmd(int mode, ActionType type,
+                             double v[], double angular[]) {
     if (monitor_) {
-        monitor_->set_ToAgvCmd(mode, type, v, angular, 0,space_id, distance);
+        monitor_->set_ToAgvCmd(mode, type, v, angular);
         if (type == eRotation)
             RWheel_position_ = eR;
         if (type == eVertical)
@@ -1010,6 +1124,30 @@ void Navigation::SendMoveCmd(int mode, ActionType type, double v, double angular
     }
 }
 
+void Navigation::SendMoveCmd(int mode, ActionType type, double v[], double angular[], int space_id, double distance) {
+    if (monitor_) {
+        monitor_->set_ToAgvCmd(mode, type, v, angular, 0, space_id, distance);
+        if (type == eRotation)
+            RWheel_position_ = eR;
+        if (type == eVertical)
+            RWheel_position_ = eX;
+        if (type == eHorizontal)
+            RWheel_position_ = eY;
+    }
+}
+
+//void Navigation::SendMoveCmd(int mode, ActionType type, double v[], double angular[], double yaw_diff[] ,int space_id, double distance) {
+//    if (monitor_) {
+//        monitor_->set_ToAgvCmd(mode, type, v, angular, yaw_diff ,0,space_id, distance);
+//        if (type == eRotation)
+//            RWheel_position_ = eR;
+//        if (type == eVertical)
+//            RWheel_position_ = eX;
+//        if (type == eHorizontal)
+//            RWheel_position_ = eY;
+//    }
+//}
+
 bool Navigation::clamp_close() {
     if (monitor_) {
         printf("Clamp closing...\n");
@@ -1052,6 +1190,30 @@ bool Navigation::clamp_open() {
     return false;
 }
 
+
+bool Navigation::clamp_fully_open(){
+    if (monitor_){
+        printf("Clamp fully openning...\n");
+        monitor_->clamp_fully_open(move_mode_);
+        actionType_ = eClampFullyOpen;
+        while (cancel_ == false) {
+            if (timed_clamp_.timeout()) {
+                printf("timed clamp is timeout\n");
+                return false;
+            }
+            if (timed_clamp_.Get() == eFullyOpened)
+                return true;
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            monitor_->clamp_fully_open(move_mode_);
+            actionType_ = eClampFullyOpen;
+        }
+        return false;
+    }
+    return false;
+
+}
+
+
 bool Navigation::lifter_rise() {
     if (monitor_) {
         printf("Lifter upping...\n");
@@ -1095,6 +1257,8 @@ bool Navigation::lifter_down() {
 }
 
 Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit limit_v, bool autoDirect) {
+//    LogWriter("MpcToTarget beg");
+
     if (IsArrived(node)) {
         printf(" current already in target completed !!!\n");
         return eMpcSuccess;
@@ -1110,7 +1274,7 @@ Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit
     Pose2d current = timedPose_.Get();
     Pose2d target(node.x(), node.y(), 0);
     //生成轨迹
-    Trajectory traj = Trajectory::create_line_trajectory(current, target);
+    Trajectory traj = Trajectory::create_line_trajectory(current, target, 0.1);
     if (traj.size() == 0)
         return eMpcSuccess;
     //判断 巡线方向
@@ -1125,38 +1289,57 @@ Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit
         }
     }
     printf(" exec along autoDirect:%d\n", autoDirect);
+
+    //文件log
+    std::ofstream ofs;  //创建流对象
+    std::string log_file_dir = "../data/";
+    time_t t = time(0);
+    char tmp[32]={NULL};
+    strftime(tmp, sizeof(tmp), "%Y_%m_%d_%H_%M_%S.txt",localtime(&t));
+    std::string log_file_name = tmp;
+    ofs.open(log_file_dir+log_file_name,std::ios::app);  //打开的地址和方式
+    auto beg_time = std::chrono::steady_clock::now();
+
     while (cancel_ == false) {
-        std::this_thread::sleep_for(std::chrono::milliseconds(30));
+        std::this_thread::sleep_for(std::chrono::milliseconds(20));
         if (pause_ == true) {
             //发送暂停消息
             continue;
         }
         if (PoseTimeout()) {
             printf(" navigation Error:Pose is timeout \n");
+            ofs.close();//关闭文件
             return eMpcFailed;
         }
         if (timedV_.timeout() || timedA_.timeout()) {
             printf(" navigation Error:v/a is timeout | __LINE__:%d \n", __LINE__);
+            ofs.close();//关闭文件
             return eMpcFailed;
         }
         //判断是否到达终点
         if (IsArrived(node)) {
             if (Stop()) {
                 printf(" exec along completed !!!\n");
+                ofs.close();//关闭文件
                 return eMpcSuccess;
             }
         }
 
         //一次变速
         std::vector<double> out;
+//        std::vector<double> diff_yaw; //两车分别与整车的相对角度
         bool ret;
         TimerRecord::Execute([&, this]() {
             ret = mpc_once(traj, limit_v, out, directY);
         }, "mpc_once");
         if (ret == false) {
             Stop();
+            ofs.close();//关闭文件
             return eMpcFailed;
         }
+        const int down_count = 3;//下发前多少步
+        double down_v[down_count] ={out[0], out[2], out[4]};//下发线速度
+        double down_w[down_count] ={out[1], out[3], out[5]};//下发角速度
         /*
          * AGV 在终点附近低速巡航时,设置最小速度0.05
          */
@@ -1165,29 +1348,35 @@ Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit
             target_in_agv = target_in_agv.rotate(M_PI / 2.0);
         }
         if (Pose2d::abs(target_in_agv) < Pose2d(0.2, 2, M_PI * 2)) {
-            if (out[0] >= 0 && out[0] < limit_v.min)
-                out[0] = limit_v.min;
-            if (out[0] < 0 && out[0] > -limit_v.min)
-                out[0] = -limit_v.min;
+            for (int i = 0; i < down_count; ++i) {
+                if (down_v[i] >= 0 && down_v[i] < limit_v.min)
+                    down_v[i] = limit_v.min;
+                if (down_v[i] < 0 && down_v[i] > -limit_v.min)
+                    down_v[i] = -limit_v.min;
+            }
         }
 
         //放大角速度
-        out[1] *= 10;
+//        out[1] *= 10;
 
         //入库,行进方向上最后一米不纠偏
         if (newUnfinished_cations_.front().type() == 1 && node.id().find('S')!=-1){//入库
-            if(fabs(target_in_agv.x()) < 1.4){
+            if(fabs(target_in_agv.x()) < 0.5){
                 printf("target_in_agv: %f", target_in_agv.x());
-                out[1] = 0.0;
+                for (double & i : down_w) {
+                    i = 0.0;
+                }
             }
         }else if (newUnfinished_cations_.front().type() == 2){//出库,行进方向上开始一米不纠偏
             Pose2d agv_in_space =
                     Pose2d::relativePose(
                             Pose2d(newUnfinished_cations_.front().spacenode().x(), newUnfinished_cations_.front().spacenode().y(), 0),
                             timedPose_.Get());
-            if(fabs(agv_in_space.x()) < 1.3){
+            if(fabs(agv_in_space.x()) < 0.3){
                 printf("agv_in_space: %f", agv_in_space.x());
-                out[1] = 0.0;
+                for (double & i : down_w) {
+                    i = 0.0;
+                }
             }
         }
 
@@ -1200,11 +1389,42 @@ Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit
             std::string id = node.id().substr(1,node.id().length()-1);
             space_id = stoi(id);
         }
+//        double diff_yaw_[2] = {diff_yaw[0], diff_yaw[1]};
         if (directY == false)
-            SendMoveCmd(move_mode_, eVertical, out[0], out[1], space_id, distance);
+            SendMoveCmd(move_mode_, eVertical, down_v, down_w, space_id, distance);
         else
-            SendMoveCmd(move_mode_, eHorizontal, out[0], out[1], space_id, distance);
+            SendMoveCmd(move_mode_, eHorizontal, down_v, down_w, space_id, distance);
         actionType_ = directY ? eHorizontal : eVertical;
+
+        //日志打印
+        std::string log_inf_line = std::to_string(move_mode_);
+        log_inf_line += " ";
+
+        log_inf_line += std::to_string(parameter_.x_mpc_parameter().shortest_radius())+" "+std::to_string(parameter_.x_mpc_parameter().acc_angular());
+        log_inf_line += " ";
+
+        Pose2d cur_pose = timedPose_.Get();//自身x,y,theta
+        log_inf_line += std::to_string(cur_pose.x()) + " " + std::to_string(cur_pose.y()) + " " + std::to_string(cur_pose.theta());
+        log_inf_line += " ";
+
+        Pose2d cur_Bro_pose = timedBrotherPose_.Get();//另一节x,y,theta
+        log_inf_line += std::to_string(cur_Bro_pose.x()) + " " + std::to_string(cur_Bro_pose.y()) + " " + std::to_string(cur_Bro_pose.theta());
+        log_inf_line += " ";
+
+        log_inf_line += std::to_string(out[0]) + " " + std::to_string(out[1]);//下发速度
+        log_inf_line += " ";
+        log_inf_line += std::to_string(out[2]) + " " + std::to_string(out[3]);//下发速度
+        log_inf_line += " ";
+        log_inf_line += std::to_string(out[4]) + " " + std::to_string(out[5]);//下发速度
+        log_inf_line += " ";
+
+        auto cur_time = std::chrono::steady_clock::now();
+        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(cur_time - beg_time);
+        double time =
+                double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
+        log_inf_line += std::to_string(time);
+
+        ofs << log_inf_line << std::endl;  //一行日志的内容
         /*
          * 判断车辆是否在终点附近徘徊,无法到达终点
          */
@@ -1214,10 +1434,12 @@ Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit
                 SlowlyStop();
             else
                 Stop();
+            ofs.close();//关闭文件
             return eImpossibleToTarget;
         }
     }
 
+    ofs.close();//关闭文件
     return eMpcFailed;
 }
 
@@ -1284,8 +1506,11 @@ bool Navigation::PossibleToTarget(NavMessage::PathNode targetNode, bool directY)
     }
 
 
-    printf(" impossible to target:%f %f l:%f,w:%f theta:%f\n",
+    printf(" impossible to target:%f %f l:%f,w:%f theta:%f, ",
            targetNode.x(), targetNode.y(), targetNode.l(), targetNode.w(), targetNode.theta());
+    printf(" current:%f, %f, %f\n",
+           current.x(), current.y(),current.theta());
+
     return false;
 }
 
@@ -1320,12 +1545,16 @@ void Navigation::Start(const NavMessage::NavCmd &cmd, NavMessage::NavResponse &r
         NavMessage::NewAction act = newUnfinished_cations_.front();
         if (act.type() == 1) {  //入库
             space_id_ = act.spacenode().id();
-            isInSpace_ = true;
+            obs_w_=1.25;
+            obs_h_=1.87;
             if (!execute_InOut_space(act)) {
                 printf(" In space failed\n");
+                isInSpace_ = false;
                 break;
             }
         } else if (act.type() == 2) {  //出库
+            obs_w_=1.25;
+            obs_h_=1.87;
             if (!execute_InOut_space(act)) {
                 printf(" out space failed\n");
                 break;
@@ -1333,8 +1562,12 @@ void Navigation::Start(const NavMessage::NavCmd &cmd, NavMessage::NavResponse &r
                 isInSpace_ = false;
             }
         } else if (act.type() == 3 || act.type() == 4) { //马路导航
-            if (!execute_nodes(act))
+            obs_w_=1.25;
+            obs_h_=1.87;
+            if (!execute_nodes(act)){
+                printf(" street nav failed\n");
                 break;
+            }
         } else if (act.type() == 5) {
             printf(" 汽车模型导航....\n");
 
@@ -1402,45 +1635,46 @@ float Navigation::compute_cuv(const Pose2d &target) {
 }
 
 void Navigation::ManualOperation(const NavMessage::ManualCmd &cmd, NavMessage::NavResponse &response) {
-    pause_ = false;
-    cancel_ = false;
-    running_ = true;
-    actionType_ = eReady;
-    printf("ManualOperation: %d | start...\n", cmd.operation_type());
-
-    float symbol = cmd.velocity() < 0 ? -1 : 1; // 判断为正方向or负方向
-    double velocity;
-    std::this_thread::sleep_for(std::chrono::milliseconds(100));
-    switch (cmd.operation_type()) {
-        case 1: // 旋转
-            velocity = 2.0 * M_PI / 180.0 * symbol;
-            SendMoveCmd(move_mode_, eRotation, 0, velocity);
-            actionType_ = eRotation;
-            printf(" ManualOperation: %d | input angular_v: %f, down: %f\n",
-                   cmd.operation_type(), timedA_.Get(), velocity);
-            break;
-        case 2: // X平移
-            velocity = 1.0 * symbol;
-            SendMoveCmd(move_mode_, eVertical, velocity, 0);
-            actionType_ = eVertical;
-            printf(" ManualOperation: %d | input line_v   : %f, down: %f\n",
-                   cmd.operation_type(), timedV_.Get(), velocity);
-            break;
-        case 3: // Y平移
-            velocity = 1.0 * symbol;
-            SendMoveCmd(move_mode_, eHorizontal, velocity, 0);
-            actionType_ = eHorizontal;
-            printf(" ManualOperation: %d | input line_v: %f, down: %f\n",
-                   cmd.operation_type(), timedV_.Get(), velocity);
-            break;
-        default:
-            break;
-    }
-
-    actionType_ = eReady;
-    response.set_ret(-3);
-    response.set_info("ManualOperation: %d, canceled!!!", cmd.operation_type());
-    printf("ManualOperation: %d | canceled!!!\n", cmd.operation_type());
-    running_ = false;
+    return;
+//    pause_ = false;
+//    cancel_ = false;
+//    running_ = true;
+//    actionType_ = eReady;
+//    printf("ManualOperation: %d | start...\n", cmd.operation_type());
+//
+//    float symbol = cmd.velocity() < 0 ? -1 : 1; // 判断为正方向or负方向
+//    double velocity;
+//    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+//    switch (cmd.operation_type()) {
+//        case 1: // 旋转
+//            velocity = 2.0 * M_PI / 180.0 * symbol;
+//            SendMoveCmd(move_mode_, eRotation, 0, velocity);
+//            actionType_ = eRotation;
+//            printf(" ManualOperation: %d | input angular_v: %f, down: %f\n",
+//                   cmd.operation_type(), timedA_.Get(), velocity);
+//            break;
+//        case 2: // X平移
+//            velocity = 1.0 * symbol;
+//            SendMoveCmd(move_mode_, eVertical, velocity, 0);
+//            actionType_ = eVertical;
+//            printf(" ManualOperation: %d | input line_v   : %f, down: %f\n",
+//                   cmd.operation_type(), timedV_.Get(), velocity);
+//            break;
+//        case 3: // Y平移
+//            velocity = 1.0 * symbol;
+//            SendMoveCmd(move_mode_, eHorizontal, velocity, 0);
+//            actionType_ = eHorizontal;
+//            printf(" ManualOperation: %d | input line_v: %f, down: %f\n",
+//                   cmd.operation_type(), timedV_.Get(), velocity);
+//            break;
+//        default:
+//            break;
+//    }
+//
+//    actionType_ = eReady;
+//    response.set_ret(-3);
+//    response.set_info("ManualOperation: %d, canceled!!!", cmd.operation_type());
+//    printf("ManualOperation: %d | canceled!!!\n", cmd.operation_type());
+//    running_ = false;
 }
 

+ 35 - 2
MPC/navigation.h

@@ -14,6 +14,8 @@
 #include "parameter.pb.h"
 #include <queue>
 #include <thread>
+#include <fstream>
+#include <time.h>
 
 class Navigation {
 public:
@@ -31,7 +33,8 @@ public:
     enum ClampStatu {
         eInvalid = 0,
         eClosed = 1,
-        eOpened = 2
+        eOpened = 2,    //半开位(默认)
+        eFullyOpened = 3 //全开位
     };
 
     enum MpcResult {
@@ -84,12 +87,33 @@ public:
 
     bool PoseTimeout();
 
+    // 测试日志打印
+    bool LogWriter(std::string lines){
+        {
+            std::ofstream ofs;  //创建流对象
+            std::string log_file_dir = "../data/12_12/";
+            std::string log_file_name = "12_12.txt";
+            ofs.open(log_file_dir+log_file_name,std::ios::app);  //打开的地址和方式
+
+            time_t t = time(0);
+            char tmp[32]={NULL};
+            strftime(tmp, sizeof(tmp), "%Y_%m_%d_%H_%M_%S",localtime(&t));
+            std::string time = tmp;
+            std::string log_inf_line = lines + ". " + time;
+            ofs << log_inf_line << std::endl;  //一行日志的内容
+            ofs.close();
+        }
+    }
+
 protected:
     virtual void HandleAgvStatu(const MqttMsg &msg);
 
     virtual void SendMoveCmd(int mode, ActionType type, double v, double angular);
 
-    virtual void SendMoveCmd(int mode, ActionType type, double v, double angular, int space_id, double distance);
+    virtual void SendMoveCmd(int mode, ActionType type, double v[], double angular[]);
+
+    virtual void SendMoveCmd(int mode, ActionType type, double v[], double angular[], int space_id, double distance);
+//    virtual void SendMoveCmd(int mode, ActionType type, double v[], double angular[], double diff_yaw[], int space_id, double distance);
 
     static void RobotPoseCallback(const MqttMsg &msg, void *context);
 
@@ -138,10 +162,15 @@ protected:
     virtual Navigation::MpcResult
     RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target);
 
+    virtual Navigation::MpcResult
+    RotateAfterOutSpace();
+
     virtual bool clamp_close();
 
     virtual bool clamp_open();
 
+    virtual bool clamp_fully_open();
+
     virtual bool lifter_rise();
 
     virtual bool lifter_down();
@@ -205,6 +234,10 @@ protected:
 
     NavParameter::Navigation_parameter parameter_;
     RWheelPosition RWheel_position_;
+
+    double obs_w_;
+    double obs_h_;
+    TimedLockData<bool> isFront_;
 };
 
 double limit_gause(double x, double min, double max);

+ 56 - 40
MPC/navigation_main.cpp

@@ -36,6 +36,10 @@ void NavigationMain::ResetPose(const Pose2d &pose) {
         Pose2d agv = Pose2d((pose.x() + brother.x()) / 2.0, (pose.y() + brother.y()) / 2.0, theta);
 
         Navigation::ResetPose(agv);
+//        timedPose_().m_diffYaw1=pose.theta()-theta;
+//        timedPose_().m_diffYaw2=brother.theta()-theta;
+//        printf("m_diffYaw1:%f, m_diffYaw2:%f\n",timedPose_().m_diffYaw1, timedPose_().m_diffYaw2);
+
     } else
         Navigation::ResetPose(pose);
 }
@@ -58,9 +62,21 @@ void NavigationMain::Start(const NavMessage::NavCmd &cmd, NavMessage::NavRespons
 }
 
 void NavigationMain::SendMoveCmd(int mode, ActionType type,
-                                 double v, double angular) {
+                                 double v[], double angular[]) {
     if (monitor_) {
-        monitor_->set_speed(mode, type, v, angular, wheelBase_);
+        monitor_->set_ToAgvCmd(mode, type, v, angular, wheelBase_);
+    }
+}
+
+void NavigationMain::SendMoveCmd(int mode, ActionType type, double v[], double angular[], int space_id, double distance) {
+    if (monitor_) {
+        monitor_->set_ToAgvCmd(mode, type, v, angular, wheelBase_, space_id, distance);
+        if (type == eRotation)
+            RWheel_position_ = eR;
+        if (type == eVertical)
+            RWheel_position_ = eX;
+        if (type == eHorizontal)
+            RWheel_position_ = eY;
     }
 }
 
@@ -100,7 +116,7 @@ bool NavigationMain::clamp_close() {
     printf("双车夹持\n");
     if (monitor_) {
         monitor_->clamp_close(move_mode_);
-        while (exit_ == false) {
+        while (cancel_ == false) {
             if (timed_clamp_.timeout() || timed_other_clamp_.timeout()) {
                 printf("timed clamp is timeout\n");
                 return false;
@@ -124,7 +140,7 @@ bool NavigationMain::clamp_open() {
     if (monitor_) {
         printf("双车松夹持\n");
         monitor_->clamp_open(move_mode_);
-        while (exit_ == false) {
+        while (cancel_ == false) {
             if (timed_clamp_.timeout() || timed_other_clamp_.timeout()) {
                 printf("timed clamp is timeout\n");
                 return false;
@@ -148,7 +164,7 @@ bool NavigationMain::lifter_rise() {
     if (monitor_) {
         printf("双车提升机构提升\n");
         monitor_->lifter_rise(move_mode_);
-        while (exit_ == false) {
+        while (cancel_ == false) {
             if (timed_lifter_.timeout() || timed_other_lifter_.timeout()) {
                 printf("timed lifter is timeout\n");
                 return false;
@@ -172,7 +188,7 @@ bool NavigationMain::lifter_down() {
     if (monitor_) {
         printf("双车提升机构下降\n");
         monitor_->lifter_down(move_mode_);
-        while (exit_ == false) {
+        while (cancel_ == false) {
             if (timed_lifter_.timeout() || timed_other_lifter_.timeout()) {
                 printf("timed lifter is timeout\n");
                 return false;
@@ -202,37 +218,55 @@ NavigationMain::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelb
     stLimit limit_rotate = {2 * M_PI / 180.0, 15 * M_PI / 180.0};
     double acc_angular = 25 * M_PI / 180.0;
     double dt = 0.1;
-    Pose2d rotated = Pose2d(space.x(), space.y(), space.theta());
 
+    Pose2d rotated = timedPose_.Get();
     double x = space.x();
     double y = space.y();
-    //后车先到,前车进入2点,保持与后车一致的朝向
-    if (brother.in_space() && brother.space_id() == space.id()) {
-        printf("RotateBeforeEnterSpace | 后车先到, __LINE__ = %d\n", __LINE__);
-        rotated.mutable_theta() = brother.odom().theta();
+    Pose2d vec(x - rotated.x(), y - rotated.y(), 0);
+    rotated.mutable_theta() = Pose2d::vector2yaw(vec.x(), vec.y());
+    bool isFront=isFront_.Get();
+    if(rotated.theta()<0.)
+        isFront=!isFront;
+
+    //前车先到,后车进入2点,保持与前车一致的朝向
+    if (isFront==false ) {
+        printf("后车 RotateBeforeEnterSpace | , __LINE__ = %d\n", __LINE__);
         if (move_mode_ == eSingle) {
-            x += wheelbase * cos(rotated.theta());
-            y += wheelbase * sin(rotated.theta());
+            x -= wheelbase * cos(rotated.theta());
+            y -= wheelbase * sin(rotated.theta());
+            printf("确定车位点:eSingle\n");
         }
-    } else { //当前车先到,正向
-        printf("RotateBeforeEnterSpace | 前车先到, __LINE__ = %d\n", __LINE__);
-        rotated.mutable_theta() = space.theta();
+    } else { //当后车先到,倒车入库
+        printf("前车RotateBeforeEnterSpace | __LINE__ = %d\n", __LINE__);
+        //rotated.mutable_theta() = space.theta();
+
     }
 
+
     if (move_mode_ == eDouble){
         x -= wheelbase/2 * cos(rotated.theta());
         y -= wheelbase/2 * sin(rotated.theta());
         printf("RotateBeforeEnterSpace | 整车模式, __LINE__ = %d\n", __LINE__);
     }
+    if(rotated.theta()<0.)
+        rotated = rotated.rotate(rotated.x(), rotated.y(), M_PI);
 
     target.set_x(x);
     target.set_y(y);
     target.set_theta(rotated.theta());
-    target.set_l(0.05);
+    target.set_l(0.02);
     target.set_w(0.05);
     target.set_id(space.id());
     printf("RotateBeforeEnterSpace | target:[x:%f,y:%f,theta:%f]\n",x,y,target.theta());
 
+    if (move_mode_ == eDouble) {
+        double yawDiff1 = (rotated - timedPose_.Get()).theta();
+        double yawDiff2 = (rotated + Pose2d(0, 0, M_PI) - timedPose_.Get()).theta();
+        if (fabs(yawDiff1) > fabs(yawDiff2)) {
+            rotated = rotated + Pose2d(0, 0, M_PI);
+        }
+    }
+
     while (cancel_ == false) {
         std::this_thread::sleep_for(std::chrono::milliseconds(100));
         Pose2d current = timedPose_.Get();
@@ -250,39 +284,21 @@ NavigationMain::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelb
         }
 
         //下发速度
-        if (fabs(yawDiff) < 0.5 * M_PI / 180.0 && fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
+        if (fabs(yawDiff) < 0.3 * M_PI / 180.0 && fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
             printf(" RotateBeforeEnterSpace refer target completed\\n,cuv:%f\n", yawDiff);
             Stop();
             return eMpcSuccess;
         } else{
-            SendMoveCmd(move_mode_, eRotation, 0, out[0]);
+            const int down_count = 3;
+            double v[down_count] = {0,0,0};
+            double w[down_count] = {out[0], out[1], out[2]};
+            SendMoveCmd(move_mode_, eRotation, v, w);
             actionType_ = eRotation;
             printf(" RotateBeforeEnterSpace | input anguar:%f, down:%f(%f), diff:%f anyDirect:false\n",
                    timedA_.Get(), out[0], out[0]/M_PI*180, yawDiff);
         }
         continue;
 
-//    std::this_thread::sleep_for(std::chrono::milliseconds(100));
-//    Pose2d current = timedPose_.Get();
-//    double yawDiff = (rotated - current).theta();
-//    if (fabs(yawDiff) > 1 * M_PI / 180.0) {
-//      double theta = limit_gause(yawDiff, limit_rotate.min, limit_rotate.max);
-//      double angular = next_speed(timedA_.Get(), theta, acc_angular, dt);
-//      double limit_angular = limit(angular, limit_rotate.min, limit_rotate.max);
-//
-//      SendMoveCmd(move_mode_, Monitor_emqx::eRotation, 0, limit_angular);
-//      actionType_ = eRotation;
-//      printf(" RotateBeforeEnterSpace | input anguar:%f,next angular:%f,down:%f diff:%f anyDirect:false\n",
-//             timedA_.Get(), angular, limit_angular, yawDiff);
-//
-//      continue;
-//    } else {
-//      if (fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
-//        printf(" RotateBeforeEnterSpace refer target completed\n");
-//        printf("---------------- update new target :%f %f %f \n",target.x(),target.y(),target.theta());
-//        return true;
-//      }
-//    }
     }
     return eMpcFailed;
 }

+ 2 - 2
MPC/navigation_main.h

@@ -70,8 +70,8 @@ protected:
     virtual Navigation::MpcResult
     RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target);
 
-    virtual void SendMoveCmd(int mode, ActionType type,
-                             double v, double angular);
+    virtual void SendMoveCmd(int mode, ActionType type, double v[], double angular[]);
+    virtual void SendMoveCmd(int mode, ActionType type, double v[], double angular[], int space_id, double distance);
 
     virtual bool clamp_close();
 

+ 2 - 0
MPC/pose2d.cpp

@@ -10,6 +10,8 @@
 Pose2d::Pose2d()
         :m_x(0),m_y(0),m_theta(0)
 {
+//    m_diffYaw1=0;
+//    m_diffYaw2=0;
 }
 Pose2d::Pose2d(float x,float y,float theta)
         :m_x(x),m_y(y)

+ 5 - 2
MPC/pose2d.h

@@ -94,7 +94,7 @@ class Pose2d
     }
 
     /*
-     * 将点时针旋转theta
+     * 将点时针旋转theta
      */
     Pose2d rotate(float theta)const;
     //绕xy旋转
@@ -128,11 +128,14 @@ class Pose2d
       poses.push_back(pose*Pose2d(0,h/2.0,pose.theta()));
       return poses;
     }
-
+//public:
+//    float         m_diffYaw1;
+//    float           m_diffYaw2;
  protected:
     float                     m_x;
     float                     m_y;
     float                      m_theta;        //梯度角,与x轴正方形逆时针为正,单位弧度
+
 };
 
 

+ 12 - 7
MPC/rotate_mpc.cpp

@@ -8,9 +8,11 @@
 #include <cppad/ipopt/solve.hpp>
 
 size_t mpc_rotate_steps = 20;                  //优化考虑后面多少步
-size_t mpc_rotate_delay = 2;  // 发送到执行的延迟,即几个周期的时间
+size_t mpc_rotate_delay = 0;  // 发送到执行的延迟,即几个周期的时间
+size_t mpc_rotate_down_count = 3;//下发前多少步
 #define N mpc_rotate_steps
 #define delay mpc_rotate_delay
+#define down_count mpc_rotate_down_count
 
 class FG_eval_rotate {
 public:
@@ -122,9 +124,9 @@ RotateMPC::solve(Pose2d current_to_target, Eigen::VectorXd statu, MPC_parameter
 
     /// 定义最大最小角度,角速度,角加速度(不区分方向)
     double max_angular = M_PI;
-    double max_angular_velocity = 15.0 / 180 * M_PI;
-    double min_angular_velocity = 0.01 / 180 * M_PI;
-    double max_angular_acceleration_velocity = 30.0 / 180 * M_PI;//mpc_param.acc_angular; //
+    double max_angular_velocity = 5.0 / 180 * M_PI  / (1 + exp(-10 * fabs(current_to_target.theta()) - 0.1));
+    double min_angular_velocity = 1 / 180 * M_PI;
+    double max_angular_acceleration_velocity = mpc_param.acc_angular; //30.0 / 180 * M_PI;//
     /// 调整输入
     if (angular_velocity > max_angular_velocity) angular_velocity = max_angular_velocity;
     if (angular_velocity < -max_angular_velocity) angular_velocity = -max_angular_velocity;
@@ -241,9 +243,12 @@ RotateMPC::solve(Pose2d current_to_target, Eigen::VectorXd statu, MPC_parameter
 
     // 输出第一步的角速度
     out.clear();
-    double solve_angular_velocity = solution.x[N+delay];
-
-    out.push_back(solve_angular_velocity);
+    double solve_angular_velocity;
+    for (int i = 0; i < down_count; ++i) {
+        solve_angular_velocity = solution.x[i + N + delay];
+        out.push_back(solve_angular_velocity);
+//        printf("P[%d]: %f\n", i, solve_angular_velocity);
+    }
 
     return success;
 }

+ 6 - 0
define/timedlockdata.hpp

@@ -15,6 +15,7 @@ class TimedLockData
     void reset(const T& tdata,double timeout=0.1);
     bool timeout();
     T Get();
+//    T& operator()();
 
  protected:
     T data_;
@@ -54,6 +55,11 @@ T TimedLockData<T>::Get()
   std::lock_guard<std::mutex> lck (mutex_);
   return data_;
 }
+//template <typename T>
+//T& TimedLockData<T>::operator()(void ){
+//    std::lock_guard<std::mutex> lck (mutex_);
+//    return data_;
+//}
 
 
 #endif //LIO_LIVOX_CPP_DEFINE_TIME_DATA_H_

+ 13 - 9
message.proto

@@ -20,15 +20,19 @@ message AgvStatu {
 }
 
 message ToAgvCmd {
-    int32 H = 1;  //心跳
-    int32 M = 2;    //模式:2整车模式,1:单车
-    int32 T = 3; // 1:原地旋转, 2:横移, 3:MPC巡线/前进, 5:夹持, 6:松夹持, 7:提升机构抬升, 8:抬升机构下降, 其他/未接收到:停止
-    float V = 4;  //角速度
-    float W = 5;  //线速度
-    float L = 6;  //轴距
-    int32 P = 7; //车位编号
-    float D = 8; //距目标点距离
-    int32 end = 9;
+    int32 H1 = 1;  //心跳
+    int32 M1 = 2;    //模式:2整车模式,1:单车
+    int32 T1 = 3; // 1:原地旋转, 2:横移, 3:MPC巡线/前进, 5:夹持, 6:松夹持半开位, 7:提升机构抬升, 8:抬升机构下降, 9:松夹持全开位,其他/未接收到:停止
+    float V1 = 4;  //线速度
+    float W1 = 5;  //角速度
+    float V2 = 6;  //线速度
+    float W2 = 7;  //角速度
+    float V3 = 8;  //线速度
+    float W3 = 9;  //角速度
+    float L1 = 10;  //轴距
+    int32 P1 = 11; //车位编号
+    float D1 = 12; //距目标点距离
+    int32 end = 13;
 }
 
 message Pose2d