12 Commits e4229c5522 ... 05b064a60b

Author SHA1 Message Date
  gf 05b064a60b 1.MPC旋转添加延时预判 1 year ago
  gf 91ec7090c0 1.修改入库点基准,由载车板中心位置基准改为载车板靠墙侧车轮挡板位置为基准 1 year ago
  gf 86ef728e25 1.进库下发指令时,添加车位号与距目标距离信息 1 year ago
  gf e912f14130 1.添加预判延迟后下发速度与角速度。 1 year ago
  gf 1e479cb802 1.降低到库精度要求 1 year ago
  gf 6c7f15c46b 1.开启子车位置获取 1 year ago
  gf a389a89837 1进库时添加提升机构抬升动作 1 year ago
  gf 550825e749 1.修复整车提升机构状态发布时。另一节状态不对问题 1 year ago
  gf 2470ff6202 1.添加提升机构控制模块 1 year ago
  gf 473e08c87f 1.优化MPC旋转调整输入 1 year ago
  gf a67162a112 1.修复MPC旋转计算时未加入当前角速度与下一时刻角速度约束问题 1 year ago
  gf e53307d077 1.修复MPC旋转计算时未加入当前角速度与下一时刻角速度约束问题 1 year ago

+ 13 - 1
MPC/custom_type.h

@@ -98,7 +98,19 @@ enum ActionType {
     eHorizontal = 2,
     eVertical = 3,
     eClampClose = 5,
-    eClampOpen = 6
+    eClampOpen = 6,
+    eLifterRise = 7,    //提升机构上升
+    eLifterDown =8
+};
+///////////////////////////////////////////////
+
+///////////////////////////////////////////////
+/// 提升机构运动状态
+enum LifterStatus {
+    eInvalid = 0,
+    eRose = 1,//上升到位
+    eDowned = 2//下降到位
 };
 //////////////////////////////////////////////////
+
 #endif //NAVIGATION_CUSTOM_TYPE_H

+ 16 - 3
MPC/loaded_mpc.cpp

@@ -8,6 +8,7 @@
 #include <cppad/ipopt/solve.hpp>
 
 size_t N = 15;                  //优化考虑后面多少步
+size_t delay = 2;  // 发送到执行的延迟,即几个周期的时间
 
 size_t nx = 0;
 size_t ny = nx + N;
@@ -197,6 +198,7 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
     //根据当前点和目标点距离,计算目标速度
 
     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
@@ -244,6 +246,7 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
      * 障碍物是否进入 碰撞检测范围内
      */
     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;
@@ -258,11 +261,21 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
     for (int i = nv; i < nv + N; i++) {
         constraints_lowerbound[i] = -max_acc_line_velocity;
         constraints_upperbound[i] = max_acc_line_velocity;
+        //延迟处理,前delay个周期内认定为匀速运动(加速度为0)
+        if (i < nv+delay) {
+            constraints_lowerbound[i] = 0;
+            constraints_upperbound[i] = 0;
+        }
     }
     //// acc ndlt
     for (int i = ndlt; i < ndlt + N; i++) {
         constraints_lowerbound[i] = -max_acc_dlt;
         constraints_upperbound[i] = max_acc_dlt;
+        //延迟处理,前delay个周期内认定为匀速运动(加速度为0)
+        if (i < nv+delay){
+            constraints_lowerbound[i] = 0;
+            constraints_upperbound[i] = 0;
+        }
     }
 
     // 与障碍物保持距离的约束
@@ -340,8 +353,8 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
 
     out.clear();
 
-    double solve_velocity = solution.x[nv];
-    double solve_angular = solution.x[ndlt];
+    double solve_velocity = solution.x[nv+delay];
+    double solve_angular = solution.x[ndlt+delay];
 
     //纠正角速度/线速度,使其满足最小转弯半径
     double correct_angular = solve_angular;
@@ -350,7 +363,7 @@ MpcError LoadedMPC::solve(Trajectory trajectory, Pose2d target, Eigen::VectorXd
         if (solve_angular < 0) correct_angular = -correct_angular;
     }
     ///-----
-    printf("input:%.4f %.5f(%.5f) output:%.4f %.5f(%.5f) ref:%.3f max_v:%f time:%.3f\n",
+    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);
 

+ 184 - 52
MPC/monitor/emqx/message.pb.cc

@@ -54,6 +54,10 @@ PROTOBUF_CONSTEXPR AgvStatu::AgvStatu(
 
   , /*decltype(_impl_.clamp_other_)*/ 0
 
+  , /*decltype(_impl_.lifter_)*/ 0
+
+  , /*decltype(_impl_.lifter_other_)*/ 0
+
   , /*decltype(_impl_._cached_size_)*/{}} {}
 struct AgvStatuDefaultTypeInternal {
   PROTOBUF_CONSTEXPR AgvStatuDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
@@ -80,6 +84,10 @@ PROTOBUF_CONSTEXPR ToAgvCmd::ToAgvCmd(
 
   , /*decltype(_impl_.l_)*/ 0
 
+  , /*decltype(_impl_.p_)*/ 0
+
+  , /*decltype(_impl_.d_)*/ 0
+
   , /*decltype(_impl_.end_)*/ 0
 
   , /*decltype(_impl_._cached_size_)*/{}} {}
@@ -333,6 +341,8 @@ const ::uint32_t TableStruct_message_2eproto::offsets[] PROTOBUF_SECTION_VARIABL
     PROTOBUF_FIELD_OFFSET(::NavMessage::AgvStatu, _impl_.w_),
     PROTOBUF_FIELD_OFFSET(::NavMessage::AgvStatu, _impl_.clamp_),
     PROTOBUF_FIELD_OFFSET(::NavMessage::AgvStatu, _impl_.clamp_other_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::AgvStatu, _impl_.lifter_),
+    PROTOBUF_FIELD_OFFSET(::NavMessage::AgvStatu, _impl_.lifter_other_),
     ~0u,  // no _has_bits_
     PROTOBUF_FIELD_OFFSET(::NavMessage::ToAgvCmd, _internal_metadata_),
     ~0u,  // no _extensions_
@@ -347,6 +357,8 @@ const ::uint32_t TableStruct_message_2eproto::offsets[] PROTOBUF_SECTION_VARIABL
     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_.end_),
     ~0u,  // no _has_bits_
     PROTOBUF_FIELD_OFFSET(::NavMessage::Pose2d, _internal_metadata_),
@@ -484,16 +496,16 @@ static const ::_pbi::MigrationSchema
     schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
         { 0, -1, -1, sizeof(::NavMessage::LidarOdomStatu)},
         { 13, -1, -1, sizeof(::NavMessage::AgvStatu)},
