Browse Source

增加自动导航测试代码

zx 2 years ago
parent
commit
c0e9a4e5a5
8 changed files with 2045 additions and 77 deletions
  1. 164 0
      config/map.prototxt
  2. 2 0
      dijkstra/dijkstra.cpp
  3. 144 75
      main.cpp
  4. 896 0
      map.pb.cc
  5. 791 0
      map.pb.h
  6. 20 0
      map.proto
  7. 23 2
      pangolinViewer.cpp
  8. 5 0
      pangolinViewer.h

+ 164 - 0
config/map.prototxt

@@ -0,0 +1,164 @@
+nodes
+{
+    id:1
+    x:3.3
+    y:3.5
+}
+
+nodes
+{
+    id:2
+    x:10.3
+    y:3.5
+}
+
+nodes
+{
+    id:3
+    x:15.4
+    y:3.5
+}
+nodes
+{
+    id:4
+    x:17.9
+    y:3.5
+}
+
+nodes
+{
+    id:5
+    x:10.3
+    y:17.7
+}
+
+nodes
+{
+    id:6
+    x:14.95
+    y:17.7
+}
+nodes
+{
+    id:7
+    x:17.9
+    y:17.7
+}
+
+nodes
+{
+    id:8
+    x:10.3
+    y:-0.18
+}
+nodes
+{
+    id:9
+    x:15.4
+    y:7.5
+}
+nodes
+{
+    id:10
+    x:14.85
+    y:13.7
+}
+nodes
+{
+    id:11
+    x:18.8
+    y:3.5
+}
+edges{
+    id1:1
+    id2:2
+    directed:false
+}
+edges{
+    id1:1
+    id2:3
+    directed:false
+}
+edges{
+    id1:1
+    id2:4
+    directed:false
+}
+edges{
+    id1:1
+    id2:11
+    directed:false
+}
+edges{
+    id1:2
+    id2:3
+    directed:false
+}
+edges{
+    id1:2
+    id2:4
+    directed:false
+}
+edges{
+    id1:2
+    id2:5
+    directed:false
+}
+edges{
+    id1:2
+    id2:11
+    directed:false
+}
+edges{
+    id1:2
+    id2:8
+    directed:false
+}
+edges{
+    id1:3
+    id2:4
+    directed:false
+}
+edges{
+    id1:3
+    id2:11
+    directed:false
+}
+edges{
+    id1:4
+    id2:11
+    directed:false
+}
+edges{
+    id1:5
+    id2:6
+    directed:false
+}
+edges{
+    id1:5
+    id2:7
+    directed:false
+}
+edges{
+    id1:5
+    id2:8
+    directed:false
+}
+edges{
+    id1:6
+    id2:7
+    directed:false
+}
+
+#------------------------------------------
+edges{
+    id1:9
+    id2:3
+    directed:false
+}
+edges{
+    id1:10
+    id2:6
+    directed:false
+}
+

+ 2 - 0
dijkstra/dijkstra.cpp

