main.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. #include <csignal>
  2. #include "pangolinViewer.h"
  3. #include "dijkstra/dijkstra.h"
  4. #include "define/timedlockdata.hpp"
  5. #include "define/TimerRecord.h"
  6. #include <glog/logging.h>
  7. #include "dijkstra/trajectory.h"
  8. #include "emqx/terminator_emqx.h"
  9. #include "tool/pathcreator.h"
  10. #include "tool/proto_tool.h"
  11. #include <queue>
  12. #include "map.pb.h"
  13. Terminator_emqx* g_terminator= nullptr;
  14. //路径相关
  15. int node_beg=1,node_end=6;
  16. std::mutex pathMutex;
  17. std::vector<int> shortest_path;
  18. PathMap DijkstraMap;
  19. //控制相关
  20. TimedLockData<NavMessage::NavStatu> timed_navStatu_;
  21. TimedLockData<NavMessage::AGVStatu> timed_AgvStatu_;
  22. TimedLockData<NavMessage::AGVStatu> timed_AgvBrotherStatu_;
  23. bool Create_trajectoris(PathMap& map,std::vector<int> nodes_id,std::queue<Trajectory>& trajs);
  24. bool InitMap(std::string config_file);
  25. void pangolinSpinOnce(PangolinViewer* viewer) {
  26. if (timed_AgvStatu_.timeout() == false) {
  27. NavMessage::AGVStatu statu = timed_AgvStatu_.Get();
  28. Pose2d pose2d(statu.x(), statu.y(), statu.theta());
  29. Eigen::Matrix3d rotation_matrix3;
  30. rotation_matrix3 = Eigen::AngleAxisd(pose2d.theta(), Eigen::Vector3d::UnitZ()) *
  31. Eigen::AngleAxisd(0, Eigen::Vector3d::UnitY()) *
  32. Eigen::AngleAxisd(0, Eigen::Vector3d::UnitX());
  33. Eigen::Matrix4d pose;
  34. pose.topLeftCorner(3, 3) = rotation_matrix3;
  35. pose.topRightCorner(3, 1) = Eigen::Vector3d(pose2d.x(), pose2d.y(), 0);
  36. viewer->ShowRealtimeStatu(pose, statu.v(), statu.vth());
  37. }
  38. //显示另一节agv状态
  39. if (timed_AgvBrotherStatu_.timeout() == false) {
  40. NavMessage::AGVStatu statu = timed_AgvBrotherStatu_.Get();
  41. Pose2d pose2d(statu.x(), statu.y(), statu.theta());
  42. Eigen::Matrix3d rotation_matrix3;
  43. rotation_matrix3 = Eigen::AngleAxisd(pose2d.theta(), Eigen::Vector3d::UnitZ()) *
  44. Eigen::AngleAxisd(0, Eigen::Vector3d::UnitY()) *
  45. Eigen::AngleAxisd(0, Eigen::Vector3d::UnitX());
  46. Eigen::Matrix4d pose;
  47. pose.topLeftCorner(3, 3) = rotation_matrix3;
  48. pose.topRightCorner(3, 1) = Eigen::Vector3d(pose2d.x(), pose2d.y(), 0);
  49. viewer->ShowBrotherStatu(pose, statu.v(), statu.vth());
  50. }
  51. //绘制导航实时状态
  52. if (timed_navStatu_.timeout() == false) {
  53. NavMessage::NavStatu statu = timed_navStatu_.Get();
  54. Trajectory select_traj;
  55. Trajectory predict_traj;
  56. for (int i = 0; i < statu.selected_traj().poses_size(); ++i) {
  57. select_traj.push_point(Pose2d(statu.selected_traj().poses(i).x(),
  58. statu.selected_traj().poses(i).y(),
  59. statu.selected_traj().poses(i).theta()));
  60. }
  61. for (int i = 0; i < statu.predict_traj().poses_size(); ++i) {
  62. predict_traj.push_point(Pose2d(statu.predict_traj().poses(i).x(),
  63. statu.predict_traj().poses(i).y(),
  64. statu.predict_traj().poses(i).theta()));
  65. }
  66. viewer->DrawTrajectory(select_traj, 1, 0, 0, 12);
  67. viewer->DrawTrajectory(predict_traj, 0, 1, 1, 15);
  68. }
  69. //绘制dijkstra地图及最短路径
  70. pathMutex.lock();
  71. std::vector<int> solve_path = shortest_path;
  72. pathMutex.unlock();
  73. std::reverse(solve_path.begin(), solve_path.end());
  74. solve_path.push_back(node_end);
  75. viewer->DrawDijkastraMap(DijkstraMap, solve_path);
  76. }
  77. bool OnDijkstraBtn(int beg,int end,float& distance,
  78. std::vector<int>& shortestPath)
  79. {
  80. bool ret= DijkstraMap.GetShortestPath(beg, end, shortestPath, distance);
  81. if(ret)
  82. {
  83. node_beg=beg;
  84. node_end=end;
  85. pathMutex.lock();
  86. shortest_path = shortestPath;
  87. pathMutex.unlock();
  88. }
  89. return ret;
  90. }
  91. bool CreateNavCmd(std::vector<int> nodes,NavMessage::NavCmd& cmd);
  92. void navigation_start()
  93. {
  94. pathMutex.lock();
  95. std::vector<int> solve_path=shortest_path;
  96. pathMutex.unlock();
  97. std::reverse(solve_path.begin(),solve_path.end());
  98. solve_path.push_back(node_end);
  99. //std::queue<Trajectory> global_trajectorys;
  100. //Create_trajectoris(DijkstraMap,solve_path,global_trajectorys);
  101. //发布指令
  102. NavMessage::NavCmd cmd;
  103. if(false==CreateNavCmd(solve_path,cmd))
  104. return;
  105. std::cout<<" ------------------------------------new NavCmd ---------------------------"<<std::endl;
  106. std::cout<<cmd.DebugString()<<std::endl<<std::endl;
  107. if(g_terminator) {
  108. MqttMsg msg;
  109. msg.fromProtoMessage(cmd);
  110. g_terminator->Publish("agv1_child/nav_cmd", msg);
  111. }
  112. }
  113. void navigation_pause()
  114. {
  115. NavMessage::NavCmd cmd;
  116. cmd.set_action(1); //暂停
  117. if(g_terminator) {
  118. MqttMsg msg;
  119. msg.fromProtoMessage(cmd);
  120. g_terminator->Publish("agv1_child/nav_cmd", msg);
  121. }
  122. }
  123. void navigation_stop()
  124. {
  125. NavMessage::NavCmd cmd;
  126. cmd.set_action(3); //取消导航
  127. if(g_terminator) {
  128. MqttMsg msg;
  129. msg.fromProtoMessage(cmd);
  130. g_terminator->Publish("agv1_child/nav_cmd", msg);
  131. }
  132. }
  133. void AgvStatuArrived(const MqttMsg& msg,void* context)
  134. {
  135. NavMessage::AGVStatu statu;
  136. if(msg.toProtoMessage(statu))
  137. timed_AgvStatu_.reset(statu,0.5);
  138. }
  139. void AgvBrotherStatuArrived(const MqttMsg& msg,void* context)
  140. {
  141. NavMessage::AGVStatu statu;
  142. if(msg.toProtoMessage(statu))
  143. timed_AgvBrotherStatu_.reset(statu,0.5);
  144. }
  145. void NavStatuArrived(const MqttMsg& msg,void* context)
  146. {
  147. NavMessage::NavStatu statu;
  148. if(msg.toProtoMessage(statu))
  149. timed_navStatu_.reset(statu,0.5);
  150. }
  151. int main(int argc, char** argv)
  152. {
  153. if(argc<2)
  154. {
  155. printf(" argc must >2 exe mapfile\n");
  156. return -1;
  157. }
  158. std::string config_file=argv[1];
  159. if(InitMap(config_file)==false)
  160. return -1;
  161. //"agv1/nav_statu"
  162. g_terminator=new Terminator_emqx("UI_nav-child");
  163. if(g_terminator->Connect("192.168.0.70",1883)==false)
  164. {
  165. printf(" AGV emqx connect failed\n");
  166. return -1;
  167. }
  168. g_terminator->AddCallback("agv1_child/nav_statu",NavStatuArrived, nullptr);
  169. g_terminator->AddCallback("agv1_child/agv_statu",AgvStatuArrived, nullptr);
  170. g_terminator->AddCallback("agv1/agv_statu",AgvBrotherStatuArrived, nullptr);
  171. PangolinViewer* viewer=PangolinViewer::CreateViewer();
  172. viewer->SetCallbacks(pangolinSpinOnce,OnDijkstraBtn);
  173. viewer->SetNavigationCallbacks(navigation_start,navigation_pause,navigation_stop);
  174. viewer->Join();
  175. TimerRecord::PrintAll();
  176. delete viewer;
  177. delete g_terminator;
  178. return 0;
  179. }
  180. bool InitMap(std::string config_file)
  181. {
  182. MapMessage::Map proto_map;
  183. if(proto_tool::read_proto_param(config_file,proto_map)==false)
  184. {
  185. printf(" read map proto failed\n");
  186. return false;
  187. }
  188. std::map<int,int> exist_id;
  189. for(int i=0;i<proto_map.nodes_size();++i)
  190. {
  191. MapMessage::Node node=proto_map.nodes(i);
  192. if(exist_id.find(node.id())!=exist_id.end())
  193. {
  194. printf("Can not add vertex, Node Id :%d exist\n",node.id());
  195. return false;
  196. }
  197. DijkstraMap.AddVertex(node.id(),node.x(),node.y());
  198. exist_id[node.id()]=0;
  199. }
  200. for(int i=0;i<proto_map.edges_size();++i)
  201. {
  202. MapMessage::Edge edge=proto_map.edges(i);
  203. if(exist_id.find(edge.id1())!=exist_id.end() && exist_id.find(edge.id2())!=exist_id.end())
  204. {
  205. if(false==DijkstraMap.AddEdge(edge.id1(),edge.id2(),edge.directed()))
  206. return false;
  207. }
  208. else
  209. {
  210. printf(" Cant add edge id1 or id2 (%d %d) is not exist\n",edge.id1(),edge.id2());
  211. return false;
  212. }
  213. }
  214. return true;
  215. }
  216. bool Create_trajectoris(PathMap& map,std::vector<int> nodes_id,std::queue<Trajectory>& trajs)
  217. {
  218. if(nodes_id.size()<2)
  219. return false;
  220. for(int i=0;i<nodes_id.size()-1;++i)
  221. {
  222. float x1,y1,x2,y2;
  223. map.GetVertexPos(nodes_id[i],x1,y1);
  224. map.GetVertexPos(nodes_id[i+1],x2,y2);
  225. Pose2d start(x1,y1,0);
  226. Pose2d end(x2,y2,0);
  227. Trajectory traj=Trajectory::create_line_trajectory(start,end,0.05);
  228. if(traj.size()>1)
  229. trajs.push(traj);
  230. else
  231. return false;
  232. }
  233. return true;
  234. }
  235. bool CreateNavCmd(std::vector<int> nodes,NavMessage::NavCmd& cmd)
  236. {
  237. if(nodes.size()==0)
  238. return false;
  239. cmd.set_action(0); //开始新导航
  240. char key[255]={0};
  241. static int N=1111;
  242. sprintf(key,"abcd-efg-%d",N++);
  243. cmd.set_key(key);
  244. NavMessage::Pose2d headdiff,enddiff;
  245. headdiff.set_x(0.1);
  246. headdiff.set_y(0.1);
  247. headdiff.set_theta(2*M_PI/180.0);
  248. enddiff.set_x(0.03);
  249. enddiff.set_y(0.05);
  250. enddiff.set_theta(0.5*M_PI/180.0);
  251. //调整到起点,朝向与当前朝向一致
  252. if(timed_AgvStatu_.timeout())
  253. {
  254. printf(" agv statu is timeout can not get current direction\n");
  255. return false;
  256. }
  257. float current_theta=timed_AgvStatu_.Get().theta();
  258. float x,y;
  259. DijkstraMap.GetVertexPos(nodes[0],x,y);
  260. NavMessage::SpeedLimit v_limit,angular_limit,horize_limit;
  261. v_limit.set_min(0.1);
  262. v_limit.set_max(0.2);
  263. horize_limit.set_min(0.05);
  264. horize_limit.set_max(0.2);
  265. angular_limit.set_min(1);
  266. angular_limit.set_max(10);
  267. NavMessage::SpeedLimit mpc_x_limit,mpc_angular_limit;
  268. mpc_x_limit.set_min(0.05);
  269. mpc_x_limit.set_max(1.0);
  270. mpc_angular_limit.set_min(0*M_PI/180.0);
  271. mpc_angular_limit.set_max(3*M_PI/180.0);
  272. NavMessage::Action act_head;
  273. act_head.set_type(1);
  274. act_head.mutable_target()->set_x(x);
  275. act_head.mutable_target()->set_y(y);
  276. act_head.mutable_target()->set_theta(current_theta);
  277. act_head.mutable_target_diff()->CopyFrom(headdiff);
  278. act_head.mutable_velocity_limit()->CopyFrom(v_limit);
  279. act_head.mutable_horize_limit()->CopyFrom(horize_limit);
  280. act_head.mutable_angular_limit()->CopyFrom(angular_limit);
  281. cmd.add_actions()->CopyFrom(act_head);
  282. Pose2d begin;
  283. for(int i=1;i<nodes.size();++i)
  284. {
  285. //调整到上一点位姿,朝向当前点
  286. float lx,ly;
  287. DijkstraMap.GetVertexPos(nodes[i-1],lx,ly);
  288. DijkstraMap.GetVertexPos(nodes[i],x,y);
  289. float theta=Trajectory::gen_axis_angle(Pose2d(lx,ly,0),Pose2d(x,y,0));
  290. begin=Pose2d(lx,ly,theta);
  291. NavMessage::Action act_adjust;
  292. act_adjust.set_type(1);
  293. act_adjust.mutable_target()->set_x(lx);
  294. act_adjust.mutable_target()->set_y(ly);
  295. act_adjust.mutable_target()->set_theta(theta);
  296. act_adjust.mutable_target_diff()->CopyFrom(headdiff);
  297. act_adjust.mutable_velocity_limit()->CopyFrom(v_limit);
  298. act_adjust.mutable_horize_limit()->CopyFrom(horize_limit);
  299. act_adjust.mutable_angular_limit()->CopyFrom(angular_limit);
  300. cmd.add_actions()->CopyFrom(act_adjust);
  301. //MPC 控制
  302. NavMessage::Action act_along;
  303. act_along.set_type(2);
  304. act_along.mutable_begin()->set_x(begin.x());
  305. act_along.mutable_begin()->set_y(begin.y());
  306. act_along.mutable_begin()->set_theta(begin.theta());
  307. act_along.mutable_target()->set_x(x);
  308. act_along.mutable_target()->set_y(y);
  309. act_along.mutable_target()->set_theta(theta);
  310. if(i==nodes.size()-1) //最后一个节点
  311. act_along.mutable_target_diff()->CopyFrom(enddiff);
  312. else
  313. act_along.mutable_target_diff()->CopyFrom(headdiff);
  314. act_along.mutable_velocity_limit()->CopyFrom(mpc_x_limit);
  315. act_along.mutable_angular_limit()->CopyFrom(mpc_angular_limit);
  316. cmd.add_actions()->CopyFrom(act_along);
  317. }
  318. return true;
  319. }