-        { 25, -1, -1, sizeof(::NavMessage::ToAgvCmd)},
-        { 40, -1, -1, sizeof(::NavMessage::Pose2d)},
-        { 51, -1, -1, sizeof(::NavMessage::PathNode)},
-        { 65, -1, -1, sizeof(::NavMessage::Trajectory)},
-        { 74, 89, -1, sizeof(::NavMessage::NewAction)},
-        { 96, -1, -1, sizeof(::NavMessage::NavCmd)},
-        { 107, -1, -1, sizeof(::NavMessage::NavResponse)},
-        { 117, -1, -1, sizeof(::NavMessage::ManualCmd)},
-        { 128, 145, -1, sizeof(::NavMessage::NavStatu)},
-        { 154, 166, -1, sizeof(::NavMessage::RobotStatu)},
+        { 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)},
 };
 
 static const ::_pb::Message* const file_default_instances[] = {
@@ -513,46 +525,47 @@ static const ::_pb::Message* const file_default_instances[] = {
 const char descriptor_table_protodef_message_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
     "\n\rmessage.proto\022\nNavMessage\"M\n\016LidarOdom"
     "Statu\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\t\n\001v\030\004 \001(\002\022\013\n\003vth\030\005 \001(\002\"D\n\010AgvStatu\022\t"
+    "(\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\"Y\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\013\n\003end\030\007 \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\010Pa"
-    "thNode\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\tsp"
-    "aceNode\030\002 \001(\0132\024.NavMessage.PathNode\022&\n\010p"
-    "assNode\030\003 \001(\0132\024.NavMessage.PathNode\022(\n\ns"
-    "treetNode\030\004 \001(\0132\024.NavMessage.PathNode\022\'\n"
-    "\tpathNodes\030\005 \003(\0132\024.NavMessage.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\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\016operatio"
-    "n_type\030\002 \001(\005\022\020\n\010velocity\030\003 \001(\002\"\366\001\n\010NavSt"
-    "atu\022\r\n\005statu\030\001 \001(\005\022\020\n\010main_agv\030\002 \001(\010\022\021\n\t"
-    "move_mode\030\003 \001(\005\022(\n\004odom\030\004 \001(\0132\032.NavMessa"
-    "ge.LidarOdomStatu\022\013\n\003key\030\005 \001(\t\022-\n\rselect"
-    "ed_traj\030\006 \001(\0132\026.NavMessage.Trajectory\022,\n"
-    "\014predict_traj\030\007 \001(\0132\026.NavMessage.Traject"
-    "ory\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\005t"
-    "heta\030\003 \001(\002\022&\n\010agvStatu\030\004 \001(\0132\024.NavMessag"
-    "e.AgvStatu2\302\001\n\nNavExcutor\0226\n\005Start\022\022.Nav"
-    "Message.NavCmd\032\027.NavMessage.NavResponse\""
-    "\000\0227\n\006Cancel\022\022.NavMessage.NavCmd\032\027.NavMes"
-    "sage.NavResponse\"\000\022C\n\017ManualOperation\022\025."
-    "NavMessage.ManualCmd\032\027.NavMessage.NavRes"
-    "ponse\"\000b\006proto3"
+    "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"
 };
 static ::absl::once_flag descriptor_table_message_2eproto_once;
 const ::_pbi::DescriptorTable descriptor_table_message_2eproto = {
     false,
     false,
-    1415,
+    1475,
     descriptor_table_protodef_message_2eproto,
     "message.proto",
     &descriptor_table_message_2eproto_once,
@@ -957,6 +970,10 @@ inline void AgvStatu::SharedCtor(::_pb::Arena* arena) {
 
     , decltype(_impl_.clamp_other_) { 0 }
 
+    , decltype(_impl_.lifter_) { 0 }
+
+    , decltype(_impl_.lifter_other_) { 0 }
+
     , /*decltype(_impl_._cached_size_)*/{}
   };
 }
@@ -985,8 +1002,8 @@ void AgvStatu::Clear() {
   (void) cached_has_bits;
 
   ::memset(&_impl_.v_, 0, static_cast<::size_t>(
-      reinterpret_cast<char*>(&_impl_.clamp_other_) -
-      reinterpret_cast<char*>(&_impl_.v_)) + sizeof(_impl_.clamp_other_));
+      reinterpret_cast<char*>(&_impl_.lifter_other_) -
+      reinterpret_cast<char*>(&_impl_.v_)) + sizeof(_impl_.lifter_other_));
   _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
 }
 
@@ -1032,6 +1049,24 @@ const char* AgvStatu::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx)
           goto handle_unusual;
         }
         continue;
+      // int32 lifter = 5;
+      case 5:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 40)) {
+          _impl_.lifter_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+          CHK_(ptr);
+        } else {
+          goto handle_unusual;
+        }
+        continue;
+      // int32 lifter_other = 6;
+      case 6:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 48)) {
+          _impl_.lifter_other_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+          CHK_(ptr);
+        } else {
+          goto handle_unusual;
+        }
+        continue;
       default:
         goto handle_unusual;
     }  // switch
@@ -1097,6 +1132,20 @@ failure:
         4, this->_internal_clamp_other(), target);
   }
 
+  // int32 lifter = 5;
+  if (this->_internal_lifter() != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::_pbi::WireFormatLite::WriteInt32ToArray(
+        5, this->_internal_lifter(), target);
+  }
+
+  // int32 lifter_other = 6;
+  if (this->_internal_lifter_other() != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::_pbi::WireFormatLite::WriteInt32ToArray(
+        6, this->_internal_lifter_other(), target);
+  }
+
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
     target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
         _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
@@ -1143,6 +1192,18 @@ failure:
         this->_internal_clamp_other());
   }
 
+  // int32 lifter = 5;
+  if (this->_internal_lifter() != 0) {
+    total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
+        this->_internal_lifter());
+  }
+
+  // int32 lifter_other = 6;
+  if (this->_internal_lifter_other() != 0) {
+    total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
+        this->_internal_lifter_other());
+  }
+
   return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
 }
 
@@ -1181,6 +1242,12 @@ void AgvStatu::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTO
   if (from._internal_clamp_other() != 0) {
     _this->_internal_set_clamp_other(from._internal_clamp_other());
   }
+  if (from._internal_lifter() != 0) {
+    _this->_internal_set_lifter(from._internal_lifter());
+  }
+  if (from._internal_lifter_other() != 0) {
+    _this->_internal_set_lifter_other(from._internal_lifter_other());
+  }
   _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
 }
 
@@ -1199,8 +1266,8 @@ void AgvStatu::InternalSwap(AgvStatu* other) {
   using std::swap;
   _internal_metadata_.InternalSwap(&other->_internal_metadata_);
   ::PROTOBUF_NAMESPACE_ID::internal::memswap<
-      PROTOBUF_FIELD_OFFSET(AgvStatu, _impl_.clamp_other_)
-      + sizeof(AgvStatu::_impl_.clamp_other_)
+      PROTOBUF_FIELD_OFFSET(AgvStatu, _impl_.lifter_other_)
+      + sizeof(AgvStatu::_impl_.lifter_other_)
       - PROTOBUF_FIELD_OFFSET(AgvStatu, _impl_.v_)>(
           reinterpret_cast<char*>(&_impl_.v_),
           reinterpret_cast<char*>(&other->_impl_.v_));
@@ -1244,6 +1311,10 @@ inline void ToAgvCmd::SharedCtor(::_pb::Arena* arena) {
 
     , decltype(_impl_.l_) { 0 }
 
+    , decltype(_impl_.p_) { 0 }
+
+    , decltype(_impl_.d_) { 0 }
+
     , decltype(_impl_.end_) { 0 }
 
     , /*decltype(_impl_._cached_size_)*/{}
@@ -1339,9 +1410,27 @@ const char* ToAgvCmd::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx)
           goto handle_unusual;
         }
         continue;
