// // Created by zx on 23-5-8. // #include "navigation_main.h" #include "TimerRecord.h" NavigationMain::NavigationMain() { move_mode_ = eSingle; wheelBase_ = 0; } NavigationMain::~NavigationMain() { } void NavigationMain::ResetPose(const Pose2d &pose) { if (move_mode_ == eDouble) { 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::Start(const NavMessage::NavCmd &cmd, NavMessage::NavResponse &response) { /*if(move_mode_!=Monitor_emqx::eDouble) { printf(" navigation mode must set main,parameter:Pose2d\n"); return false; }*/ Navigation::Start(cmd, response); } void NavigationMain::SendMoveCmd(int mode, 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()); robotStatu.mutable_agvstatu()->set_lifter_other(timed_other_lifter_.Get()); return true; } //std::cout<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; } return false; } bool NavigationMain::clamp_open() { if (move_mode_ == 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; } 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() == eRose && timed_other_lifter_.Get() == eRose) { 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; } 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.10); target.set_id(space.id()); //后车先到,当前车进入2点,保持与后车一致的朝向 if (brother.in_space() && brother.space_id() == space.id()) { printf("RotateBeforeEnterSpace | 后车先到, __LINE__ = %d\n", __LINE__); rotated.mutable_theta() = brother.odom().theta(); } else { //当前车先到,正向 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"); } 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 out; bool ret; TimerRecord::Execute([&, this]() { ret = Rotation_mpc_once(Pose2d(0, 0, yawDiff), limit_rotate, out); }, "Rotation_mpc_once"); if (ret == false) { Stop(); return eMpcFailed; } //下发速度 if (fabs(yawDiff) < 0.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; // std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pose2d current = timedPose_.Get(); // double yawDiff = (rotated - current).theta(); // if (fabs(yawDiff) > 1 * M_PI / 180.0) { // double theta = limit_gause(yawDiff, limit_rotate.min, limit_rotate.max); // double angular = next_speed(timedA_.Get(), theta, acc_angular, dt); // double limit_angular = limit(angular, limit_rotate.min, limit_rotate.max); // // SendMoveCmd(move_mode_, Monitor_emqx::eRotation, 0, limit_angular); // actionType_ = eRotation; // printf(" RotateBeforeEnterSpace | input anguar:%f,next angular:%f,down:%f diff:%f anyDirect:false\n", // timedA_.Get(), angular, limit_angular, yawDiff); // // continue; // } else { // if (fabs(timedA_.Get()) < 5 * M_PI / 180.0) { // printf(" RotateBeforeEnterSpace refer target completed\n"); // printf("---------------- update new target :%f %f %f \n",target.x(),target.y(),target.theta()); // return true; // } // } } return eMpcFailed; }