Browse Source

1.进出库修改旋转控制方式为MPC

gf 2 years ago
parent
commit
37f9dabedc
4 changed files with 240 additions and 201 deletions
  1. 62 39
      MPC/navigation.cpp
  2. 1 1
      MPC/navigation.h
  3. 176 160
      MPC/navigation_main.cpp
  4. 1 1
      MPC/navigation_main.h

+ 62 - 39
MPC/navigation.cpp

@@ -439,29 +439,27 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
         // 自由方向
         if (directions) {
             std::vector<double> yaw_diffs;
-            if (directions & MpcRotateDirection::eForward){
+            if (directions & MpcRotateDirection::eForward) {
                 yaw_diffs.push_back(target_yaw_diff);
             }
-            if (directions & MpcRotateDirection::eBackward){
+            if (directions & MpcRotateDirection::eBackward) {
                 Pose2d relative_pose = Pose2d::relativePose(targetInPose, Pose2d(0, 0, M_PI));
                 yaw_diffs.push_back(Pose2d::vector2yaw(relative_pose.x(), relative_pose.y()));
             }
             if (directions & MpcRotateDirection::eLeft) {
-                Pose2d relative_pose = Pose2d::relativePose(targetInPose, Pose2d(0, 0, 1.0/2*M_PI));
+                Pose2d relative_pose = Pose2d::relativePose(targetInPose, Pose2d(0, 0, 1.0 / 2 * M_PI));
                 yaw_diffs.push_back(Pose2d::vector2yaw(relative_pose.x(), relative_pose.y()));
             }
-            if (directions & MpcRotateDirection::eRight){
-                Pose2d relative_pose = Pose2d::relativePose(targetInPose, Pose2d(0, 0, 3.0/2*M_PI));
+            if (directions & MpcRotateDirection::eRight) {
+                Pose2d relative_pose = Pose2d::relativePose(targetInPose, Pose2d(0, 0, 3.0 / 2 * M_PI));
                 yaw_diffs.push_back(Pose2d::vector2yaw(relative_pose.x(), relative_pose.y()));
             }
 
-            std::cout << " yaw_diffs[i] = ";
             for (auto i = 0; i < yaw_diffs.size(); ++i) {
-                std::cout << yaw_diffs[i] << " ";
                 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;
         }
 
@@ -469,7 +467,7 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
         std::vector<double> out;
         bool ret;
         TimerRecord::Execute([&, this]() {
-            ret = Rotation_mpc_once(Pose2d(0,0,target_yaw_diff), limit_rotate, out);
+            ret = Rotation_mpc_once(Pose2d(0, 0, target_yaw_diff), limit_rotate, out);
         }, "Rotation_mpc_once");
         if (ret == false) {
             Stop();
@@ -477,7 +475,7 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
         }
 
         //下发速度
-        if (fabs(target_yaw_diff) > 2 * M_PI / 180.0) {
+        if (fabs(target_yaw_diff) > 1 * M_PI / 180.0) {
             SendMoveCmd(move_mode_, Monitor_emqx::eRotate, 0, out[0]);
             actionType_ = eRotation;
             printf(" MPC_rotate | input angular_v:%f, down:%f, diff:%f autoDirect:%d\n",
@@ -491,7 +489,6 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
     return eMpcFailed;
 }
 
-
 bool Navigation::MoveToTarget(NavMessage::PathNode node, Navigation::stLimit limit_v, Navigation::stLimit limit_w,
                               bool anyDirect, bool enable_rotate) {
     if (IsArrived(node)) {
@@ -524,11 +521,13 @@ bool Navigation::MoveToTarget(NavMessage::PathNode node, Navigation::stLimit lim
             }
             Pose2d target(node.x(), node.y(), 0);
 //        if (RotateReferToTarget(target, limit_w, anyDirect) == false) {
-            int direction = MpcRotateDirection::eForward | MpcRotateDirection::eBackward |
-                            MpcRotateDirection::eLeft | MpcRotateDirection::eRight;
-            if (RotateReferToTarget(node, limit_w, direction) != eMpcSuccess) {
+            int directions = MpcRotateDirection::eForward;
+            if (anyDirect)
+                directions = MpcRotateDirection::eForward | MpcRotateDirection::eBackward |
+                             MpcRotateDirection::eLeft | MpcRotateDirection::eRight;
+            if (RotateReferToTarget(node, limit_w, directions) != eMpcSuccess) {
                 std::cout << " Rotate refer to target failed,target: " << target <<
-                          " direction: " << direction << " line_: " << __LINE__ << std::endl;
+                          " directions: " << std::hex << directions << " line_: " << __LINE__ << std::endl;
                 return false;
             }
             continue;
@@ -590,10 +589,11 @@ bool Navigation::execute_nodes(NavMessage::NewAction action) {
     return false;
 }
 
-bool Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target) {
+Navigation::MpcResult
+Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target) {
     if (timedBrotherNavStatu_.timeout() || timedPose_.timeout()) {
         printf(" rotate failed : timedBrotherNavStatu_ or pose timeout\n");
-        return false;
+        return eMpcFailed;
     }
     NavMessage::NavStatu brother = timedBrotherNavStatu_.Get();
 
@@ -631,26 +631,51 @@ bool Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheel
         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::eRotate, 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);
+        //一次变速
+        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;
+        }
 
-            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;
-            }
+        //下发速度
+        if (fabs(yawDiff) > 1 * M_PI / 180.0) {
+            SendMoveCmd(move_mode_, Monitor_emqx::eRotate, 0, out[0]);
+            actionType_ = eRotation;
+            printf(" RotateBeforeEnterSpace | input anguar:%f, down:%f diff:%f anyDirect:false\n",
+                   timedA_.Get(), out[0], yawDiff);
+        } else if (fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
+            printf(" RotateBeforeEnterSpace refer target completed\\n,cuv:%f\n", yawDiff);
+            return eMpcSuccess;
         }
+        continue;
+
+
+//        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::eRotate, 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 false;
+    return eMpcFailed;
 
 }
 
@@ -687,11 +712,11 @@ bool Navigation::execute_InOut_space(NavMessage::NewAction action) {
         //计算车位朝向
         action.mutable_spacenode()->set_theta(Pose2d::vector2yaw(vec.x(), vec.y()));
         //计算当前车是进入车位1点还是2点
-        NavMessage::PathNode new_atrget;
-        if (RotateBeforeEnterSpace(action.spacenode(), action.wheelbase(), new_atrget) == false) {
+        NavMessage::PathNode new_target;
+        if (RotateBeforeEnterSpace(action.spacenode(), action.wheelbase(), new_target) == eMpcFailed) {
             return false;
         }
-        if (MoveToTarget(new_atrget, limit_v, limit_w, true, false) == false) {
+        if (MoveToTarget(new_target, limit_v, limit_w, true, false) == false) {
             printf(" Enter space failed type:%d: MoveTo StreetNode failed\n", action.type());
             return false;
         }
@@ -763,7 +788,6 @@ bool Navigation::Rotation_mpc_once(Pose2d current_to_target, Navigation::stLimit
     return ret == success || ret == no_solution;
 }
 
-
 bool Navigation::mpc_once(Trajectory traj, stLimit limit_v, std::vector<double> &out, bool directY) {
     if (PoseTimeout() == true) {
         printf(" MPC once Error:Pose is timeout \n");
@@ -836,7 +860,6 @@ bool Navigation::mpc_once(Trajectory traj, stLimit limit_v, std::vector<double>
     return ret == success || ret == no_solution;
 }
 
-
 bool Navigation::IsArrived(NavMessage::PathNode targetNode) {
     if (timedPose_.timeout() || timedV_.timeout() || timedA_.timeout()) {
         printf(" pose / v / w    timeout,IsArrived return false\n");
@@ -924,7 +947,6 @@ bool Navigation::clamp_open() {
     return false;
 }
 
-
 Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit limit_v, bool autoDirect) {
     if (IsArrived(node)) {
         printf(" current already in target completed !!!\n");
@@ -1067,6 +1089,7 @@ bool Navigation::PossibleToTarget(NavMessage::PathNode targetNode, bool directY)
                    minR,ax,ay);*/
             return true;
         } else if (nagY && posiY) {
+            std::cout<<"nagY && posiY"<<std::endl;
             return true;
         }
         printf("directY:%d targetInPose:%f %f l:%f,w:%f theta:%f  minR:%f ax:%f,ay:%f\n", directY,

+ 1 - 1
MPC/navigation.h

@@ -137,7 +137,7 @@ protected:
      * space:输入车位点,
      * target:输出目标点
      */
-    virtual bool RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target);
+    virtual Navigation::MpcResult RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target);
 
     virtual bool clamp_close();
 

+ 176 - 160
MPC/navigation_main.cpp

@@ -3,200 +3,216 @@
 //
 
 #include "navigation_main.h"
+#include "TimerRecord.h"
 
 
-NavigationMain::NavigationMain(){
-  move_mode_=Monitor_emqx::eSingle;
-  wheelBase_=0;
+NavigationMain::NavigationMain() {
+    move_mode_ = Monitor_emqx::eSingle;
+    wheelBase_ = 0;
 }
-NavigationMain::~NavigationMain(){
 
-}
+NavigationMain::~NavigationMain() {
 
-void NavigationMain::ResetPose(const Pose2d& pose){
-  if(move_mode_==Monitor_emqx::eMain) {
-    if(timedBrotherPose_.timeout()==true)
-    {
-      std::cout<<"Brother pose is timeout can not set MainAGV pose"<<std::endl;
-      return;
-    }
-    //Pose2d transform(-wheelBase_/2.0,0,0);
-    //Navigation::ResetPose(pose * transform);
-    Pose2d brother=timedBrotherPose_.Get();
-    Pose2d diff=Pose2d::abs(Pose2d::relativePose(brother,pose));
+}
 
-    if(diff.x()>3.6 || diff.x()<2.2 || diff.y()>0.3 || diff.theta()>5*M_PI/180.0)
-    {
-      std::cout<<" distance with two agv is too far diff: "<<diff<<std::endl;
-      return;
-    }
-    Pose2d abs_diff=pose-brother;
-    //计算两车朝向的方向
-    float theta=Pose2d::vector2yaw(abs_diff.x(),abs_diff.y());
-    Pose2d agv=Pose2d((pose.x()+brother.x())/2.0,(pose.y()+brother.y())/2.0,theta);
-
-    Navigation::ResetPose(agv);
-  }
-  else
-    Navigation::ResetPose(pose);
+void NavigationMain::ResetPose(const Pose2d &pose) {
+    if (move_mode_ == Monitor_emqx::eMain) {
+        if (timedBrotherPose_.timeout() == true) {
+            std::cout << "Brother pose is timeout can not set MainAGV pose" << std::endl;
+            return;
+        }
+        //Pose2d transform(-wheelBase_/2.0,0,0);
+        //Navigation::ResetPose(pose * transform);
+        Pose2d brother = timedBrotherPose_.Get();
+        Pose2d diff = Pose2d::abs(Pose2d::relativePose(brother, pose));
+
+        if (diff.x() > 3.6 || diff.x() < 2.2 || diff.y() > 0.3 || diff.theta() > 5 * M_PI / 180.0) {
+            std::cout << " distance with two agv is too far diff: " << diff << std::endl;
+            return;
+        }
+        Pose2d abs_diff = pose - brother;
+        //计算两车朝向的方向
+        float theta = Pose2d::vector2yaw(abs_diff.x(), abs_diff.y());
+        Pose2d agv = Pose2d((pose.x() + brother.x()) / 2.0, (pose.y() + brother.y()) / 2.0, theta);
+
+        Navigation::ResetPose(agv);
+    } else
+        Navigation::ResetPose(pose);
 }
 
-void NavigationMain::publish_statu(NavMessage::NavStatu& statu)
-{
-  statu.set_main_agv(true);
-  Navigation::publish_statu(statu);
+void NavigationMain::publish_statu(NavMessage::NavStatu &statu) {
+    statu.set_main_agv(true);
+    Navigation::publish_statu(statu);
 }
 
 
-void NavigationMain::Start(const NavMessage::NavCmd& cmd,NavMessage::NavResponse& response)
-{
-  /*if(move_mode_!=Monitor_emqx::eMain)
-  {
-    printf(" navigation mode must set main,parameter:Pose2d\n");
-    return false;
-  }*/
+void NavigationMain::Start(const NavMessage::NavCmd &cmd, NavMessage::NavResponse &response) {
+    /*if(move_mode_!=Monitor_emqx::eMain)
+    {
+      printf(" navigation mode must set main,parameter:Pose2d\n");
+      return false;
+    }*/
 
-  Navigation::Start(cmd,response);
+    Navigation::Start(cmd, response);
 
 }
 
-void NavigationMain::SendMoveCmd(Monitor_emqx::ActionMode mode,Monitor_emqx::ActionType type,
-                double v,double angular)
-{
-  if(monitor_)
-  {
-    monitor_->set_speed(mode,type,v,angular,wheelBase_);
-  }
+void NavigationMain::SendMoveCmd(Monitor_emqx::ActionMode mode, Monitor_emqx::ActionType type,
+                                 double v, double angular) {
+    if (monitor_) {
+        monitor_->set_speed(mode, type, v, angular, wheelBase_);
+    }
 
 }
 
-bool NavigationMain::CreateRobotStatuMsg(NavMessage::RobotStatu& robotStatu)
-{
-  if(Navigation::CreateRobotStatuMsg(robotStatu)) {
-    robotStatu.mutable_agvstatu()->set_clamp_other(timed_other_clamp_.Get());
-    return true;
-  }
-  //std::cout<<agvStatu.DebugString()<<std::endl;
-  return false;
+bool NavigationMain::CreateRobotStatuMsg(NavMessage::RobotStatu &robotStatu) {
+    if (Navigation::CreateRobotStatuMsg(robotStatu)) {
+        robotStatu.mutable_agvstatu()->set_clamp_other(timed_other_clamp_.Get());
+        return true;
+    }
+    //std::cout<<agvStatu.DebugString()<<std::endl;
+    return false;
 }
 
-void NavigationMain::ResetOtherClamp(ClampStatu statu)
-{
-  timed_other_clamp_.reset(statu,1);
+void NavigationMain::ResetOtherClamp(ClampStatu statu) {
+    timed_other_clamp_.reset(statu, 1);
 }
 
-void NavigationMain::HandleAgvStatu(const MqttMsg& msg)
-{
-  NavMessage::AgvStatu speed;
-  if(msg.toProtoMessage(speed))
-  {
-    ResetStatu(speed.v(),speed.w());
-    ResetClamp((ClampStatu)speed.clamp());
-    ResetOtherClamp((ClampStatu)speed.clamp_other());
-    //printf(" clamp:%d   other:%d\n",speed.clamp(),speed.clamp_other());
-  }
+void NavigationMain::HandleAgvStatu(const MqttMsg &msg) {
+    NavMessage::AgvStatu speed;
+    if (msg.toProtoMessage(speed)) {
+        ResetStatu(speed.v(), speed.w());
+        ResetClamp((ClampStatu) speed.clamp());
+        ResetOtherClamp((ClampStatu) speed.clamp_other());
+        //printf(" clamp:%d   other:%d\n",speed.clamp(),speed.clamp_other());
+    }
 }
 
-bool NavigationMain::clamp_close()
-{
-  if(move_mode_==Monitor_emqx::eSingle)
-    return Navigation::clamp_close();
-  printf("双车夹持\n");
-  if(monitor_) {
-    monitor_->clamp_close(move_mode_);
-    while (exit_ == false) {
-      if (timed_clamp_.timeout() || timed_other_clamp_.timeout()) {
-        printf("timed clamp is timeout\n");
+bool NavigationMain::clamp_close() {
+    if (move_mode_ == Monitor_emqx::eSingle)
+        return Navigation::clamp_close();
+    printf("双车夹持\n");
+    if (monitor_) {
+        monitor_->clamp_close(move_mode_);
+        while (exit_ == false) {
+            if (timed_clamp_.timeout() || timed_other_clamp_.timeout()) {
+                printf("timed clamp is timeout\n");
+                return false;
+            }
+            if (timed_clamp_.Get() == eClosed && timed_other_clamp_.Get() == eClosed) {
+                printf("双车夹持completed!!!\n");
+                return true;
+            }
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            monitor_->clamp_close(move_mode_);
+        }
         return false;
-      }
-      if (timed_clamp_.Get() == eClosed && timed_other_clamp_.Get()==eClosed) {
-        printf("双车夹持completed!!!\n");
-        return true;
-      }
-      std::this_thread::sleep_for(std::chrono::milliseconds(100));
-      monitor_->clamp_close(move_mode_);
     }
     return false;
-  }
-  return false;
 }
-bool NavigationMain::clamp_open() {
-  if(move_mode_==Monitor_emqx::eSingle)
-    return Navigation::clamp_open();
 
-  if(monitor_) {
-    printf("双车松夹持\n");
-    monitor_->clamp_open(move_mode_);
-    while(exit_==false)
-    {
-      if(timed_clamp_.timeout()||timed_other_clamp_.timeout())
-      {
-        printf("timed clamp is timeout\n");
+bool NavigationMain::clamp_open() {
+    if (move_mode_ == Monitor_emqx::eSingle)
+        return Navigation::clamp_open();
+
+    if (monitor_) {
+        printf("双车松夹持\n");
+        monitor_->clamp_open(move_mode_);
+        while (exit_ == false) {
+            if (timed_clamp_.timeout() || timed_other_clamp_.timeout()) {
+                printf("timed clamp is timeout\n");
+                return false;
+            }
+            if (timed_clamp_.Get() == eOpened && timed_other_clamp_.Get() == eOpened) {
+                printf("双车松夹持completed!!!\n");
+                return true;
+            }
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            monitor_->clamp_open(move_mode_);
+        }
         return false;
-      }
-      if(timed_clamp_.Get()==eOpened&&timed_other_clamp_.Get()==eOpened) {
-        printf("双车松夹持completed!!!\n");
-        return true;
-      }
-      std::this_thread::sleep_for(std::chrono::milliseconds(100));
-      monitor_->clamp_open(move_mode_);
     }
     return false;
-  }
-  return false;
 }
 
-bool NavigationMain::RotateBeforeEnterSpace(NavMessage::PathNode space,double wheelbase,NavMessage::PathNode& target) {
-  if (timedBrotherNavStatu_.timeout() || timedPose_.timeout()) {
-    printf(" rotate failed : timedBrotherNavStatu_ or pose timeout\n");
-    return false;
-  }
-
-  NavMessage::NavStatu brother = timedBrotherNavStatu_.Get();
-
-  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());
-  target.set_l(0.05);
-  target.set_w(0.03);
-  target.set_id(space.id());
-  //后车先到,当前车进入2点,保持与后车一致的朝向
-  if (brother.in_space() && brother.space_id() == space.id()) {
-    rotated.mutable_theta() = brother.odom().theta();
-  } else { //当前车先到,正向
-    rotated.mutable_theta() = space.theta();
-  }
-  std::cout<<"===============================> RotateBeforeEnterSpace ,target:"<<rotated<<std::endl;
-  double x = space.x() + wheelbase/2.0 * cos(rotated.theta());
-  double y = space.y() + wheelbase/2.0 * sin(rotated.theta());
-  target.set_x(x);
-  target.set_y(y);
-  target.set_theta(rotated.theta());
-
-  while (cancel_ == false) {
-    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::eRotate, 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;
-      }
+Navigation::MpcResult
+NavigationMain::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target) {
+    if (timedBrotherNavStatu_.timeout() || timedPose_.timeout()) {
+        printf(" rotate failed : timedBrotherNavStatu_ or pose timeout\n");
+        return eMpcFailed;
     }
-  }
-  return false;
 
+    NavMessage::NavStatu brother = timedBrotherNavStatu_.Get();
+
+    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());
+    target.set_l(0.05);
+    target.set_w(0.03);
+    target.set_id(space.id());
+    //后车先到,当前车进入2点,保持与后车一致的朝向
+    if (brother.in_space() && brother.space_id() == space.id()) {
+        rotated.mutable_theta() = brother.odom().theta();
+    } else { //当前车先到,正向
+        rotated.mutable_theta() = space.theta();
+    }
+    std::cout << "===============================> RotateBeforeEnterSpace ,target:" << rotated << std::endl;
+    double x = space.x() + wheelbase / 2.0 * cos(rotated.theta());
+    double y = space.y() + wheelbase / 2.0 * sin(rotated.theta());
+    target.set_x(x);
+    target.set_y(y);
+    target.set_theta(rotated.theta());
+
+    while (cancel_ == false) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        Pose2d current = timedPose_.Get();
+        double yawDiff = (rotated - 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) > 1 * M_PI / 180.0) {
+            SendMoveCmd(move_mode_, Monitor_emqx::eRotate, 0, out[0]);
+            actionType_ = eRotation;
+            printf(" RotateBeforeEnterSpace | input anguar:%f, down:%f diff:%f anyDirect:false\n",
+                   timedA_.Get(), out[0], yawDiff);
+        } else if (fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
+            printf(" RotateBeforeEnterSpace refer target completed\\n,cuv:%f\n", yawDiff);
+            return eMpcSuccess;
+        }
+        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::eRotate, 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;
 }

+ 1 - 1
MPC/navigation_main.h

@@ -49,7 +49,7 @@ public:
 
 
 protected:
-    virtual bool RotateBeforeEnterSpace(NavMessage::PathNode space,double wheelbase,NavMessage::PathNode& target);
+    virtual Navigation::MpcResult RotateBeforeEnterSpace(NavMessage::PathNode space,double wheelbase,NavMessage::PathNode& target);
     virtual void SendMoveCmd(Monitor_emqx::ActionMode mode,Monitor_emqx::ActionType type,
                              double v,double angular);
     virtual bool clamp_close();