-      // int32 end = 7;
+      // int32 P = 7;
       case 7:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 56)) {
+          _impl_.p_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+          CHK_(ptr);
+        } else {
+          goto handle_unusual;
+        }
+        continue;
+      // float D = 8;
+      case 8:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 69)) {
+          _impl_.d_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          ptr += sizeof(float);
+        } else {
+          goto handle_unusual;
+        }
+        continue;
+      // int32 end = 9;
+      case 9:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::uint8_t>(tag) == 72)) {
           _impl_.end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
           CHK_(ptr);
         } else {
@@ -1431,11 +1520,29 @@ failure:
         6, this->_internal_l(), target);
   }
 
-  // int32 end = 7;
+  // int32 P = 7;
+  if (this->_internal_p() != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::_pbi::WireFormatLite::WriteInt32ToArray(
+        7, this->_internal_p(), target);
+  }
+
+  // float D = 8;
+  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) {
+    target = stream->EnsureSpace(target);
+    target = ::_pbi::WireFormatLite::WriteFloatToArray(
+        8, this->_internal_d(), target);
+  }
+
+  // int32 end = 9;
   if (this->_internal_end() != 0) {
     target = stream->EnsureSpace(target);
     target = ::_pbi::WireFormatLite::WriteInt32ToArray(
-        7, this->_internal_end(), target);
+        9, this->_internal_end(), target);
   }
 
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
@@ -1499,7 +1606,22 @@ failure:
     total_size += 5;
   }
 
-  // int32 end = 7;
+  // int32 P = 7;
+  if (this->_internal_p() != 0) {
+    total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
+        this->_internal_p());
+  }
+
+  // float D = 8;
+  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) {
+    total_size += 5;
+  }
+
+  // int32 end = 9;
   if (this->_internal_end() != 0) {
     total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
         this->_internal_end());
@@ -1553,6 +1675,16 @@ void ToAgvCmd::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTO
   if (raw_l != 0) {
     _this->_internal_set_l(from._internal_l());
   }
+  if (from._internal_p() != 0) {
+    _this->_internal_set_p(from._internal_p());
+  }
+  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());
+  }
   if (from._internal_end() != 0) {
     _this->_internal_set_end(from._internal_end());
   }

+ 131 - 3
MPC/monitor/emqx/message.pb.h

@@ -457,6 +457,8 @@ class AgvStatu final :
     kWFieldNumber = 2,
     kClampFieldNumber = 3,
     kClampOtherFieldNumber = 4,
+    kLifterFieldNumber = 5,
+    kLifterOtherFieldNumber = 6,
   };
   // float v = 1;
   void clear_v() ;
@@ -497,6 +499,26 @@ class AgvStatu final :
   ::int32_t _internal_clamp_other() const;
   void _internal_set_clamp_other(::int32_t value);
 
+  public:
+  // int32 lifter = 5;
+  void clear_lifter() ;
+  ::int32_t lifter() const;
+  void set_lifter(::int32_t value);
+
+  private:
+  ::int32_t _internal_lifter() const;
+  void _internal_set_lifter(::int32_t value);
+
+  public:
+  // int32 lifter_other = 6;
+  void clear_lifter_other() ;
+  ::int32_t lifter_other() const;
+  void set_lifter_other(::int32_t value);
+
+  private:
+  ::int32_t _internal_lifter_other() const;
+  void _internal_set_lifter_other(::int32_t value);
+
   public:
   // @@protoc_insertion_point(class_scope:NavMessage.AgvStatu)
  private:
@@ -510,6 +532,8 @@ class AgvStatu final :
     float w_;
     ::int32_t clamp_;
     ::int32_t clamp_other_;
+    ::int32_t lifter_;
+    ::int32_t lifter_other_;
     mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
   };
   union { Impl_ _impl_; };
@@ -650,7 +674,9 @@ class ToAgvCmd final :
     kVFieldNumber = 4,
     kWFieldNumber = 5,
     kLFieldNumber = 6,
-    kEndFieldNumber = 7,
+    kPFieldNumber = 7,
+    kDFieldNumber = 8,
+    kEndFieldNumber = 9,
   };
   // int32 H = 1;
   void clear_h() ;
@@ -712,7 +738,27 @@ class ToAgvCmd final :
   void _internal_set_l(float value);
 
   public:
-  // int32 end = 7;
+  // int32 P = 7;
+  void clear_p() ;
+  ::int32_t p() const;
+  void set_p(::int32_t value);
+
+  private:
+  ::int32_t _internal_p() const;
+  void _internal_set_p(::int32_t value);
+
+  public:
+  // float D = 8;
+  void clear_d() ;
+  float d() const;
+  void set_d(float value);
+
+  private:
+  float _internal_d() const;
+  void _internal_set_d(float value);
+
+  public:
+  // int32 end = 9;
   void clear_end() ;
   ::int32_t end() const;
   void set_end(::int32_t value);
@@ -736,6 +782,8 @@ class ToAgvCmd final :
     float v_;
     float w_;
     float l_;
+    ::int32_t p_;
+    float d_;
     ::int32_t end_;
     mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
   };
@@ -2807,6 +2855,46 @@ inline void AgvStatu::_internal_set_clamp_other(::int32_t value) {
   _impl_.clamp_other_ = value;
 }
 
+// int32 lifter = 5;
+inline void AgvStatu::clear_lifter() {
+  _impl_.lifter_ = 0;
+}
+inline ::int32_t AgvStatu::lifter() const {
+  // @@protoc_insertion_point(field_get:NavMessage.AgvStatu.lifter)
+  return _internal_lifter();
+}
+inline void AgvStatu::set_lifter(::int32_t value) {
+  _internal_set_lifter(value);
+  // @@protoc_insertion_point(field_set:NavMessage.AgvStatu.lifter)
+}
+inline ::int32_t AgvStatu::_internal_lifter() const {
+  return _impl_.lifter_;
+}
+inline void AgvStatu::_internal_set_lifter(::int32_t value) {
+  ;
+  _impl_.lifter_ = value;
+}
+
+// int32 lifter_other = 6;
+inline void AgvStatu::clear_lifter_other() {
+  _impl_.lifter_other_ = 0;
+}
+inline ::int32_t AgvStatu::lifter_other() const {
+  // @@protoc_insertion_point(field_get:NavMessage.AgvStatu.lifter_other)
+  return _internal_lifter_other();
+}
+inline void AgvStatu::set_lifter_other(::int32_t value) {
+  _internal_set_lifter_other(value);
+  // @@protoc_insertion_point(field_set:NavMessage.AgvStatu.lifter_other)
+}
+inline ::int32_t AgvStatu::_internal_lifter_other() const {
+  return _impl_.lifter_other_;
+}
+inline void AgvStatu::_internal_set_lifter_other(::int32_t value) {
+  ;
+  _impl_.lifter_other_ = value;
+}
+
 // -------------------------------------------------------------------
 
 // ToAgvCmd
@@ -2931,7 +3019,47 @@ inline void ToAgvCmd::_internal_set_l(float value) {
   _impl_.l_ = value;
 }
 