@@ -145,6 +145,8 @@ bool PathMap::AddEdge(int id1,int id2,bool directed)
 
 bool PathMap::GetShortestPath(int id1,int id2,std::vector<int>& path,float& shortest_distance)
 {
+  if(id1==id2)
+    return false;
   if(node_.find(id1)!=node_.end() && node_.find(id2)!=node_.end())
   {
     dijkstra_shortest_path(grapher_, parent_, distance_, id1);

+ 144 - 75
main.cpp

@@ -16,23 +16,153 @@
 
 Terminator_emqx* g_terminator= nullptr;
 //路径相关
-int node_beg=1,node_end=6;
 std::mutex pathMutex;
-std::vector<int> shortest_path;
+std::vector<int> g_shortest_path;
 PathMap DijkstraMap;
+bool g_auto_test=false;
+int auto_test_count=0;
+int next_begin_node=0;
+int end_node=0;
+
+bool last_nav_statu_completed=true;
 
 //控制相关
 TimedLockData<NavMessage::NavStatu> timed_navStatu_;
 TimedLockData<NavMessage::AGVStatu> timed_AgvStatu_;
 TimedLockData<NavMessage::AGVStatu> timed_AgvBrotherStatu_;
 
+bool CreateNavCmd(std::vector<int> nodes,NavMessage::NavCmd& cmd);
+bool NavIsCompleted()
+{
+  if(timed_navStatu_.timeout()==false)
+  {
+    if(timed_navStatu_.Get().unfinished_actions_size()>0)
+    {
+      return false;
+    }
+    return true;
+  }
+  return false;
+}
 
 bool Create_trajectoris(PathMap& map,std::vector<int> nodes_id,std::queue<Trajectory>& trajs);
 
 bool InitMap(std::string config_file);
 
+bool OnDijkstraBtn(int beg,int end,float& distance,
+                   std::vector<int>& shortestPath)
+{
+  if(beg==0 || end==0)
+    return false;
+  next_begin_node=beg;
+  end_node=end;
+  bool ret= DijkstraMap.GetShortestPath(beg, end, shortestPath, distance);
+  if(ret)
+  {
+    pathMutex.lock();
+    g_shortest_path= shortestPath;
+    std::reverse(g_shortest_path.begin(),g_shortest_path.end());
+    g_shortest_path.push_back(end_node);
+    pathMutex.unlock();
+  }
+  return ret;
+}
+void navigation_start() {
+
+  if (NavIsCompleted() == false) {
+    printf("Last nav has not completed!!\n");
+    return;
+  }
+
+  if (next_begin_node == 0) {
+    printf(" Last node == 0 ,not allow to start nav\n");
+    return;
+  }
+
+  std::vector<int> t_shortestPath;
+  float distance = -1;
+  bool ret = DijkstraMap.GetShortestPath(next_begin_node, end_node, t_shortestPath, distance);
+  if (ret) {
+    pathMutex.lock();
+    g_shortest_path = t_shortestPath;
+    std::reverse(g_shortest_path.begin(), g_shortest_path.end());
+    g_shortest_path.push_back(end_node);
+    pathMutex.unlock();
+  }
+
+  auto_test_count++;
+  //发布指令
+  NavMessage::NavCmd cmd;
+  if (false == CreateNavCmd(g_shortest_path, cmd))
+    return;
+  std::cout << " ------------------------------------new NavCmd ---------------------------" << std::endl;
+  printf("----第 %d 次测试---- from %d ---- %d -------begin navigatting...-----\n\n",
+         auto_test_count,next_begin_node,end_node);
+
+  if (g_terminator) {
+    MqttMsg msg;
+    msg.fromProtoMessage(cmd);
+    g_terminator->Publish("agv1_child/nav_cmd", msg);
+  }
+
+}
+
+void navigation_pause()
+{
+  NavMessage::NavCmd cmd;
+  cmd.set_action(1);  //暂停
+  if(g_terminator) {
+    MqttMsg msg;
+    msg.fromProtoMessage(cmd);
+    g_terminator->Publish("agv1_child/nav_cmd", msg);
+  }
+}
+void navigation_stop()
+{
+  if(NavIsCompleted()==false)
+  {
+    printf("Last nav has not completed!! set last node = -1\n");
+    next_begin_node=0;
+  }
 
+  NavMessage::NavCmd cmd;
+  cmd.set_action(3);  //取消导航
+  if(g_terminator) {
+    MqttMsg msg;
+    msg.fromProtoMessage(cmd);
+    g_terminator->Publish("agv1_child/nav_cmd", msg);
+  }
+}
+
+void navigation_autoTest()
+{
+  g_auto_test=true;
+}
 void pangolinSpinOnce(PangolinViewer* viewer) {
+  ///导航结束,修改起点为上一任务终点,重置终点为0
+  if(last_nav_statu_completed==false) {
+    if (NavIsCompleted() == true) {
+      if (end_node != 0) {
+        next_begin_node = end_node;
+        //随机终点
+        int randid=0; //[1-8]
+        while(randid==0 || randid==next_begin_node) {
+          randid = rand() % 7 + 1;
+          usleep(1000*1000);
+        }
+        printf(" nav completed ...... reset beg:%d  rand end:%d\n",next_begin_node,randid);
+        end_node = randid;
+        float distance;
+        std::vector<int> shortestPath;
+
+        if(OnDijkstraBtn(next_begin_node,end_node,distance,shortestPath))
+          viewer->ResetPathInfo(next_begin_node, end_node,distance);
+        last_nav_statu_completed=true;
+        if(g_auto_test)
+          navigation_start();
+      }
+    }
+  }
 
   if (timed_AgvStatu_.timeout() == false) {
     NavMessage::AGVStatu statu = timed_AgvStatu_.Get();
@@ -82,76 +212,8 @@ void pangolinSpinOnce(PangolinViewer* viewer) {
   }
 
   //绘制dijkstra地图及最短路径
-  pathMutex.lock();
-  std::vector<int> solve_path = shortest_path;
-  pathMutex.unlock();
-  std::reverse(solve_path.begin(), solve_path.end());
-  solve_path.push_back(node_end);
-  viewer->DrawDijkastraMap(DijkstraMap, solve_path);
-
-}
+  viewer->DrawDijkastraMap(DijkstraMap, g_shortest_path);
 
-bool OnDijkstraBtn(int beg,int end,float& distance,
-        std::vector<int>& shortestPath)
-{
-  bool ret= DijkstraMap.GetShortestPath(beg, end, shortestPath, distance);
-  if(ret)
-  {
-    node_beg=beg;
-    node_end=end;
-    pathMutex.lock();
-    shortest_path = shortestPath;
-    pathMutex.unlock();
-  }
-  return ret;
-}
-
-bool CreateNavCmd(std::vector<int> nodes,NavMessage::NavCmd& cmd);
-
-void navigation_start()
-{
-  pathMutex.lock();
-  std::vector<int> solve_path=shortest_path;
-  pathMutex.unlock();
-  std::reverse(solve_path.begin(),solve_path.end());
-  solve_path.push_back(node_end);
-
-  //std::queue<Trajectory> global_trajectorys;
-  //Create_trajectoris(DijkstraMap,solve_path,global_trajectorys);
-
-  //发布指令
-  NavMessage::NavCmd cmd;
-  if(false==CreateNavCmd(solve_path,cmd))
-    return;
-  std::cout<<" ------------------------------------new NavCmd ---------------------------"<<std::endl;
-  std::cout<<cmd.DebugString()<<std::endl<<std::endl;
-  if(g_terminator) {
-    MqttMsg msg;
-    msg.fromProtoMessage(cmd);
-    g_terminator->Publish("agv1_child/nav_cmd", msg);
-  }
-
-}
-
-void navigation_pause()
-{
-  NavMessage::NavCmd cmd;
-  cmd.set_action(1);  //暂停
-  if(g_terminator) {
-    MqttMsg msg;
-    msg.fromProtoMessage(cmd);
-    g_terminator->Publish("agv1_child/nav_cmd", msg);
-  }
-}
-void navigation_stop()
-{
-  NavMessage::NavCmd cmd;
-  cmd.set_action(3);  //取消导航
-  if(g_terminator) {
-    MqttMsg msg;
-    msg.fromProtoMessage(cmd);
-    g_terminator->Publish("agv1_child/nav_cmd", msg);
-  }
 }
 
 void AgvStatuArrived(const MqttMsg& msg,void* context)
@@ -172,13 +234,19 @@ void NavStatuArrived(const MqttMsg& msg,void* context)
 {
   NavMessage::NavStatu statu;
   if(msg.toProtoMessage(statu))
-    timed_navStatu_.reset(statu,0.5);
+    timed_navStatu_.reset(statu,1.0);
+  if(last_nav_statu_completed==true)
+  {
+    if(NavIsCompleted()==false)
+      last_nav_statu_completed=false;
+  }
 
 }
 
 
 int main(int argc, char** argv)
 {
+  srand((unsigned int)time(nullptr));
   if(argc<2)
   {
     printf(" argc must >2  exe mapfile\n");
@@ -205,6 +273,7 @@ int main(int argc, char** argv)
   PangolinViewer* viewer=PangolinViewer::CreateViewer();
   viewer->SetCallbacks(pangolinSpinOnce,OnDijkstraBtn);
   viewer->SetNavigationCallbacks(navigation_start,navigation_pause,navigation_stop);
+  viewer->SetAutoTestNavCallback(navigation_autoTest);
   viewer->Join();
 
   TimerRecord::PrintAll();
@@ -292,11 +361,11 @@ bool CreateNavCmd(std::vector<int> nodes,NavMessage::NavCmd& cmd)
   NavMessage::Pose2d headdiff,enddiff;
   headdiff.set_x(0.1);
   headdiff.set_y(0.1);
-  headdiff.set_theta(2*M_PI/180.0);
+  headdiff.set_theta(1.0*M_PI/180.0);
 
   enddiff.set_x(0.03);
   enddiff.set_y(0.05);
-  enddiff.set_theta(0.5*M_PI/180.0);
+  enddiff.set_theta(1.0*M_PI/180.0);
 
 
   //调整到起点,朝向与当前朝向一致
@@ -315,7 +384,7 @@ bool CreateNavCmd(std::vector<int> nodes,NavMessage::NavCmd& cmd)
   horize_limit.set_min(0.05);
   horize_limit.set_max(0.2);
   angular_limit.set_min(1);
-  angular_limit.set_max(10);
+  angular_limit.set_max(30);
 
   NavMessage::SpeedLimit mpc_x_limit,mpc_angular_limit;
   mpc_x_limit.set_min(0.05);

+ 896 - 0
map.pb.cc

@@ -0,0 +1,896 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: map.proto
+
+#include "map.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+extern PROTOBUF_INTERNAL_EXPORT_map_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Edge_map_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_map_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Node_map_2eproto;
+namespace MapMessage {
+class NodeDefaultTypeInternal {
+ public:
+  ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<Node> _instance;
+} _Node_default_instance_;
+class EdgeDefaultTypeInternal {
+ public:
+  ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<Edge> _instance;
+} _Edge_default_instance_;
+class MapDefaultTypeInternal {
+ public:
+  ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<Map> _instance;
+} _Map_default_instance_;
+}  // namespace MapMessage
+static void InitDefaultsscc_info_Edge_map_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::MapMessage::_Edge_default_instance_;
+    new (ptr) ::MapMessage::Edge();
+    ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::MapMessage::Edge::InitAsDefaultInstance();
+}
+
+::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Edge_map_2eproto =
+    {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_Edge_map_2eproto}, {}};
+
+static void InitDefaultsscc_info_Map_map_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::MapMessage::_Map_default_instance_;
+    new (ptr) ::MapMessage::Map();
+    ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::MapMessage::Map::InitAsDefaultInstance();
+}
+
+::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_Map_map_2eproto =
+    {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 2, 0, InitDefaultsscc_info_Map_map_2eproto}, {
+      &scc_info_Node_map_2eproto.base,
+      &scc_info_Edge_map_2eproto.base,}};
+
+static void InitDefaultsscc_info_Node_map_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::MapMessage::_Node_default_instance_;
+    new (ptr) ::MapMessage::Node();
+    ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::MapMessage::Node::InitAsDefaultInstance();
+}
+
+::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Node_map_2eproto =
+    {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_Node_map_2eproto}, {}};
+
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_map_2eproto[3];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_map_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_map_2eproto = nullptr;
+
+const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_map_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Node, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Node, id_),
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Node, x_),
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Node, y_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Edge, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Edge, id1_),
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Edge, id2_),
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Edge, directed_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Map, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Map, nodes_),
+  PROTOBUF_FIELD_OFFSET(::MapMessage::Map, edges_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  { 0, -1, sizeof(::MapMessage::Node)},
+  { 8, -1, sizeof(::MapMessage::Edge)},
+  { 16, -1, sizeof(::MapMessage::Map)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::MapMessage::_Node_default_instance_),
+  reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::MapMessage::_Edge_default_instance_),
+  reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::MapMessage::_Map_default_instance_),
+};
+
+const char descriptor_table_protodef_map_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+  "\n\tmap.proto\022\nMapMessage\"(\n\004Node\022\n\n\002id\030\001 "
+  "\001(\005\022\t\n\001x\030\002 \001(\002\022\t\n\001y\030\003 \001(\002\"2\n\004Edge\022\013\n\003id1"
+  "\030\001 \001(\005\022\013\n\003id2\030\002 \001(\005\022\020\n\010directed\030\003 \001(\010\"G\n"
+  "\003Map\022\037\n\005nodes\030\001 \003(\0132\020.MapMessage.Node\022\037\n"
+  "\005edges\030\002 \003(\0132\020.MapMessage.Edgeb\006proto3"
+  ;
+static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_map_2eproto_deps[1] = {
+};
+static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_map_2eproto_sccs[3] = {
+  &scc_info_Edge_map_2eproto.base,
+  &scc_info_Map_map_2eproto.base,
+  &scc_info_Node_map_2eproto.base,
+};
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_map_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_map_2eproto = {
+  false, false, descriptor_table_protodef_map_2eproto, "map.proto", 198,
+  &descriptor_table_map_2eproto_once, descriptor_table_map_2eproto_sccs, descriptor_table_map_2eproto_deps, 3, 0,
+  schemas, file_default_instances, TableStruct_map_2eproto::offsets,
+  file_level_metadata_map_2eproto, 3, file_level_enum_descriptors_map_2eproto, file_level_service_descriptors_map_2eproto,
+};
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_map_2eproto = (static_cast<void>(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_map_2eproto)), true);
+namespace MapMessage {
+
+// ===================================================================
+
+void Node::InitAsDefaultInstance() {
+}
+class Node::_Internal {
+ public:
+};
+
+Node::Node(::PROTOBUF_NAMESPACE_ID::Arena* arena)
+  : ::PROTOBUF_NAMESPACE_ID::Message(arena) {
+  SharedCtor();
+  RegisterArenaDtor(arena);
+  // @@protoc_insertion_point(arena_constructor:MapMessage.Node)
+}
+Node::Node(const Node& from)
+  : ::PROTOBUF_NAMESPACE_ID::Message() {
+  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+  ::memcpy(&id_, &from.id_,
+    static_cast<size_t>(reinterpret_cast<char*>(&y_) -
+    reinterpret_cast<char*>(&id_)) + sizeof(y_));
+  // @@protoc_insertion_point(copy_constructor:MapMessage.Node)
+}
+
+void Node::SharedCtor() {
+  ::memset(&id_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&y_) -
+      reinterpret_cast<char*>(&id_)) + sizeof(y_));
+}
+
+Node::~Node() {
+  // @@protoc_insertion_point(destructor:MapMessage.Node)
+  SharedDtor();
+  _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+void Node::SharedDtor() {
+  GOOGLE_DCHECK(GetArena() == nullptr);
+}
+
+void Node::ArenaDtor(void* object) {
+  Node* _this = reinterpret_cast< Node* >(object);
+  (void)_this;
+}
+void Node::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Node::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Node& Node::default_instance() {
+  ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_Node_map_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Node::Clear() {
+// @@protoc_insertion_point(message_clear_start:MapMessage.Node)
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  ::memset(&id_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&y_) -
+      reinterpret_cast<char*>(&id_)) + sizeof(y_));
+  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Node::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+  ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena;
+  while (!ctx->Done(&ptr)) {
+    ::PROTOBUF_NAMESPACE_ID::uint32 tag;
+    ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+    CHK_(ptr);
+    switch (tag >> 3) {
+      // int32 id = 1;
+      case 1:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) {
+          id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+          CHK_(ptr);
+        } else goto handle_unusual;
+        continue;
+      // float x = 2;
+      case 2:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 21)) {
+          x_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          ptr += sizeof(float);
+        } else goto handle_unusual;
+        continue;
+      // float y = 3;
+      case 3:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 29)) {
+          y_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+          ptr += sizeof(float);
+        } else goto handle_unusual;
+        continue;
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->SetLastTag(tag);
+          goto success;
+        }
+        ptr = UnknownFieldParse(tag,
+            _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+            ptr, ctx);
+        CHK_(ptr != nullptr);
+        continue;
+      }
+    }  // switch
+  }  // while
+success:
+  return ptr;
+failure:
+  ptr = nullptr;
+  goto success;
+#undef CHK_
+}
+
+::PROTOBUF_NAMESPACE_ID::uint8* Node::_InternalSerialize(
+    ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+  // @@protoc_insertion_point(serialize_to_array_start:MapMessage.Node)
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // int32 id = 1;
+  if (this->id() != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_id(), target);
+  }
+
+  // float x = 2;
+  if (!(this->x() <= 0 && this->x() >= 0)) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFloatToArray(2, this->_internal_x(), target);
+  }
+
+  // float y = 3;
+  if (!(this->y() <= 0 && this->y() >= 0)) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFloatToArray(3, this->_internal_y(), target);
+  }
+
+  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:MapMessage.Node)
+  return target;
+}
+
+size_t Node::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:MapMessage.Node)
+  size_t total_size = 0;
+
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // int32 id = 1;
+  if (this->id() != 0) {
+    total_size += 1 +
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size(
+        this->_internal_id());
+  }
+
+  // float x = 2;
+  if (!(this->x() <= 0 && this->x() >= 0)) {
+    total_size += 1 + 4;
+  }
+
+  // float y = 3;
+  if (!(this->y() <= 0 && this->y() >= 0)) {
+    total_size += 1 + 4;
+  }
+
+  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+    return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize(
+        _internal_metadata_, total_size, &_cached_size_);
+  }
+  int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Node::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:MapMessage.Node)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Node* source =
+      ::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Node>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:MapMessage.Node)
+    ::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:MapMessage.Node)
+    MergeFrom(*source);
+  }
+}
+
+void Node::MergeFrom(const Node& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:MapMessage.Node)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.id() != 0) {
+    _internal_set_id(from._internal_id());
+  }
+  if (!(from.x() <= 0 && from.x() >= 0)) {
+    _internal_set_x(from._internal_x());
+  }
+  if (!(from.y() <= 0 && from.y() >= 0)) {
+    _internal_set_y(from._internal_y());
+  }
+}
+
+void Node::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:MapMessage.Node)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Node::CopyFrom(const Node& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:MapMessage.Node)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Node::IsInitialized() const {
+  return true;
+}
+
+void Node::InternalSwap(Node* other) {
+  using std::swap;
+  _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_);
+  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+      PROTOBUF_FIELD_OFFSET(Node, y_)
+      + sizeof(Node::y_)
+      - PROTOBUF_FIELD_OFFSET(Node, id_)>(
+          reinterpret_cast<char*>(&id_),
+          reinterpret_cast<char*>(&other->id_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Node::GetMetadata() const {
+  return GetMetadataStatic();
+}
+
+
+// ===================================================================
+
+void Edge::InitAsDefaultInstance() {
+}
+class Edge::_Internal {
+ public:
+};
+
+Edge::Edge(::PROTOBUF_NAMESPACE_ID::Arena* arena)
+  : ::PROTOBUF_NAMESPACE_ID::Message(arena) {
+  SharedCtor();
+  RegisterArenaDtor(arena);
+  // @@protoc_insertion_point(arena_constructor:MapMessage.Edge)
+}
+Edge::Edge(const Edge& from)
+  : ::PROTOBUF_NAMESPACE_ID::Message() {
+  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+  ::memcpy(&id1_, &from.id1_,
+    static_cast<size_t>(reinterpret_cast<char*>(&directed_) -
+    reinterpret_cast<char*>(&id1_)) + sizeof(directed_));
+  // @@protoc_insertion_point(copy_constructor:MapMessage.Edge)
+}
+
+void Edge::SharedCtor() {
+  ::memset(&id1_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&directed_) -
+      reinterpret_cast<char*>(&id1_)) + sizeof(directed_));
+}
+
+Edge::~Edge() {
+  // @@protoc_insertion_point(destructor:MapMessage.Edge)
+  SharedDtor();
+  _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+void Edge::SharedDtor() {
+  GOOGLE_DCHECK(GetArena() == nullptr);
+}
+
+void Edge::ArenaDtor(void* object) {
+  Edge* _this = reinterpret_cast< Edge* >(object);
+  (void)_this;
+}
+void Edge::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Edge::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Edge& Edge::default_instance() {
+  ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_Edge_map_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Edge::Clear() {
+// @@protoc_insertion_point(message_clear_start:MapMessage.Edge)
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  ::memset(&id1_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&directed_) -
+      reinterpret_cast<char*>(&id1_)) + sizeof(directed_));
+  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Edge::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+  ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena;
+  while (!ctx->Done(&ptr)) {
+    ::PROTOBUF_NAMESPACE_ID::uint32 tag;
+    ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+    CHK_(ptr);
+    switch (tag >> 3) {
+      // int32 id1 = 1;
+      case 1:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) {
+          id1_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+          CHK_(ptr);
+        } else goto handle_unusual;
+        continue;
+      // int32 id2 = 2;
+      case 2:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) {
+          id2_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+          CHK_(ptr);
+        } else goto handle_unusual;
+        continue;
+      // bool directed = 3;
+      case 3:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) {
+          directed_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+          CHK_(ptr);
+        } else goto handle_unusual;
+        continue;
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->SetLastTag(tag);
+          goto success;
+        }
+        ptr = UnknownFieldParse(tag,
+            _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+            ptr, ctx);
+        CHK_(ptr != nullptr);
+        continue;
+      }
+    }  // switch
+  }  // while
+success:
+  return ptr;
+failure:
+  ptr = nullptr;
+  goto success;
+#undef CHK_
+}
+
+::PROTOBUF_NAMESPACE_ID::uint8* Edge::_InternalSerialize(
+    ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+  // @@protoc_insertion_point(serialize_to_array_start:MapMessage.Edge)
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // int32 id1 = 1;
+  if (this->id1() != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_id1(), target);
+  }
+
+  // int32 id2 = 2;
+  if (this->id2() != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_id2(), target);
+  }
+
+  // bool directed = 3;
+  if (this->directed() != 0) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_directed(), target);
+  }
+
+  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:MapMessage.Edge)
+  return target;
+}
+
+size_t Edge::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:MapMessage.Edge)
+  size_t total_size = 0;
+
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // int32 id1 = 1;
+  if (this->id1() != 0) {
+    total_size += 1 +
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size(
+        this->_internal_id1());
+  }
+
+  // int32 id2 = 2;
+  if (this->id2() != 0) {
+    total_size += 1 +
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size(
+        this->_internal_id2());
+  }
+
+  // bool directed = 3;
+  if (this->directed() != 0) {
+    total_size += 1 + 1;
+  }
+
+  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+    return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize(
+        _internal_metadata_, total_size, &_cached_size_);
+  }
+  int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Edge::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:MapMessage.Edge)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Edge* source =
+      ::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Edge>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:MapMessage.Edge)
+    ::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:MapMessage.Edge)
+    MergeFrom(*source);
+  }
+}
+
+void Edge::MergeFrom(const Edge& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:MapMessage.Edge)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.id1() != 0) {
+    _internal_set_id1(from._internal_id1());
+  }
+  if (from.id2() != 0) {
+    _internal_set_id2(from._internal_id2());
+  }
+  if (from.directed() != 0) {
+    _internal_set_directed(from._internal_directed());
+  }
+}
+
+void Edge::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:MapMessage.Edge)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Edge::CopyFrom(const Edge& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:MapMessage.Edge)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Edge::IsInitialized() const {
+  return true;
+}
+
+void Edge::InternalSwap(Edge* other) {
+  using std::swap;
+  _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_);
+  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+      PROTOBUF_FIELD_OFFSET(Edge, directed_)
+      + sizeof(Edge::directed_)
+      - PROTOBUF_FIELD_OFFSET(Edge, id1_)>(
+          reinterpret_cast<char*>(&id1_),
+          reinterpret_cast<char*>(&other->id1_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Edge::GetMetadata() const {
+  return GetMetadataStatic();
+}
+
+
+// ===================================================================
+
+void Map::InitAsDefaultInstance() {
+}
+class Map::_Internal {
+ public:
+};
+
+Map::Map(::PROTOBUF_NAMESPACE_ID::Arena* arena)
+  : ::PROTOBUF_NAMESPACE_ID::Message(arena),
+  nodes_(arena),
+  edges_(arena) {
+  SharedCtor();
+  RegisterArenaDtor(arena);
+  // @@protoc_insertion_point(arena_constructor:MapMessage.Map)
+}
+Map::Map(const Map& from)
+  : ::PROTOBUF_NAMESPACE_ID::Message(),
+      nodes_(from.nodes_),
+      edges_(from.edges_) {
+  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+  // @@protoc_insertion_point(copy_constructor:MapMessage.Map)
+}
+
+void Map::SharedCtor() {
+  ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Map_map_2eproto.base);
+}
+
+Map::~Map() {
+  // @@protoc_insertion_point(destructor:MapMessage.Map)
+  SharedDtor();
+  _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+void Map::SharedDtor() {
+  GOOGLE_DCHECK(GetArena() == nullptr);
+}
+
+void Map::ArenaDtor(void* object) {
+  Map* _this = reinterpret_cast< Map* >(object);
+  (void)_this;
+}
+void Map::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Map::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Map& Map::default_instance() {
+  ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_Map_map_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Map::Clear() {
+// @@protoc_insertion_point(message_clear_start:MapMessage.Map)
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  nodes_.Clear();
+  edges_.Clear();
+  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Map::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+  ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); (void)arena;
+  while (!ctx->Done(&ptr)) {
+    ::PROTOBUF_NAMESPACE_ID::uint32 tag;
+    ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+    CHK_(ptr);
+    switch (tag >> 3) {
+      // repeated .MapMessage.Node nodes = 1;
+      case 1:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) {
+          ptr -= 1;
+          do {
+            ptr += 1;
+            ptr = ctx->ParseMessage(_internal_add_nodes(), ptr);
+            CHK_(ptr);
+            if (!ctx->DataAvailable(ptr)) break;
+          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
+        } else goto handle_unusual;
+        continue;
+      // repeated .MapMessage.Edge edges = 2;
+      case 2:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) {
+          ptr -= 1;
+          do {
+            ptr += 1;
+            ptr = ctx->ParseMessage(_internal_add_edges(), ptr);
+            CHK_(ptr);
+            if (!ctx->DataAvailable(ptr)) break;
+          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
+        } else goto handle_unusual;
+        continue;
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->SetLastTag(tag);
+          goto success;
+        }
+        ptr = UnknownFieldParse(tag,
+            _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+            ptr, ctx);
+        CHK_(ptr != nullptr);
+        continue;
+      }
+    }  // switch
+  }  // while
+success:
+  return ptr;
+failure:
+  ptr = nullptr;
+  goto success;
+#undef CHK_
+}
+
+::PROTOBUF_NAMESPACE_ID::uint8* Map::_InternalSerialize(
+    ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+  // @@protoc_insertion_point(serialize_to_array_start:MapMessage.Map)
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .MapMessage.Node nodes = 1;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->_internal_nodes_size()); i < n; i++) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+      InternalWriteMessage(1, this->_internal_nodes(i), target, stream);
+  }
+
+  // repeated .MapMessage.Edge edges = 2;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->_internal_edges_size()); i < n; i++) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+      InternalWriteMessage(2, this->_internal_edges(i), target, stream);
+  }
+
+  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:MapMessage.Map)
+  return target;
+}
+
+size_t Map::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:MapMessage.Map)
+  size_t total_size = 0;
+
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .MapMessage.Node nodes = 1;
+  total_size += 1UL * this->_internal_nodes_size();
+  for (const auto& msg : this->nodes_) {
+    total_size +=
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+  }
+
+  // repeated .MapMessage.Edge edges = 2;
+  total_size += 1UL * this->_internal_edges_size();
+  for (const auto& msg : this->edges_) {
+    total_size +=
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+  }
+
+  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+    return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize(
+        _internal_metadata_, total_size, &_cached_size_);
+  }
+  int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Map::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:MapMessage.Map)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Map* source =
+      ::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Map>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:MapMessage.Map)
+    ::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:MapMessage.Map)
+    MergeFrom(*source);
+  }
+}
+
+void Map::MergeFrom(const Map& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:MapMessage.Map)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  nodes_.MergeFrom(from.nodes_);
+  edges_.MergeFrom(from.edges_);
+}
+
+void Map::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:MapMessage.Map)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Map::CopyFrom(const Map& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:MapMessage.Map)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Map::IsInitialized() const {
+  return true;
+}
+
+void Map::InternalSwap(Map* other) {
+  using std::swap;
+  _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_);
+  nodes_.InternalSwap(&other->nodes_);
+  edges_.InternalSwap(&other->edges_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Map::GetMetadata() const {
+  return GetMetadataStatic();
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace MapMessage
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::MapMessage::Node* Arena::CreateMaybeMessage< ::MapMessage::Node >(Arena* arena) {
+  return Arena::CreateMessageInternal< ::MapMessage::Node >(arena);
+}
+template<> PROTOBUF_NOINLINE ::MapMessage::Edge* Arena::CreateMaybeMessage< ::MapMessage::Edge >(Arena* arena) {
+  return Arena::CreateMessageInternal< ::MapMessage::Edge >(arena);
+}
+template<> PROTOBUF_NOINLINE ::MapMessage::Map* Arena::CreateMaybeMessage< ::MapMessage::Map >(Arena* arena) {
+  return Arena::CreateMessageInternal< ::MapMessage::Map >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>

+ 791 - 0
map.pb.h

@@ -0,0 +1,791 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: map.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_map_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_map_2eproto
+
+#include <limits>
+#include <string>
+
+#include <google/protobuf/port_def.inc>
+#if PROTOBUF_VERSION < 3013000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3013000 < PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/port_undef.inc>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/inlined_string_field.h>
+#include <google/protobuf/metadata_lite.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
+#include <google/protobuf/extension_set.h>  // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_map_2eproto
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+}  // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_map_2eproto {
+  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[3]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+  static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+  static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
+};
+extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_map_2eproto;
+namespace MapMessage {
+class Edge;
+class EdgeDefaultTypeInternal;
+extern EdgeDefaultTypeInternal _Edge_default_instance_;
+class Map;
+class MapDefaultTypeInternal;
+extern MapDefaultTypeInternal _Map_default_instance_;
+class Node;
+class NodeDefaultTypeInternal;
+extern NodeDefaultTypeInternal _Node_default_instance_;
+}  // namespace MapMessage
+PROTOBUF_NAMESPACE_OPEN
+template<> ::MapMessage::Edge* Arena::CreateMaybeMessage<::MapMessage::Edge>(Arena*);
+template<> ::MapMessage::Map* Arena::CreateMaybeMessage<::MapMessage::Map>(Arena*);
+template<> ::MapMessage::Node* Arena::CreateMaybeMessage<::MapMessage::Node>(Arena*);
+PROTOBUF_NAMESPACE_CLOSE
+namespace MapMessage {
+
+// ===================================================================
+
+class Node PROTOBUF_FINAL :
+    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:MapMessage.Node) */ {
+ public:
+  inline Node() : Node(nullptr) {}
+  virtual ~Node();
+
+  Node(const Node& from);
+  Node(Node&& from) noexcept
+    : Node() {
+    *this = ::std::move(from);
+  }
+
+  inline Node& operator=(const Node& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  inline Node& operator=(Node&& from) noexcept {
+    if (GetArena() == from.GetArena()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+
+  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+    return GetDescriptor();
+  }
+  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+    return GetMetadataStatic().descriptor;
+  }
+  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+    return GetMetadataStatic().reflection;
+  }
+  static const Node& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Node* internal_default_instance() {
+    return reinterpret_cast<const Node*>(
+               &_Node_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    0;
+
+  friend void swap(Node& a, Node& b) {
+    a.Swap(&b);
+  }
+  inline void Swap(Node* other) {
+    if (other == this) return;
+    if (GetArena() == other->GetArena()) {
+      InternalSwap(other);
+    } else {
+      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+    }
+  }
+  void UnsafeArenaSwap(Node* other) {
+    if (other == this) return;
+    GOOGLE_DCHECK(GetArena() == other->GetArena());
+    InternalSwap(other);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Node* New() const final {
+    return CreateMaybeMessage<Node>(nullptr);
+  }
+
+  Node* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+    return CreateMaybeMessage<Node>(arena);
+  }
+  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
+  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
+  void CopyFrom(const Node& from);
+  void MergeFrom(const Node& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
+      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  inline void SharedCtor();
+  inline void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Node* other);
+  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+    return "MapMessage.Node";
+  }
+  protected:
+  explicit Node(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+  private:
+  static void ArenaDtor(void* object);
+  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+  public:
+
+  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+  private:
+  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
+    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_map_2eproto);
+    return ::descriptor_table_map_2eproto.file_level_metadata[kIndexInFileMessages];
+  }
+
+  public:
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  enum : int {
+    kIdFieldNumber = 1,
+    kXFieldNumber = 2,
+    kYFieldNumber = 3,
+  };
+  // int32 id = 1;
+  void clear_id();
+  ::PROTOBUF_NAMESPACE_ID::int32 id() const;
+  void set_id(::PROTOBUF_NAMESPACE_ID::int32 value);
+  private:
+  ::PROTOBUF_NAMESPACE_ID::int32 _internal_id() const;
+  void _internal_set_id(::PROTOBUF_NAMESPACE_ID::int32 value);
+  public:
+
+  // float x = 2;
+  void clear_x();
+  float x() const;
+  void set_x(float value);
+  private:
+  float _internal_x() const;
+  void _internal_set_x(float value);
+  public:
+
+  // float y = 3;
+  void clear_y();
+  float y() const;
+  void set_y(float value);
+  private:
+  float _internal_y() const;
+  void _internal_set_y(float value);
+  public:
+
+  // @@protoc_insertion_point(class_scope:MapMessage.Node)
+ private:
+  class _Internal;
+
+  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+  typedef void InternalArenaConstructable_;
+  typedef void DestructorSkippable_;
+  ::PROTOBUF_NAMESPACE_ID::int32 id_;
+  float x_;
+  float y_;
+  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_map_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Edge PROTOBUF_FINAL :
+    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:MapMessage.Edge) */ {
+ public:
+  inline Edge() : Edge(nullptr) {}
+  virtual ~Edge();
+
+  Edge(const Edge& from);
+  Edge(Edge&& from) noexcept
+    : Edge() {
+    *this = ::std::move(from);
+  }
+
+  inline Edge& operator=(const Edge& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  inline Edge& operator=(Edge&& from) noexcept {
+    if (GetArena() == from.GetArena()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+
+  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+    return GetDescriptor();
+  }
+  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+    return GetMetadataStatic().descriptor;
+  }
+  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+    return GetMetadataStatic().reflection;
+  }
+  static const Edge& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Edge* internal_default_instance() {
+    return reinterpret_cast<const Edge*>(
+               &_Edge_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    1;
+
+  friend void swap(Edge& a, Edge& b) {
+    a.Swap(&b);
+  }
+  inline void Swap(Edge* other) {
+    if (other == this) return;
+    if (GetArena() == other->GetArena()) {
+      InternalSwap(other);
+    } else {
+      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+    }
+  }
+  void UnsafeArenaSwap(Edge* other) {
+    if (other == this) return;
+    GOOGLE_DCHECK(GetArena() == other->GetArena());
+    InternalSwap(other);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Edge* New() const final {
+    return CreateMaybeMessage<Edge>(nullptr);
+  }
+
+  Edge* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+    return CreateMaybeMessage<Edge>(arena);
+  }
+  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
+  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
+  void CopyFrom(const Edge& from);
+  void MergeFrom(const Edge& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
+      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  inline void SharedCtor();
+  inline void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Edge* other);
+  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+    return "MapMessage.Edge";
+  }
+  protected:
+  explicit Edge(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+  private:
+  static void ArenaDtor(void* object);
+  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+  public:
+
+  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+  private:
+  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
+    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_map_2eproto);
+    return ::descriptor_table_map_2eproto.file_level_metadata[kIndexInFileMessages];
+  }
+
+  public:
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  enum : int {
+    kId1FieldNumber = 1,
+    kId2FieldNumber = 2,
+    kDirectedFieldNumber = 3,
+  };
+  // int32 id1 = 1;
+  void clear_id1();
+  ::PROTOBUF_NAMESPACE_ID::int32 id1() const;
+  void set_id1(::PROTOBUF_NAMESPACE_ID::int32 value);
+  private:
+  ::PROTOBUF_NAMESPACE_ID::int32 _internal_id1() const;
+  void _internal_set_id1(::PROTOBUF_NAMESPACE_ID::int32 value);
+  public:
+
+  // int32 id2 = 2;
+  void clear_id2();
+  ::PROTOBUF_NAMESPACE_ID::int32 id2() const;
+  void set_id2(::PROTOBUF_NAMESPACE_ID::int32 value);
+  private:
+  ::PROTOBUF_NAMESPACE_ID::int32 _internal_id2() const;
+  void _internal_set_id2(::PROTOBUF_NAMESPACE_ID::int32 value);
+  public:
+
+  // bool directed = 3;
+  void clear_directed();
+  bool directed() const;
+  void set_directed(bool value);
+  private:
+  bool _internal_directed() const;
+  void _internal_set_directed(bool value);
+  public:
+
+  // @@protoc_insertion_point(class_scope:MapMessage.Edge)
+ private:
+  class _Internal;
+
+  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+  typedef void InternalArenaConstructable_;
+  typedef void DestructorSkippable_;
+  ::PROTOBUF_NAMESPACE_ID::int32 id1_;
+  ::PROTOBUF_NAMESPACE_ID::int32 id2_;
+  bool directed_;
+  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_map_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Map PROTOBUF_FINAL :
+    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:MapMessage.Map) */ {
+ public:
+  inline Map() : Map(nullptr) {}
+  virtual ~Map();
+
+  Map(const Map& from);
+  Map(Map&& from) noexcept
+    : Map() {
+    *this = ::std::move(from);
+  }
+
+  inline Map& operator=(const Map& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  inline Map& operator=(Map&& from) noexcept {
+    if (GetArena() == from.GetArena()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+
+  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+    return GetDescriptor();
+  }
+  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+    return GetMetadataStatic().descriptor;
+  }
+  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+    return GetMetadataStatic().reflection;
+  }
+  static const Map& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Map* internal_default_instance() {
+    return reinterpret_cast<const Map*>(
+               &_Map_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    2;
+
+  friend void swap(Map& a, Map& b) {
+    a.Swap(&b);
+  }
+  inline void Swap(Map* other) {
+    if (other == this) return;
+    if (GetArena() == other->GetArena()) {
+      InternalSwap(other);
+    } else {
+      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+    }
+  }
+  void UnsafeArenaSwap(Map* other) {
+    if (other == this) return;
+    GOOGLE_DCHECK(GetArena() == other->GetArena());
+    InternalSwap(other);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Map* New() const final {
+    return CreateMaybeMessage<Map>(nullptr);
+  }
+
+  Map* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+    return CreateMaybeMessage<Map>(arena);
+  }
+  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
+  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
+  void CopyFrom(const Map& from);
+  void MergeFrom(const Map& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
+      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  inline void SharedCtor();
+  inline void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Map* other);
+  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+    return "MapMessage.Map";
+  }
+  protected:
+  explicit Map(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+  private:
+  static void ArenaDtor(void* object);
+  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+  public:
+
+  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+  private:
+  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
+    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_map_2eproto);
+    return ::descriptor_table_map_2eproto.file_level_metadata[kIndexInFileMessages];
+  }
+
+  public:
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  enum : int {
+    kNodesFieldNumber = 1,
+    kEdgesFieldNumber = 2,
+  };
+  // repeated .MapMessage.Node nodes = 1;
+  int nodes_size() const;
+  private:
+  int _internal_nodes_size() const;
+  public:
+  void clear_nodes();
+  ::MapMessage::Node* mutable_nodes(int index);
+  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Node >*
+      mutable_nodes();
+  private:
+  const ::MapMessage::Node& _internal_nodes(int index) const;
+  ::MapMessage::Node* _internal_add_nodes();
+  public:
+  const ::MapMessage::Node& nodes(int index) const;
+  ::MapMessage::Node* add_nodes();
+  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Node >&
+      nodes() const;
+
+  // repeated .MapMessage.Edge edges = 2;
+  int edges_size() const;
+  private:
+  int _internal_edges_size() const;
+  public:
+  void clear_edges();
+  ::MapMessage::Edge* mutable_edges(int index);
+  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Edge >*
+      mutable_edges();
+  private:
+  const ::MapMessage::Edge& _internal_edges(int index) const;
+  ::MapMessage::Edge* _internal_add_edges();
+  public:
+  const ::MapMessage::Edge& edges(int index) const;
+  ::MapMessage::Edge* add_edges();
+  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Edge >&
+      edges() const;
+
+  // @@protoc_insertion_point(class_scope:MapMessage.Map)
+ private:
+  class _Internal;
+
+  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+  typedef void InternalArenaConstructable_;
+  typedef void DestructorSkippable_;
+  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Node > nodes_;
+  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Edge > edges_;
+  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_map_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif  // __GNUC__
+// Node
+
+// int32 id = 1;
+inline void Node::clear_id() {
+  id_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::int32 Node::_internal_id() const {
+  return id_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::int32 Node::id() const {
+  // @@protoc_insertion_point(field_get:MapMessage.Node.id)
+  return _internal_id();
+}
+inline void Node::_internal_set_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
+  
+  id_ = value;
+}
+inline void Node::set_id(::PROTOBUF_NAMESPACE_ID::int32 value) {
+  _internal_set_id(value);
+  // @@protoc_insertion_point(field_set:MapMessage.Node.id)
+}
+
+// float x = 2;
+inline void Node::clear_x() {
+  x_ = 0;
+}
+inline float Node::_internal_x() const {
+  return x_;
+}
+inline float Node::x() const {
+  // @@protoc_insertion_point(field_get:MapMessage.Node.x)
+  return _internal_x();
+}
+inline void Node::_internal_set_x(float value) {
+  
+  x_ = value;
+}
+inline void Node::set_x(float value) {
+  _internal_set_x(value);
+  // @@protoc_insertion_point(field_set:MapMessage.Node.x)
+}
+
+// float y = 3;
+inline void Node::clear_y() {
+  y_ = 0;
+}
+inline float Node::_internal_y() const {
+  return y_;
+}
+inline float Node::y() const {
+  // @@protoc_insertion_point(field_get:MapMessage.Node.y)
+  return _internal_y();
+}
+inline void Node::_internal_set_y(float value) {
+  
+  y_ = value;
+}
+inline void Node::set_y(float value) {
+  _internal_set_y(value);
+  // @@protoc_insertion_point(field_set:MapMessage.Node.y)
+}
+
+// -------------------------------------------------------------------
+
+// Edge
+
+// int32 id1 = 1;
+inline void Edge::clear_id1() {
+  id1_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::int32 Edge::_internal_id1() const {
+  return id1_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::int32 Edge::id1() const {
+  // @@protoc_insertion_point(field_get:MapMessage.Edge.id1)
+  return _internal_id1();
+}
+inline void Edge::_internal_set_id1(::PROTOBUF_NAMESPACE_ID::int32 value) {
+  
+  id1_ = value;
+}
+inline void Edge::set_id1(::PROTOBUF_NAMESPACE_ID::int32 value) {
+  _internal_set_id1(value);
+  // @@protoc_insertion_point(field_set:MapMessage.Edge.id1)
+}
+
+// int32 id2 = 2;
+inline void Edge::clear_id2() {
+  id2_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::int32 Edge::_internal_id2() const {
+  return id2_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::int32 Edge::id2() const {
+  // @@protoc_insertion_point(field_get:MapMessage.Edge.id2)
+  return _internal_id2();
+}
+inline void Edge::_internal_set_id2(::PROTOBUF_NAMESPACE_ID::int32 value) {
+  
+  id2_ = value;
+}
+inline void Edge::set_id2(::PROTOBUF_NAMESPACE_ID::int32 value) {
+  _internal_set_id2(value);
+  // @@protoc_insertion_point(field_set:MapMessage.Edge.id2)
+}
+
+// bool directed = 3;
+inline void Edge::clear_directed() {
+  directed_ = false;
+}
+inline bool Edge::_internal_directed() const {
+  return directed_;
+}
+inline bool Edge::directed() const {
+  // @@protoc_insertion_point(field_get:MapMessage.Edge.directed)
+  return _internal_directed();
+}
+inline void Edge::_internal_set_directed(bool value) {
+  
+  directed_ = value;
+}
+inline void Edge::set_directed(bool value) {
+  _internal_set_directed(value);
+  // @@protoc_insertion_point(field_set:MapMessage.Edge.directed)
+}
+
+// -------------------------------------------------------------------
+
+// Map
+
+// repeated .MapMessage.Node nodes = 1;
+inline int Map::_internal_nodes_size() const {
+  return nodes_.size();
+}
+inline int Map::nodes_size() const {
+  return _internal_nodes_size();
+}
+inline void Map::clear_nodes() {
+  nodes_.Clear();
+}
+inline ::MapMessage::Node* Map::mutable_nodes(int index) {
+  // @@protoc_insertion_point(field_mutable:MapMessage.Map.nodes)
+  return nodes_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Node >*
+Map::mutable_nodes() {
+  // @@protoc_insertion_point(field_mutable_list:MapMessage.Map.nodes)
+  return &nodes_;
+}
+inline const ::MapMessage::Node& Map::_internal_nodes(int index) const {
+  return nodes_.Get(index);
+}
+inline const ::MapMessage::Node& Map::nodes(int index) const {
+  // @@protoc_insertion_point(field_get:MapMessage.Map.nodes)
+  return _internal_nodes(index);
+}
+inline ::MapMessage::Node* Map::_internal_add_nodes() {
+  return nodes_.Add();
+}
+inline ::MapMessage::Node* Map::add_nodes() {
+  // @@protoc_insertion_point(field_add:MapMessage.Map.nodes)
+  return _internal_add_nodes();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Node >&
+Map::nodes() const {
+  // @@protoc_insertion_point(field_list:MapMessage.Map.nodes)
+  return nodes_;
+}
+
+// repeated .MapMessage.Edge edges = 2;
+inline int Map::_internal_edges_size() const {
+  return edges_.size();
+}
+inline int Map::edges_size() const {
+  return _internal_edges_size();
+}
+inline void Map::clear_edges() {
+  edges_.Clear();
+}
+inline ::MapMessage::Edge* Map::mutable_edges(int index) {
+  // @@protoc_insertion_point(field_mutable:MapMessage.Map.edges)
+  return edges_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Edge >*
+Map::mutable_edges() {
+  // @@protoc_insertion_point(field_mutable_list:MapMessage.Map.edges)
+  return &edges_;
+}
+inline const ::MapMessage::Edge& Map::_internal_edges(int index) const {
+  return edges_.Get(index);
+}
+inline const ::MapMessage::Edge& Map::edges(int index) const {
+  // @@protoc_insertion_point(field_get:MapMessage.Map.edges)
+  return _internal_edges(index);
+}
+inline ::MapMessage::Edge* Map::_internal_add_edges() {
+  return edges_.Add();
+}
+inline ::MapMessage::Edge* Map::add_edges() {
+  // @@protoc_insertion_point(field_add:MapMessage.Map.edges)
+  return _internal_add_edges();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::MapMessage::Edge >&
+Map::edges() const {
+  // @@protoc_insertion_point(field_list:MapMessage.Map.edges)
+  return edges_;
+}
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic pop
+#endif  // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace MapMessage
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_map_2eproto

+ 20 - 0
map.proto

@@ -0,0 +1,20 @@
+syntax = "proto3";
+package MapMessage;
+message Node {
+  int32 id=1;
+  float x=2;
+  float y=3;
+}
+
+message Edge
+{
+  int32 id1=1;
+  int32 id2=2;
+  bool directed=3; //是否单项
+}
+
+message Map {
+  repeated Node nodes=1;
+  repeated Edge edges=2;
+}
+

+ 23 - 2
pangolinViewer.cpp

@@ -39,6 +39,11 @@ void PangolinViewer::Join()
   }
 }
 
+void PangolinViewer::SetAutoTestNavCallback(AutoTestBtnCallback callback)
+{
+  navigation_AutoBtn_callback_=callback;
+}
+
 void PangolinViewer::SetNavigationCallbacks(StartBtnCallback startBtn,
                                             PauseBtnCallback pauseBtn,
                             StopBtnCallback stopBtn)
@@ -54,6 +59,15 @@ void PangolinViewer::SetCallbacks(ViewerSpinOnceCallback spinOnce,DijkstraBtnCal
   dijkstraBtn_callback_=dijkstra;
 }
 
+void PangolinViewer::ResetPathInfo(int beg,int end,float distance)
+{
+  *beg_Int_=beg;
+  *end_Int_=end;
+  char cost[64]={0};
+  sprintf(cost, "d(%d-%d):%f", beg, end, distance);
+  *distance_string_=cost;
+}
+
 void PangolinViewer::Init()
 {
   pangolin::CreateWindowAndBind("Main", 1280, 760);
@@ -80,8 +94,8 @@ void PangolinViewer::Init()
   rpy_string_=new pangolin::Var<std::string>("ui.rpy_String", "rpy");
   velocity_string_=new pangolin::Var<std::string>("ui.velocity", "");
 
-  beg_Int_=new pangolin::Var<int>("ui.beg", 1, 1, 8);
-  end_Int_=new pangolin::Var<int>("ui.end", 5, 1, 8);
+  beg_Int_=new pangolin::Var<int>("ui.beg", 1, 0, 11);
+  end_Int_=new pangolin::Var<int>("ui.end", 10, 0, 11);
   v_=new pangolin::Var<double>("ui.v", 1.0, -2.0,2.0 );
   a_=new pangolin::Var<double>("ui.a", 1.0, -10.0, 10.0);
   path_string_=new pangolin::Var<std::string>("ui.path", "cost");
@@ -147,6 +161,13 @@ void PangolinViewer::Init()
       navigation_stopBtn_callback_();
   });
 
+  pangolin::Var<std::function<void(void)>> navigation_auto_test("ui.nav_auto_test", [&]()
+  {
+
+      if(navigation_AutoBtn_callback_!= nullptr)
+        navigation_AutoBtn_callback_();
+  });
+
 
 }
 

+ 5 - 0
pangolinViewer.h

@@ -27,6 +27,7 @@ class PangolinViewer
     typedef void(*StartBtnCallback)();
     typedef void(*PauseBtnCallback)();
     typedef void(*StopBtnCallback)();
+    typedef void(*AutoTestBtnCallback)();
     typedef void(*FreqChangedCallback)(int);
     typedef bool(*DijkstraBtnCallback)(int ,int ,float& ,std::vector<int>&);
  public:
@@ -37,9 +38,12 @@ class PangolinViewer
     void SetNavigationCallbacks(StartBtnCallback startBtn,
                                 PauseBtnCallback pauseBtn,
                       StopBtnCallback stopBtn);
+    void SetAutoTestNavCallback(AutoTestBtnCallback callback);
     void ShowRealtimeStatu(Eigen::Matrix4d pose,double velocity,double angular);
     void ShowBrotherStatu(Eigen::Matrix4d pose,double velocity,double angular);
 
+    void ResetPathInfo(int beg,int end,float distance);
+
     void DrawCloud(PointCloud::Ptr cloud,double r,double g,double b,
      double alpha,double psize);
     void DrawDijkastraMap(PathMap& map,std::vector<int> path);
@@ -91,6 +95,7 @@ class PangolinViewer
     StartBtnCallback naviagtion_startBtn_callback_=nullptr;
     PauseBtnCallback naviagtion_pauseBtn_callback_=nullptr;
     StopBtnCallback navigation_stopBtn_callback_= nullptr;
+    AutoTestBtnCallback navigation_AutoBtn_callback_= nullptr;
 
 };