-// int32 end = 7;
+// int32 P = 7;
+inline void ToAgvCmd::clear_p() {
+  _impl_.p_ = 0;
+}
+inline ::int32_t ToAgvCmd::p() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.P)
+  return _internal_p();
+}
+inline void ToAgvCmd::set_p(::int32_t value) {
+  _internal_set_p(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.P)
+}
+inline ::int32_t ToAgvCmd::_internal_p() const {
+  return _impl_.p_;
+}
+inline void ToAgvCmd::_internal_set_p(::int32_t value) {
+  ;
+  _impl_.p_ = value;
+}
+
+// float D = 8;
+inline void ToAgvCmd::clear_d() {
+  _impl_.d_ = 0;
+}
+inline float ToAgvCmd::d() const {
+  // @@protoc_insertion_point(field_get:NavMessage.ToAgvCmd.D)
+  return _internal_d();
+}
+inline void ToAgvCmd::set_d(float value) {
+  _internal_set_d(value);
+  // @@protoc_insertion_point(field_set:NavMessage.ToAgvCmd.D)
+}
+inline float ToAgvCmd::_internal_d() const {
+  return _impl_.d_;
+}
+inline void ToAgvCmd::_internal_set_d(float value) {
+  ;
+  _impl_.d_ = value;
+}
+
+// int32 end = 9;
 inline void ToAgvCmd::clear_end() {
   _impl_.end_ = 0;
 }

+ 53 - 0
MPC/monitor/monitor_emqx.cpp

@@ -52,6 +52,34 @@ void Monitor_emqx::clamp_open(int mode)
   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_m(mode);
+    speed.set_end(1);
+    msg.fromProtoMessage(speed);
+    Publish(speedcmd_topic_,msg);
+}
+
+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_m(mode);
+    speed.set_end(1);
+    msg.fromProtoMessage(speed);
+    Publish(speedcmd_topic_,msg);
+}
+
 void Monitor_emqx::set_speed(int mode,ActionType type,double v,double a,double L)
 {
   if(mode == eDouble && type == eVertical && fabs(L) < 1e-3)
@@ -107,5 +135,30 @@ void Monitor_emqx::stop()
   Publish(speedcmd_topic_,msg);
 }
 
+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;
+    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_end(1);
+    msg.fromProtoMessage(agvCmd);
+    Publish(speedcmd_topic_,msg);
+}
+
 
 

+ 3 - 0
MPC/monitor/monitor_emqx.h

@@ -17,8 +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 clamp_close(int mode);
     void clamp_open(int mode);
+    void lifter_rise(int mode);
+    void lifter_down(int mode);
     void stop();
 
  protected:

+ 0 - 1
MPC/monitor/terminator_emqx.cpp

@@ -54,7 +54,6 @@ bool Terminator_emqx::AddCallback(std::string topic,Callback callback,void* cont
   }
 }
 
-
 Terminator_emqx::Terminator_emqx(std::string nodeId)
     :client_(nullptr),nodeId_(nodeId),connected_(false)
 {

+ 271 - 91
MPC/navigation.cpp

@@ -56,15 +56,16 @@ double next_speed(double speed, double target_speed, double acc, double dt) {
 }
 
 bool Navigation::PoseTimeout() {
-    if (timedPose_.timeout() == false && timedBrotherPose_.timeout() == false) {
+//    if (timedPose_.timeout() == false && timedBrotherPose_.timeout() == false) {
+    if (timedPose_.timeout() == false) {
         return false;
     } else {
         if (timedPose_.timeout()) {
             printf(" current pose is timeout \n");
         }
-        if (timedBrotherPose_.timeout()) {
-            printf(" brother pose is timeout \n");
-        }
+//        if (timedBrotherPose_.timeout()) {
+//            printf(" brother pose is timeout \n");
+//        }
         return true;
     }
 }
@@ -99,13 +100,13 @@ bool Navigation::Init(const NavParameter::Navigation_parameter &parameter) {
         if (brotherEmqx_ == nullptr) {
             brotherEmqx_ = new Terminator_emqx(brotherEmqx.nodeid());
 
-//            if (brotherEmqx_->Connect(brotherEmqx.ip(), brotherEmqx.port()) == true) {
-//                brotherEmqx_->AddCallback(brotherEmqx.subbrotherstatutopic(), Navigation::BrotherAgvStatuCallback,
-//                                          this);
-//            } else {
-//                printf(" brother emqx connected failed\n");
-//                // return false;
-//            }
+            if (brotherEmqx_->Connect(brotherEmqx.ip(), brotherEmqx.port()) == true) {
+                brotherEmqx_->AddCallback(brotherEmqx.subbrotherstatutopic(), Navigation::BrotherAgvStatuCallback,
+                                          this);
+            } else {
+                printf(" brother emqx connected failed\n");
+                // return false;
+            }
 //
         }
     }
@@ -137,6 +138,7 @@ void Navigation::HandleAgvStatu(const MqttMsg &msg) {
     if (msg.toProtoMessage(speed)) {
         ResetStatu(speed.v(), speed.w());
         ResetClamp((ClampStatu) speed.clamp());
+        ResetLifter((LifterStatus) speed.lifter());
     }
 }
 
@@ -231,6 +233,7 @@ bool Navigation::CreateRobotStatuMsg(NavMessage::RobotStatu &robotStatu) {
             plc.set_v(timedV_.Get());
             plc.set_w(timedA_.Get());
             plc.set_clamp(timed_clamp_.Get());
+            plc.set_lifter(timed_lifter_.Get());
             //printf(" timed_clamp_:%d\n ",timed_clamp_.Get());
             robotStatu.mutable_agvstatu()->CopyFrom(plc);
         }
@@ -248,6 +251,10 @@ void Navigation::ResetClamp(ClampStatu statu) {
     timed_clamp_.reset(statu, 1);
 }
 
+void Navigation::ResetLifter(LifterStatus status) {
+    timed_lifter_.reset(status, 1);
+}
+
 void Navigation::ResetPose(const Pose2d &pose) {
     timedPose_.reset(pose, 1.0);
 }
@@ -338,7 +345,7 @@ void Navigation::BrotherAgvStatuCallback(const MqttMsg &msg, void *context) {
     }
 }
 
-
+//未使用
 bool Navigation::RotateReferToTarget(const Pose2d &target, stLimit limit_rotate, bool anyDirect) {
 
     while (cancel_ == false) {
@@ -475,16 +482,29 @@ Navigation::MpcResult Navigation::RotateReferToTarget(NavMessage::PathNode node,
         }
 
         //下发速度
-        if (fabs(target_yaw_diff) > 2 * M_PI / 180.0) {
+        if (fabs(target_yaw_diff) < 0.5 * 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]);
             actionType_ = eRotation;
-            printf(" MPC_rotate | input angular_v:%f, down:%f, diff:%f autoDirect:%d\n",
-                   timedA_.Get(), out[0], target_yaw_diff, directions);
-        } else if (fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
-            printf(" MPC_rotate refer target completed,cuv:%f\n", target_yaw_diff);
-            return eMpcSuccess;
+            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);
         }
         continue;
+
+//        //下发速度
+//        if (fabs(target_yaw_diff) > 2 * M_PI / 180.0) {
+//            SendMoveCmd(move_mode_, eRotation, 0, out[0]);
+//            actionType_ = eRotation;
+//            printf(" MPC_rotate | input angular_v:%f, down:%f, diff:%f autoDirect:%d\n",
+//                   timedA_.Get(), out[0], target_yaw_diff, directions);
+//        } else if (fabs(timedA_.Get()) < 5 * M_PI / 180.0) {
+//            printf(" MPC_rotate refer target completed,cuv:%f\n", target_yaw_diff);
+//            return eMpcSuccess;
+//        }
+//        continue;
     }
     return eMpcFailed;
 }
@@ -539,7 +559,7 @@ bool Navigation::MoveToTarget(NavMessage::PathNode node, Navigation::stLimit lim
                    node.x(), node.y(), node.l(), node.w(), node.theta());
             break;
         } else if (ret == eImpossibleToTarget) {
-            printf(" MPC to target:%f %f l:%f,w:%f theta:%f  impossible ,retry ..............................\n",
+            printf(" MPC to target:%f %f l:%f,w:%f theta:%f  impossible ,retry ...\n",
                    node.x(), node.y(), node.l(), node.w(), node.theta());
         } else {
             return false;
@@ -570,13 +590,13 @@ 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.3);
-                node.set_w(0.1);
+                node.set_l(0.10);
+                node.set_w(0.10);
 
             } else {
                 node.set_theta(0);
-                node.set_w(0.2);
-                node.set_l(0.2);
+                node.set_w(0.10);
+                node.set_l(0.10);
             }
             if (MoveToTarget(node, mpc_velocity, adjust_angular, anyDirect, true) == false)
                 return false;
@@ -591,7 +611,8 @@ bool Navigation::execute_nodes(NavMessage::NewAction action) {
 
 Navigation::MpcResult
 Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase, NavMessage::PathNode &target) {
-    if (timedBrotherNavStatu_.timeout() || timedPose_.timeout()) {
+//    if (timedBrotherNavStatu_.timeout() || timedPose_.timeout()) {
+    if (timedPose_.timeout()) {
         printf(" rotate failed : timedBrotherNavStatu_ or pose timeout\n");
         return eMpcFailed;
     }
@@ -602,39 +623,41 @@ Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase,
     double dt = 0.1;
     Pose2d rotated = timedPose_.Get();
 
-    //前车先到,当前车进入2点,保持与前车一致的朝向
+    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();
-    } else { //当前车先到(后车),倒车入库
+        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);
     }
-
-    double x = space.x();
-    double y = space.y();
-    if (move_mode_ == eSingle) {
-        x -= wheelbase / 2 * cos(rotated.theta());
-        y -= wheelbase / 2 * sin(rotated.theta());
-        printf("确定车位点:eSingle\n");
-    }
     target.set_x(x);
     target.set_y(y);
     target.set_theta(rotated.theta());
     target.set_l(0.05);
-    target.set_w(0.03);
+    target.set_w(0.05);
     target.set_id(space.id());
-
-    //整车协调的时候,保持前后与车位一致即可
-    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);
-        }
-    }
+    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));
+        std::this_thread::sleep_for(std::chrono::milliseconds(30));
         Pose2d current = timedPose_.Get();
         double yawDiff = (rotated - current).theta();
 
@@ -650,36 +673,18 @@ Navigation::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelbase,
         }
 
         //下发速度
-        if (fabs(yawDiff) > 1 * M_PI / 180.0) {
-            SendMoveCmd(move_mode_, eRotation, 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) {
+        if (fabs(yawDiff) < 0.5 * 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]);
+            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;
 
-
-//        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;
 
@@ -706,8 +711,8 @@ bool Navigation::execute_InOut_space(NavMessage::NewAction action) {
     if (action.type() == 1) {
         Pose2d vec(action.spacenode().x() - action.streetnode().x(), action.spacenode().y() - action.streetnode().y(),
                    0);
-        action.mutable_streetnode()->set_l(0.2);
-        action.mutable_streetnode()->set_w(0.05);
+        action.mutable_streetnode()->set_l(0.06);
+        action.mutable_streetnode()->set_w(0.06);
         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());
@@ -722,24 +727,90 @@ bool Navigation::execute_InOut_space(NavMessage::NewAction action) {
         if (RotateBeforeEnterSpace(action.spacenode(), action.wheelbase(), new_target) == eMpcFailed) {
             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;
+            }
+        }
+
+        //入库
+        printf("Enter space beg...\n");
         if (MoveToTarget(new_target, limit_v, limit_w, true, false) == false) {
-            printf(" Enter space failed type:%d: MoveTo StreetNode failed\n", action.type());
+            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.y() < 0.05) {
+        if (diff.x() < 0.05 || diff.y() < 0.05) {
             //出库,移动到马路点,允许自由方向,不允许中途旋转
             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);
+            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());
                 return false;
             }
+
+            //出库后提升机构下降
+            if (lifter_down() == false){
+                printf(" Out space | lifter down failed. line:%d\n",__LINE__);
+            }
+
         } else {
             std::cout << " Out space failed: current pose too far from space node:" << space << ",diff:" << diff
                       << std::endl;
@@ -783,7 +854,7 @@ bool Navigation::Rotation_mpc_once(Pose2d current_to_target, Navigation::stLimit
     Pose2d brother_in_self = Pose2d::relativePose(brother, pose);
 //    std::cout<<" brother_in_self: "<<brother_in_self<<std::endl;
     if (move_mode_ == eDouble) {
-        brother_in_self = Pose2d(pose.x()+100,pose.y()+100,0);
+        brother_in_self = Pose2d(pose.x() + 100, pose.y() + 100, 0);
     }
     RotateMPC MPC(brother_in_self, obs_w, obs_h, limit_wmg.min, limit_wmg.max);
     RotateMPC::MPC_parameter parameter = {mpc_parameter.shortest_radius(), mpc_parameter.dt(),
@@ -793,10 +864,16 @@ 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);
-    } else
-    {
-        double min_angular_velocity = 3.0/180*M_PI;
-        if (out[0] < min_angular_velocity) out[0] = min_angular_velocity;
+    } 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 {}
+        }
     }
     return ret == success || ret == no_solution;
 }
@@ -886,6 +963,9 @@ bool Navigation::IsArrived(NavMessage::PathNode targetNode) {
     double l = fabs(targetNode.l());
     double w = fabs(targetNode.w());
     double theta = -targetNode.theta();
+    if (newUnfinished_cations_.front().type() == 1 && targetNode.id().find('S')!=-1){//入库只判断前后方向上是否到达
+        tx = x;
+    }
 
     if (l < 1e-10 || w < 1e-10) {
         printf("IsArrived: Error target l or w == 0\n");
@@ -918,6 +998,18 @@ void Navigation::SendMoveCmd(int mode, ActionType type,
     }
 }
 
+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;
+    }
+}
+
 bool Navigation::clamp_close() {
     if (monitor_) {
         printf("Clamp closing...\n");
@@ -960,6 +1052,48 @@ bool Navigation::clamp_open() {
     return false;
 }
 
+bool Navigation::lifter_rise() {
+    if (monitor_) {
+        printf("Lifter upping...\n");
+        monitor_->lifter_rise(move_mode_);
+        actionType_ = eLifterRise;
+        while (cancel_ == false) {
+            if (timed_lifter_.timeout()) {
+                printf("timed lifter is timeout\n");
+                return false;
+            }
+            if (timed_lifter_.Get() == eRose)
+                return true;
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            monitor_->lifter_rise(move_mode_);
+            actionType_ = eLifterRise;
+        }
+        return false;
+    }
+    return false;
+}
+
+bool Navigation::lifter_down() {
+    if (monitor_) {
+        printf("Lifter downing...\n");
+        monitor_->lifter_down(move_mode_);
+        actionType_ = eLifterDown;
+        while (cancel_ == false) {
+            if (timed_lifter_.timeout()) {
+                printf("timed lifter is timeout\n");
+                return false;
+            }
+            if (timed_lifter_.Get() == eDowned)
+                return true;
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            monitor_->lifter_down(move_mode_);
+            actionType_ = eLifterDown;
+        }
+        return false;
+    }
+    return false;
+}
+
 Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit limit_v, bool autoDirect) {
     if (IsArrived(node)) {
         printf(" current already in target completed !!!\n");
@@ -1036,12 +1170,40 @@ Navigation::MpcResult Navigation::MpcToTarget(NavMessage::PathNode node, stLimit
             if (out[0] < 0 && out[0] > -limit_v.min)
                 out[0] = -limit_v.min;
         }
+
+        //放大角速度
+        out[1] *= 10;
+
+        //入库,行进方向上最后一米不纠偏
+        if (newUnfinished_cations_.front().type() == 1 && node.id().find('S')!=-1){//入库
+            if(fabs(target_in_agv.x()) < 1.4){
+                printf("target_in_agv: %f", target_in_agv.x());
+                out[1] = 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){
+                printf("agv_in_space: %f", agv_in_space.x());
+                out[1] = 0.0;
+            }
+        }
+
         //下发速度
         //printf("  nav  input :%f   out:%f\n",timedV_.Get(),out[0]);
+        //添加车位号,距目标点距离信息
+        double distance = Pose2d::distance(target_in_agv, Pose2d(0,0,0));
+        int space_id = 0;
+        if(node.id().find('S') != -1){
+            std::string id = node.id().substr(1,node.id().length()-1);
+            space_id = stoi(id);
+        }
         if (directY == false)
-            SendMoveCmd(move_mode_, eVertical, out[0], out[1]);
+            SendMoveCmd(move_mode_, eVertical, out[0], out[1], space_id, distance);
         else
-            SendMoveCmd(move_mode_, eHorizontal, out[0], out[1]);
+            SendMoveCmd(move_mode_, eHorizontal, out[0], out[1], space_id, distance);
         actionType_ = directY ? eHorizontal : eVertical;
         /*
          * 判断车辆是否在终点附近徘徊,无法到达终点
@@ -1064,6 +1226,10 @@ bool Navigation::PossibleToTarget(NavMessage::PathNode targetNode, bool directY)
         return false;
     }
     Pose2d current = timedPose_.Get();
+    if(targetNode.id().find('S') != -1){
+        //车位点强制可到达
+        return true;
+    }
 
     double tx = targetNode.x();
     double ty = targetNode.y();
@@ -1071,12 +1237,18 @@ bool Navigation::PossibleToTarget(NavMessage::PathNode targetNode, bool directY)
     double w = fabs(targetNode.w());
     double theta = -targetNode.theta();
 
-    double W = 2.45;
-    double L = 1.3;
-    double minYaw = 3 * M_PI / 180.0;
+//    double W = 2.45;
+//    double L = 1.3;
+//    double minYaw = 3 * M_PI / 180.0;
+//    if (move_mode_ == eDouble) {
+//        L = 1.3 + 2.7;
+//
+//    }
+    double W = 2.5;
+    double L = 1.565;
+    double minYaw = 5 * M_PI / 180.0;
     if (move_mode_ == eDouble) {
-        L = 1.3 + 2.7;
-
+        L = 1.565 + 2.78;
     }
     if (directY) {
         current = current.rotate(current.x(), current.y(), M_PI / 2);
@@ -1141,7 +1313,7 @@ void Navigation::Start(const NavMessage::NavCmd &cmd, NavMessage::NavResponse &r
     cancel_ = false;
     running_ = true;
     actionType_ = eReady;
-    printf(" navigation beg...\n");
+    printf("Navigation beg...\n");
 
     while (newUnfinished_cations_.empty() == false && cancel_ == false) {
         std::cout << "unfinished size:" << newUnfinished_cations_.size() << std::endl;
@@ -1161,7 +1333,6 @@ void Navigation::Start(const NavMessage::NavCmd &cmd, NavMessage::NavResponse &r
                 isInSpace_ = false;
             }
         } else if (act.type() == 3 || act.type() == 4) { //马路导航
-
             if (!execute_nodes(act))
                 break;
         } else if (act.type() == 5) {
@@ -1179,9 +1350,18 @@ void Navigation::Start(const NavMessage::NavCmd &cmd, NavMessage::NavResponse &r
             }
         } else if (act.type() == 8) { //切换模式
             SwitchMode(act.changedmode(), act.wheelbase());
-        } else {
-            printf(" action type invalid not handled !!\n");
-            break;
+        } else if (act.type() == 9) { //提升机构提升
+            if (this->lifter_rise() == false) {
+                printf("提升failed ...\n");
+                break;
+            }
+        } else if (act.type() == 10) { //提升机构下降
+            if (this->lifter_down() == false) {
+                printf("下降failed ...\n");
+                break;
+            }
+        }else {
+            printf(" action type invalid not handled !!\n");break;
         }
         newUnfinished_cations_.pop();
     }

+ 10 - 1
MPC/navigation.h

@@ -55,6 +55,8 @@ public:
 
     virtual void ResetClamp(ClampStatu statu);
 
+    virtual void ResetLifter(LifterStatus status);
+
     TimedLockData<Pose2d> &RealTimePose() {
         return timedPose_;
     }
@@ -87,6 +89,8 @@ protected:
 
     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);
+
     static void RobotPoseCallback(const MqttMsg &msg, void *context);
 
     static void RobotSpeedCallback(const MqttMsg &msg, void *context);
@@ -138,6 +142,10 @@ protected:
 
     virtual bool clamp_open();
 
+    virtual bool lifter_rise();
+
+    virtual bool lifter_down();
+
     bool mpc_once(Trajectory traj, stLimit limit_v, std::vector<double> &out, bool directY = false);
 
     /* 原地旋转mpc
@@ -173,7 +181,8 @@ protected:
     TimedLockData<Pose2d> timedPose_;           //当前位姿
     TimedLockData<double> timedV_;              //底盘数据
     TimedLockData<double> timedA_;
-    TimedLockData<ClampStatu> timed_clamp_;
+    TimedLockData<ClampStatu> timed_clamp_;     //加持杆
+    TimedLockData<LifterStatus> timed_lifter_;    //提升机构
 
     TimedLockData<Pose2d> timedBrotherPose_;           //当前位姿
     TimedLockData<double> timedBrotherV_;              //底盘数据

+ 82 - 19
MPC/navigation_main.cpp

@@ -62,12 +62,12 @@ void NavigationMain::SendMoveCmd(int mode, ActionType type,
     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());
+        robotStatu.mutable_agvstatu()->set_lifter_other(timed_other_lifter_.Get());
         return true;
     }
     //std::cout<<agvStatu.DebugString()<<std::endl;
@@ -78,12 +78,18 @@ void NavigationMain::ResetOtherClamp(ClampStatu statu) {
     timed_other_clamp_.reset(statu, 1);
 }
 
+void NavigationMain::ResetOtherLifter(LifterStatus status) {
+    timed_other_lifter_.reset(status, 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());
+        ResetLifter((LifterStatus) speed.lifter());
+        ResetOtherLifter((LifterStatus) speed.lifter_other());
         //printf(" clamp:%d   other:%d\n",speed.clamp(),speed.clamp_other());
     }
 }
@@ -135,9 +141,58 @@ bool NavigationMain::clamp_open() {
     return false;
 }
 
+bool NavigationMain::lifter_rise() {
+    if (move_mode_ == eSingle) {
+        return Navigation::lifter_rise();
+    }
+    if (monitor_) {
+        printf("双车提升机构提升\n");
+        monitor_->lifter_rise(move_mode_);
+        while (exit_ == false) {
+            if (timed_lifter_.timeout() || timed_other_lifter_.timeout()) {
+                printf("timed lifter is timeout\n");
+                return false;
+            }
+            if (timed_lifter_.Get() == eRose && timed_other_lifter_.Get() == eRose) {
+                printf("双车提升机构提升completed!!!\n");
+                return true;
+            }
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            monitor_->lifter_rise(move_mode_);
+        }
+        return false;
+    }
+    return false;
+}
+
+bool NavigationMain::lifter_down() {
+    if (move_mode_ == eSingle) {
+        return Navigation::lifter_down();
+    }
+    if (monitor_) {
+        printf("双车提升机构下降\n");
+        monitor_->lifter_down(move_mode_);
+        while (exit_ == false) {
+            if (timed_lifter_.timeout() || timed_other_lifter_.timeout()) {
+                printf("timed lifter is timeout\n");
+                return false;
+            }
+            if (timed_lifter_.Get() == eDowned && timed_other_lifter_.Get() == eDowned) {
+                printf("双车提升机构下降completed!!!\n");
+                return true;
+            }
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            monitor_->lifter_down(move_mode_);
+        }
+        return false;
+    }
+    return false;
+}
+
 Navigation::MpcResult
 NavigationMain::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");
         return eMpcFailed;
     }
@@ -148,28 +203,35 @@ NavigationMain::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelb
     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点,保持与后车一致的朝向
+
+    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();
+        if (move_mode_ == eSingle) {
+            x += wheelbase * cos(rotated.theta());
+            y += wheelbase * sin(rotated.theta());
+        }
     } else { //当前车先到,正向
-        printf("RotateBeforeEnterSpace | 该车先到, __LINE__ = %d\n", __LINE__);
+        printf("RotateBeforeEnterSpace | 车先到, __LINE__ = %d\n", __LINE__);
         rotated.mutable_theta() = space.theta();
     }
-    std::cout << "===============================> RotateBeforeEnterSpace ,target:" << rotated << std::endl;
-    double x = space.x();
-    double y = space.y();
-    if (move_mode_ == eSingle) {
-        x += wheelbase / 2 * cos(rotated.theta());
-        y += wheelbase / 2 * sin(rotated.theta());
-        printf("确定车位点:eSingle\n");
+
+    if (move_mode_ == eDouble){
+        x -= wheelbase/2 * cos(rotated.theta());
+        y -= wheelbase/2 * sin(rotated.theta());
+        printf("RotateBeforeEnterSpace | 整车模式, __LINE__ = %d\n", __LINE__);
     }
+
     target.set_x(x);
     target.set_y(y);
     target.set_theta(rotated.theta());
+    target.set_l(0.05);
+    target.set_w(0.05);
+    target.set_id(space.id());
+    printf("RotateBeforeEnterSpace | target:[x:%f,y:%f,theta:%f]\n",x,y,target.theta());
 
     while (cancel_ == false) {
         std::this_thread::sleep_for(std::chrono::milliseconds(100));
@@ -188,14 +250,15 @@ NavigationMain::RotateBeforeEnterSpace(NavMessage::PathNode space, double wheelb
         }
 
         //下发速度
-        if (fabs(yawDiff) > 1 * M_PI / 180.0) {
-            SendMoveCmd(move_mode_, eRotation, 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) {
+        if (fabs(yawDiff) < 0.5 * 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]);
+            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;
 

+ 9 - 1
MPC/navigation_main.h

@@ -23,9 +23,12 @@ public:
 
     void ResetOtherClamp(ClampStatu statu);
 
+    void ResetOtherLifter(LifterStatus status);
+
     virtual void HandleAgvStatu(const MqttMsg &msg);
 
     virtual void SwitchMode(int mode, float wheelBase) {
+        printf("change mode to:%d\n", mode);
         if (move_mode_ == mode)
             return;
         if (mode == eDouble) {
@@ -57,7 +60,7 @@ public:
             else
                 mode = mode | eChildOppositeToMain;
 
-            printf(" Switch MoveMode --> main(%d)\n", mode);
+            printf(" Switch MoveMode --> main(%d), wheelBase: %f\n", mode, wheelBase);
         }
         wheelBase_ = wheelBase;
         move_mode_ = mode;
@@ -74,11 +77,16 @@ protected:
 
     virtual bool clamp_open();
 
+    virtual bool lifter_rise();
+
+    virtual bool lifter_down();
+
     virtual bool CreateRobotStatuMsg(NavMessage::RobotStatu &robotStatu);
 
 protected:
     float wheelBase_;   //两节agv的位姿与单节的位姿变换
     TimedLockData<int> timed_other_clamp_;
+    TimedLockData<int> timed_other_lifter_;
 };
 
 #endif //NAVIGATION_NAVIGATION_MAIN_H

+ 22 - 19
MPC/rotate_mpc.cpp

@@ -8,7 +8,9 @@
 #include <cppad/ipopt/solve.hpp>
 
 size_t mpc_rotate_steps = 20;                  //优化考虑后面多少步
+size_t mpc_rotate_delay = 2;  // 发送到执行的延迟,即几个周期的时间
 #define N mpc_rotate_steps
+#define delay mpc_rotate_delay
 
 class FG_eval_rotate {
 public:
@@ -43,7 +45,7 @@ public:
         // 代价函数计算
         for (int t = 0; t < N - 1; ++t) {
             /// 角速度,角加速度weight loss
-            //fg[0] += angular_velocity_cost_weight * CppAD::pow(vars[N + t], 2);
+            fg[0] += angular_velocity_cost_weight * CppAD::pow(vars[N + t], 2);
             fg[0] += angular_acceleration_cost_weight * CppAD::pow(vars[N + t + 1] - vars[N + t], 2);
             /// 目标角度 loss
             fg[0] += angular_cost_weight * CppAD::pow(target_theta - vars[t], 2);
@@ -55,7 +57,7 @@ public:
         int n_obs = n_angular_acceleration + N;
 
         /// 角度等式约束 1~N
-        fg[n_angular] = vars[0] - vars[N] * dt;
+        fg[n_angular] = vars[0] - angular_velocity * dt;
         for (int t = 1; t < N; ++t) {
             // State at time t + 1
             CppAD::AD<double> theta1 = vars[t];
@@ -68,13 +70,13 @@ public:
             fg[n_angular + t] = theta1 - (theta0 + angular_velocity0 * dt);
         }
 
-        /// 角加速度等式约束 N+1~2N
+        /// 角加速度等式约束 N+1~2N
         fg[n_angular_acceleration] = (vars[0 + N] - angular_velocity) / dt;
         for (int t = 1; t < N; ++t) {
             fg[n_angular_acceleration + t] = (vars[t + N] - vars[t + N - 1]) / dt;
         }
 
-        /// 障碍物距离等式约束 2N+1~3N
+        /// 障碍物距离等式约束 2N+1~3N
         if (m_statu.size() == 1 + 3) {
             float obs_x = m_statu[1];
             float obs_y = m_statu[2];
@@ -120,11 +122,12 @@ RotateMPC::solve(Pose2d current_to_target, Eigen::VectorXd statu, MPC_parameter
 
     /// 定义最大最小角度,角速度,角加速度(不区分方向)
     double max_angular = M_PI;
-    double max_angular_velocity = 6.0 / 180 * M_PI;
-    double min_angular_velocity = 0.1 / 180 * M_PI;
-    double max_angular_acceleration_velocity = 3.0 / 180 * M_PI;//mpc_param.acc_angular; //
+    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; //
     /// 调整输入
     if (angular_velocity > max_angular_velocity) angular_velocity = max_angular_velocity;
+    if (angular_velocity < -max_angular_velocity) angular_velocity = -max_angular_velocity;
 
     // 优化
     typedef CPPAD_TESTVECTOR(double) Dvector;
@@ -154,10 +157,11 @@ RotateMPC::solve(Pose2d current_to_target, Eigen::VectorXd statu, MPC_parameter
 
     // Lower and upper limits for the constraints
     /// 障碍物是否进入 碰撞检测范围内
-    float distance = Pose2d::distance(obs_relative_pose_, Pose2d(0, 0, 0));
+//    float distance = Pose2d::distance(obs_relative_pose_, Pose2d(0, 0, 0));
+    float distance = 1000;//屏蔽障碍物
     bool find_obs = distance < 5;
     if (find_obs) printf(" find obs ..............................\n");
-    size_t n_constraints = 2 * N + find_obs * N;// 0~N角度,N~2N角加速度, 2N~3N障碍物约束
+    size_t n_constraints = 2 * N + find_obs * N;// 0~N角度约束,N~2N角加速度约束, 2N~3N障碍物约束
     Dvector constraints_lowerbound(n_constraints);
     Dvector constraints_upperbound(n_constraints);
     for (auto i = 0; i < n_constraints; ++i) {
@@ -166,8 +170,14 @@ RotateMPC::solve(Pose2d current_to_target, Eigen::VectorXd statu, MPC_parameter
     }
     /// limit of angular acceleration
     for (auto i = N; i < 2 * N; ++i) {
-        constraints_lowerbound[i] = -max_angular_acceleration_velocity;
-        constraints_upperbound[i] = max_angular_acceleration_velocity;
+        //延迟处理,前delay个周期内认定为匀速运动(加速度为0)
+        if (i < N + delay) {
+            constraints_lowerbound[i] = 0;
+            constraints_upperbound[i] = 0;
+        } else{
+            constraints_lowerbound[i] = -max_angular_acceleration_velocity;
+            constraints_upperbound[i] = max_angular_acceleration_velocity;
+        }
     }
     /// limit of obs distance
     if (find_obs)
@@ -189,13 +199,6 @@ RotateMPC::solve(Pose2d current_to_target, Eigen::VectorXd statu, MPC_parameter
 
 
     Pose2d targetAngularInAGV = current_to_target;
-    /// 调整到适合的目标角度
-    double acc_time = (max_angular_velocity - angular_velocity) / max_angular_acceleration_velocity;
-    double max_angular_once = max_angular_velocity * N * dt - acc_time * (max_angular_velocity - angular_velocity);
-    if (targetAngularInAGV.theta() > max_angular_once ) {
-        targetAngularInAGV.set_theta(max_angular_once);
-    }
-
 
     Eigen::VectorXd condition(4);
     condition << dt, targetAngularInAGV.theta(), obs_w_, obs_h_;
@@ -238,7 +241,7 @@ RotateMPC::solve(Pose2d current_to_target, Eigen::VectorXd statu, MPC_parameter
 
     // 输出第一步的角速度
     out.clear();
-    double solve_angular_velocity = solution.x[N];
+    double solve_angular_velocity = solution.x[N+delay];
 
     out.push_back(solve_angular_velocity);
 

+ 4 - 4
config/navigation_main.prototxt

@@ -1,4 +1,4 @@
-#127.0.0.1
+
 main_agv:true
 rpc_ipport:"192.168.0.70:9090"
 Agv_emqx
@@ -6,9 +6,9 @@ Agv_emqx
 	NodeId:"agv-main"
 	ip:"192.168.0.70"
 	port:1883
-	pubSpeedTopic:"monitor_main/speedcmd"
-	subPoseTopic:"monitor_main/statu"
-	subSpeedTopic:"monitor_main/speed"
+	pubSpeedTopic:"monitor_child/speedcmd"
+	subPoseTopic:"monitor_child/statu"
+	subSpeedTopic:"monitor_child/speed"
 }
 
 Terminal_emqx

+ 8 - 5
message.proto

@@ -15,17 +15,20 @@ message AgvStatu {
     float w = 2;
     int32 clamp = 3;    //夹持状态  0,中间状态,1夹紧到位,2,打开到位,
     int32 clamp_other = 4; //另外一节
-
+    int32 lifter = 5;   //提升机构 0中间状态,1上升到位, 2下降到位
+    int32 lifter_other = 6;     //另外一节
 }
 
 message ToAgvCmd {
     int32 H = 1;  //心跳
     int32 M = 2;    //模式:2整车模式,1:单车
-    int32 T = 3; // 1:原地旋转,2:横移,3:MPC巡线/前进, 5,夹持,6,松夹持,其他/未接收到:停止
+    int32 T = 3; // 1:原地旋转, 2:横移, 3:MPC巡线/前进, 5:夹持, 6:松夹持, 7:提升机构抬升, 8:抬升机构下降, 其他/未接收到:停止
     float V = 4;  //角速度
     float W = 5;  //线速度
     float L = 6;  //轴距
-    int32 end = 7;
+    int32 P = 7; //车位编号
+    float D = 8; //距目标点距离
+    int32 end = 9;
 }
 
 message Pose2d
@@ -53,7 +56,7 @@ message Trajectory
 //----------------------------
 message NewAction //进库,出库,轨迹导航,夹持,松夹持
 {
-    int32 type = 1; //1,进库,2,出库,3,自动选择动作导航,4,保证agv朝前导航,5,汽车模型导航,6:夹持,7:松夹持,8:切换模式
+    int32 type = 1; //1,进库,2,出库,3,自动选择动作导航,4,保证agv朝前导航,5,汽车模型导航,6:夹持,7:松夹持,8:切换模式, 9:提升机构提升, 10: 提升机构下降
     PathNode spaceNode = 2; //进出库起点
     PathNode passNode = 3; //进出库途径点
     PathNode streetNode = 4; //进出库终点
@@ -90,7 +93,7 @@ service NavExcutor {
 
 message NavStatu
 {
-    int32 statu = 1; //0:ready  1:原地旋转,2:Horizon,3:vrtical,4:MPC,5:夹持开,6:夹持关
+    int32 statu = 1; //0:ready  1:原地旋转,2:Horizon,3:vrtical,4:MPC,5:夹持开,6:夹持关,7:提升机构提升, 8: 提升机构下降
     bool main_agv = 2; //是否是两节控制plc
     int32 move_mode = 3; //运动模式,1:single,2:双车
     LidarOdomStatu odom = 4;

+ 4 - 0
parameter.proto

@@ -59,3 +59,7 @@ message Navigation_parameter
   string rpc_ipport=10;
 }
 
+message Version
+{
+  string version=1;
+}